summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/server_https.hpp
blob: e721cbb3e2590d8865769243869c890c9a545362 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// license:MIT
// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
#ifndef SERVER_HTTPS_HPP
#define SERVER_HTTPS_HPP

#include "server_http.hpp"
#include "asio/ssl.hpp"
#include <openssl/ssl.h>
#include <algorithm>

namespace webpp {
	using HTTPS = asio::ssl::stream<asio::ip::tcp::socket>;

	template<>
	class Server<HTTPS> : public ServerBase<HTTPS> {
		std::string session_id_context;
		bool set_session_id_context = false;
	public:
		Server(unsigned short port, size_t thread_pool_size, const std::string& cert_file, const std::string& private_key_file,
			long timeout_request = 5, long timeout_content = 300,
			const std::string& verify_file = std::string()) :
				Server(cert_file, private_key_file, verify_file) {
			 m_config.port=port;
			 m_config.thread_pool_size= thread_pool_size;
			 m_config.timeout_request=timeout_request;
			 m_config.timeout_content=timeout_content;
		 }

		Server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file = std::string()) :
			ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {

			context.use_certificate_chain_file(cert_file);
			context.use_private_key_file(private_key_file, asio::ssl::context::pem);

			if (verify_file.size() > 0) {
				context.load_verify_file(verify_file);
				context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert |
					asio::ssl::verify_client_once);
				set_session_id_context = true;
			}
		}
		void start() override {
			if (set_session_id_context) {
								// Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
					session_id_context = std::to_string(m_config.port) + ':';
				session_id_context.append(m_config.address.rbegin(), m_config.address.rend());
				SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char*>(session_id_context.data()),
					std::min<size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));

			}
			ServerBase::start();
		}

	protected:
		asio::ssl::context context;

		void accept() override {
			//Create new socket for this connection
			//Shared_ptr is used to pass temporary objects to the asynchronous functions
			auto socket = std::make_shared<HTTPS>(*m_io_context, context);

			acceptor->async_accept((*socket).lowest_layer(), [this, socket](const std::error_code& ec) {
				//Immediately start accepting a new connection (if io_context hasn't been stopped)
				if (ec != asio::error::operation_aborted)
					accept();


				if(!ec) {
					asio::ip::tcp::no_delay option(true);
					socket->lowest_layer().set_option(option);

					//Set timeout on the following asio::ssl::stream::async_handshake
					auto timer = get_timeout_timer(socket, m_config.timeout_request);
					socket->async_handshake(asio::ssl::stream_base::server, [this, socket, timer]
							(const std::error_code& ec) {
						if(timer)
							timer->cancel();
						if(!ec)
							read_request_and_content(socket);
						else if(on_error)
							on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
					});
				}
				else if(on_error)
					on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
			});
		}
	};

	class https_server : public Server<HTTPS> {
	public:
		explicit https_server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file = std::string()) : Server<HTTPS>::Server(cert_file, private_key_file, verify_file) {}
	};

}


#endif  /* SERVER_HTTPS_HPP */
897 898 899 900 901 902 903 904 905 906 907 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 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
/***************************************************************************
Namco NA-1 / NA-2 System

NA-1 Games:
-   Bakuretsu Quiz Ma-Q Dai Bouken
-   F/A / Fighter & Attacker
-   Super World Court (C354, C357)
-   Exvania (C350, C354)
-   Cosmo Gang the Puzzle (C356)
-   Tinkle Pit (C354, C367)
-   Emeraldia (C354, C358)

NA-2 Games:
-   Knuckle Heads
-   Numan Athletics
-   Emeraldia (C354, C358)
-   Nettou! Gekitou! Quiztou!! (C354, C365 - both are 32pin)
-   X-Day 2

To Do:
- Remove remaining MCU simulation hacks
- View area / screen resolution controlled by registers?

- X-Day 2:
    Rom board  M112
    Rom board custom Key chip i.d. C394
    Game uses a small cash-register type printer (connects to rom board)
    Game also has a large L.E.D. type score board with several
    displays for various scores. (connects to rom board)
    Game uses coin-type battery on rom board. (not suicide)
    Game won't startup unless printer is connected and with paper.

The board has a 28c16 EEPROM

No other CPUs on the board, but there are many custom chips.
Mother Board:
210 (28pin SOP)
C69 or C70 (80pin PQFP)
215 (176pin PQFP)
C218 (208pin PQFP)
219 (160pin PQFP)
Plus 1 or 2 custom chips on ROM board.

Notes:

-   NA-2 is backwards compatible with NA-1.

-   Some NA-1 PCBs are known to have the NA-2 (C70) MCU BIOS, so that cannot
    be used to tell them apart.

-   Test mode for NA2 games includes an additional item: UART Test.
    No games are known to actually link up and use the UART feature.
    It's been confirmed that a Numan Athletics fails the UART test,
    behaving as it does in MAME.

-   Quiz games use 1p button 1 to pick test, 2p button 1 to begin test,
    and 2p button 2 to exit. Because quiz games doesn't have joystick.

-   Almost all quiz games using JAMMA edge connector assign
    button1 to up, button 2 to down, button 3 to left, button 4 to right.
    But Taito F2 quiz games assign button 3 to right and button 4 to left.

-   Emeralda: Byte 0x25 of the NVRAM, when zero, enables the FBI logo.


Namco NA2 hardware
------------------

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

NA-2 GAME PCB
8627961102
(8627963102)
|---------------------------------------------|
|  LA4705           T062               |----| |
|         JP3   51568  LC7881          | 6  | |
|J        210              LH52250     | 8  | |
|A    VOL1      VOL2       LH52250     | 0  | |
|M                         |--------|  | 0  | |
|M            |------|     |  C218  |  | 0  | |
|A  TC514256  | 215  |     |        |  |----| |
|   TC514256  |      |     |        |         |
|             |------|     |--------|50.113MHz|
|            |---------ROM-BOARD--------------+
|     TC51832|  LH5168       TC514256         |
|   DSW(2)   |               TC514256         |
|            |               TC514256         |
|            |               TC514256         |
|            | |----|       |--------|    J103|
|4   IR2C24  | |C70 |       |  219   |        |
|8           | |----|       |        |        |
|W   PC9D10  |              |        |        |
|A     IR2C24|              |--------|        |
|Y           |       3773           TC51832   |
|------------+--------------------------------|
Notes:
       68000 clock - 12.5282MHz [50.113/4]
       TC51832     - 32k x8 SRAM (SOP28)
       TC514256    - 256k x4 DRAM (ZIP19)
       LH5168      - 8k x8 SRAM (SOP28)
       LC7881      - Sanyo 16bit DAC (SOIC20)
       LH52250     - 32k x8 SRAM (SOP28)
       51568       - ??, possibly audio related functions, manufactured by Mitsubishi (SOIC24)
       LA4705      - 15W 2-Channel Audio Power Amplifier (SIL18)
       T062        - Op AMP? (SOIC8)
       3773        - System reset and watchdog IC (SOIC8)
       J103        - Multi pin connector for ROM Board
       JP3         - Stereo/Mono jumper. For stereo, use pin 1 and 2 of the 48-WAY Namco connector for the 2nd speaker
       VSync       - 60Hz
       HSync       - 15.73kHz
       Namco Custom-
                     C218- (QFP208)
                     C70 - rebadged M37702 (QFP80)
                     219 - (QFP160)
                     215 - (QFP176)
                     210 - tied to some audio parts & C215 (SOP28)

ROM Board
---------

NA E4M8 ROM PCB
8626961200
(8626963200)
|--------------------------------+
| PAL1    28C16        KEYCUS    |
| PAL2                           |
|                                |
| ROM.7F   ROM.5F  ROM.3F        |
|   ROM.6F  ROM.4F  ROM.2F   J201|
|                                |
|                                |
|                                |
| ROM.7C   ROM.5C  ROM.3C        |
|   ROM.6C  ROM.4C  ROM.2C       |
+--------------------------------|
Notes:
      J201   - Multi pin connector for main board
      KEYCUS - C365 for 'Nettou! Gekitou! Quiztou!!' (DIP32)
      PAL1   - PAL16L8 labelled 'NR1R2' (DIP20)
      PAL2   - PAL16L8 labelled 'NR1R10' (DIP20)
      ROMs   -
               7F/6F/7C/6C - 27C040 EPROM (DIP32)
               All other ROMs are MB838000 8MBit MaskROM (DIP32)
               ROM Names/locations for 'Nettou! Gekitou! Quiztou!!'....
               QT1EP1L.7C
               QT1EP1U.7F
               QT1EP0L.6C
               QT1EP0U.6F
               QT1MA3L.5C
               QT1MA3U.5F
               QT1MA2L.4C
               QT1MA2U.4F
               QT1MA1L.3C
               QT1MA1U.3F
               QT1MA0L.2C
               QT1MA0U.2F

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

#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "includes/namcona1.h"
#include "sound/c140.h"
#include "cpu/m37710/m37710.h"


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

static const UINT8 ExvaniaDefaultNvMem[] =
{
/* This data oughtn't be necessary; when Exbania's EPROM area is uninitialized,
 * the game software automatically writes these values there, but then jumps
 * to an unmapped (bogus) address, causing MAME to crash.
 */
	0x30,0x32,0x4f,0x63,0x74,0x39,0x32,0x52,0x45,0x56,0x49,0x53,0x49,0x4f,0x4e,0x35,
	0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,
	0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02
}; /* ExvaniaDefaultNvMem */

