mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
Add support for reading SAP (Systeme d'Archivage Pukall) disk images to Thomson systems
This commit is contained in:
parent
bccdfc9e04
commit
eb2a834625
@ -5,9 +5,8 @@ license:CC0-1.0
|
||||
|
||||
Thanks to DCMOTO (http://dcmoto.free.fr) for info!
|
||||
|
||||
FIXME: Many of these images should be 5.25" rather than 3.5". (The old custom Thomson floppy emulation didn't care about form factor.)
|
||||
TODO: SAP format is not currently supported.
|
||||
TBD: Which images are compatible with which systems?
|
||||
FIXME: Some images should be 5.25" rather than 3.5", though TO8/TO9/TO9+ software can assumed to be the latter.
|
||||
(The old custom Thomson floppy emulation didn't care about form factor, and many images are probably conversions.)
|
||||
-->
|
||||
<softwarelist name="to_flop" description="Thomson TO-series floppy disks">
|
||||
|
||||
|
@ -1771,6 +1771,18 @@ if opt_tool(FORMATS, "RX50_DSK") then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/sap_dsk.h,FORMATS["SAP_DSK"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if opt_tool(FORMATS, "SAP_DSK") then
|
||||
files {
|
||||
MAME_DIR.. "src/lib/formats/sap_dsk.cpp",
|
||||
MAME_DIR.. "src/lib/formats/sap_dsk.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/sc3000_bit.h,FORMATS["SC3000_BIT"] = true
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cd90_015.h"
|
||||
#include "formats/sap_dsk.h"
|
||||
#include "formats/thom_dsk.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(CD90_015, cd90_015_device, "cd90_015", "Thomson CD 90-015 floppy drive controller")
|
||||
@ -78,6 +79,7 @@ void cd90_015_device::floppy_drives(device_slot_interface &device)
|
||||
void cd90_015_device::floppy_formats(format_registration &fr)
|
||||
{
|
||||
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
||||
fr.add(FLOPPY_SAP_FORMAT);
|
||||
}
|
||||
|
||||
void cd90_015_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cd90_351.h"
|
||||
#include "formats/sap_dsk.h"
|
||||
#include "formats/thom_dsk.h"
|
||||
#include "machine/thmfc1.h"
|
||||
|
||||
@ -60,6 +61,7 @@ void cd90_351_device::floppy_formats(format_registration &fr)
|
||||
{
|
||||
fr.add_pc_formats();
|
||||
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
||||
fr.add(FLOPPY_SAP_FORMAT);
|
||||
}
|
||||
|
||||
void cd90_351_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cd90_640.h"
|
||||
#include "formats/sap_dsk.h"
|
||||
#include "formats/thom_dsk.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(CD90_640, cd90_640_device, "cd90_640", "Thomson CD 90-640 floppy drive controller")
|
||||
@ -49,6 +50,7 @@ void cd90_640_device::floppy_drives(device_slot_interface &device)
|
||||
void cd90_640_device::floppy_formats(format_registration &fr)
|
||||
{
|
||||
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
||||
fr.add(FLOPPY_SAP_FORMAT);
|
||||
}
|
||||
|
||||
void cd90_640_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -576,6 +576,10 @@
|
||||
#include "rx50_dsk.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FORMATS_SAP_DSK
|
||||
#include "sap_dsk.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FORMATS_SC3000_BIT
|
||||
#include "sc3000_bit.h"
|
||||
#endif
|
||||
@ -1339,6 +1343,9 @@ void mame_formats_full_list(mame_formats_enumerator &en)
|
||||
en.add(FLOPPY_THOMSON_525_FORMAT); // thom_dsk.h
|
||||
en.add(FLOPPY_THOMSON_35_FORMAT); // thom_dsk.h
|
||||
#endif
|
||||
#ifdef HAS_FORMATS_SAP_DSK
|
||||
en.add(FLOPPY_SAP_FORMAT);
|
||||
#endif
|
||||
|
||||
en.category("Texas Instruments");
|
||||
#ifdef HAS_FORMATS_TI99_DSK
|
||||
|
168
src/lib/formats/sap_dsk.cpp
Normal file
168
src/lib/formats/sap_dsk.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#include "sap_dsk.h"
|
||||
|
||||
#include "ioprocs.h"
|
||||
#include "multibyte.h"
|
||||
|
||||
static constexpr unsigned HEADER_LENGTH = 66;
|
||||
static constexpr uint8_t MAGIC_XOR = 0xb3;
|
||||
|
||||
const sap_dsk_format FLOPPY_SAP_FORMAT;
|
||||
|
||||
inline uint16_t sap_dsk_format::accumulate_crc(uint16_t crc, uint8_t data) noexcept
|
||||
{
|
||||
// Almost CRC16-CCITT, but not quite...
|
||||
for (int shift : {0, 4})
|
||||
crc = ((crc >> 4) & 0xfff) ^ 0x1081 * ((crc ^ (data >> shift)) & 0xf);
|
||||
return crc;
|
||||
}
|
||||
|
||||
const char *sap_dsk_format::name() const noexcept
|
||||
{
|
||||
return "sap_dsk";
|
||||
}
|
||||
|
||||
const char *sap_dsk_format::description() const noexcept
|
||||
{
|
||||
return "Thomson SAP disk image (Systeme d'Archivage Pukall)";
|
||||
}
|
||||
|
||||
const char *sap_dsk_format::extensions() const noexcept
|
||||
{
|
||||
return "sap";
|
||||
}
|
||||
|
||||
bool sap_dsk_format::supports_save() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int sap_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
|
||||
{
|
||||
uint8_t buffer[HEADER_LENGTH];
|
||||
auto [err, actual] = read_at(io, 0, buffer, HEADER_LENGTH);
|
||||
if (err || actual != HEADER_LENGTH)
|
||||
return 0;
|
||||
|
||||
// Check ID string
|
||||
if (memcmp(&buffer[1], "SYSTEME D'ARCHIVAGE PUKALL S.A.P. (c) Alexandre PUKALL Avril 1998", HEADER_LENGTH - 1) != 0)
|
||||
return 0;
|
||||
|
||||
// Check disk format
|
||||
if (form_factor == floppy_image::FF_35)
|
||||
{
|
||||
// 3.5" disks must have 80 double-density tracks
|
||||
if ((buffer[0] & 0x7f) != 0x01)
|
||||
return 0;
|
||||
}
|
||||
else if (form_factor == floppy_image::FF_525)
|
||||
{
|
||||
// 5.25" disks must have 40 tracks
|
||||
if ((buffer[0] & 0x7e) != 0x02)
|
||||
return 0;
|
||||
}
|
||||
else if (form_factor != floppy_image::FF_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
uint32_t expected_size = HEADER_LENGTH + uint32_t((buffer[0] & 0x01) ? 256 + 6 : 128 + 6) * ((buffer[0] & 0x02) ? 40 : 80) * 16 * ((buffer[0] & 0x80) ? 2 : 1);
|
||||
uint64_t actual_size;
|
||||
if (!io.length(actual_size) && expected_size == actual_size)
|
||||
return FIFID_SIGN | FIFID_SIZE;
|
||||
else
|
||||
return FIFID_SIGN;
|
||||
}
|
||||
|
||||
bool sap_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const
|
||||
{
|
||||
uint8_t disk_type;
|
||||
if (auto [err, actual] = read_at(io, 0, &disk_type, 1); err || actual != 1)
|
||||
return false;
|
||||
|
||||
int track_count = (disk_type & 0x02) ? 40 : 80;
|
||||
int head_count = (disk_type & 0x80) ? 2 : 1;
|
||||
int max_tracks, max_heads;
|
||||
image.get_maximal_geometry(max_tracks, max_heads);
|
||||
if (max_heads < head_count || max_tracks < track_count)
|
||||
return false;
|
||||
|
||||
switch (disk_type & 0x03)
|
||||
{
|
||||
case 0x01:
|
||||
image.set_form_variant(floppy_image::FF_35, (disk_type & 0x80) ? floppy_image::DSDD : floppy_image::SSDD);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
image.set_form_variant(floppy_image::FF_525, (disk_type & 0x80) ? floppy_image::DSSD : floppy_image::SSSD);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
image.set_form_variant(floppy_image::FF_525, (disk_type & 0x80) ? floppy_image::DSDD : floppy_image::SSDD);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t sector_buf[16 * 1024];
|
||||
uint8_t sector_header[4];
|
||||
uint8_t sector_crc[2];
|
||||
desc_pc_sector sectors[16];
|
||||
|
||||
size_t read_offset = HEADER_LENGTH;
|
||||
for (int head = 0; head < head_count; head++)
|
||||
{
|
||||
for (int track = 0; track < track_count; track++)
|
||||
{
|
||||
uint8_t *bufptr = §or_buf[0];
|
||||
uint8_t track_size = 16;
|
||||
int sector_count = 0;
|
||||
bool is_mfm = disk_type & 0x01;
|
||||
while (track_size != 0)
|
||||
{
|
||||
if (auto [err, actual] = read_at(io, read_offset, §or_header[0], 4); err || actual != 4)
|
||||
return false;
|
||||
if (sector_count == 0 && sector_header[0] == 1)
|
||||
is_mfm = false;
|
||||
uint8_t sector_size = (sector_header[0] & 2) ? 4 >> (sector_header[0] & 1) : 1;
|
||||
if (track_size < sector_size)
|
||||
return false;
|
||||
uint16_t sector_octets = sector_size * (is_mfm ? 256 : 128);
|
||||
if (auto [err, actual] = read_at(io, read_offset + 4, bufptr, sector_octets); err || actual != sector_octets)
|
||||
return false;
|
||||
if (auto [err, actual] = read_at(io, read_offset + 4 + sector_octets, §or_crc[0], 2); err || actual != 2)
|
||||
return false;
|
||||
|
||||
uint16_t crc = 0xffff;
|
||||
for (uint8_t data : sector_header)
|
||||
crc = accumulate_crc(crc, data);
|
||||
for (uint16_t i = 0; i < sector_octets; i++)
|
||||
{
|
||||
bufptr[i] ^= MAGIC_XOR;
|
||||
crc = accumulate_crc(crc, bufptr[i]);
|
||||
}
|
||||
|
||||
sectors[sector_count].track = sector_header[2];
|
||||
sectors[sector_count].head = head;
|
||||
sectors[sector_count].sector = sector_header[3];
|
||||
sectors[sector_count].size = sector_size;
|
||||
sectors[sector_count].actual_size = sector_octets;
|
||||
sectors[sector_count].data = bufptr;
|
||||
sectors[sector_count].deleted = false;
|
||||
sectors[sector_count].bad_crc = crc != get_u16be(sector_crc);
|
||||
|
||||
read_offset += sector_octets + 6;
|
||||
bufptr += sector_octets;
|
||||
track_size -= sector_size;
|
||||
sector_count++;
|
||||
}
|
||||
if (is_mfm)
|
||||
build_pc_track_mfm(track, head, image, 100000, sector_count, sectors, calc_default_pc_gap3_size(form_factor, sectors[0].actual_size));
|
||||
else
|
||||
build_pc_track_fm(track, head, image, 100000 / 2, sector_count, sectors, calc_default_pc_gap3_size(form_factor, sectors[0].actual_size));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
30
src/lib/formats/sap_dsk.h
Normal file
30
src/lib/formats/sap_dsk.h
Normal file
@ -0,0 +1,30 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_FORMATS_SAP_DSK_H
|
||||
#define MAME_FORMATS_SAP_DSK_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flopimg.h"
|
||||
|
||||
class sap_dsk_format : public floppy_image_format_t
|
||||
{
|
||||
public:
|
||||
sap_dsk_format() = default;
|
||||
|
||||
virtual const char *name() const noexcept override;
|
||||
virtual const char *description() const noexcept override;
|
||||
virtual const char *extensions() const noexcept override;
|
||||
virtual bool supports_save() const noexcept override;
|
||||
|
||||
virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const override;
|
||||
virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const override;
|
||||
|
||||
private:
|
||||
static inline uint16_t accumulate_crc(uint16_t crc, uint8_t data) noexcept;
|
||||
};
|
||||
|
||||
extern const sap_dsk_format FLOPPY_SAP_FORMAT;
|
||||
|
||||
#endif // MAME_FORMATS_SAP_DSK_H
|
@ -97,6 +97,7 @@
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "formats/sap_dsk.h"
|
||||
#include "formats/thom_cas.h"
|
||||
#include "formats/thom_dsk.h"
|
||||
|
||||
@ -494,6 +495,7 @@ static void to35_floppy_formats(format_registration &fr)
|
||||
{
|
||||
fr.add_pc_formats();
|
||||
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
||||
fr.add(FLOPPY_SAP_FORMAT);
|
||||
}
|
||||
|
||||
/* ------------ driver ------------ */
|
||||
|
Loading…
Reference in New Issue
Block a user