mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +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!
|
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.)
|
FIXME: Some images should be 5.25" rather than 3.5", though TO8/TO9/TO9+ software can assumed to be the latter.
|
||||||
TODO: SAP format is not currently supported.
|
(The old custom Thomson floppy emulation didn't care about form factor, and many images are probably conversions.)
|
||||||
TBD: Which images are compatible with which systems?
|
|
||||||
-->
|
-->
|
||||||
<softwarelist name="to_flop" description="Thomson TO-series floppy disks">
|
<softwarelist name="to_flop" description="Thomson TO-series floppy disks">
|
||||||
|
|
||||||
|
@ -1771,6 +1771,18 @@ if opt_tool(FORMATS, "RX50_DSK") then
|
|||||||
}
|
}
|
||||||
end
|
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
|
--@src/lib/formats/sc3000_bit.h,FORMATS["SC3000_BIT"] = true
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cd90_015.h"
|
#include "cd90_015.h"
|
||||||
|
#include "formats/sap_dsk.h"
|
||||||
#include "formats/thom_dsk.h"
|
#include "formats/thom_dsk.h"
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(CD90_015, cd90_015_device, "cd90_015", "Thomson CD 90-015 floppy drive controller")
|
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)
|
void cd90_015_device::floppy_formats(format_registration &fr)
|
||||||
{
|
{
|
||||||
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
||||||
|
fr.add(FLOPPY_SAP_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cd90_015_device::device_add_mconfig(machine_config &config)
|
void cd90_015_device::device_add_mconfig(machine_config &config)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cd90_351.h"
|
#include "cd90_351.h"
|
||||||
|
#include "formats/sap_dsk.h"
|
||||||
#include "formats/thom_dsk.h"
|
#include "formats/thom_dsk.h"
|
||||||
#include "machine/thmfc1.h"
|
#include "machine/thmfc1.h"
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ void cd90_351_device::floppy_formats(format_registration &fr)
|
|||||||
{
|
{
|
||||||
fr.add_pc_formats();
|
fr.add_pc_formats();
|
||||||
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
||||||
|
fr.add(FLOPPY_SAP_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cd90_351_device::device_add_mconfig(machine_config &config)
|
void cd90_351_device::device_add_mconfig(machine_config &config)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cd90_640.h"
|
#include "cd90_640.h"
|
||||||
|
#include "formats/sap_dsk.h"
|
||||||
#include "formats/thom_dsk.h"
|
#include "formats/thom_dsk.h"
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(CD90_640, cd90_640_device, "cd90_640", "Thomson CD 90-640 floppy drive controller")
|
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)
|
void cd90_640_device::floppy_formats(format_registration &fr)
|
||||||
{
|
{
|
||||||
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
fr.add(FLOPPY_THOMSON_525_FORMAT);
|
||||||
|
fr.add(FLOPPY_SAP_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cd90_640_device::device_add_mconfig(machine_config &config)
|
void cd90_640_device::device_add_mconfig(machine_config &config)
|
||||||
|
@ -576,6 +576,10 @@
|
|||||||
#include "rx50_dsk.h"
|
#include "rx50_dsk.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_FORMATS_SAP_DSK
|
||||||
|
#include "sap_dsk.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_FORMATS_SC3000_BIT
|
#ifdef HAS_FORMATS_SC3000_BIT
|
||||||
#include "sc3000_bit.h"
|
#include "sc3000_bit.h"
|
||||||
#endif
|
#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_525_FORMAT); // thom_dsk.h
|
||||||
en.add(FLOPPY_THOMSON_35_FORMAT); // thom_dsk.h
|
en.add(FLOPPY_THOMSON_35_FORMAT); // thom_dsk.h
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_FORMATS_SAP_DSK
|
||||||
|
en.add(FLOPPY_SAP_FORMAT);
|
||||||
|
#endif
|
||||||
|
|
||||||
en.category("Texas Instruments");
|
en.category("Texas Instruments");
|
||||||
#ifdef HAS_FORMATS_TI99_DSK
|
#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 "softlist_dev.h"
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
|
|
||||||
|
#include "formats/sap_dsk.h"
|
||||||
#include "formats/thom_cas.h"
|
#include "formats/thom_cas.h"
|
||||||
#include "formats/thom_dsk.h"
|
#include "formats/thom_dsk.h"
|
||||||
|
|
||||||
@ -494,6 +495,7 @@ static void to35_floppy_formats(format_registration &fr)
|
|||||||
{
|
{
|
||||||
fr.add_pc_formats();
|
fr.add_pc_formats();
|
||||||
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
fr.add(FLOPPY_THOMSON_35_FORMAT);
|
||||||
|
fr.add(FLOPPY_SAP_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------ driver ------------ */
|
/* ------------ driver ------------ */
|
||||||
|
Loading…
Reference in New Issue
Block a user