trunk/src/mess/drivers/ssem.c
| r32321 | r32322 | |
| 7 | 7 | |
| 8 | 8 | #include "emu.h" |
| 9 | 9 | #include "cpu/ssem/ssem.h" |
| 10 | | #include "imagedev/cartslot.h" |
| 11 | | #include <stdarg.h> |
| 10 | #include "imagedev/snapquik.h" |
| 12 | 11 | |
| 13 | 12 | class ssem_state : public driver_device |
| 14 | 13 | { |
| r32321 | r32322 | |
| 24 | 23 | required_device<screen_device> m_screen; |
| 25 | 24 | |
| 26 | 25 | UINT8 m_store_line; |
| 26 | virtual void machine_start(); |
| 27 | 27 | virtual void machine_reset(); |
| 28 | 28 | UINT32 screen_update_ssem(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 29 | 29 | DECLARE_INPUT_CHANGED_MEMBER(panel_check); |
| 30 | | DECLARE_DEVICE_IMAGE_LOAD_MEMBER(ssem_store); |
| 30 | DECLARE_QUICKLOAD_LOAD_MEMBER(ssem_store); |
| 31 | 31 | inline UINT32 reverse(UINT32 v); |
| 32 | 32 | void glyph_print(bitmap_rgb32 &bitmap, INT32 x, INT32 y, const char *msg, ...) ATTR_PRINTF(5,6); |
| 33 | 33 | void strlower(char *buf); |
| r32321 | r32322 | |
| 45 | 45 | // un-reversed before being used. |
| 46 | 46 | inline UINT32 ssem_state::reverse(UINT32 v) |
| 47 | 47 | { |
| 48 | | // Taken from http://www-graphics.stanford.edu/~seander/bithacks.html#ReverseParallel |
| 48 | // Taken from http://www.graphics.stanford.edu/~seander/bithacks.html#ReverseParallel |
| 49 | 49 | // swap odd and even bits |
| 50 | 50 | v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1); |
| 51 | 51 | // swap consecutive pairs |
| r32321 | r32322 | |
| 518 | 518 | * Image loading * |
| 519 | 519 | \****************************************************/ |
| 520 | 520 | |
| 521 | | DEVICE_IMAGE_LOAD_MEMBER(ssem_state,ssem_store) |
| 521 | QUICKLOAD_LOAD_MEMBER(ssem_state, ssem_store) |
| 522 | 522 | { |
| 523 | | const char* image_name = image.filename(); |
| 524 | | char image_ext[5] = { 0 }; |
| 523 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 525 | 524 | char image_line[100] = { 0 }; |
| 526 | 525 | char token_buf[100] = { 0 }; |
| 527 | 526 | int num_lines = 0; |
| 528 | | int i = 0; |
| 529 | 527 | |
| 530 | | // Isolate file extension and convert to lower-case |
| 531 | | memcpy(image_ext, image_name + (strlen(image_name) - 4), 5); |
| 532 | | strlower(image_ext); |
| 533 | | |
| 534 | 528 | image.fgets(image_line, 99); |
| 535 | 529 | sscanf(image_line, "%d", &num_lines); |
| 536 | 530 | |
| 537 | | if(num_lines) |
| 531 | if (num_lines) |
| 538 | 532 | { |
| 539 | | for(i = 0; i < num_lines; i++) |
| 533 | for (int i = 0; i < num_lines; i++) |
| 540 | 534 | { |
| 541 | 535 | UINT32 line = 0; |
| 542 | 536 | image.fgets(image_line, 99); |
| r32321 | r32322 | |
| 546 | 540 | token_buf[4] = '\0'; |
| 547 | 541 | sscanf(token_buf, "%04d", &line); |
| 548 | 542 | |
| 549 | | if(strcmp(image_ext, ".snp") == 0) |
| 543 | if (!core_stricmp(image.filetype(), "snp")) |
| 550 | 544 | { |
| 551 | 545 | UINT32 word = 0; |
| 552 | | int b = 0; |
| 553 | 546 | |
| 554 | 547 | // Parse a line such as: 0000:00000110101001000100000100000100 |
| 555 | | for(b = 0; b < 32; b++) |
| 548 | for (int b = 0; b < 32; b++) |
| 556 | 549 | { |
| 557 | | if(image_line[5 + b] == '1') |
| 558 | | { |
| 550 | if (image_line[5 + b] == '1') |
| 559 | 551 | word |= 1 << (31 - b); |
| 560 | | } |
| 561 | 552 | } |
| 562 | 553 | |
| 563 | | m_store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 564 | | m_store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 565 | | m_store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 566 | | m_store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 554 | space.write_byte((line << 2) + 0, (word >> 24) & 0x000000ff); |
| 555 | space.write_byte((line << 2) + 1, (word >> 16) & 0x000000ff); |
| 556 | space.write_byte((line << 2) + 2, (word >> 8) & 0x000000ff); |
| 557 | space.write_byte((line << 2) + 3, (word >> 0) & 0x000000ff); |
| 567 | 558 | } |
| 568 | | else if(strcmp(image_ext, ".asm") == 0) |
| 559 | else if (!core_stricmp(image.filetype(), "asm")) |
| 569 | 560 | { |
| 570 | 561 | char op_buf[4] = { 0 }; |
| 571 | 562 | INT32 value = 0; |
| r32321 | r32322 | |
| 581 | 572 | sscanf(image_line + 9, "%d", &value); |
| 582 | 573 | unsigned_value = reverse((UINT32)value); |
| 583 | 574 | |
| 584 | | if(strcmp(op_buf, "num") == 0) |
| 585 | | { |
| 575 | if (!core_stricmp(op_buf, "num")) |
| 586 | 576 | word = unsigned_value; |
| 587 | | } |
| 588 | | else if(strcmp(op_buf, "jmp") == 0) |
| 589 | | { |
| 577 | else if (!core_stricmp(op_buf, "jmp")) |
| 590 | 578 | word = 0x00000000 | unsigned_value ; |
| 591 | | } |
| 592 | | else if(strcmp(op_buf, "jrp") == 0) |
| 593 | | { |
| 579 | else if (!core_stricmp(op_buf, "jrp")) |
| 594 | 580 | word = 0x00040000 | unsigned_value; |
| 595 | | } |
| 596 | | else if(strcmp(op_buf, "ldn") == 0) |
| 597 | | { |
| 581 | else if (!core_stricmp(op_buf, "ldn")) |
| 598 | 582 | word = 0x00020000 | unsigned_value; |
| 599 | | } |
| 600 | | else if(strcmp(op_buf, "sto") == 0) |
| 601 | | { |
| 583 | else if (!core_stricmp(op_buf, "sto")) |
| 602 | 584 | word = 0x00060000 | unsigned_value; |
| 603 | | } |
| 604 | | else if(strcmp(op_buf, "sub") == 0) |
| 605 | | { |
| 585 | else if (!core_stricmp(op_buf, "sub")) |
| 606 | 586 | word = 0x00010000 | unsigned_value; |
| 607 | | } |
| 608 | | else if(strcmp(op_buf, "cmp") == 0) |
| 609 | | { |
| 587 | else if (!core_stricmp(op_buf, "cmp")) |
| 610 | 588 | word = 0x00030000 | unsigned_value; |
| 611 | | } |
| 612 | | else if(strcmp(op_buf, "stp") == 0) |
| 613 | | { |
| 589 | else if (!core_stricmp(op_buf, "stp")) |
| 614 | 590 | word = 0x00070000 | unsigned_value; |
| 615 | | } |
| 616 | 591 | |
| 617 | | m_store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 618 | | m_store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 619 | | m_store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 620 | | m_store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 592 | space.write_byte((line << 2) + 0, (word >> 24) & 0x000000ff); |
| 593 | space.write_byte((line << 2) + 1, (word >> 16) & 0x000000ff); |
| 594 | space.write_byte((line << 2) + 2, (word >> 8) & 0x000000ff); |
| 595 | space.write_byte((line << 2) + 3, (word >> 0) & 0x000000ff); |
| 621 | 596 | } |
| 622 | 597 | } |
| 623 | 598 | } |
| r32321 | r32322 | |
| 629 | 604 | * Machine definition * |
| 630 | 605 | \****************************************************/ |
| 631 | 606 | |
| 607 | void ssem_state::machine_start() |
| 608 | { |
| 609 | save_item(NAME(m_store_line)); |
| 610 | } |
| 611 | |
| 632 | 612 | void ssem_state::machine_reset() |
| 633 | 613 | { |
| 634 | 614 | m_store_line = 0; |
| r32321 | r32322 | |
| 639 | 619 | MCFG_CPU_ADD("maincpu", SSEMCPU, 700) |
| 640 | 620 | MCFG_CPU_PROGRAM_MAP(ssem_map) |
| 641 | 621 | |
| 642 | | |
| 643 | 622 | /* video hardware */ |
| 644 | 623 | MCFG_SCREEN_ADD("screen", RASTER) |
| 645 | 624 | MCFG_SCREEN_REFRESH_RATE(50) |
| r32321 | r32322 | |
| 649 | 628 | MCFG_SCREEN_UPDATE_DRIVER(ssem_state, screen_update_ssem) |
| 650 | 629 | MCFG_PALETTE_ADD_BLACK_AND_WHITE("palette") |
| 651 | 630 | |
| 652 | | /* cartridge */ |
| 653 | | MCFG_CARTSLOT_ADD("cart") |
| 654 | | MCFG_CARTSLOT_EXTENSION_LIST("snp,asm") |
| 655 | | MCFG_CARTSLOT_LOAD(ssem_state,ssem_store) |
| 631 | /* quickload */ |
| 632 | MCFG_QUICKLOAD_ADD("quickload", ssem_state, ssem_store, "snp,asm", 1) |
| 656 | 633 | MACHINE_CONFIG_END |
| 657 | 634 | |
| 635 | |
| 658 | 636 | ROM_START( ssem ) |
| 659 | 637 | ROM_REGION( 0x80, "maincpu", ROMREGION_ERASE00 ) /* Main Store */ |
| 660 | 638 | ROM_END |
| 661 | 639 | |
| 640 | |
| 662 | 641 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |
| 663 | | COMP(1948, ssem, 0, 0, ssem, ssem, driver_device, 0, "Manchester University", "Small-Scale Experimental Machine (SSEM), 'Baby'", GAME_NO_SOUND_HW ) |
| 642 | COMP(1948, ssem, 0, 0, ssem, ssem, driver_device, 0, "Manchester University", "Small-Scale Experimental Machine (SSEM), 'Baby'", GAME_NO_SOUND_HW | GAME_SUPPORTS_SAVE ) |