static const UINT8 QuiztouDefaultNvMem[] =
{
/* This data oughtn't be necessary; when QuiztouDefaultNvMem's EPROM area is uninitialized,
 * the game software automatically writes these values there, but then jumps
 * to an unmapped (bogus) address, causing MAME to crash.
 */
	0x30,0x32,0x4F,0x63,0x74,0x39,0x32,0x52,0x45,0x56,0x49,0x53,0x49,0x4F,0x4E,0x35,
	0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,
	0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02
}; /* QuiztouDefaultNvMem */

static const UINT8 CgangpzlDefaultNvMem[] =
{
/* This data oughtn't be necessary; when Cgangpzl's EPROM area is uninitialized,
 * the game software automatically writes these values there, but then hangs.
 */
	0x30,0x32,0x4F,0x63,0x74,0x39,0x32,0x52,0x45,0x56,0x49,0x53,0x49,0x4F,0x4E,0x35,
	0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,
	0x00,0x02,0x00,0x00,0x00,0x01
}; /* CgangpzlDefaultNvMem */


static NVRAM_HANDLER( namcosna1 )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	if( read_or_write )
	{
		file->write( state->m_nvmem, NA1_NVRAM_SIZE );
	}
	else
	{
		if (file)
		{
			file->read( state->m_nvmem, NA1_NVRAM_SIZE );
		}
		else
		{
			memset( state->m_nvmem, 0x00, NA1_NVRAM_SIZE );

			switch( state->m_gametype )
			{
			case NAMCO_EXBANIA:
				memcpy( state->m_nvmem, ExvaniaDefaultNvMem, sizeof(ExvaniaDefaultNvMem) );
				break;

			case NAMCO_QUIZTOU:
				memcpy( state->m_nvmem, QuiztouDefaultNvMem, sizeof(QuiztouDefaultNvMem) );
				break;

			case NAMCO_CGANGPZL:
				memcpy( state->m_nvmem, CgangpzlDefaultNvMem, sizeof(CgangpzlDefaultNvMem) );
				break;
			}
		}
	}
} /* namcosna1_nvram_handler */

static READ16_HANDLER( namcona1_nvram_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_nvmem[offset];
} /* namcona1_nvram_r */

static WRITE16_HANDLER( namcona1_nvram_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	if( ACCESSING_BITS_0_7 )
	{
		state->m_nvmem[offset] = data&0xff;
	}
} /* namcona1_nvram_w */

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

static INPUT_PORTS_START( namcona1_joy )
	PORT_START("P1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )

	PORT_START("P2")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )

	PORT_START("P3")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START3 )

	PORT_START("P4")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START4 )

	PORT_START("DSW")
	PORT_DIPNAME( 0x01, 0x01, "DIP2 (Freeze)" )
	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x02, 0x02, "DIP1 (Test)" )
	PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN4 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN3 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_SERVICE( 0x40, IP_ACTIVE_LOW )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
INPUT_PORTS_END

static INPUT_PORTS_START( namcona1_quiz )
	PORT_START("P1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )

	PORT_START("P2")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )

	PORT_START("P3")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START3 )

	PORT_START("P4")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(4)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START4 )

	PORT_START("DSW")
	PORT_DIPNAME( 0x01, 0x01, "DIP2 (Freeze)" )
	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x02, 0x02, "DIP1 (Test)" )
	PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN4 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN3 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_SERVICE( 0x40, IP_ACTIVE_LOW )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
INPUT_PORTS_END


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

/* FIXME: These two functions shouldn't be necessary? */
static void simulate_mcu( running_machine &machine )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	state->m_workram[0xf60/2] = 0x0000; /* mcu ready */
}


/* NA2 hardware sends a special command to the MCU, then tests to
 * see if the proper BIOS version string appears in shared memory.
 */
static void write_version_info( namcona1_state *state )
{
	static const UINT16 source[0x8] =
	{ /* "NSA-BIOS ver"... */
		0x534e,0x2d41,0x4942,0x534f,0x7620,0x7265,0x2e31,0x3133
	};
	int i;
	for( i=0; i<8; i++ )
	{
		state->m_workram[0x1000/2+i] = source[i];
	}
}

/**
 * "Custom Key" Emulation
 *
 * The primary purpose of the custom key chip is protection.  It prevents
 * ROM swaps from working with games that otherwise run on the same hardware.
 *
 * The secondary purpose of the custom key chip is to act as a random number
 * generator in some games.
 */
static READ16_HANDLER( custom_key_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	int old_count;

	old_count = state->m_count;
	do
	{
		state->m_count = space->machine().rand();
	} while( old_count == state->m_count );

	switch( state->m_gametype )
	{
	case NAMCO_BKRTMAQ:
		if( offset==2 ) return 0x015c;
		break;

	case NAMCO_FA:
		if( offset==2 ) return 0x015d;
		if( offset==4 ) return state->m_count;
		break;

	case NAMCO_EXBANIA:
		if( offset==2 ) return 0x015e;
		break;

	case NAMCO_CGANGPZL:
		if( offset==1 ) return 0x0164;
		if( offset==2 ) return state->m_count;
		break;

	case NAMCO_SWCOURT:
		if( offset==1 ) return 0x0165;
		if( offset==2 ) return state->m_count;
		break;

	case NAMCO_EMERALDA:
		if( offset==1 ) return 0x0166;
		if( offset==2 ) return state->m_count;
		break;

	case NAMCO_NUMANATH:
		if( offset==1 ) return 0x0167;
		if( offset==2 ) return state->m_count;
		break;

	case NAMCO_KNCKHEAD:
		if( offset==1 ) return 0x0168;
		if( offset==2 ) return state->m_count;
		break;

	case NAMCO_QUIZTOU:
		if( offset==2 ) return 0x016d;
		break;

	case NAMCO_TINKLPIT:
		if( offset==7 ) return 0x016f;
		if( offset==4 ) state->m_keyval = 0;
		if( offset==3 )
		{
			UINT16 res;
			res = BITSWAP16(state->m_keyval, 22,26,31,23,18,20,16,30,24,21,25,19,17,29,28,27);

			state->m_keyval >>= 1;
//          printf("popcount(%08X) = %d\n", state->m_keyval & 0x58000c00, popcount(state->m_keyval & 0x58000c00));
			if((!state->m_keyval) || (popcount(state->m_keyval & 0x58000c00) & 1))
				state->m_keyval ^= 0x80000000;

			return res;
		}
		break;

	case NAMCO_XDAY2:
		if( offset==2 ) return 0x018a;
		if( offset==3 ) return state->m_count;
		break;

	default:
		return 0;
	}
	return space->machine().rand()&0xffff;
} /* custom_key_r */

static WRITE16_HANDLER( custom_key_w )
{
} /* custom_key_w */

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

static READ16_HANDLER( namcona1_vreg_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_vreg[offset];
} /* namcona1_vreg_r */

static int transfer_dword( running_machine &machine, UINT32 dest, UINT32 source )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	UINT16 data;
	address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);

	if( source>=0x400000 && source<0xc00000 )
	{
		data = state->m_mpBank1[(source-0x400000)/2];
	}
	else if( source>=0xc00000 && source<0xe00000 )
	{
		data = state->m_mpBank0[(source-0xc00000)/2];
	}
	else if( source<0x80000 && source>=0x1000 )
	{
		data = state->m_workram[source/2];
	}
	else
	{
		logerror( "bad blt src %08x\n", source );
		return -1;
	}
	if( dest>=0xf00000 && dest<0xf02000 )
	{
		namcona1_paletteram_w(space, (dest-0xf00000)/2, data, 0xffff );
	}
	else if( dest>=0xf40000 && dest<0xf80000 )
	{
		namcona1_gfxram_w(space, (dest-0xf40000)/2, data, 0xffff );
	}
	else if( dest>=0xff0000 && dest<0xffc000 )
	{
		namcona1_videoram_w(space, (dest-0xff0000)/2, data, 0xffff );
	}
	else if( dest>=0xfff000 && dest<0x1000000 )
	{
		state->m_spriteram[(dest-0xfff000)/2] = data;
	}
	else
	{
		logerror( "bad blit dest %08x\n", dest );
		return -1;
	}
	return 0;
} /* transfer_dword */

