src/osd/sdl/debugwin.c
| r9240 | r9241 | |
| 22 | 22 | #include "debug-sup.h" |
| 23 | 23 | #include "debug-cb.h" |
| 24 | 24 | |
| 25 | #include "config.h" |
| 26 | |
| 25 | 27 | //============================================================ |
| 26 | 28 | // PARAMETERS |
| 27 | 29 | //============================================================ |
| r9240 | r9241 | |
| 74 | 76 | running_device * cpu; // current CPU |
| 75 | 77 | }; |
| 76 | 78 | |
| 79 | struct windowState |
| 80 | { |
| 81 | windowState() : type(0), |
| 82 | sizeX(-1), sizeY(-1), |
| 83 | positionX(-1), positionY(-1) { } |
| 84 | ~windowState() { } |
| 85 | |
| 86 | void loadFromXmlDataNode(xml_data_node* wnode) |
| 87 | { |
| 88 | if (!wnode) return; |
| 89 | |
| 90 | type = xml_get_attribute_int(wnode, "type", type); |
| 77 | 91 | |
| 92 | sizeX = xml_get_attribute_int(wnode, "size_x", sizeX); |
| 93 | sizeY = xml_get_attribute_int(wnode, "size_y", sizeY); |
| 94 | positionX = xml_get_attribute_int(wnode, "position_x", positionX); |
| 95 | positionY = xml_get_attribute_int(wnode, "position_y", positionY); |
| 96 | } |
| 97 | |
| 98 | int type; |
| 99 | int sizeX; |
| 100 | int sizeY; |
| 101 | int positionX; |
| 102 | int positionY; |
| 103 | }; |
| 104 | windowState windowStateArray[64]; |
| 105 | int windowStateCount = 0; |
| 106 | |
| 78 | 107 | //============================================================ |
| 79 | 108 | // LOCAL VARIABLES |
| 80 | 109 | //============================================================ |
| r9240 | r9241 | |
| 86 | 115 | //============================================================ |
| 87 | 116 | |
| 88 | 117 | static void debugmain_init(running_machine *machine); |
| 118 | static void memorywin_new(running_machine *machine); |
| 119 | static void disasmwin_new(running_machine *machine); |
| 120 | static void logwin_new(running_machine *machine); |
| 89 | 121 | |
| 90 | 122 | |
| 91 | 123 | //============================================================ |
| r9240 | r9241 | |
| 444 | 476 | } |
| 445 | 477 | |
| 446 | 478 | |
| 479 | //============================================================ |
| 480 | // configuration_load |
| 481 | //============================================================ |
| 447 | 482 | |
| 483 | static void configuration_load(running_machine *machine, int config_type, xml_data_node *parentnode) |
| 484 | { |
| 485 | xml_data_node *wnode; |
| 486 | |
| 487 | /* we only care about game files */ |
| 488 | if (config_type != CONFIG_TYPE_GAME) |
| 489 | return; |
| 490 | |
| 491 | /* might not have any data */ |
| 492 | if (parentnode == NULL) |
| 493 | return; |
| 494 | |
| 495 | /* configuration load */ |
| 496 | int i = 0; |
| 497 | for (wnode = xml_get_sibling(parentnode->child, "window"); wnode != NULL; wnode = xml_get_sibling(wnode->next, "window")) |
| 498 | { |
| 499 | windowStateArray[i].loadFromXmlDataNode(wnode); |
| 500 | i++; |
| 501 | } |
| 502 | windowStateCount = i; |
| 503 | } |
| 504 | |
| 448 | 505 | //============================================================ |
| 506 | // configuration_save |
| 507 | //============================================================ |
| 508 | |
| 509 | static void configuration_save(running_machine *machine, int config_type, xml_data_node *parentnode) |
| 510 | { |
| 511 | /* we only care about game files */ |
| 512 | if (config_type != CONFIG_TYPE_GAME) |
| 513 | return; |
| 514 | |
| 515 | // Loop over all the nodes |
| 516 | for(win_i *p = win_list; p != NULL; p = p->next) |
| 517 | { |
| 518 | /* create a node */ |
| 519 | xml_data_node *debugger_node; |
| 520 | debugger_node = xml_add_child(parentnode, "window", NULL); |
| 521 | |
| 522 | xml_set_attribute_int(debugger_node, "type", p->type); |
| 523 | |
| 524 | if (debugger_node != NULL) |
| 525 | { |
| 526 | int x, y; |
| 527 | gtk_window_get_position(GTK_WINDOW(p->win), &x, &y); |
| 528 | xml_set_attribute_int(debugger_node, "position_x", x); |
| 529 | xml_set_attribute_int(debugger_node, "position_y", y); |
| 530 | |
| 531 | gtk_window_get_size(GTK_WINDOW(p->win), &x, &y); |
| 532 | xml_set_attribute_int(debugger_node, "size_x", x); |
| 533 | xml_set_attribute_int(debugger_node, "size_y", y); |
| 534 | } |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | |
| 539 | //============================================================ |
| 540 | // osd_init_debugger |
| 541 | //============================================================ |
| 542 | |
| 543 | void osd_init_debugger(running_machine *machine) |
| 544 | { |
| 545 | /* register callbacks */ |
| 546 | config_register(machine, "debugger", configuration_load, configuration_save); |
| 547 | } |
| 548 | |
| 549 | |
| 550 | //============================================================ |
| 449 | 551 | // osd_wait_for_debugger |
| 450 | 552 | //============================================================ |
| 451 | 553 | |
| 452 | 554 | void osd_wait_for_debugger(running_device *device, int firststop) |
| 453 | 555 | { |
| 454 | 556 | win_i *dmain = get_first_win_i(WIN_TYPE_MAIN); |
| 455 | | // create a console window |
| 557 | |
| 558 | // Create a console window if one doesn't already exist |
| 456 | 559 | if(!dmain) |
| 457 | 560 | { |
| 458 | 561 | // GTK init should probably be done earlier |
| 459 | 562 | gtk_init(0, 0); |
| 460 | 563 | debugmain_init(device->machine); |
| 564 | |
| 565 | // Resize the main window |
| 566 | for (int i = 0; i < windowStateCount; i++) |
| 567 | { |
| 568 | if (windowStateArray[i].type == WIN_TYPE_MAIN) |
| 569 | { |
| 570 | gtk_window_move(GTK_WINDOW(win_list->win), windowStateArray[i].positionX, windowStateArray[i].positionY); |
| 571 | gtk_window_resize(GTK_WINDOW(win_list->win), windowStateArray[i].sizeX, windowStateArray[i].sizeY); |
| 572 | } |
| 573 | } |
| 574 | |
| 575 | // Respawn and reposition every other window |
| 576 | for (int i = 0; i < windowStateCount; i++) |
| 577 | { |
| 578 | if (!windowStateArray[i].type || windowStateArray[i].type == WIN_TYPE_MAIN) |
| 579 | continue; |
| 580 | |
| 581 | switch (windowStateArray[i].type) |
| 582 | { |
| 583 | case WIN_TYPE_MEMORY: memorywin_new(device->machine); break; |
| 584 | case WIN_TYPE_DISASM: disasmwin_new(device->machine); break; |
| 585 | case WIN_TYPE_LOG: logwin_new(device->machine); break; |
| 586 | default: break; |
| 587 | } |
| 588 | |
| 589 | gtk_window_move(GTK_WINDOW(win_list->win), windowStateArray[i].positionX, windowStateArray[i].positionY); |
| 590 | gtk_window_resize(GTK_WINDOW(win_list->win), windowStateArray[i].sizeX, windowStateArray[i].sizeY); |
| 591 | } |
| 461 | 592 | } |
| 462 | 593 | |
| 463 | 594 | // update the views in the console to reflect the current CPU |
| r9240 | r9241 | |
| 468 | 599 | } |
| 469 | 600 | |
| 470 | 601 | |
| 471 | | |
| 472 | 602 | //============================================================ |
| 473 | 603 | // debugwin_update_during_game |
| 474 | 604 | //============================================================ |
| r9240 | r9241 | |
| 483 | 613 | } |
| 484 | 614 | |
| 485 | 615 | |
| 486 | | |
| 487 | 616 | //============================================================ |
| 488 | 617 | // debugmain_process_string |
| 489 | 618 | //============================================================ |
| r9240 | r9241 | |
| 1143 | 1272 | #include "emu.h" |
| 1144 | 1273 | |
| 1145 | 1274 | // win32 stubs for linking |
| 1275 | void osd_init_debugger(running_machine *machine) |
| 1276 | { |
| 1277 | } |
| 1278 | |
| 1146 | 1279 | void osd_wait_for_debugger(running_device *device, int firststop) |
| 1147 | 1280 | { |
| 1148 | 1281 | } |
src/emu/cpu/sh2/sh2comn.c
| r9240 | r9241 | |
| 150 | 150 | b) in the CPU_EXECUTE loop |
| 151 | 151 | |
| 152 | 152 | |
| 153 | | we're currently doing b) |
| 153 | we're currently doing a) |
| 154 | b) seems to cause issues with ST-V games |
| 154 | 155 | |
| 155 | 156 | */ |
| 156 | 157 | |
| 158 | // Fever Soccer requires stupidly fast DMA or the palette gets corrupt due |
| 159 | // to DMA being cancelled mid-flight. Are we incorrectly emulating some other register? |
| 160 | #define DMA_TIMER_STEP (ATTOTIME_IN_NSEC(1)) |
| 161 | // have a bigger delay if no data is available, as it will take some time before there is |
| 162 | // any, and having such a high frequency timer with no data is not a good idea |
| 163 | #define DMA_TIMER_STEP_IF_UNAVAILABLE (ATTOTIME_IN_NSEC(1000)) |
| 157 | 164 | |
| 158 | 165 | void sh2_do_dma(sh2_state *sh2, int dma) |
| 159 | 166 | { |
| r9240 | r9241 | |
| 163 | 170 | |
| 164 | 171 | if (sh2->active_dma_count[dma] > 0) |
| 165 | 172 | { |
| 166 | | #ifdef USE_TIMER_FOR_DMA |
| 167 | | //schedule next DMA callback |
| 168 | | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 169 | | #endif |
| 170 | 173 | |
| 174 | |
| 171 | 175 | // process current DMA |
| 172 | 176 | switch(sh2->active_dma_size[dma]) |
| 173 | 177 | { |
| r9240 | r9241 | |
| 192 | 196 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 193 | 197 | |
| 194 | 198 | if (!available) |
| 199 | { |
| 200 | #ifdef USE_TIMER_FOR_DMA |
| 201 | //schedule next DMA callback |
| 202 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP_IF_UNAVAILABLE , dma); |
| 203 | #endif |
| 195 | 204 | return; |
| 205 | } |
| 206 | |
| 196 | 207 | } |
| 197 | 208 | |
| 209 | #ifdef USE_TIMER_FOR_DMA |
| 210 | //schedule next DMA callback |
| 211 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP , dma); |
| 212 | #endif |
| 198 | 213 | |
| 199 | 214 | dmadata = sh2->program->read_byte(tempsrc); |
| 200 | 215 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| r9240 | r9241 | |
| 231 | 246 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 232 | 247 | |
| 233 | 248 | if (!available) |
| 249 | { |
| 250 | #ifdef USE_TIMER_FOR_DMA |
| 251 | //schedule next DMA callback |
| 252 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP_IF_UNAVAILABLE , dma); |
| 253 | #endif |
| 234 | 254 | return; |
| 255 | } |
| 235 | 256 | } |
| 236 | 257 | |
| 258 | #ifdef USE_TIMER_FOR_DMA |
| 259 | //schedule next DMA callback |
| 260 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP , dma); |
| 261 | #endif |
| 262 | |
| 237 | 263 | // check: should this really be using read_word_32 / write_word_32? |
| 238 | 264 | dmadata = sh2->program->read_word(tempsrc); |
| 239 | 265 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| r9240 | r9241 | |
| 269 | 295 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 270 | 296 | |
| 271 | 297 | if (!available) |
| 298 | { |
| 299 | #ifdef USE_TIMER_FOR_DMA |
| 300 | //schedule next DMA callback |
| 301 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP_IF_UNAVAILABLE , dma); |
| 302 | #endif |
| 272 | 303 | return; |
| 304 | } |
| 273 | 305 | } |
| 274 | 306 | |
| 307 | #ifdef USE_TIMER_FOR_DMA |
| 308 | //schedule next DMA callback |
| 309 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP , dma); |
| 310 | #endif |
| 311 | |
| 275 | 312 | dmadata = sh2->program->read_dword(tempsrc); |
| 276 | 313 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| 277 | 314 | sh2->program->write_dword(tempdst, dmadata); |
| r9240 | r9241 | |
| 308 | 345 | fatalerror("SH2 dma_callback_fifo_data_available == 0 in unsupported mode"); |
| 309 | 346 | } |
| 310 | 347 | |
| 348 | |
| 349 | #ifdef USE_TIMER_FOR_DMA |
| 350 | //schedule next DMA callback |
| 351 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], DMA_TIMER_STEP , dma); |
| 352 | #endif |
| 353 | |
| 311 | 354 | dmadata = sh2->program->read_dword(tempsrc); |
| 312 | 355 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| 313 | 356 | sh2->program->write_dword(tempdst, dmadata); |
| r9240 | r9241 | |
| 406 | 449 | } |
| 407 | 450 | #ifdef USE_TIMER_FOR_DMA |
| 408 | 451 | // start DMA timer |
| 409 | | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 452 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], attotime_zero, dma); |
| 410 | 453 | #endif |
| 411 | 454 | |
| 412 | 455 | } |
src/emu/machine/er2055.c
| r0 | r9241 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | er2055.c |
| 4 | |
| 5 | GI 512 bit electrically alterable read-only memory. |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Aaron Giles |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #include "emu.h" |
| 41 | #include "machine/er2055.h" |
| 42 | |
| 43 | |
| 44 | //************************************************************************** |
| 45 | // GLOBAL VARIABLES |
| 46 | //************************************************************************** |
| 47 | |
| 48 | const device_type ER2055 = er2055_device_config::static_alloc_device_config; |
| 49 | |
| 50 | static ADDRESS_MAP_START( er2055_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 51 | AM_RANGE(0x0000, 0x003f) AM_RAM |
| 52 | ADDRESS_MAP_END |
| 53 | |
| 54 | |
| 55 | |
| 56 | //************************************************************************** |
| 57 | // DEVICE CONFIGURATION |
| 58 | //************************************************************************** |
| 59 | |
| 60 | //------------------------------------------------- |
| 61 | // er2055_device_config - constructor |
| 62 | //------------------------------------------------- |
| 63 | |
| 64 | er2055_device_config::er2055_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 65 | : device_config(mconfig, static_alloc_device_config, "ER2055", tag, owner, clock), |
| 66 | device_config_memory_interface(mconfig, *this), |
| 67 | device_config_nvram_interface(mconfig, *this), |
| 68 | m_space_config("EAROM", ENDIANNESS_BIG, 8, 6, 0, *ADDRESS_MAP_NAME(er2055_map)) |
| 69 | { |
| 70 | } |
| 71 | |
| 72 | |
| 73 | //------------------------------------------------- |
| 74 | // static_alloc_device_config - allocate a new |
| 75 | // configuration object |
| 76 | //------------------------------------------------- |
| 77 | |
| 78 | device_config *er2055_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 79 | { |
| 80 | return global_alloc(er2055_device_config(mconfig, tag, owner, clock)); |
| 81 | } |
| 82 | |
| 83 | |
| 84 | //------------------------------------------------- |
| 85 | // alloc_device - allocate a new device object |
| 86 | //------------------------------------------------- |
| 87 | |
| 88 | device_t *er2055_device_config::alloc_device(running_machine &machine) const |
| 89 | { |
| 90 | return auto_alloc(&machine, er2055_device(machine, *this)); |
| 91 | } |
| 92 | |
| 93 | |
| 94 | //------------------------------------------------- |
| 95 | // memory_space_config - return a description of |
| 96 | // any address spaces owned by this device |
| 97 | //------------------------------------------------- |
| 98 | |
| 99 | const address_space_config *er2055_device_config::memory_space_config(int spacenum) const |
| 100 | { |
| 101 | return (spacenum == 0) ? &m_space_config : NULL; |
| 102 | } |
| 103 | |
| 104 | |
| 105 | |
| 106 | //************************************************************************** |
| 107 | // LIVE DEVICE |
| 108 | //************************************************************************** |
| 109 | |
| 110 | //------------------------------------------------- |
| 111 | // er2055_device - constructor |
| 112 | //------------------------------------------------- |
| 113 | |
| 114 | er2055_device::er2055_device(running_machine &_machine, const er2055_device_config &config) |
| 115 | : device_t(_machine, config), |
| 116 | device_memory_interface(_machine, config, *this), |
| 117 | device_nvram_interface(_machine, config, *this), |
| 118 | m_config(config), |
| 119 | m_control_state(0), |
| 120 | m_address(0), |
| 121 | m_data(0) |
| 122 | { |
| 123 | } |
| 124 | |
| 125 | |
| 126 | //------------------------------------------------- |
| 127 | // device_start - device-specific startup |
| 128 | //------------------------------------------------- |
| 129 | |
| 130 | void er2055_device::device_start() |
| 131 | { |
| 132 | state_save_register_device_item(this, 0, m_control_state); |
| 133 | state_save_register_device_item(this, 0, m_address); |
| 134 | state_save_register_device_item(this, 0, m_data); |
| 135 | |
| 136 | m_control_state = 0; |
| 137 | } |
| 138 | |
| 139 | |
| 140 | //------------------------------------------------- |
| 141 | // nvram_default - called to initialize NVRAM to |
| 142 | // its default state |
| 143 | //------------------------------------------------- |
| 144 | |
| 145 | void er2055_device::nvram_default() |
| 146 | { |
| 147 | // default to all-0xff |
| 148 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 149 | m_addrspace[0]->write_byte(byte, 0xff); |
| 150 | |
| 151 | // populate from a memory region if present |
| 152 | if (m_region != NULL) |
| 153 | { |
| 154 | if (m_region->bytes() != SIZE_DATA) |
| 155 | fatalerror("er2055 region '%s' wrong size (expected size = 0x100)", tag()); |
| 156 | if (m_region->width() != 1) |
| 157 | fatalerror("er2055 region '%s' needs to be an 8-bit region", tag()); |
| 158 | |
| 159 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 160 | m_addrspace[0]->write_byte(byte, m_region->u8(byte)); |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | |
| 165 | //------------------------------------------------- |
| 166 | // nvram_read - called to read NVRAM from the |
| 167 | // .nv file |
| 168 | //------------------------------------------------- |
| 169 | |
| 170 | void er2055_device::nvram_read(mame_file &file) |
| 171 | { |
| 172 | UINT8 buffer[SIZE_DATA]; |
| 173 | mame_fread(&file, buffer, sizeof(buffer)); |
| 174 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 175 | m_addrspace[0]->write_byte(byte, buffer[byte]); |
| 176 | } |
| 177 | |
| 178 | |
| 179 | //------------------------------------------------- |
| 180 | // nvram_write - called to write NVRAM to the |
| 181 | // .nv file |
| 182 | //------------------------------------------------- |
| 183 | |
| 184 | void er2055_device::nvram_write(mame_file &file) |
| 185 | { |
| 186 | UINT8 buffer[SIZE_DATA]; |
| 187 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 188 | buffer[byte] = m_addrspace[0]->read_byte(byte); |
| 189 | mame_fwrite(&file, buffer, sizeof(buffer)); |
| 190 | } |
| 191 | |
| 192 | |
| 193 | |
| 194 | //************************************************************************** |
| 195 | // I/O OPERATIONS |
| 196 | //************************************************************************** |
| 197 | |
| 198 | //------------------------------------------------- |
| 199 | // set_control - set the control lines; these |
| 200 | // must be done simultaneously because the chip |
| 201 | // reacts to various combinations |
| 202 | //------------------------------------------------- |
| 203 | |
| 204 | void er2055_device::set_control(UINT8 cs1, UINT8 cs2, UINT8 c1, UINT8 c2, UINT8 ck) |
| 205 | { |
| 206 | // create a new composite control state |
| 207 | UINT8 oldstate = m_control_state; |
| 208 | m_control_state = (ck != 0) ? CK : 0; |
| 209 | m_control_state |= (c1 != 0) ? C1 : 0; |
| 210 | m_control_state |= (c2 != 0) ? C2 : 0; |
| 211 | m_control_state |= (cs1 != 0) ? CS1 : 0; |
| 212 | m_control_state |= (cs2 != 0) ? CS2 : 0; |
| 213 | |
| 214 | // if not selected, or if change from previous, we're done |
| 215 | if ((m_control_state & (CS1 | CS2)) != (CS1 | CS2) || m_control_state == oldstate) |
| 216 | return; |
| 217 | |
| 218 | // something changed, see what it is based on what mode we're in |
| 219 | switch (m_control_state & (C1 | C2)) |
| 220 | { |
| 221 | // write mode; erasing is required, so we perform an AND against previous |
| 222 | // data to simulate incorrect behavior if erasing was not done |
| 223 | case 0: |
| 224 | m_addrspace[0]->write_byte(m_address, m_addrspace[0]->read_byte(m_address) & m_data); |
| 225 | //printf("Write %02X = %02X\n", m_address, m_data); |
| 226 | break; |
| 227 | |
| 228 | // erase mode |
| 229 | case C2: |
| 230 | m_addrspace[0]->write_byte(m_address, 0xff); |
| 231 | //printf("Erase %02X\n", m_address); |
| 232 | break; |
| 233 | |
| 234 | // read mode |
| 235 | case C1: |
| 236 | if ((oldstate & CK) != 0 && (m_control_state & CK) == 0) |
| 237 | { |
| 238 | m_data = m_addrspace[0]->read_byte(m_address); |
| 239 | //printf("Read %02X = %02X\n", m_address, m_data); |
| 240 | } |
| 241 | break; |
| 242 | } |
| 243 | } |
src/emu/machine/er2055.h
| r0 | r9241 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | er2055.h |
| 4 | |
| 5 | GI 512 bit electrically alterable read-only memory. |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Aaron Giles |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #pragma once |
| 41 | |
| 42 | #ifndef __ER2055_H__ |
| 43 | #define __ER2055_H__ |
| 44 | |
| 45 | |
| 46 | |
| 47 | //************************************************************************** |
| 48 | // INTERFACE CONFIGURATION MACROS |
| 49 | //************************************************************************** |
| 50 | |
| 51 | #define MDRV_ER2055_ADD(_tag) \ |
| 52 | MDRV_DEVICE_ADD(_tag, ER2055, 0) \ |
| 53 | |
| 54 | |
| 55 | |
| 56 | //************************************************************************** |
| 57 | // TYPE DEFINITIONS |
| 58 | //************************************************************************** |
| 59 | |
| 60 | |
| 61 | // ======================> er2055_device_config |
| 62 | |
| 63 | class er2055_device_config : public device_config, |
| 64 | public device_config_memory_interface, |
| 65 | public device_config_nvram_interface |
| 66 | { |
| 67 | friend class er2055_device; |
| 68 | |
| 69 | // construction/destruction |
| 70 | er2055_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 71 | |
| 72 | public: |
| 73 | // allocators |
| 74 | static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 75 | virtual device_t *alloc_device(running_machine &machine) const; |
| 76 | |
| 77 | protected: |
| 78 | // device_config_memory_interface overrides |
| 79 | virtual const address_space_config *memory_space_config(int spacenum = 0) const; |
| 80 | |
| 81 | // device-specific configuration |
| 82 | address_space_config m_space_config; |
| 83 | }; |
| 84 | |
| 85 | |
| 86 | // ======================> er2055_device |
| 87 | |
| 88 | class er2055_device : public device_t, |
| 89 | public device_memory_interface, |
| 90 | public device_nvram_interface |
| 91 | { |
| 92 | friend class er2055_device_config; |
| 93 | |
| 94 | // construction/destruction |
| 95 | er2055_device(running_machine &_machine, const er2055_device_config &config); |
| 96 | |
| 97 | public: |
| 98 | // I/O operations |
| 99 | UINT8 data() const { return m_data; } |
| 100 | void set_address(UINT8 address) { m_address = address & 0x3f; } |
| 101 | void set_data(UINT8 data) { m_data = data; } |
| 102 | |
| 103 | // control lines -- all lines are specified as active-high (even CS2) |
| 104 | void set_control(UINT8 cs1, UINT8 cs2, UINT8 c1, UINT8 c2, UINT8 ck); |
| 105 | |
| 106 | protected: |
| 107 | // device-level overrides |
| 108 | virtual void device_start(); |
| 109 | |
| 110 | // device_nvram_interface overrides |
| 111 | virtual void nvram_default(); |
| 112 | virtual void nvram_read(mame_file &file); |
| 113 | virtual void nvram_write(mame_file &file); |
| 114 | |
| 115 | static const int SIZE_DATA = 0x40; |
| 116 | |
| 117 | static const UINT8 CK = 0x01; |
| 118 | static const UINT8 C1 = 0x02; |
| 119 | static const UINT8 C2 = 0x04; |
| 120 | static const UINT8 CS1 = 0x08; |
| 121 | static const UINT8 CS2 = 0x10; |
| 122 | |
| 123 | // internal state |
| 124 | const er2055_device_config &m_config; |
| 125 | |
| 126 | UINT8 m_control_state; |
| 127 | UINT8 m_address; |
| 128 | UINT8 m_data; |
| 129 | }; |
| 130 | |
| 131 | |
| 132 | // device type definition |
| 133 | extern const device_type ER2055; |
| 134 | |
| 135 | |
| 136 | #endif |
src/emu/machine/x2212.c
| r9240 | r9241 | |
| 1 | | /* |
| 2 | | * Xicor X2212 |
| 3 | | * |
| 4 | | * 256 x 4 bit Nonvolatile Static RAM |
| 5 | | * |
| 6 | | */ |
| 1 | /*************************************************************************** |
| 7 | 2 | |
| 3 | x2212.c |
| 4 | |
| 5 | Xicor X2212 256 x 4 bit Nonvolatile Static RAM. |
| 6 | |
| 7 | ***************************************************************************/ |
| 8 | |
| 8 | 9 | #include "emu.h" |
| 9 | 10 | #include "machine/x2212.h" |
| 10 | 11 | |
| 11 | | #define SIZE_DATA ( 0x100 ) |
| 12 | 12 | |
| 13 | | typedef struct |
| 13 | //************************************************************************** |
| 14 | // GLOBAL VARIABLES |
| 15 | //************************************************************************** |
| 16 | |
| 17 | const device_type X2212 = x2212_device_config::static_alloc_device_config; |
| 18 | |
| 19 | static ADDRESS_MAP_START( x2212_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 20 | AM_RANGE(0x0000, 0x00ff) AM_RAM |
| 21 | ADDRESS_MAP_END |
| 22 | |
| 23 | |
| 24 | |
| 25 | //************************************************************************** |
| 26 | // DEVICE CONFIGURATION |
| 27 | //************************************************************************** |
| 28 | |
| 29 | //------------------------------------------------- |
| 30 | // x2212_device_config - constructor |
| 31 | //------------------------------------------------- |
| 32 | |
| 33 | x2212_device_config::x2212_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 34 | : device_config(mconfig, static_alloc_device_config, "X2212", tag, owner, clock), |
| 35 | device_config_memory_interface(mconfig, *this), |
| 36 | device_config_nvram_interface(mconfig, *this), |
| 37 | m_sram_space_config("SRAM", ENDIANNESS_BIG, 8, 8, 0, *ADDRESS_MAP_NAME(x2212_map)), |
| 38 | m_e2prom_space_config("E2PROM", ENDIANNESS_BIG, 8, 8, 0, *ADDRESS_MAP_NAME(x2212_map)), |
| 39 | m_auto_save(false) |
| 14 | 40 | { |
| 15 | | UINT8 *sram; |
| 16 | | UINT8 *e2prom; |
| 17 | | UINT8 *default_data; |
| 18 | | int store; |
| 19 | | int array_recall; |
| 20 | | } x2212_state; |
| 41 | } |
| 21 | 42 | |
| 22 | | /*------------------------------------------------- |
| 23 | | get_safe_token - makes sure that the passed |
| 24 | | in device is, in fact, an X2212 |
| 25 | | -------------------------------------------------*/ |
| 26 | 43 | |
| 27 | | INLINE x2212_state *get_safe_token(running_device *device) |
| 44 | //------------------------------------------------- |
| 45 | // static_alloc_device_config - allocate a new |
| 46 | // configuration object |
| 47 | //------------------------------------------------- |
| 48 | |
| 49 | device_config *x2212_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 28 | 50 | { |
| 29 | | assert(device != NULL); |
| 30 | | assert(device->type() == X2212); |
| 51 | return global_alloc(x2212_device_config(mconfig, tag, owner, clock)); |
| 52 | } |
| 31 | 53 | |
| 32 | | return (x2212_state *)downcast<legacy_device_base *>(device)->token(); |
| 54 | |
| 55 | //------------------------------------------------- |
| 56 | // alloc_device - allocate a new device object |
| 57 | //------------------------------------------------- |
| 58 | |
| 59 | device_t *x2212_device_config::alloc_device(running_machine &machine) const |
| 60 | { |
| 61 | return auto_alloc(&machine, x2212_device(machine, *this)); |
| 33 | 62 | } |
| 34 | 63 | |
| 35 | | WRITE8_DEVICE_HANDLER( x2212_write ) |
| 64 | |
| 65 | //------------------------------------------------- |
| 66 | // memory_space_config - return a description of |
| 67 | // any address spaces owned by this device |
| 68 | //------------------------------------------------- |
| 69 | |
| 70 | const address_space_config *x2212_device_config::memory_space_config(int spacenum) const |
| 36 | 71 | { |
| 37 | | x2212_state *c = get_safe_token(device); |
| 72 | return (spacenum == 0) ? &m_sram_space_config : (spacenum == 1) ? &m_e2prom_space_config : NULL; |
| 73 | } |
| 38 | 74 | |
| 39 | | c->sram[ offset ] = data; |
| 75 | |
| 76 | //------------------------------------------------- |
| 77 | // static_set_auto_save - configuration helper |
| 78 | // to set the auto-save flag |
| 79 | //------------------------------------------------- |
| 80 | |
| 81 | void x2212_device_config::static_set_auto_save(device_config *device) |
| 82 | { |
| 83 | downcast<x2212_device_config *>(device)->m_auto_save = true; |
| 40 | 84 | } |
| 41 | 85 | |
| 42 | 86 | |
| 43 | | READ8_DEVICE_HANDLER( x2212_read ) |
| 87 | |
| 88 | //************************************************************************** |
| 89 | // LIVE DEVICE |
| 90 | //************************************************************************** |
| 91 | |
| 92 | //------------------------------------------------- |
| 93 | // x2212_device - constructor |
| 94 | //------------------------------------------------- |
| 95 | |
| 96 | x2212_device::x2212_device(running_machine &_machine, const x2212_device_config &config) |
| 97 | : device_t(_machine, config), |
| 98 | device_memory_interface(_machine, config, *this), |
| 99 | device_nvram_interface(_machine, config, *this), |
| 100 | m_config(config), |
| 101 | m_store(false), |
| 102 | m_array_recall(false) |
| 44 | 103 | { |
| 45 | | x2212_state *c = get_safe_token(device); |
| 104 | } |
| 46 | 105 | |
| 47 | | return c->sram[ offset ]; |
| 106 | |
| 107 | //------------------------------------------------- |
| 108 | // device_start - device-specific startup |
| 109 | //------------------------------------------------- |
| 110 | |
| 111 | void x2212_device::device_start() |
| 112 | { |
| 113 | state_save_register_device_item(this, 0, m_store); |
| 114 | state_save_register_device_item(this, 0, m_array_recall); |
| 115 | |
| 116 | m_sram = m_addrspace[0]; |
| 117 | m_e2prom = m_addrspace[1]; |
| 48 | 118 | } |
| 49 | 119 | |
| 50 | | WRITE_LINE_DEVICE_HANDLER( x2212_store ) |
| 120 | |
| 121 | //------------------------------------------------- |
| 122 | // nvram_default - called to initialize NVRAM to |
| 123 | // its default state |
| 124 | //------------------------------------------------- |
| 125 | |
| 126 | void x2212_device::nvram_default() |
| 51 | 127 | { |
| 52 | | x2212_state *c = get_safe_token(device); |
| 128 | // default to all-0xff |
| 129 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 130 | { |
| 131 | m_sram->write_byte(byte, 0xff); |
| 132 | m_e2prom->write_byte(byte, 0xff); |
| 133 | } |
| 53 | 134 | |
| 54 | | state &= 1; |
| 55 | | if( !state && c->store ) |
| 135 | // populate from a memory region if present |
| 136 | if (m_region != NULL) |
| 56 | 137 | { |
| 57 | | memcpy( c->e2prom, c->sram, SIZE_DATA ); |
| 138 | if (m_region->bytes() != SIZE_DATA) |
| 139 | fatalerror("x2212 region '%s' wrong size (expected size = 0x100)", tag()); |
| 140 | if (m_region->width() != 1) |
| 141 | fatalerror("x2212 region '%s' needs to be an 8-bit region", tag()); |
| 142 | |
| 143 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 144 | m_e2prom->write_byte(byte, m_region->u8(byte)); |
| 58 | 145 | } |
| 59 | | |
| 60 | | c->store = state; |
| 61 | 146 | } |
| 62 | 147 | |
| 63 | | WRITE_LINE_DEVICE_HANDLER( x2212_array_recall ) |
| 148 | |
| 149 | //------------------------------------------------- |
| 150 | // nvram_read - called to read NVRAM from the |
| 151 | // .nv file |
| 152 | //------------------------------------------------- |
| 153 | |
| 154 | void x2212_device::nvram_read(mame_file &file) |
| 64 | 155 | { |
| 65 | | x2212_state *c = get_safe_token(device); |
| 66 | | |
| 67 | | state &= 1; |
| 68 | | if( !state && c->array_recall ) |
| 156 | UINT8 buffer[SIZE_DATA]; |
| 157 | mame_fread(&file, buffer, sizeof(buffer)); |
| 158 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 69 | 159 | { |
| 70 | | memcpy( c->sram, c->e2prom, SIZE_DATA ); |
| 160 | m_sram->write_byte(byte, 0xff); |
| 161 | m_e2prom->write_byte(byte, buffer[byte]); |
| 71 | 162 | } |
| 72 | | |
| 73 | | c->array_recall = state; |
| 74 | 163 | } |
| 75 | 164 | |
| 76 | | /*------------------------------------------------- |
| 77 | | device start callback |
| 78 | | -------------------------------------------------*/ |
| 79 | 165 | |
| 80 | | static DEVICE_START(x2212) |
| 166 | //------------------------------------------------- |
| 167 | // nvram_write - called to write NVRAM to the |
| 168 | // .nv file |
| 169 | //------------------------------------------------- |
| 170 | |
| 171 | void x2212_device::nvram_write(mame_file &file) |
| 81 | 172 | { |
| 82 | | x2212_state *c = get_safe_token(device); |
| 173 | // auto-save causes an implicit store prior to exiting (writing) |
| 174 | if (m_config.m_auto_save) |
| 175 | store(); |
| 176 | |
| 177 | UINT8 buffer[SIZE_DATA]; |
| 178 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 179 | buffer[byte] = m_e2prom->read_byte(byte); |
| 180 | mame_fwrite(&file, buffer, sizeof(buffer)); |
| 181 | } |
| 83 | 182 | |
| 84 | | /* validate some basic stuff */ |
| 85 | | assert(device != NULL); |
| 86 | | assert(device->baseconfig().static_config() == NULL); |
| 87 | | assert(downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config() == NULL); |
| 88 | | assert(device->machine != NULL); |
| 89 | | assert(device->machine->config != NULL); |
| 90 | 183 | |
| 91 | | c->sram = auto_alloc_array( device->machine, UINT8, SIZE_DATA ); |
| 92 | | c->e2prom = auto_alloc_array( device->machine, UINT8, SIZE_DATA ); |
| 93 | | c->store = 1; |
| 94 | | c->array_recall = 1; |
| 95 | 184 | |
| 96 | | c->default_data = *device->region(); |
| 185 | //************************************************************************** |
| 186 | // INTERNAL HELPERS |
| 187 | //************************************************************************** |
| 97 | 188 | |
| 98 | | state_save_register_device_item_pointer( device, 0, c->sram, SIZE_DATA ); |
| 99 | | state_save_register_device_item_pointer( device, 0, c->e2prom, SIZE_DATA ); |
| 100 | | state_save_register_device_item( device, 0, c->store ); |
| 101 | | state_save_register_device_item( device, 0, c->array_recall ); |
| 189 | //------------------------------------------------- |
| 190 | // store - store data from live RAM into the |
| 191 | // EEPROM |
| 192 | //------------------------------------------------- |
| 193 | |
| 194 | void x2212_device::store() |
| 195 | { |
| 196 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 197 | m_e2prom->write_byte(byte, m_sram->read_byte(byte)); |
| 102 | 198 | } |
| 103 | 199 | |
| 104 | | /*------------------------------------------------- |
| 105 | | device reset callback |
| 106 | | -------------------------------------------------*/ |
| 107 | 200 | |
| 108 | | static DEVICE_RESET(x2212) |
| 201 | //------------------------------------------------- |
| 202 | // recall - fetch data from the EEPROM into live |
| 203 | // RAM |
| 204 | //------------------------------------------------- |
| 205 | |
| 206 | void x2212_device::recall() |
| 109 | 207 | { |
| 208 | for (int byte = 0; byte < SIZE_DATA; byte++) |
| 209 | m_sram->write_byte(byte, m_e2prom->read_byte(byte)); |
| 110 | 210 | } |
| 111 | 211 | |
| 112 | | static DEVICE_NVRAM(x2212) |
| 212 | |
| 213 | |
| 214 | //************************************************************************** |
| 215 | // READ/WRITE HANDLERS |
| 216 | //************************************************************************** |
| 217 | |
| 218 | //------------------------------------------------- |
| 219 | // write - store to the live RAM |
| 220 | //------------------------------------------------- |
| 221 | |
| 222 | WRITE8_MEMBER( x2212_device::write ) |
| 113 | 223 | { |
| 114 | | x2212_state *c = get_safe_token(device); |
| 224 | m_sram->write_byte(offset, data & 0x0f); |
| 225 | } |
| 115 | 226 | |
| 116 | | if( read_or_write ) |
| 117 | | { |
| 118 | | mame_fwrite( file, c->sram, SIZE_DATA ); |
| 119 | | } |
| 120 | | else |
| 121 | | { |
| 122 | | if( file ) |
| 123 | | { |
| 124 | | mame_fread( file, c->e2prom, SIZE_DATA ); |
| 125 | | } |
| 126 | | else |
| 127 | | { |
| 128 | | if( c->default_data != NULL ) |
| 129 | | { |
| 130 | | memcpy( c->e2prom, c->default_data, SIZE_DATA ); |
| 131 | | } |
| 132 | | else |
| 133 | | { |
| 134 | | memset( c->e2prom, 0xff, SIZE_DATA ); |
| 135 | | } |
| 136 | | } |
| 137 | 227 | |
| 138 | | memcpy( c->sram, c->e2prom, SIZE_DATA ); |
| 139 | | } |
| 228 | //------------------------------------------------- |
| 229 | // read - read from the live RAM |
| 230 | //------------------------------------------------- |
| 231 | |
| 232 | READ8_MEMBER( x2212_device::read ) |
| 233 | { |
| 234 | return (m_sram->read_byte(offset) & 0x0f) | (space.unmap() & 0xf0); |
| 140 | 235 | } |
| 141 | 236 | |
| 142 | | /*------------------------------------------------- |
| 143 | | device definition |
| 144 | | -------------------------------------------------*/ |
| 145 | 237 | |
| 146 | | static const char DEVTEMPLATE_SOURCE[] = __FILE__; |
| 238 | //------------------------------------------------- |
| 239 | // store - set the state of the store line |
| 240 | // (active high) |
| 241 | //------------------------------------------------- |
| 147 | 242 | |
| 148 | | #define DEVTEMPLATE_ID( p, s ) p##x2212##s |
| 149 | | #define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET | DT_HAS_NVRAM |
| 150 | | #define DEVTEMPLATE_NAME "X2212" |
| 151 | | #define DEVTEMPLATE_FAMILY "EEPROM" |
| 152 | | #define DEVTEMPLATE_CLASS DEVICE_CLASS_PERIPHERAL |
| 153 | | #include "devtempl.h" |
| 243 | WRITE_LINE_MEMBER( x2212_device::store ) |
| 244 | { |
| 245 | if (state != 0 && !m_store) |
| 246 | store(); |
| 247 | m_store = (state != 0); |
| 248 | } |
| 154 | 249 | |
| 155 | 250 | |
| 156 | | DEFINE_LEGACY_NVRAM_DEVICE(X2212, x2212); |
| 251 | //------------------------------------------------- |
| 252 | // recall - set the state of the recall line |
| 253 | // (active high) |
| 254 | //------------------------------------------------- |
| 255 | |
| 256 | WRITE_LINE_MEMBER( x2212_device::recall ) |
| 257 | { |
| 258 | if (state != 0 && !m_array_recall) |
| 259 | recall(); |
| 260 | m_array_recall = (state != 0); |
| 261 | } |
src/emu/machine/x2212.h
| r9240 | r9241 | |
| 1 | | /* |
| 2 | | * Xicor X2212 |
| 3 | | * |
| 4 | | * 256 x 4 bit Nonvolatile Static RAM |
| 5 | | * |
| 6 | | */ |
| 1 | /*************************************************************************** |
| 7 | 2 | |
| 8 | | #if !defined( X2212_H ) |
| 9 | | #define X2212_H ( 1 ) |
| 3 | x2212.h |
| 10 | 4 | |
| 11 | | #include "devlegcy.h" |
| 5 | Xicor X2212 256 x 4 bit Nonvolatile Static RAM. |
| 12 | 6 | |
| 13 | | /* default nvram contents should be in memory region |
| 14 | | * with the same tag as device. |
| 15 | | */ |
| 7 | ***************************************************************************/ |
| 16 | 8 | |
| 17 | | DECLARE_LEGACY_NVRAM_DEVICE(X2212, x2212); |
| 9 | #pragma once |
| 18 | 10 | |
| 11 | #ifndef __X2212_H__ |
| 12 | #define __X2212_H__ |
| 13 | |
| 14 | |
| 15 | |
| 16 | //************************************************************************** |
| 17 | // INTERFACE CONFIGURATION MACROS |
| 18 | //************************************************************************** |
| 19 | |
| 19 | 20 | #define MDRV_X2212_ADD(_tag) \ |
| 20 | | MDRV_DEVICE_ADD(_tag, X2212, 0) |
| 21 | MDRV_DEVICE_ADD(_tag, X2212, 0) \ |
| 21 | 22 | |
| 22 | | WRITE8_DEVICE_HANDLER( x2212_write ); |
| 23 | | READ8_DEVICE_HANDLER( x2212_read ); |
| 24 | | WRITE_LINE_DEVICE_HANDLER( x2212_store ); |
| 25 | | WRITE_LINE_DEVICE_HANDLER( x2212_array_recall ); |
| 23 | // some systems (like many early Atari games) wire up the /STORE signal |
| 24 | // to fire on power-down, effectively creating an "auto-save" functionality |
| 25 | #define MDRV_X2212_ADD_AUTOSAVE(_tag) \ |
| 26 | MDRV_DEVICE_ADD(_tag, X2212, 0) \ |
| 27 | x2212_device_config::static_set_auto_save(device); \ |
| 26 | 28 | |
| 29 | |
| 30 | |
| 31 | //************************************************************************** |
| 32 | // TYPE DEFINITIONS |
| 33 | //************************************************************************** |
| 34 | |
| 35 | |
| 36 | // ======================> x2212_device_config |
| 37 | |
| 38 | class x2212_device_config : public device_config, |
| 39 | public device_config_memory_interface, |
| 40 | public device_config_nvram_interface |
| 41 | { |
| 42 | friend class x2212_device; |
| 43 | |
| 44 | // construction/destruction |
| 45 | x2212_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 46 | |
| 47 | public: |
| 48 | // allocators |
| 49 | static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 50 | virtual device_t *alloc_device(running_machine &machine) const; |
| 51 | |
| 52 | // inline configuration helpers |
| 53 | static void static_set_auto_save(device_config *device); |
| 54 | |
| 55 | protected: |
| 56 | // device_config_memory_interface overrides |
| 57 | virtual const address_space_config *memory_space_config(int spacenum = 0) const; |
| 58 | |
| 59 | // device-specific configuration |
| 60 | address_space_config m_sram_space_config; |
| 61 | address_space_config m_e2prom_space_config; |
| 62 | |
| 63 | // internal state |
| 64 | bool m_auto_save; |
| 65 | }; |
| 66 | |
| 67 | |
| 68 | // ======================> x2212_device |
| 69 | |
| 70 | class x2212_device : public device_t, |
| 71 | public device_memory_interface, |
| 72 | public device_nvram_interface |
| 73 | { |
| 74 | friend class x2212_device_config; |
| 75 | |
| 76 | // construction/destruction |
| 77 | x2212_device(running_machine &_machine, const x2212_device_config &config); |
| 78 | |
| 79 | public: |
| 80 | // I/O operations |
| 81 | DECLARE_READ8_MEMBER( read ); |
| 82 | DECLARE_WRITE8_MEMBER( write ); |
| 83 | |
| 84 | DECLARE_WRITE_LINE_MEMBER( store ); |
| 85 | DECLARE_WRITE_LINE_MEMBER( recall ); |
| 86 | |
| 87 | protected: |
| 88 | // internal helpers |
| 89 | void store(); |
| 90 | void recall(); |
| 91 | |
| 92 | // device-level overrides |
| 93 | virtual void device_start(); |
| 94 | |
| 95 | // device_nvram_interface overrides |
| 96 | virtual void nvram_default(); |
| 97 | virtual void nvram_read(mame_file &file); |
| 98 | virtual void nvram_write(mame_file &file); |
| 99 | |
| 100 | static const int SIZE_DATA = 0x100; |
| 101 | |
| 102 | // internal state |
| 103 | const x2212_device_config &m_config; |
| 104 | |
| 105 | address_space * m_sram; |
| 106 | address_space * m_e2prom; |
| 107 | |
| 108 | bool m_store; |
| 109 | bool m_array_recall; |
| 110 | }; |
| 111 | |
| 112 | |
| 113 | // device type definition |
| 114 | extern const device_type X2212; |
| 115 | |
| 116 | |
| 27 | 117 | #endif |
src/emu/addrmap.h
| r9240 | r9241 | |
| 856 | 856 | curentry->set_handler(devconfig, _tag, _rhandler, #_rhandler, _whandler, #_whandler, _unitmask); \ |
| 857 | 857 | |
| 858 | 858 | |
| 859 | // driver data base reads |
| 860 | #define AM_READ_BASE(_class, _handler) \ |
| 861 | curentry->set_handler(devconfig, NULL, read_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler)); \ |
| 862 | |
| 863 | #define AM_READ8_BASE(_class, _handler, _unitmask) \ |
| 864 | curentry->set_handler(devconfig, NULL, read8_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 865 | |
| 866 | #define AM_READ16_BASE(_class, _handler, _unitmask) \ |
| 867 | curentry->set_handler(devconfig, NULL, read16_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 868 | |
| 869 | #define AM_READ32_BASE(_class, _handler, _unitmask) \ |
| 870 | curentry->set_handler(devconfig, NULL, read32_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 871 | |
| 872 | |
| 873 | // driver data base writes |
| 874 | #define AM_WRITE_BASE(_class, _handler) \ |
| 875 | curentry->set_handler(devconfig, NULL, write_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler)); \ |
| 876 | |
| 877 | #define AM_WRITE8_BASE(_class, _handler, _unitmask) \ |
| 878 | curentry->set_handler(devconfig, NULL, write8_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 879 | |
| 880 | #define AM_WRITE16_BASE(_class, _handler, _unitmask) \ |
| 881 | curentry->set_handler(devconfig, NULL, write16_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 882 | |
| 883 | #define AM_WRITE32_BASE(_class, _handler, _unitmask) \ |
| 884 | curentry->set_handler(devconfig, NULL, write32_proto_delegate::_create_member<_class, &_class::_handler>("driver_data::" #_handler), _unitmask); \ |
| 885 | |
| 886 | |
| 887 | // driver data base reads/writes |
| 888 | #define AM_READWRITE_BASE(_class, _rhandler, _whandler) \ |
| 889 | curentry->set_handler(devconfig, NULL, read_proto_delegate::_create_member<_class, &_class::_rhandler>("driver_data::" #_rhandler), write_proto_delegate::_create_member<_class, &_class::_whandler>("driver_data::" #_whandler)); \ |
| 890 | |
| 891 | #define AM_READWRITE8_BASE(_class, _rhandler, _whandler, _unitmask) \ |
| 892 | curentry->set_handler(devconfig, NULL, read8_proto_delegate::_create_member<_class, &_class::_rhandler>("driver_data::" #_rhandler), write8_proto_delegate::_create_member<_class, &_class::_whandler>("driver_data::" #_whandler), _unitmask); \ |
| 893 | |
| 894 | #define AM_READWRITE16_BASE(_class, _rhandler, _whandler, _unitmask) \ |
| 895 | curentry->set_handler(devconfig, NULL, read16_proto_delegate::_create_member<_class, &_class::_rhandler>("driver_data::" #_rhandler), write16_proto_delegate::_create_member<_class, &_class::_whandler>("driver_data::" #_whandler), _unitmask); \ |
| 896 | |
| 897 | #define AM_READWRITE32_BASE(_class, _rhandler, _whandler, _unitmask) \ |
| 898 | curentry->set_handler(devconfig, NULL, read32_proto_delegate::_create_member<_class, &_class::_rhandler>("driver_data::" #_rhandler), write32_proto_delegate::_create_member<_class, &_class::_whandler>("driver_data::" #_whandler), _unitmask); \ |
| 899 | |
| 900 | |
| 859 | 901 | // driver data reads |
| 860 | 902 | #define AM_READ(_handler) \ |
| 861 | 903 | curentry->set_handler(devconfig, NULL, read_proto_delegate::_create_member<drivdata_class, &drivdata_class::_handler>("driver_data::" #_handler)); \ |