diff --git a/src/mame/drivers/sorcerer.cpp b/src/mame/drivers/sorcerer.cpp index 75e3b6fca95..1bffa307d8c 100644 --- a/src/mame/drivers/sorcerer.cpp +++ b/src/mame/drivers/sorcerer.cpp @@ -173,19 +173,11 @@ Exidy Sorcerer Video/Disk Unit: void sorcerer_state::sorcerer_mem(address_map &map) { map.unmap_value_high(); - map(0x0000, 0xbfff).ram(); + map(0x0000, 0xffff).ram(); //map(0xc000, 0xdfff).rom(); // mapped by the cartslot map(0xe000, 0xefff).rom().region("maincpu", 0).nopw(); // bios - map(0xf000, 0xf7ff).ram(); // screen ram map(0xf800, 0xfbff).rom().region("chargen", 0).nopw(); // inbuilt characters - map(0xfc00, 0xffff).ram().share("pcg"); // PCG -} - -void sorcerer_state::sorcererb_mem(address_map &map) -{ - map.unmap_value_high(); - sorcerer_mem(map); - map(0xc000, 0xdfff).ram(); + map(0xfc00, 0xffff).share("pcg"); // PCG } void sorcererd_state::sorcererd_mem(address_map &map) @@ -477,8 +469,9 @@ void sorcerer_state::sorcerer(machine_config &config) INPUT_BUFFER(config, "cent_status_in"); /* quickload */ - SNAPSHOT(config, "snapshot", "snp", attotime::from_seconds(4)).set_load_callback(FUNC(sorcerer_state::snapshot_cb)); - QUICKLOAD(config, "quickload", "bin", attotime::from_seconds(4)).set_load_callback(FUNC(sorcerer_state::quickload_cb)); + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin,snp", attotime::from_seconds(4))); + quickload.set_load_callback(FUNC(sorcerer_state::quickload_cb)); + quickload.set_interface("sorcerer_quik"); CASSETTE(config, m_cassette1); m_cassette1->set_formats(sorcerer_cassette_formats); @@ -498,6 +491,7 @@ void sorcerer_state::sorcerer(machine_config &config) /* software lists */ SOFTWARE_LIST(config, "cart_list").set_original("sorcerer_cart"); SOFTWARE_LIST(config, "cass_list").set_original("sorcerer_cass"); + SOFTWARE_LIST(config, "quik_list").set_original("sorcerer_quik"); // internal ram RAM(config, RAM_TAG).set_default_size("48K").set_extra_options("8K,16K,32K"); @@ -559,7 +553,6 @@ void sorcerer_state::sorcerera(machine_config &config) void sorcerer_state::sorcererb(machine_config &config) { sorcerer(config); - m_maincpu->set_addrmap(AS_PROGRAM, &sorcerer_state::sorcererb_mem); m_maincpu->set_addrmap(AS_IO, &sorcerer_state::sorcererb_io); Z80DMA(config, m_dma, ES_CPU_CLOCK); diff --git a/src/mame/includes/sorcerer.h b/src/mame/includes/sorcerer.h index c23f65589d7..75dc96390f2 100644 --- a/src/mame/includes/sorcerer.h +++ b/src/mame/includes/sorcerer.h @@ -97,7 +97,6 @@ protected: void portff_w(u8 data); TIMER_CALLBACK_MEMBER(cassette_tc); TIMER_CALLBACK_MEMBER(serial_tc); - DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb); DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); void machine_start_common(offs_t endmem); void machine_reset_common(); diff --git a/src/mame/machine/sorcerer.cpp b/src/mame/machine/sorcerer.cpp index cdb9ed0782c..06071372f7d 100644 --- a/src/mame/machine/sorcerer.cpp +++ b/src/mame/machine/sorcerer.cpp @@ -529,121 +529,137 @@ void sorcererd_state::machine_reset() } -/****************************************************************************** - Snapshot Handling -******************************************************************************/ - -SNAPSHOT_LOAD_MEMBER(sorcerer_state::snapshot_cb) -{ - u8 *RAM = memregion(m_maincpu->tag())->base(); - address_space &space = m_maincpu->space(AS_PROGRAM); - u8 header[28]; - unsigned char s_byte; - - /* check size */ - if (image.length() != 0x1001c) - { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Snapshot must be 65564 bytes"); - image.message("Snapshot must be 65564 bytes"); - return image_init_result::FAIL; - } - - /* get the header */ - image.fread( &header, sizeof(header)); - - /* write it to ram */ - for (int i = 0; i < 0xc000; i++) - { - image.fread( &s_byte, 1); - space.write_byte(i, s_byte); - } - image.fread( RAM+0xc000, 0x4000); - - /* patch CPU registers */ - m_maincpu->set_state_int(Z80_I, header[0]); - m_maincpu->set_state_int(Z80_HL2, header[1] | (header[2] << 8)); - m_maincpu->set_state_int(Z80_DE2, header[3] | (header[4] << 8)); - m_maincpu->set_state_int(Z80_BC2, header[5] | (header[6] << 8)); - m_maincpu->set_state_int(Z80_AF2, header[7] | (header[8] << 8)); - m_maincpu->set_state_int(Z80_HL, header[9] | (header[10] << 8)); - m_maincpu->set_state_int(Z80_DE, header[11] | (header[12] << 8)); - m_maincpu->set_state_int(Z80_BC, header[13] | (header[14] << 8)); - m_maincpu->set_state_int(Z80_IY, header[15] | (header[16] << 8)); - m_maincpu->set_state_int(Z80_IX, header[17] | (header[18] << 8)); - m_maincpu->set_state_int(Z80_IFF1, header[19]&2 ? 1 : 0); - m_maincpu->set_state_int(Z80_IFF2, header[19]&4 ? 1 : 0); - m_maincpu->set_state_int(Z80_R, header[20]); - m_maincpu->set_state_int(Z80_AF, header[21] | (header[22] << 8)); - m_maincpu->set_state_int(STATE_GENSP, header[23] | (header[24] << 8)); - m_maincpu->set_state_int(Z80_IM, header[25]); - m_maincpu->set_pc(header[26] | (header[27] << 8)); - - return image_init_result::PASS; -} - - /*------------------------------------------------- QUICKLOAD_LOAD_MEMBER( sorcerer_state, sorcerer ) + Handles BIN and SNP extensions. -------------------------------------------------*/ QUICKLOAD_LOAD_MEMBER(sorcerer_state::quickload_cb) { - uint16_t execute_address, start_address, end_address; - int autorun; + // get autorun setting + bool autorun = BIT(m_iop_config->read(), 0); address_space &space = m_maincpu->space(AS_PROGRAM); - /* load the binary into memory */ - if (z80bin_load_file(image, space, execute_address, start_address, end_address) != image_init_result::PASS) - return image_init_result::FAIL; - - /* is this file executable? */ - if (execute_address != 0xffff) + if (image.is_filetype("bin")) { - /* check to see if autorun is on */ - autorun = m_iop_config->read() & 1; + u16 execute_address, start_address, end_address; - if ((execute_address >= 0xc000) && (execute_address <= 0xdfff) && (space.read_byte(0xdffa) != 0xc3)) - return image_init_result::FAIL; /* can't run a program if the cartridge isn't in */ + // load the binary into memory + if (z80bin_load_file(image, space, execute_address, start_address, end_address) != image_init_result::PASS) + return image_init_result::FAIL; - /* Since Exidy Basic is by Microsoft, it needs some preprocessing before it can be run. - 1. A start address of 01D5 indicates a basic program which needs its pointers fixed up. - 2. If autorunning, jump to C689 (command processor), else jump to C3DD (READY prompt). - Important addresses: - 01D5 = start (load) address of a conventional basic program - C858 = an autorun basic program will have this exec address on the tape - C3DD = part of basic that displays READY and lets user enter input */ - - if (((start_address == 0x1d5) || (execute_address == 0xc858)) && (space.read_byte(0xdffa) == 0xc3)) + // is this file executable? + if (execute_address != 0xffff) { - static const u8 data[]={ - 0xcd, 0x26, 0xc4, // CALL C426 ;set up other pointers - 0x21, 0xd4, 1, // LD HL,01D4 ;start of program address (used by C689) - 0x36, 0, // LD (HL),00 ;make sure dummy end-of-line is there - 0xc3, 0x89, 0xc6 // JP C689 ;run program - }; - for (u8 i = 0; i < std::size(data); i++) - space.write_byte(0xf01f + i, data[i]); + if ((execute_address >= 0xc000) && (execute_address <= 0xdfff) && (space.read_byte(0xdffa) != 0xc3)) + return image_init_result::FAIL; // can't run a program if the cartridge isn't in - if (!autorun) - space.write_word(0xf028,0xc3dd); + /* Since Exidy Basic is by Microsoft, it needs some preprocessing before it can be run. + 1. A start address of 01D5 indicates a basic program which needs its pointers fixed up. + 2. If autorunning, jump to C689 (command processor), else jump to C3DD (READY prompt). + Important addresses: + 01D5 = start (load) address of a conventional basic program + C858 = an autorun basic program will have this exec address on the tape + C3DD = part of basic that displays READY and lets user enter input */ - /* tell BASIC where program ends */ - space.write_byte(0x1b7, end_address & 0xff); - space.write_byte(0x1b8, (end_address >> 8) & 0xff); + if (((start_address == 0x1d5) || (execute_address == 0xc858)) && (space.read_byte(0xdffa) == 0xc3)) + { + static const u8 data[]={ + 0xcd, 0x26, 0xc4, // CALL C426 ;set up other pointers + 0x21, 0xd4, 1, // LD HL,01D4 ;start of program address (used by C689) + 0x36, 0, // LD (HL),00 ;make sure dummy end-of-line is there + 0xc3, 0x89, 0xc6 // JP C689 ;run program + }; - if ((execute_address != 0xc858) && autorun) - space.write_word(0xf028, execute_address); + for (u8 i = 0; i < std::size(data); i++) + space.write_byte(0xf01f + i, data[i]); - m_maincpu->set_pc(0xf01f); + if (!autorun) + space.write_word(0xf028,0xc3dd); + + /* tell BASIC where program ends */ + space.write_byte(0x1b7, end_address & 0xff); + space.write_byte(0x1b8, (end_address >> 8) & 0xff); + + if ((execute_address != 0xc858) && autorun) + space.write_word(0xf028, execute_address); + + m_maincpu->set_pc(0xf01f); + } + else + { + if (autorun) + m_maincpu->set_pc(execute_address); + } } - else + } + else + { + // SNP extension + // check size + if (image.length() != 0x1001c) { - if (autorun) - m_maincpu->set_pc(execute_address); + image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Snapshot must be 65564 bytes"); + image.message("Snapshot must be 65564 bytes"); + return image_init_result::FAIL; } + u8 header[28]; + + /* get the header */ + image.fread( &header, sizeof(header)); + + // write it to ram, and skip roms + unsigned char s_byte; + for (int i = 0; i < 0xe000; i++) + { + image.fread( &s_byte, 1); + space.write_byte(i, s_byte); // ram + } + + for (int i = 0xe000; i < 0xf000; i++) + image.fread( &s_byte, 1); + + for (int i = 0xf000; i < 0xf800; i++) + { + image.fread( &s_byte, 1); + space.write_byte(i, s_byte); // screen + } + + for (int i = 0xf800; i < 0xfc00; i++) + image.fread( &s_byte, 1); + + for (int i = 0xfc00; i < 0x10000; i++) + { + image.fread( &s_byte, 1); + space.write_byte(i, s_byte); //pcg + } + + // it's assumed if autorun was off that you wished to examine the image rather than to play it + if (autorun) + { + // patch CPU registers + m_maincpu->set_state_int(Z80_I, header[0]); + m_maincpu->set_state_int(Z80_HL2, header[1] | (header[2] << 8)); + m_maincpu->set_state_int(Z80_DE2, header[3] | (header[4] << 8)); + m_maincpu->set_state_int(Z80_BC2, header[5] | (header[6] << 8)); + m_maincpu->set_state_int(Z80_AF2, header[7] | (header[8] << 8)); + m_maincpu->set_state_int(Z80_HL, header[9] | (header[10] << 8)); + m_maincpu->set_state_int(Z80_DE, header[11] | (header[12] << 8)); + m_maincpu->set_state_int(Z80_BC, header[13] | (header[14] << 8)); + m_maincpu->set_state_int(Z80_IY, header[15] | (header[16] << 8)); + m_maincpu->set_state_int(Z80_IX, header[17] | (header[18] << 8)); + m_maincpu->set_state_int(Z80_IFF1, header[19]&2 ? 1 : 0); + m_maincpu->set_state_int(Z80_IFF2, header[19]&4 ? 1 : 0); + m_maincpu->set_state_int(Z80_R, header[20]); + m_maincpu->set_state_int(Z80_AF, header[21] | (header[22] << 8)); + m_maincpu->set_state_int(STATE_GENSP, header[23] | (header[24] << 8)); + m_maincpu->set_state_int(Z80_IM, header[25]); + m_maincpu->set_pc(header[26] | (header[27] << 8)); + } } return image_init_result::PASS; } +