static void blit_setup( int format, int *bytes_per_row, int *pitch, int mode )
{
	if( mode == 3 )
	{ /* TILE DATA */
		switch( format )
		{
		case 0x0001:
			*bytes_per_row = 0x1000;
			*pitch = 0x1000;
			break;

		case 0x0081:
			*bytes_per_row = 4*8;
			*pitch = 36*8;
			break;

		default:
//      case 0x00f1:
//      case 0x00f9:
//      case 0x00fd:
			*bytes_per_row = (64 - (format>>2))*0x08;
			*pitch = 0x200;
			break;
		}
	}
	else
	{ /* SHAPE DATA */
		switch( format )
		{
		case 0x00bd: /* Numan Athletics */
			*bytes_per_row = 4;
			*pitch = 0x120;
			break;
		case 0x008d: /* Numan Athletics */
			*bytes_per_row = 8;
			*pitch = 0x120;
			break;

		case 0x0000: /* Numan (used to clear spriteram) */
//      0000 0000 0000 : src0
//      0000 0001 0000 : dst0
//      003d 75a0      : src (7AEB40)
//      ---- ----      : spriteram
//      0800           : numbytes
//      0000           : blit
			*bytes_per_row = 0x10;
			*pitch = 0;
			break;

		case 0x0001:
			*bytes_per_row = 0x1000;
			*pitch = 0x1000;
			break;

		case 0x0401: /* F/A */
			*bytes_per_row = 4*0x40;
			*pitch = 36*0x40;
			break;

		default:
//      case 0x00f1:
//      case 0x0781:
//      case 0x07c1:
//      case 0x07e1:
			*bytes_per_row = (64 - (format>>5))*0x40;
			*pitch = 0x1000;
			break;
		}
	}
} /* blit_setup */

static void namcona1_blit( running_machine &machine )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	int src0 = state->m_vreg[0x0];
	int src1 = state->m_vreg[0x1];
	int src2 = state->m_vreg[0x2];

	int dst0 = state->m_vreg[0x3];
	int dst1 = state->m_vreg[0x4];
	int dst2 = state->m_vreg[0x5];

	int gfxbank = state->m_vreg[0x6];

	/* dest and source are provided as dword offsets */
	UINT32 src_baseaddr	= 2*(0xffffff&((state->m_vreg[0x7]<<16)|state->m_vreg[0x8]));
	UINT32 dst_baseaddr	= 2*(0xffffff&((state->m_vreg[0x9]<<16)|state->m_vreg[0xa]));

	int num_bytes = state->m_vreg[0xb];

	int dst_offset, src_offset;
	int dst_bytes_per_row, dst_pitch;
	int src_bytes_per_row, src_pitch;

	(void)dst2;
	(void)dst0;
	(void)src2;
	(void)src0;
/*
    logerror( "%s: blt(%08x,%08x,numBytes=%04x);src=%04x %04x %04x; dst=%04x %04x %04x; gfx=%04x\n",
        machine.describe_context(),
        dst_baseaddr,src_baseaddr,num_bytes,
        src0,src1,src2,
        dst0,dst1,dst2,
        gfxbank );
*/
	blit_setup( dst1, &dst_bytes_per_row, &dst_pitch, gfxbank);
	blit_setup( src1, &src_bytes_per_row, &src_pitch, gfxbank );

	if( num_bytes&1 )
	{
		num_bytes++;
	}

	if( dst_baseaddr < 0xf00000 )
	{
		dst_baseaddr += 0xf40000;
	}

	dst_offset = 0;
	src_offset = 0;

	while( num_bytes>0 )
	{
		if( transfer_dword(machine,
			dst_baseaddr + dst_offset,
			src_baseaddr + src_offset ) )
		{
			return;
		}

		num_bytes -= 2;

		dst_offset+=2;
		if( dst_offset >= dst_bytes_per_row )
		{
			dst_baseaddr += dst_pitch;
			dst_offset = 0;
		}

		src_offset+=2;
		if( src_offset >= src_bytes_per_row )
		{
			src_baseaddr += src_pitch;
			src_offset = 0;
		}
	}
} /* namcona1_blit */

static WRITE16_HANDLER( namcona1_vreg_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	COMBINE_DATA( &state->m_vreg[offset] );

	switch( offset )
	{
	case 0x18/2:
		namcona1_blit(space->machine());
		/* see also 0x1e */
		break;

	case 0x1a/2:
		state->m_mEnableInterrupts = 1;
		/* interrupt enable mask; 0 enables INT level */
		break;
	}
} /* namcona1_vreg_w */

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

// MCU "mailslot" handler - has 8 16-bit slots mirrored

static READ16_HANDLER( mcu_mailbox_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_mcu_mailbox[offset%8];
}

static WRITE16_HANDLER( mcu_mailbox_w_68k )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
//  logerror("mailbox_w_68k: %x @ %x\n", data, offset);

	if (offset == 4)
		cputag_set_input_line(space->machine(), "mcu", M37710_LINE_IRQ0, HOLD_LINE);

	COMBINE_DATA(&state->m_mcu_mailbox[offset%8]);

	/* FIXME: This shouldn't be necessary now that the C70 BIOS is implemented,
    but for some reason the MCU never responds to the version string command */
	if ( (state->m_gametype == NAMCO_NUMANATH) || (state->m_gametype == NAMCO_KNCKHEAD) )
	{
		if ((state->m_workram[0xf72/2] >> 8) == 7)
			write_version_info(state);
	}
}

static WRITE16_HANDLER( mcu_mailbox_w_mcu )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	COMBINE_DATA(&state->m_mcu_mailbox[offset%8]);
}

