trunk/src/mess/drivers/vboy.c
r17441 | r17442 | |
133 | 133 | void m_timer_tick(void); |
134 | 134 | void m_scanline_tick(int scanline, UINT8 screen_type); |
135 | 135 | void m_set_irq(UINT16 irq_vector); |
| 136 | UINT8 *m_nvptr; |
| 137 | UINT32 m_vboy_sram[0x10000/4]; |
| 138 | device_t *m_nvimage; |
| 139 | DECLARE_READ32_MEMBER(sram_r); |
| 140 | DECLARE_WRITE32_MEMBER(sram_w); |
136 | 141 | |
137 | 142 | void m_pcg_debug(UINT16 offset,UINT16 data,UINT16 mem_mask); |
138 | 143 | |
r17441 | r17442 | |
1084 | 1089 | AM_RANGE( 0x02000000, 0x0200002b ) AM_MIRROR(0x0ffff00) AM_READWRITE(io_r, io_w) // Hardware control registers mask 0xff |
1085 | 1090 | //AM_RANGE( 0x04000000, 0x04ffffff ) // Expansion area |
1086 | 1091 | AM_RANGE( 0x05000000, 0x0500ffff ) AM_MIRROR(0x0ff0000) AM_RAM AM_SHARE("wram")// Main RAM - 64K mask 0xffff |
1087 | | AM_RANGE( 0x06000000, 0x06003fff ) AM_RAM AM_SHARE("nvram") // Cart RAM - 8K NVRAM |
1088 | | AM_RANGE( 0x07000000, 0x071fffff ) AM_MIRROR(0x0e00000) AM_ROM AM_REGION("user1", 0) /* ROM */ |
| 1092 | // AM_RANGE( 0x06000000, 0x06003fff ) AM_RAM AM_SHARE("nvram") // Cart RAM - 8K NVRAM |
| 1093 | AM_RANGE( 0x07000000, 0x071fffff ) AM_MIRROR(0x0e00000) AM_ROM AM_REGION("cartridge", 0) /* ROM */ |
1089 | 1094 | ADDRESS_MAP_END |
1090 | 1095 | |
1091 | 1096 | static ADDRESS_MAP_START( vboy_io, AS_IO, 32, vboy_state ) |
r17441 | r17442 | |
1114 | 1119 | // AM_RANGE( 0x04000000, 0x04ffffff ) // Expansion area |
1115 | 1120 | AM_RANGE( 0x05000000, 0x0500ffff ) AM_MIRROR(0x0ff0000) AM_RAM AM_SHARE("wram") // Main RAM - 64K mask 0xffff |
1116 | 1121 | AM_RANGE( 0x06000000, 0x06003fff ) AM_RAM AM_SHARE("nvram") // Cart RAM - 8K NVRAM |
1117 | | AM_RANGE( 0x07000000, 0x071fffff ) AM_MIRROR(0x0e00000) AM_ROM AM_REGION("user1", 0) /* ROM */ |
| 1122 | AM_RANGE( 0x07000000, 0x071fffff ) AM_MIRROR(0x0e00000) AM_ROM AM_REGION("cartridge", 0) /* ROM */ |
1118 | 1123 | ADDRESS_MAP_END |
1119 | 1124 | |
1120 | 1125 | /* Input ports */ |
r17441 | r17442 | |
1138 | 1143 | PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED ) // Battery low |
1139 | 1144 | INPUT_PORTS_END |
1140 | 1145 | |
| 1146 | static void vboy_machine_stop(running_machine &machine) |
| 1147 | { |
| 1148 | vboy_state *state = machine.driver_data<vboy_state>(); |
1141 | 1149 | |
| 1150 | // only do this if the cart loader detected some form of backup |
| 1151 | if (state->m_nvptr != NULL) |
| 1152 | { |
| 1153 | device_image_interface *image = dynamic_cast<device_image_interface *>(state->m_nvimage); |
| 1154 | image->battery_save(state->m_nvptr, 0x10000); |
| 1155 | } |
| 1156 | } |
| 1157 | |
| 1158 | static MACHINE_START( vboy ) |
| 1159 | { |
| 1160 | // vboy_state *state = machine.driver_data<vboy_state>(); |
| 1161 | |
| 1162 | /* add a hook for battery save */ |
| 1163 | machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(vboy_machine_stop),&machine)); |
| 1164 | |
| 1165 | // state->m_vboy_sram = auto_alloc_array(machine, UINT32, 0x10000/4); |
| 1166 | } |
| 1167 | |
1142 | 1168 | static MACHINE_RESET(vboy) |
1143 | 1169 | { |
1144 | 1170 | vboy_state *state = machine.driver_data<vboy_state>(); |
r17441 | r17442 | |
1204 | 1230 | { |
1205 | 1231 | vboy_state *state = timer.machine().driver_data<vboy_state>(); |
1206 | 1232 | |
1207 | | device_set_input_line(state->m_maincpu, 0, HOLD_LINE); |
| 1233 | if((state->m_vboy_regs.kcr & 0x80) == 0) |
| 1234 | device_set_input_line(state->m_maincpu, 0, HOLD_LINE); |
1208 | 1235 | } |
1209 | 1236 | |
1210 | 1237 | static PALETTE_INIT( vboy ) |
r17441 | r17442 | |
1313 | 1340 | GFXDECODE_ENTRY( "pcg", 0x00000, vboy_pcg_8x8, 0, 1 ) |
1314 | 1341 | GFXDECODE_END |
1315 | 1342 | |
| 1343 | typedef struct _vboy_pcb vboy_pcb; |
| 1344 | struct _vboy_pcb |
| 1345 | { |
| 1346 | const char *pcb_name; |
| 1347 | int pcb_id; |
| 1348 | }; |
1316 | 1349 | |
| 1350 | READ32_MEMBER(vboy_state::sram_r) |
| 1351 | { |
| 1352 | return m_vboy_sram[offset]; |
| 1353 | } |
| 1354 | |
| 1355 | WRITE32_MEMBER(vboy_state::sram_w) |
| 1356 | { |
| 1357 | COMBINE_DATA(&m_vboy_sram[offset]); |
| 1358 | } |
| 1359 | |
| 1360 | #define VBOY_CHIP_NONE 0 |
| 1361 | #define VBOY_CHIP_SRAM 1 |
| 1362 | |
| 1363 | static const vboy_pcb pcb_list[] = |
| 1364 | { |
| 1365 | {"No", VBOY_CHIP_NONE}, |
| 1366 | {"Yes", VBOY_CHIP_SRAM} |
| 1367 | }; |
| 1368 | |
| 1369 | |
| 1370 | static int vboy_get_pcb_id(const char *pcb) |
| 1371 | { |
| 1372 | int i; |
| 1373 | |
| 1374 | for (i = 0; i < ARRAY_LENGTH(pcb_list); i++) |
| 1375 | { |
| 1376 | if (!mame_stricmp(pcb_list[i].pcb_name, pcb)) |
| 1377 | return pcb_list[i].pcb_id; |
| 1378 | } |
| 1379 | |
| 1380 | return 0; |
| 1381 | } |
| 1382 | |
| 1383 | |
| 1384 | static DEVICE_IMAGE_LOAD( vboy_cart ) |
| 1385 | { |
| 1386 | vboy_state *state = image.device().machine().driver_data<vboy_state>(); |
| 1387 | UINT32 chip = 0; |
| 1388 | UINT8 *ROM = image.device().machine().root_device().memregion("cartridge")->base(); |
| 1389 | UINT32 cart_size; |
| 1390 | |
| 1391 | state->m_nvptr = (UINT8 *)NULL; |
| 1392 | if (image.software_entry() == NULL) |
| 1393 | { |
| 1394 | cart_size = image.length(); |
| 1395 | image.fread(ROM, cart_size); |
| 1396 | } |
| 1397 | else |
| 1398 | { |
| 1399 | const char *pcb_name; |
| 1400 | cart_size = image.get_software_region_length("rom"); |
| 1401 | memcpy(ROM, image.get_software_region("rom"), cart_size); |
| 1402 | |
| 1403 | pcb_name = image.get_feature("eeprom"); |
| 1404 | if (pcb_name == NULL) |
| 1405 | chip = 0; |
| 1406 | else |
| 1407 | chip = vboy_get_pcb_id(pcb_name); |
| 1408 | |
| 1409 | } |
| 1410 | |
| 1411 | if(chip & VBOY_CHIP_SRAM) |
| 1412 | { |
| 1413 | state->m_nvptr = (UINT8 *)&state->m_vboy_sram; |
| 1414 | |
| 1415 | image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->install_read_handler(0x06000000, 0x0600ffff, read32_delegate(FUNC(vboy_state::sram_r),state)); |
| 1416 | image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->install_write_handler(0x06000000, 0x0600ffff, write32_delegate(FUNC(vboy_state::sram_w),state)); |
| 1417 | |
| 1418 | image.battery_load(state->m_nvptr, 0x10000, 0x00); |
| 1419 | state->m_nvimage = image; |
| 1420 | } |
| 1421 | else |
| 1422 | { |
| 1423 | state->m_nvimage = NULL; |
| 1424 | } |
| 1425 | |
| 1426 | return IMAGE_INIT_PASS; |
| 1427 | } |
| 1428 | |
1317 | 1429 | static MACHINE_CONFIG_START( vboy, vboy_state ) |
1318 | 1430 | |
1319 | 1431 | /* basic machine hardware */ |
r17441 | r17442 | |
1323 | 1435 | MCFG_TIMER_ADD_SCANLINE("scantimer_l", vboy_scanlineL, "3dleft", 0, 1) |
1324 | 1436 | //MCFG_TIMER_ADD_SCANLINE("scantimer_r", vboy_scanlineR, "3dright", 0, 1) |
1325 | 1437 | |
| 1438 | MCFG_MACHINE_START(vboy) |
1326 | 1439 | MCFG_MACHINE_RESET(vboy) |
1327 | 1440 | |
1328 | 1441 | // programmable timer |
r17441 | r17442 | |
1352 | 1465 | MCFG_CARTSLOT_EXTENSION_LIST("vb,bin") |
1353 | 1466 | MCFG_CARTSLOT_MANDATORY |
1354 | 1467 | MCFG_CARTSLOT_INTERFACE("vboy_cart") |
| 1468 | MCFG_CARTSLOT_LOAD(vboy_cart) |
1355 | 1469 | |
1356 | 1470 | MCFG_GFXDECODE(vboy) |
1357 | 1471 | |
r17441 | r17442 | |
1367 | 1481 | |
1368 | 1482 | /* ROM definition */ |
1369 | 1483 | ROM_START( vboy ) |
1370 | | ROM_REGION( 0x200000, "user1", 0 ) |
1371 | | ROM_CART_LOAD("cart", 0x0000, 0x200000, ROM_MIRROR) |
| 1484 | ROM_REGION( 0x2000000, "cartridge", ROMREGION_ERASEFF ) |
1372 | 1485 | |
1373 | 1486 | ROM_REGION( 0x8000, "pcg", ROMREGION_ERASE00 ) |
1374 | 1487 | ROM_END |