static ADDRESS_MAP_START( namcona1_main_map, AS_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_BASE_MEMBER(namcona1_state, m_workram)
	AM_RANGE(0x3f8000, 0x3fffff) AM_READWRITE(mcu_mailbox_r, mcu_mailbox_w_68k)
	AM_RANGE(0x400000, 0xbfffff) AM_ROM AM_REGION("maincpu", 0x280000)	/* data */
	AM_RANGE(0xc00000, 0xdfffff) AM_ROM AM_REGION("maincpu", 0x080000)	/* code */
	AM_RANGE(0xe00000, 0xe00fff) AM_READWRITE(namcona1_nvram_r, namcona1_nvram_w)
	AM_RANGE(0xe40000, 0xe4000f) AM_READWRITE(custom_key_r, custom_key_w)
	AM_RANGE(0xefff00, 0xefffff) AM_READWRITE(namcona1_vreg_r, namcona1_vreg_w) AM_BASE_MEMBER(namcona1_state, m_vreg)
	AM_RANGE(0xf00000, 0xf01fff) AM_READWRITE(namcona1_paletteram_r, namcona1_paletteram_w) AM_BASE_GENERIC(paletteram)
	AM_RANGE(0xf40000, 0xf7ffff) AM_READWRITE(namcona1_gfxram_r, namcona1_gfxram_w)
	AM_RANGE(0xff0000, 0xffbfff) AM_READWRITE(namcona1_videoram_r,    namcona1_videoram_w) AM_BASE_MEMBER(namcona1_state, m_videoram)
	AM_RANGE(0xffd000, 0xffdfff) AM_RAM /* unknown */
	AM_RANGE(0xffe000, 0xffefff) AM_RAM	AM_BASE_MEMBER(namcona1_state, m_scroll)		/* scroll registers */
	AM_RANGE(0xfff000, 0xffffff) AM_RAM	AM_BASE_MEMBER(namcona1_state, m_spriteram)			/* spriteram */
ADDRESS_MAP_END


static ADDRESS_MAP_START( namcona2_main_map, AS_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_BASE_MEMBER(namcona1_state, m_workram)
	AM_RANGE(0x3f8000, 0x3fffff) AM_READWRITE(mcu_mailbox_r, mcu_mailbox_w_68k)
	AM_RANGE(0x400000, 0xbfffff) AM_ROM AM_REGION("maincpu", 0x280000)	/* data */
	AM_RANGE(0xd00000, 0xd00001) AM_WRITENOP /* xday: serial out? */
	AM_RANGE(0xd40000, 0xd40001) AM_WRITENOP /* xday: serial out? */
	AM_RANGE(0xd80000, 0xd80001) AM_WRITENOP /* xday: serial out? */
	AM_RANGE(0xdc0000, 0xdc001f) AM_WRITENOP /* xday: serial config? */
	AM_RANGE(0xc00000, 0xdfffff) AM_ROM AM_REGION("maincpu", 0x080000)	/* code */
	AM_RANGE(0xe00000, 0xe00fff) AM_READWRITE(namcona1_nvram_r, namcona1_nvram_w)
	/* xday: additional battery-backed ram at 00E024FA? */
	AM_RANGE(0xe40000, 0xe4000f) AM_READWRITE(custom_key_r, custom_key_w)
	AM_RANGE(0xefff00, 0xefffff) AM_READWRITE(namcona1_vreg_r, namcona1_vreg_w) AM_BASE_MEMBER(namcona1_state, m_vreg)
	AM_RANGE(0xf00000, 0xf01fff) AM_READWRITE(namcona1_paletteram_r, namcona1_paletteram_w) AM_BASE_GENERIC(paletteram)
	AM_RANGE(0xf40000, 0xf7ffff) AM_READWRITE(namcona1_gfxram_r, namcona1_gfxram_w)
	AM_RANGE(0xff0000, 0xffbfff) AM_READWRITE(namcona1_videoram_r,    namcona1_videoram_w) AM_BASE_MEMBER(namcona1_state, m_videoram)
	AM_RANGE(0xffd000, 0xffdfff) AM_RAM /* unknown */
	AM_RANGE(0xffe000, 0xffefff) AM_RAM	AM_BASE_MEMBER(namcona1_state, m_scroll)		/* scroll registers */
	AM_RANGE(0xfff000, 0xffffff) AM_RAM	AM_BASE_MEMBER(namcona1_state, m_spriteram)			/* spriteram */
ADDRESS_MAP_END


/* ----- NA-1 MCU handling ----------------------------------- */

static READ16_HANDLER( na1mcu_shared_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	UINT16 data;

	data = state->m_workram[offset];

#if 0
	if (offset >= 0x70000/2)
	{
		logerror("MD: %04x @ %x PC %x\n", ((data>>8)&0xff) | ((data<<8)&0xff00), offset*2, cpu_get_pc(&space->device()));
	}
#endif

	return ((data>>8)&0xff) | ((data<<8)&0xff00);
}

static WRITE16_HANDLER( na1mcu_shared_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	mem_mask = FLIPENDIAN_INT16(mem_mask);
	data = FLIPENDIAN_INT16(data);

	COMBINE_DATA(&state->m_workram[offset]);
}

static READ16_DEVICE_HANDLER(snd_r)
{
	/* can't use DEVREADWRITE8 for this because it is opposite endianness to the CPU for some reason */
	return c140_r(device,offset*2+1) | c140_r(device,offset*2)<<8;
}

static WRITE16_DEVICE_HANDLER(snd_w)
{
	/* can't use DEVREADWRITE8 for this because it is opposite endianness to the CPU for some reason */
	if (ACCESSING_BITS_0_7)
	{
		c140_w(device,(offset*2)+1, data);
	}

	if (ACCESSING_BITS_8_15)
	{
		c140_w(device,(offset*2), data>>8);
	}
}

static ADDRESS_MAP_START( namcona1_mcu_map, AS_PROGRAM, 16 )
	AM_RANGE(0x000800, 0x000fff) AM_READWRITE(mcu_mailbox_r, mcu_mailbox_w_mcu)	// "Mailslot" communications ports
	AM_RANGE(0x001000, 0x001fff) AM_DEVREADWRITE("c140", snd_r, snd_w)	// C140-alike sound chip
	AM_RANGE(0x002000, 0x002fff) AM_READWRITE(na1mcu_shared_r, na1mcu_shared_w)	// mirror of first page of shared work RAM
	AM_RANGE(0x003000, 0x00afff) AM_RAM						// there is a 32k RAM chip according to CGFM
	AM_RANGE(0x00c000, 0x00ffff) AM_ROM AM_REGION("mcu", 0)			// internal ROM BIOS
	AM_RANGE(0x200000, 0x27ffff) AM_READWRITE(na1mcu_shared_r, na1mcu_shared_w)	// shared work RAM
ADDRESS_MAP_END


// port 4: bit 3 (0x08) enables the 68000 (see the 68k launch code at c604 in swcourt's BIOS)
static READ8_HANDLER( port4_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_mcu_port4;
}

static WRITE8_HANDLER( port4_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	if ((data & 0x08) && !(state->m_mcu_port4 & 0x08))
	{
		logerror("launching 68k, PC=%x\n", cpu_get_pc(&space->device()));

		// reset and launch the 68k
		cputag_set_input_line(space->machine(), "maincpu", INPUT_LINE_RESET, CLEAR_LINE);
	}

	state->m_mcu_port4 = data;
}

// port 5: not sure yet, but MCU code requires this interaction at least
static READ8_HANDLER( port5_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_mcu_port5;
}

static WRITE8_HANDLER( port5_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	state->m_mcu_port5 = data;

	// bit 0 must mirror bit 1 - this is checked at CCD3 in the C69 BIOS
	state->m_mcu_port5 &= 0xfe;
	state->m_mcu_port5 |= ((state->m_mcu_port5 & 0x2)>>1);
}

static READ8_HANDLER( port6_r )
{
	return 0;
}

static WRITE8_HANDLER( port6_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	state->m_mcu_port6 = data;
}

static READ8_HANDLER( port7_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	switch (state->m_mcu_port6 & 0xe0)
	{
		case 0x40:
			return input_port_read(space->machine(), "P1");

		case 0x60:
			return input_port_read(space->machine(), "P2");

		case 0x20:
			return input_port_read(space->machine(), "DSW");

		case 0x00:
			return input_port_read(space->machine(), "P4");
	}

	return 0xff;
}

static WRITE8_HANDLER( port7_w )
{
}

// port 8: bit 5 (0x20) toggles, watchdog?
static READ8_HANDLER( port8_r )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	return state->m_mcu_port8;
}

static WRITE8_HANDLER( port8_w )
{
	namcona1_state *state = space->machine().driver_data<namcona1_state>();
	state->m_mcu_port8 = data;
}


static MACHINE_START( namcona1 )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	c140_set_base(machine.device("c140"), state->m_workram);
}

// for games with the MCU emulated, the MCU boots the 68000.  don't allow it before that.
static MACHINE_RESET( namcona1_mcu )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	cputag_set_input_line(machine, "maincpu", INPUT_LINE_RESET, ASSERT_LINE);

	state->m_mcu_port5 = 1;
}

// "encrypt" player 3 inputs
// each bit of player 3's inputs is split across one of the 8 analog input ports
// bit 6 => port 0
// bit 5 => port 1
// bit 4 => port 2
// bit 0 => port 3
// bit 1 => port 4
// bit 2 => port 5
// bit 3 => port 6
// bit 7 => port 7
static READ8_HANDLER( portana_r )
{
	static const UINT8 bitnum[8] = { 0x40, 0x20, 0x10, 0x01, 0x02, 0x04, 0x08, 0x80 };
	UINT8 port = input_port_read(space->machine(), "P3");

	return (port & bitnum[offset>>1]) ? 0xff : 0x00;
}

static ADDRESS_MAP_START( namcona1_mcu_io_map, AS_IO, 8 )
	AM_RANGE(M37710_PORT4, M37710_PORT4) AM_READWRITE( port4_r, port4_w )
	AM_RANGE(M37710_PORT5, M37710_PORT5) AM_READWRITE( port5_r, port5_w )
	AM_RANGE(M37710_PORT6, M37710_PORT6) AM_READWRITE( port6_r, port6_w )
	AM_RANGE(M37710_PORT7, M37710_PORT7) AM_READWRITE( port7_r, port7_w )
	AM_RANGE(M37710_PORT8, M37710_PORT8) AM_READWRITE( port8_r, port8_w )
	AM_RANGE(0x10, 0x1f) AM_READ( portana_r )
ADDRESS_MAP_END


static TIMER_DEVICE_CALLBACK( namcona1_interrupt )
{
	namcona1_state *state = timer.machine().driver_data<namcona1_state>();
	int scanline = param;
	int enabled = state->m_mEnableInterrupts ? ~state->m_vreg[0x1a/2] : 0;
	
	// vblank
	if (scanline == 224)
	{
		simulate_mcu( timer.machine() );
		if (enabled & 8)
			device_set_input_line(state->m_maincpu, 4, HOLD_LINE);
	}

	// posirq, used with dolphin in Emeraldia's "how to play" attract mode
	int posirq_scanline = state->m_vreg[0x8a/2] & 0xff;
	if (scanline == posirq_scanline && enabled & 4)
	{
		if (posirq_scanline)
			timer.machine().primary_screen->update_partial(posirq_scanline);

		device_set_input_line(state->m_maincpu, 3, HOLD_LINE);
	}
}

// MCU interrupts: IRQ 0 => process mail slot (probably set on mail slot write from 68k)
//                 IRQ 1 =>
//                 IRQ 2 =>

static TIMER_DEVICE_CALLBACK( mcu_interrupt )
{
	namcona1_state *state = timer.machine().driver_data<namcona1_state>();
	int scanline = param;

	// vblank
	if (scanline == 224)
		device_set_input_line(state->m_mcu, M37710_LINE_IRQ1, HOLD_LINE);

	// adc (timing guessed, when does this trigger?)
	if (scanline == 0)
		device_set_input_line(state->m_mcu, M37710_LINE_ADC, HOLD_LINE);
}

static const c140_interface C140_interface_typeA =
{
	C140_TYPE_ASIC219
};

/* cropped at sides */
static MACHINE_CONFIG_START( namcona1, namcona1_state )
	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu", M68000, 50113000/4)
	MCFG_CPU_PROGRAM_MAP(namcona1_main_map)
	MCFG_TIMER_ADD_SCANLINE("scan_main", namcona1_interrupt, "screen", 0, 1)

	MCFG_CPU_ADD("mcu", M37702, 50113000/4)
	MCFG_CPU_PROGRAM_MAP(namcona1_mcu_map)
	MCFG_CPU_IO_MAP( namcona1_mcu_io_map)
	MCFG_TIMER_ADD_SCANLINE("scan_mcu", mcu_interrupt, "screen", 0, 1)

	MCFG_NVRAM_HANDLER(namcosna1)
	MCFG_MACHINE_START(namcona1)
	MCFG_MACHINE_RESET(namcona1_mcu)
	MCFG_QUANTUM_TIME(attotime::from_hz(2400))

	/* video hardware */
	MCFG_VIDEO_ATTRIBUTES(VIDEO_HAS_SHADOWS)

	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_REFRESH_RATE(60)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
	MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MCFG_SCREEN_SIZE(38*8, 32*8)
	MCFG_SCREEN_VISIBLE_AREA(8, 38*8-1-8, 4*8, 32*8-1)
	MCFG_SCREEN_UPDATE(namcona1)

	MCFG_PALETTE_LENGTH(0x2000)

	MCFG_VIDEO_START(namcona1)

	/* sound hardware */
	MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

	MCFG_SOUND_ADD("c140", C140, 44100)
	MCFG_SOUND_CONFIG(C140_interface_typeA)
	MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
	MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
MACHINE_CONFIG_END


/* full-width */
static MACHINE_CONFIG_DERIVED( namcona1w, namcona1 )

	/* basic machine hardware */

	/* video hardware */
	MCFG_SCREEN_MODIFY("screen")
	MCFG_SCREEN_VISIBLE_AREA(0, 38*8-1-0, 4*8, 32*8-1)
MACHINE_CONFIG_END


static MACHINE_CONFIG_DERIVED( namcona2, namcona1 )

	/* basic machine hardware */

	MCFG_CPU_MODIFY("maincpu")
	MCFG_CPU_PROGRAM_MAP(namcona2_main_map)
MACHINE_CONFIG_END


static void init_namcona1( running_machine &machine, int gametype )
{
	namcona1_state *state = machine.driver_data<namcona1_state>();
	UINT16 *pMem = (UINT16 *)machine.region( "maincpu" )->base();

	state->m_gametype = gametype;
	state->m_mpBank0 = &pMem[0x80000/2];
	state->m_mpBank1 = state->m_mpBank0 +  0x200000/2;

	state->m_mEnableInterrupts = 0;
}

static DRIVER_INIT( bkrtmaq ){		init_namcona1(machine, NAMCO_BKRTMAQ); }
static DRIVER_INIT( cgangpzl ){	init_namcona1(machine, NAMCO_CGANGPZL); }
static DRIVER_INIT( emeralda ){	init_namcona1(machine, NAMCO_EMERALDA); } /* NA-2 Hardware */
static DRIVER_INIT( emeraldj ){	init_namcona1(machine, NAMCO_EMERALDA); } /* NA-1 Hardware */
static DRIVER_INIT( exbania ){		init_namcona1(machine, NAMCO_EXBANIA); }
static DRIVER_INIT( fa ){	        init_namcona1(machine, NAMCO_FA); }
static DRIVER_INIT( knckhead ){	init_namcona1(machine, NAMCO_KNCKHEAD); }
static DRIVER_INIT( numanath ){	init_namcona1(machine, NAMCO_NUMANATH); }
static DRIVER_INIT( quiztou ){		init_namcona1(machine, NAMCO_QUIZTOU); }
static DRIVER_INIT( swcourt ){		init_namcona1(machine, NAMCO_SWCOURT); }
static DRIVER_INIT( tinklpit ){	init_namcona1(machine, NAMCO_TINKLPIT); }
static DRIVER_INIT( xday2 ){		init_namcona1(machine, NAMCO_XDAY2); }

ROM_START( bkrtmaq )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "mq1-ep0l.bin", 0x080001, 0x080000, CRC(f029bc57) SHA1(fdbf8b8b9f69d5755ca5197dda4f887b12dd66f4) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "mq1-ep0u.bin", 0x080000, 0x080000, CRC(4cff62b8) SHA1(5cac170dcfbeb3dcfa0840bdbe7541a9d2f44a14) )
	ROM_LOAD16_BYTE( "mq1-ep1l.bin", 0x180001, 0x080000, CRC(e3be6f4b) SHA1(75d9a4cff25e63a9d6c092aa6e241eccd1c61f91) )
	ROM_LOAD16_BYTE( "mq1-ep1u.bin", 0x180000, 0x080000, CRC(b44e31b2) SHA1(3d8c63789b98ada3663ba9e28c370815a9a9c3ed) )

	ROM_LOAD16_BYTE( "mq1-ma0l.bin", 0x280001, 0x100000, CRC(11fed35f) SHA1(511d98b6b42b330238a1874bca031b1892654a48) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "mq1-ma0u.bin", 0x280000, 0x100000, CRC(23442ac0) SHA1(fac706f24045d51a2712f51530967140ea8e875f) )
	ROM_LOAD16_BYTE( "mq1-ma1l.bin", 0x480001, 0x100000, CRC(fe82205f) SHA1(860cc7a96ae3f848ce594077c1362e4e22a36908) )
	ROM_LOAD16_BYTE( "mq1-ma1u.bin", 0x480000, 0x100000, CRC(0cdb6bd0) SHA1(b8b398477c9654e96921110fb30c754240183897) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( cgangpzl )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "cp2-ep0l.bin", 0x080001, 0x80000, CRC(8f5cdcc5) SHA1(925db3f3f16224bc28f97a57aba0ab2b51c5067c) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "cp2-ep0u.bin", 0x080000, 0x80000, CRC(3a816140) SHA1(613c367e08a0a20ec62e1938faab0128743b26f8) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( cgangpzlj )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "cp1-ep0l.bin", 0x080001, 0x80000, CRC(2825f7ba) SHA1(5f6f8df6bdf0f45656904411cdbb31fdcf8f3be0) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "cp1-ep0u.bin", 0x080000, 0x80000, CRC(94d7d6fc) SHA1(2460741e0dbb2ccff28f4fbc419a7507382467d2) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( emeraldaj ) /* NA-1 Game PCB, parent is NA-2 version listed below */
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "em1-ep0lb.bin", 0x080001, 0x080000, CRC(fcd55293) SHA1(fdabf9d5f528c37196ac1e031b097618b4c887b5) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "em1-ep0ub.bin", 0x080000, 0x080000, CRC(a52f00d5) SHA1(85f95d2a69a2df2e9195f55583645c064b0b6fe6) )
	ROM_LOAD16_BYTE( "em1-ep1l.bin",  0x180001, 0x080000, CRC(373c1c59) SHA1(385cb3bc056b798878de890dbff97a8bdd48fe4e) )
	ROM_LOAD16_BYTE( "em1-ep1u.bin",  0x180000, 0x080000, CRC(4e969152) SHA1(2c89ae5d43585f479f16cf8278f8fc001e077e45) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( emeraldaja ) /* NA-1 Game PCB, parent is NA-2 version listed below */
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "em1-ep0l.bin", 0x080001, 0x080000, CRC(443f3fce) SHA1(35b6c834e5716c1e9b55f1e39f4e7336dbbe2d9b) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "em1-ep0u.bin", 0x080000, 0x080000, CRC(484a2a81) SHA1(1b60c18dfb2aebfd4aa8b2a85a1e90883a1f8e61) )
	ROM_LOAD16_BYTE( "em1-ep1l.bin", 0x180001, 0x080000, CRC(373c1c59) SHA1(385cb3bc056b798878de890dbff97a8bdd48fe4e) )
	ROM_LOAD16_BYTE( "em1-ep1u.bin", 0x180000, 0x080000, CRC(4e969152) SHA1(2c89ae5d43585f479f16cf8278f8fc001e077e45) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( exvania )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "ex2-ep0l.4c", 0x080001, 0x080000, CRC(ccf46677) SHA1(f9d057a7b1c388323d49ef692f41242769f1a08c) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "ex2-ep0u.4f", 0x080000, 0x080000, CRC(37b8d890) SHA1(a0417a1b51d1206bd3eb5e7b58303a9a5691fa43) )

	ROM_LOAD16_BYTE( "ex1-ma0l.2c", 0x280001, 0x100000, CRC(17922cd4) SHA1(af92c2335e7110c0c5e712f3148c1534d22d3814) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "ex1-ma0u.2f", 0x280000, 0x100000, CRC(93d66106) SHA1(c5d665db04ae0e8992ef46544e2cb7b0e27c8bfe) )
	ROM_LOAD16_BYTE( "ex1-ma1l.3c", 0x480001, 0x100000, CRC(e4bba6ed) SHA1(6483ef91e5a5b8ddd13a3d889936c39829fa50d6) )
	ROM_LOAD16_BYTE( "ex1-ma1u.3f", 0x480000, 0x100000, CRC(04e7c4b0) SHA1(78180d96cd1fae583617d4d227ed4ee24f2f9e29) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( exvaniaj )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "ex1-ep0l.4c", 0x080001, 0x080000, CRC(18c12015) SHA1(e4f3524e798545c434549719b377c8b5863f580f) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "ex1-ep0u.4f", 0x080000, 0x080000, CRC(07d054d1) SHA1(e2d2cb81acd309c519686572804648bef4cbd191) )

	ROM_LOAD16_BYTE( "ex1-ma0l.2c", 0x280001, 0x100000, CRC(17922cd4) SHA1(af92c2335e7110c0c5e712f3148c1534d22d3814) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "ex1-ma0u.2f", 0x280000, 0x100000, CRC(93d66106) SHA1(c5d665db04ae0e8992ef46544e2cb7b0e27c8bfe) )
	ROM_LOAD16_BYTE( "ex1-ma1l.3c", 0x480001, 0x100000, CRC(e4bba6ed) SHA1(6483ef91e5a5b8ddd13a3d889936c39829fa50d6) )
	ROM_LOAD16_BYTE( "ex1-ma1u.3f", 0x480000, 0x100000, CRC(04e7c4b0) SHA1(78180d96cd1fae583617d4d227ed4ee24f2f9e29) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( fghtatck )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "fa2-ep0l.bin", 0x080001, 0x080000, CRC(8996db9c) SHA1(ebbe7d4cb2960a346cfbdf38c77638d71b6ba20e) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "fa2-ep0u.bin", 0x080000, 0x080000, CRC(58d5e090) SHA1(950219d4e9bf440f92e3c8765f47e23a9019d2d1) )
	ROM_LOAD16_BYTE( "fa1-ep1l.bin", 0x180001, 0x080000, CRC(b23a5b01) SHA1(4ba9bc2102fffc93a5ff73a107d557fc0f3beefd) )
	ROM_LOAD16_BYTE( "fa1-ep1u.bin", 0x180000, 0x080000, CRC(de2eb129) SHA1(912993cab1c2edcaf986478f2ae22a2f10edf807) )

	ROM_LOAD16_BYTE( "fa1-ma0l.bin", 0x280001, 0x100000, CRC(a0a95e54) SHA1(da35f8a6a5bc9e2b5b6cacf8eb0d900ef1073a67) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "fa1-ma0u.bin", 0x280000, 0x100000, CRC(1d0135bd) SHA1(2a7f8d09c213629a68376ce0379be61b37711d0a) )
	ROM_LOAD16_BYTE( "fa1-ma1l.bin", 0x480001, 0x100000, CRC(c4adf0a2) SHA1(4cc7adc68b1db7e725a973b31d52720bd7dc1140) )
	ROM_LOAD16_BYTE( "fa1-ma1u.bin", 0x480000, 0x100000, CRC(900297be) SHA1(57bb2078ff104c6f631c67219f80f8ede5ddbd09) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( fa )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "fa1-ep0l.bin", 0x080001, 0x080000, CRC(182eee5c) SHA1(49769e3b72b59fc3e7b73364fe97168977dbe66b) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "fa1-ep0u.bin", 0x080000, 0x080000, CRC(7ea7830e) SHA1(79390943eea0b8029b2b8869233caf27228e776a) )
	ROM_LOAD16_BYTE( "fa1-ep1l.bin", 0x180001, 0x080000, CRC(b23a5b01) SHA1(4ba9bc2102fffc93a5ff73a107d557fc0f3beefd) )
	ROM_LOAD16_BYTE( "fa1-ep1u.bin", 0x180000, 0x080000, CRC(de2eb129) SHA1(912993cab1c2edcaf986478f2ae22a2f10edf807) )

	ROM_LOAD16_BYTE( "fa1-ma0l.bin", 0x280001, 0x100000, CRC(a0a95e54) SHA1(da35f8a6a5bc9e2b5b6cacf8eb0d900ef1073a67) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "fa1-ma0u.bin", 0x280000, 0x100000, CRC(1d0135bd) SHA1(2a7f8d09c213629a68376ce0379be61b37711d0a) )
	ROM_LOAD16_BYTE( "fa1-ma1l.bin", 0x480001, 0x100000, CRC(c4adf0a2) SHA1(4cc7adc68b1db7e725a973b31d52720bd7dc1140) )
	ROM_LOAD16_BYTE( "fa1-ma1u.bin", 0x480000, 0x100000, CRC(900297be) SHA1(57bb2078ff104c6f631c67219f80f8ede5ddbd09) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( swcourt )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "sc2-ep0l.4c",  0x080001, 0x080000, CRC(5053a02e) SHA1(8ab5a085969cef5e01be01d8f531233002ea5bff) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "sc2-ep0u.4f",  0x080000, 0x080000, CRC(7b3fc7fa) SHA1(f96c03a03339b7677b8dc8689d907f2c8895886c) )
	ROM_LOAD16_BYTE( "sc1-ep1l.bin", 0x180001, 0x080000, CRC(fb45cf5f) SHA1(6ded351daa9b39d0b8149100caefc4fa0c598e79) )
	ROM_LOAD16_BYTE( "sc1-ep1u.bin", 0x180000, 0x080000, CRC(1ce07b15) SHA1(b1b28cc480301c9ad642597c7cdd8e9cdec996a6) )

	ROM_LOAD16_BYTE( "sc1-ma0l.bin", 0x280001, 0x100000, CRC(3e531f5e) SHA1(6da56630bdfbb19f1639c539779c180d106f6ee2) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "sc1-ma0u.bin", 0x280000, 0x100000, CRC(31e76a45) SHA1(5c278c167c1025c648ce2da2c3764645e96dcd55) )
	ROM_LOAD16_BYTE( "sc1-ma1l.bin", 0x480001, 0x100000, CRC(8ba3a4ec) SHA1(f881e7b4728f388d18450ba85e13e233071fbc88) )
	ROM_LOAD16_BYTE( "sc1-ma1u.bin", 0x480000, 0x100000, CRC(252dc4b7) SHA1(f1be6bd045495c7a0ecd97f01d1dc8ad341fecfd) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( swcourtj )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "sc1-ep0l.4c",  0x080001, 0x080000, CRC(145111dd) SHA1(f8f74f77fb80af2ea37ea8ddbf02c1f3fcaf3fdb) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "sc1-ep0u.4f",  0x080000, 0x080000, CRC(c721c138) SHA1(5d30d66629d982b54c3bb62118be940dc7b69a6b) )
	ROM_LOAD16_BYTE( "sc1-ep1l.bin", 0x180001, 0x080000, CRC(fb45cf5f) SHA1(6ded351daa9b39d0b8149100caefc4fa0c598e79) )
	ROM_LOAD16_BYTE( "sc1-ep1u.bin", 0x180000, 0x080000, CRC(1ce07b15) SHA1(b1b28cc480301c9ad642597c7cdd8e9cdec996a6) )

	ROM_LOAD16_BYTE( "sc1-ma0l.bin", 0x280001, 0x100000, CRC(3e531f5e) SHA1(6da56630bdfbb19f1639c539779c180d106f6ee2) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "sc1-ma0u.bin", 0x280000, 0x100000, CRC(31e76a45) SHA1(5c278c167c1025c648ce2da2c3764645e96dcd55) )
	ROM_LOAD16_BYTE( "sc1-ma1l.bin", 0x480001, 0x100000, CRC(8ba3a4ec) SHA1(f881e7b4728f388d18450ba85e13e233071fbc88) )
	ROM_LOAD16_BYTE( "sc1-ma1u.bin", 0x480000, 0x100000, CRC(252dc4b7) SHA1(f1be6bd045495c7a0ecd97f01d1dc8ad341fecfd) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END

ROM_START( tinklpit )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "tk1-ep0l.bin", 0x080001, 0x080000, CRC(fdccae42) SHA1(398384482ccb3eb08bfb9db495513272a5188d92) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "tk1-ep0u.bin", 0x080000, 0x080000, CRC(62cdb48c) SHA1(73c7b99b117b8dc567bc254b0ffcc117c9d42fb5) )
	ROM_LOAD16_BYTE( "tk1-ep1l.bin", 0x180001, 0x080000, CRC(7e90f104) SHA1(79e371426b2e32dc8f687e4d124d23c251198937) )
	ROM_LOAD16_BYTE( "tk1-ep1u.bin", 0x180000, 0x080000, CRC(9c0b70d6) SHA1(eac44d3470f4c2ddd9c41f82e6398bca0cc8a4fd) )

	ROM_LOAD16_BYTE( "tk1-ma0l.bin", 0x280001, 0x100000, CRC(c6b4e15d) SHA1(55252ba4d904b14940436f1b4dc5e2a6bd163bdf) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "tk1-ma0u.bin", 0x280000, 0x100000, CRC(a3ad6f67) SHA1(54289eed5347defb5464ec5a610a6748909159f6) )
	ROM_LOAD16_BYTE( "tk1-ma1l.bin", 0x480001, 0x100000, CRC(61cfb92a) SHA1(eacf0e7557f33d552045f43a116ff08c533a2771) )
	ROM_LOAD16_BYTE( "tk1-ma1u.bin", 0x480000, 0x100000, CRC(54b77816) SHA1(9341d07858623e1920eaae7b2b90126c7057297e) )
	ROM_LOAD16_BYTE( "tk1-ma2l.bin", 0x680001, 0x100000, CRC(087311d2) SHA1(6fe50f9e08551e57d15a15b01e3822a6cb7c8352) )
	ROM_LOAD16_BYTE( "tk1-ma2u.bin", 0x680000, 0x100000, CRC(5ce20c2c) SHA1(7eaff21714bae44f8b21b6db98f055e04bfbae18) )

	/* M37702 BIOS - labeled as Namco custom C69 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c69.bin",      0x000000, 0x004000, CRC(349134d9) SHA1(61a4981fc2716c228b6121fedcbf1ed6f34dc2de) )
ROM_END


/**************************************
     NA-2 Based games
**************************************/


ROM_START( emeralda ) /* NA-2 Game PCB, clones are NA-1 based; see games listed above */
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "em2-ep0l.6c", 0x080001, 0x080000, CRC(ff1479dc) SHA1(ea945d97ed909be13fb6e062742c7142c0d96c31) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "em2-ep0u.6f", 0x080000, 0x080000, CRC(ffe750a2) SHA1(d10d31489ae364572d7517dd515a6af2182ac764) )
	ROM_LOAD16_BYTE( "em2-ep1l.7c", 0x180001, 0x080000, CRC(6c3e5b53) SHA1(72b941e28c7fda8cb81240a8226386fe55c14e2d) )
	ROM_LOAD16_BYTE( "em2-ep1u.7f", 0x180000, 0x080000, CRC(dee15a81) SHA1(474a264029bd77e4205773a7461dea695e65933f) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( knckhead )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "kh2-ep0l.bin", 0x080001, 0x080000, CRC(b4b88077) SHA1(9af03d1832ad6c77222e18427f4afca330a41ce6) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "kh2-ep0u.bin", 0x080000, 0x080000, CRC(a578d97e) SHA1(9a5bb6649cca7b98daf538a66c813f61cca2e2ec) )
	ROM_LOAD16_BYTE( "kh1-ep1l.bin", 0x180001, 0x080000, CRC(27e6ab4e) SHA1(66f397cc2117c1e73652c4800c0937e6d8116380) )
	ROM_LOAD16_BYTE( "kh1-ep1u.bin", 0x180000, 0x080000, CRC(487b2434) SHA1(2d62db85ceac1fca61c39e4db92c96ae80ba3323) )

	ROM_LOAD16_BYTE( "kh1-ma0l.bin", 0x280001, 0x100000, CRC(7b2db5df) SHA1(ecc392c4683cf0718d986e73336b69952d324548) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "kh1-ma0u.bin", 0x280000, 0x100000, CRC(6983228b) SHA1(5f3eeb780e9d91445b4c11da63d4ca580e654f34) )
	ROM_LOAD16_BYTE( "kh1-ma1l.bin", 0x480001, 0x100000, CRC(b24f93e6) SHA1(3d8951485dc8a2810da9ddf2f4896efa31779bf4) )
	ROM_LOAD16_BYTE( "kh1-ma1u.bin", 0x480000, 0x100000, CRC(18a60348) SHA1(298e0e0e7649e872791c3c99c81a19f273e9eb8a) )
	ROM_LOAD16_BYTE( "kh1-ma2l.bin", 0x680001, 0x100000, CRC(82064ee9) SHA1(0b984565d17e580f49fff982a1621ef90e14c064) )
	ROM_LOAD16_BYTE( "kh1-ma2u.bin", 0x680000, 0x100000, CRC(17fe8c3d) SHA1(88c45076477725faa5f8a23512e65a40385bb27d) )
	ROM_LOAD16_BYTE( "kh1-ma3l.bin", 0x880001, 0x100000, CRC(ad9a7807) SHA1(c40f18a68306e76acd89ccb3fc82b8106556912e) )
	ROM_LOAD16_BYTE( "kh1-ma3u.bin", 0x880000, 0x100000, CRC(efeb768d) SHA1(15d016244549f3ea0d19f5cfb04bcebd65ac6134) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( knckheadj )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "kh1-ep0l.bin", 0x080001, 0x080000, CRC(94660bec) SHA1(42fa23f759cf66b05f30c2fc03a12fd14ae1f796) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "kh1-ep0u.bin", 0x080000, 0x080000, CRC(ad640d69) SHA1(62595a9d1d5952cbe3dd7266cfda9292be51d269) )
	ROM_LOAD16_BYTE( "kh1-ep1l.bin", 0x180001, 0x080000, CRC(27e6ab4e) SHA1(66f397cc2117c1e73652c4800c0937e6d8116380) )
	ROM_LOAD16_BYTE( "kh1-ep1u.bin", 0x180000, 0x080000, CRC(487b2434) SHA1(2d62db85ceac1fca61c39e4db92c96ae80ba3323) )

	ROM_LOAD16_BYTE( "kh1-ma0l.bin", 0x280001, 0x100000, CRC(7b2db5df) SHA1(ecc392c4683cf0718d986e73336b69952d324548) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "kh1-ma0u.bin", 0x280000, 0x100000, CRC(6983228b) SHA1(5f3eeb780e9d91445b4c11da63d4ca580e654f34) )
	ROM_LOAD16_BYTE( "kh1-ma1l.bin", 0x480001, 0x100000, CRC(b24f93e6) SHA1(3d8951485dc8a2810da9ddf2f4896efa31779bf4) )
	ROM_LOAD16_BYTE( "kh1-ma1u.bin", 0x480000, 0x100000, CRC(18a60348) SHA1(298e0e0e7649e872791c3c99c81a19f273e9eb8a) )
	ROM_LOAD16_BYTE( "kh1-ma2l.bin", 0x680001, 0x100000, CRC(82064ee9) SHA1(0b984565d17e580f49fff982a1621ef90e14c064) )
	ROM_LOAD16_BYTE( "kh1-ma2u.bin", 0x680000, 0x100000, CRC(17fe8c3d) SHA1(88c45076477725faa5f8a23512e65a40385bb27d) )
	ROM_LOAD16_BYTE( "kh1-ma3l.bin", 0x880001, 0x100000, CRC(ad9a7807) SHA1(c40f18a68306e76acd89ccb3fc82b8106556912e) )
	ROM_LOAD16_BYTE( "kh1-ma3u.bin", 0x880000, 0x100000, CRC(efeb768d) SHA1(15d016244549f3ea0d19f5cfb04bcebd65ac6134) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( numanath )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "nm2-ep0l.bin", 0x080001, 0x080000, CRC(f24414bb) SHA1(68b13dfdc2292afd5279edb891fe63972f991e7b) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "nm2-ep0u.bin", 0x080000, 0x080000, CRC(25c41616) SHA1(68ba67d3dd45f3bdddfa2fd21b574535306c1214) )
	ROM_LOAD16_BYTE( "nm1-ep1l.bin", 0x180001, 0x080000, CRC(4581dcb4) SHA1(1f46f98e63a7c9cdfde9e8ee2696a13c3f9bcc8e) )
	ROM_LOAD16_BYTE( "nm1-ep1u.bin", 0x180000, 0x080000, CRC(30cd589a) SHA1(74a14ec41fe4fc9f73e5357b0903f1199ed96337) )

	ROM_LOAD16_BYTE( "nm1-ma0l.bin", 0x280001, 0x100000, CRC(20faaa57) SHA1(9dbfc0dd48eec37b2c0715a5691c6e6f923fc7f7) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "nm1-ma0u.bin", 0x280000, 0x100000, CRC(ed7c37f2) SHA1(829751af33754ade941f76982e196b494d56ab0a) )
	ROM_LOAD16_BYTE( "nm1-ma1l.bin", 0x480001, 0x100000, CRC(2232e3b4) SHA1(e9da3dc34eb2576c8a88e23cb9007129e885496d) )
	ROM_LOAD16_BYTE( "nm1-ma1u.bin", 0x480000, 0x100000, CRC(6cc9675c) SHA1(fec74da4479f2a088760efc6908e6acfaea3989f) )
	ROM_LOAD16_BYTE( "nm1-ma2l.bin", 0x680001, 0x100000, CRC(208abb39) SHA1(52d7247a71c6a14467f12f5270921bba1824cc3f) )
	ROM_LOAD16_BYTE( "nm1-ma2u.bin", 0x680000, 0x100000, CRC(03a3f204) SHA1(9cb0422c8ecc819d0cc8a65c29a228369d78d986) )
	ROM_LOAD16_BYTE( "nm1-ma3l.bin", 0x880001, 0x100000, CRC(42a539e9) SHA1(1c53a5a031648891ab7a37cf026c979404ce9589) )
	ROM_LOAD16_BYTE( "nm1-ma3u.bin", 0x880000, 0x100000, CRC(f79e2112) SHA1(8bb8639a9d3a5d3ac5c9bb78e72b3d76582a9c25) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( numanathj )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "nm1-ep0l.bin", 0x080001, 0x080000, CRC(4398b898) SHA1(0d1517409ba181f796f7f413cac704c60085b505) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "nm1-ep0u.bin", 0x080000, 0x080000, CRC(be90aa79) SHA1(6884a8d72dd34c889527e8e653f5e5b4cf3fb5d6) )
	ROM_LOAD16_BYTE( "nm1-ep1l.bin", 0x180001, 0x080000, CRC(4581dcb4) SHA1(1f46f98e63a7c9cdfde9e8ee2696a13c3f9bcc8e) )
	ROM_LOAD16_BYTE( "nm1-ep1u.bin", 0x180000, 0x080000, CRC(30cd589a) SHA1(74a14ec41fe4fc9f73e5357b0903f1199ed96337) )

	ROM_LOAD16_BYTE( "nm1-ma0l.bin", 0x280001, 0x100000, CRC(20faaa57) SHA1(9dbfc0dd48eec37b2c0715a5691c6e6f923fc7f7) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "nm1-ma0u.bin", 0x280000, 0x100000, CRC(ed7c37f2) SHA1(829751af33754ade941f76982e196b494d56ab0a) )
	ROM_LOAD16_BYTE( "nm1-ma1l.bin", 0x480001, 0x100000, CRC(2232e3b4) SHA1(e9da3dc34eb2576c8a88e23cb9007129e885496d) )
	ROM_LOAD16_BYTE( "nm1-ma1u.bin", 0x480000, 0x100000, CRC(6cc9675c) SHA1(fec74da4479f2a088760efc6908e6acfaea3989f) )
	ROM_LOAD16_BYTE( "nm1-ma2l.bin", 0x680001, 0x100000, CRC(208abb39) SHA1(52d7247a71c6a14467f12f5270921bba1824cc3f) )
	ROM_LOAD16_BYTE( "nm1-ma2u.bin", 0x680000, 0x100000, CRC(03a3f204) SHA1(9cb0422c8ecc819d0cc8a65c29a228369d78d986) )
	ROM_LOAD16_BYTE( "nm1-ma3l.bin", 0x880001, 0x100000, CRC(42a539e9) SHA1(1c53a5a031648891ab7a37cf026c979404ce9589) )
	ROM_LOAD16_BYTE( "nm1-ma3u.bin", 0x880000, 0x100000, CRC(f79e2112) SHA1(8bb8639a9d3a5d3ac5c9bb78e72b3d76582a9c25) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( quiztou )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "qt1ep0l.6c", 0x080001, 0x080000, CRC(b680e543) SHA1(f10f38113a46c821d8e9d66f52d7311d9d52e595) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "qt1ep0u.6f", 0x080000, 0x080000, CRC(143c5e4d) SHA1(24c584986c97a5e6fe7e73f0e9af4af28ed20c4a) )
	ROM_LOAD16_BYTE( "qt1ep1l.7c", 0x180001, 0x080000, CRC(33a72242) SHA1(5d17f033878d28dbebba50931a549ccf84802c05) )
	ROM_LOAD16_BYTE( "qt1ep1u.7f", 0x180000, 0x080000, CRC(69f876cb) SHA1(d0c7e972a04c45d3ab34ef5be88614d6389189c6) )

	ROM_LOAD16_BYTE( "qt1ma0l.2c", 0x280001, 0x100000, CRC(5597f2b9) SHA1(747c4be867d4eb37ffab8303740729686a00b825) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "qt1ma0u.2f", 0x280000, 0x100000, CRC(f0a4cb7d) SHA1(364e85af956e7cfc29c957da11574a4b389f7797) )
	ROM_LOAD16_BYTE( "qt1ma1l.3c", 0x480001, 0x100000, CRC(1b9ce7a6) SHA1(dac1da9dd8076f238211fed5c780b4b8bededf22) )
	ROM_LOAD16_BYTE( "qt1ma1u.3f", 0x480000, 0x100000, CRC(58910872) SHA1(c0acbd64e90672564c3839fd21870672aa32e439) )
	ROM_LOAD16_BYTE( "qt1ma2l.4c", 0x680001, 0x100000, CRC(94739917) SHA1(b5be5c9fd7223d3fb601f769cb80f56a5a586de0) )
	ROM_LOAD16_BYTE( "qt1ma2u.4f", 0x680000, 0x100000, CRC(6ba5b893) SHA1(071caed9cf261f1f8af7079875bd206177baef1a) )
	ROM_LOAD16_BYTE( "qt1ma3l.5c", 0x880001, 0x100000, CRC(aa9dc6ff) SHA1(c738f8c59bb5245874576c5bcf88c7138fa9a147) )
	ROM_LOAD16_BYTE( "qt1ma3u.5f", 0x880000, 0x100000, CRC(14a5a163) SHA1(1107f50e491bedeb4ab7ac3f32cfe47727274ba9) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

ROM_START( xday2 )
	ROM_REGION( 0xa80000, "maincpu", 0 )
	ROM_LOAD16_BYTE( "xds1-mpr0.4b", 0x080001, 0x080000, CRC(83539aaa) SHA1(42d97bb2daaf5ff48efac70f0ff37869c5ba177d) ) /* 0xc00000 */
	ROM_LOAD16_BYTE( "xds1-mpr1.8b", 0x080000, 0x080000, CRC(468b36de) SHA1(52817be9913a6938ce6add2834ba1a727b1d677e) )

	ROM_LOAD16_BYTE( "xds1-dat0.4b", 0x280001, 0x200000, CRC(42cecc8b) SHA1(7510f16b908dd0f7828887dcfa26c5e4643df66c) ) /* 0x400000 */
	ROM_LOAD16_BYTE( "xds1-dat1.8b", 0x280000, 0x200000, CRC(d250b7e8) SHA1(b99251ae8e25fae062d33e74ff800ab43fb308a2) )
	ROM_LOAD16_BYTE( "xds1-dat2.4c", 0x680001, 0x200000, CRC(99d72a08) SHA1(4615b43b9a81240ffee8b0f021037f554f4f1f24) )
	ROM_LOAD16_BYTE( "xds1-dat3.8c", 0x680000, 0x200000, CRC(8980acc4) SHA1(ecd94a3d3a38923e8e322cd8863671af26e30812) )

	/* M37702 BIOS - labeled as Namco custom C70 */
	ROM_REGION16_LE( 0x4000, "mcu", 0 )
        ROM_LOAD( "c70.bin",      0x000000, 0x004000, CRC(b4015f23) SHA1(7ce91eda76e86b5cab625e2b67c463b7d143832e) )
ROM_END

// NA-1 (C69 MCU)
GAME( 1992, bkrtmaq,    0,        namcona1w, namcona1_quiz,bkrtmaq,  ROT0, "Namco", "Bakuretsu Quiz Ma-Q Dai Bouken (Japan)", 0 )
GAME( 1992, cgangpzl,   0,        namcona1w, namcona1_joy, cgangpzl, ROT0, "Namco", "Cosmo Gang the Puzzle (US)", 0 )
GAME( 1992, cgangpzlj,  cgangpzl, namcona1w, namcona1_joy, cgangpzl, ROT0, "Namco", "Cosmo Gang the Puzzle (Japan)", 0 )
GAME( 1992, exvania,    0,        namcona1,  namcona1_joy, exbania,  ROT0, "Namco", "Exvania (World)", 0 )
GAME( 1992, exvaniaj,   exvania,  namcona1,  namcona1_joy, exbania,  ROT0, "Namco", "Exvania (Japan)", 0 )
GAME( 1992, fghtatck,   0,        namcona1,  namcona1_joy, fa,       ROT90,"Namco", "Fighter & Attacker (US)", 0 )
GAME( 1992, fa,         fghtatck, namcona1,  namcona1_joy, fa,       ROT90,"Namco", "F/A (Japan)", 0 )
GAME( 1992, swcourt,    0,        namcona1w, namcona1_joy, swcourt,  ROT0, "Namco", "Super World Court (World)", 0 )
GAME( 1992, swcourtj,   swcourt,  namcona1w, namcona1_joy, swcourt,  ROT0, "Namco", "Super World Court (Japan)", 0 )
GAME( 1993, emeraldaj,  emeralda, namcona1w, namcona1_joy, emeraldj, ROT0, "Namco", "Emeraldia (Japan Version B)", 0 ) /* Parent is below on NA-2 Hardware */
GAME( 1993, emeraldaja, emeralda, namcona1w, namcona1_joy, emeraldj, ROT0, "Namco", "Emeraldia (Japan)", 0 ) /* Parent is below on NA-2 Hardware */
GAME( 1993, tinklpit,   0,        namcona1w, namcona1_joy, tinklpit, ROT0, "Namco", "Tinkle Pit (Japan)", 0 )

// NA-2 (C70 MCU)
GAME( 1992, knckhead,  0,        namcona2,  namcona1_joy, knckhead, ROT0, "Namco", "Knuckle Heads (World)", 0 )
GAME( 1992, knckheadj, knckhead, namcona2,  namcona1_joy, knckhead, ROT0, "Namco", "Knuckle Heads (Japan)", 0 )
GAME( 1993, emeralda,  0,        namcona2,  namcona1_joy, emeralda, ROT0, "Namco", "Emeraldia (World)", 0 )
GAME( 1993, numanath,  0,        namcona2,  namcona1_joy, numanath, ROT0, "Namco", "Numan Athletics (World)", 0 )
GAME( 1993, numanathj, numanath, namcona2,  namcona1_joy, numanath, ROT0, "Namco", "Numan Athletics (Japan)", 0 )
GAME( 1993, quiztou,   0,        namcona2,  namcona1_quiz,quiztou,  ROT0, "Namco", "Nettou! Gekitou! Quiztou!! (Japan)", 0 )
GAME( 1995, xday2,     0,        namcona2,  namcona1_joy, xday2,    ROT0, "Namco", "X-Day 2 (Japan)", GAME_IMPERFECT_GRAPHICS )