Skip to content

Commit

Permalink
Merge pull request #684 from mike-wiese/dsk-40-tracks
Browse files Browse the repository at this point in the history
apple2: Support 40 track 5.25 inch disk images
  • Loading branch information
tschak909 authored Nov 4, 2023
2 parents b094001 + ec3dd7d commit a232440
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 37 deletions.
53 changes: 29 additions & 24 deletions lib/device/iwm/disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,8 +502,8 @@ iwmDisk::iwmDisk()

mediatype_t iwmDisk::mount(FILE *f, const char *filename, uint32_t disksize, mediatype_t disk_type)
{
mediatype_t mt = disk_type;
uint8_t deviceSlot = data_buffer[0]; // from mount ctrl cmd
mediatype_t mt = MEDIATYPE_UNKNOWN;
Debug_printf("disk MOUNT %s\n", filename);

// Destroy any existing MediaType
Expand All @@ -515,66 +515,71 @@ mediatype_t iwmDisk::mount(FILE *f, const char *filename, uint32_t disksize, med
}

// Determine MediaType based on filename extension
if (disk_type == MEDIATYPE_UNKNOWN && filename != nullptr) {
disk_type = MediaType::discover_mediatype(filename);
if (disk_type == MEDIATYPE_DSK) {
// determine DO or PO based on file contents
disk_type = MediaType::discover_dsk_mediatype(f, disksize);
}
if (mt == MEDIATYPE_UNKNOWN && filename != nullptr) {
mt = MediaType::discover_mediatype(filename);
}

if (mt == MEDIATYPE_DSK) {
// determine DO or PO based on file contents
mt = MediaType::discover_dsk_mediatype(f, disksize);
}

if (deviceSlot < 4) // SP drive
{
switch (disk_type)
switch (mt)
{
case MEDIATYPE_DO:
Debug_printf("\r\nMedia Type DO");
_disk = new MediaTypeDO();
_disk->_media_host = host;
_disk->_mediatype = disk_type;
strcpy(_disk->_disk_filename, filename);
mt = _disk->mount(f, disksize);

device_active = true; //change status only after we are mounted
break;
case MEDIATYPE_PO:
Debug_printf("\r\nMedia Type PO");
_disk = new MediaTypePO();
break;
default:
Debug_printf("\r\nUnsupported Media Type for SmartPort");
mt = MEDIATYPE_UNKNOWN;
break;
}

if (mt != MEDIATYPE_UNKNOWN) {
_disk->_media_host = host;
_disk->_mediatype = disk_type;
_disk->_mediatype = mt;
strcpy(_disk->_disk_filename, filename);
mt = _disk->mount(f, disksize);
}

if (mt != MEDIATYPE_UNKNOWN) {
// firmware needs to believe a high score enabled disk is
// not write-protected. Otherwise it will skip write process
if (_disk->high_score_enabled)
readonly = false;

device_active = true; //change status only after we are mounted
break;
default:
Debug_printf("\r\nMedia Type UNKNOWN for SP Drive - no mount in disk.cpp");
device_active = false;
break;
}
}
else // DiskII drive
{
switch (disk_type)
switch (mt)
{
case MEDIATYPE_DO:
case MEDIATYPE_PO:
case MEDIATYPE_WOZ:
theFuji._fnDisk2s[deviceSlot - 4].init();
theFuji._fnDisk2s[deviceSlot - 4].mount(f, disk_type); // modulo to ensure device 0 or 1
mt = theFuji._fnDisk2s[deviceSlot - 4].mount(f, disksize, mt);
break;
default:
Debug_printf("\r\nMedia Type UNKNOWN for DiskII - no mount in disk.cpp");
device_active = false;
Debug_printf("\r\nUnsupported Media Type for DiskII");
mt = MEDIATYPE_UNKNOWN;
break;
}
}

if (mt == MEDIATYPE_UNKNOWN) {
Debug_printf("\r\nMedia Type UNKNOWN - no mount in disk.cpp");
device_active = false;
}

return mt;

}
Expand Down
15 changes: 9 additions & 6 deletions lib/device/iwm/disk2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void iwmDisk2::init()
device_active = false;
}

mediatype_t iwmDisk2::mount(FILE *f, mediatype_t disk_type)//, const char *filename), uint32_t disksize, mediatype_t disk_type)
mediatype_t iwmDisk2::mount(FILE *f, uint32_t disksize, mediatype_t disk_type)//, const char *filename), uint32_t disksize, mediatype_t disk_type)
{

mediatype_t mt = MEDIATYPE_UNKNOWN;
Expand All @@ -57,22 +57,25 @@ mediatype_t iwmDisk2::mount(FILE *f, mediatype_t disk_type)//, const char *filen
Debug_printf("\nMounting Media Type WOZ");
device_active = true;
_disk = new MediaTypeWOZ();
mt = ((MediaTypeWOZ *)_disk)->mount(f);
change_track(0); // initialize spi buffer
mt = ((MediaTypeWOZ *)_disk)->mount(f, disksize);
break;
case MEDIATYPE_DO:
case MEDIATYPE_PO:
Debug_printf("\nMounting Media Type DSK");
device_active = true;
_disk = new MediaTypeDSK();
_disk->_mediatype = disk_type;
mt = ((MediaTypeDSK *)_disk)->mount(f);
change_track(0); // initialize spi buffer
mt = ((MediaTypeDSK *)_disk)->mount(f, disksize);
break;
default:
break;
}

if (mt == MEDIATYPE_WOZ) {
change_track(0); // initialize spi buffer
} else {
Debug_printf("\nMedia Type UNKNOWN - no mount in disk2.cpp");
device_active = false;
break;
}

return mt;
Expand Down
2 changes: 1 addition & 1 deletion lib/device/iwm/disk2.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class iwmDisk2 : public iwmDevice
public:
iwmDisk2();
void init();
mediatype_t mount(FILE *f, mediatype_t disk_type = MEDIATYPE_UNKNOWN);
mediatype_t mount(FILE *f, uint32_t disksize, mediatype_t disk_type = MEDIATYPE_UNKNOWN);
void unmount();
bool write_blank(FILE *f, uint16_t sectorSize, uint16_t numSectors);
int get_track_pos() { return track_pos; };
Expand Down
11 changes: 11 additions & 0 deletions lib/media/apple/mediaTypeDO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ bool MediaTypeDO::format(uint16_t *respopnsesize)

mediatype_t MediaTypeDO::mount(FILE *f, uint32_t disksize)
{
switch (disksize) {
case 35 * BYTES_PER_TRACK:
case 36 * BYTES_PER_TRACK:
case 40 * BYTES_PER_TRACK:
// 35, 36, and 40 tracks are supported (same as Applesauce)
break;
default:
Debug_printf("\nMediaTypeDO error: unsupported disk image size %ld", disksize);
return MEDIATYPE_UNKNOWN;
}

diskiiemulation = false;
_media_fileh = f;
num_blocks = disksize / BYTES_PER_BLOCK;
Expand Down
21 changes: 17 additions & 4 deletions lib/media/apple/mediaTypeDSK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// #include <stdint.h>
// #include <string.h>

#define BYTES_PER_TRACK 4096

// routines to convert DSK to WOZ stolen from DSK2WOZ by Tom Harte
// https://github.com/TomHarte/dsk2woz
Expand All @@ -19,11 +20,23 @@ static void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_num

mediatype_t MediaTypeDSK::mount(FILE *f, uint32_t disksize)
{
switch (disksize) {
case 35 * BYTES_PER_TRACK:
case 36 * BYTES_PER_TRACK:
case 40 * BYTES_PER_TRACK:
// 35, 36, and 40 tracks are supported (same as Applesauce)
break;
default:
Debug_printf("\nMediaTypeDSK error: unsupported disk image size %ld", disksize);
return MEDIATYPE_UNKNOWN;
}

_media_fileh = f;
diskiiemulation = true;
num_tracks = disksize / BYTES_PER_TRACK;

// allocated SPRAM
const size_t dsk_image_size = 35 * 16 * 256;
const size_t dsk_image_size = num_tracks * BYTES_PER_TRACK;
uint8_t *dsk = (uint8_t*)heap_caps_malloc(dsk_image_size, MALLOC_CAP_SPIRAM);
if (fseek(f, 0, SEEK_SET) != 0)
return MEDIATYPE_UNKNOWN;
Expand Down Expand Up @@ -59,7 +72,7 @@ void MediaTypeDSK::dsk2woz_tmap()
// Let's start by filling the entire TMAP with empty tracks.
memset(tmap, 0xff, 160);
// Then we will add in the mappings.
for(size_t c = 0; c < 35; ++c)
for(size_t c = 0; c < num_tracks; ++c)
{
size_t track_position = c << 2;
if (c > 0)
Expand Down Expand Up @@ -91,8 +104,8 @@ bool MediaTypeDSK::dsk2woz_tracks(uint8_t *dsk)
Debug_printf("\nMediaTypeDSK is_prodos: %s", _mediatype == MEDIATYPE_PO ? "Y" : "N");

// TODO: adapt this to that
// Write out all 35 tracks.
for (size_t c = 0; c < 35; c++)
// Write out all tracks.
for (size_t c = 0; c < num_tracks; c++)
{
uint16_t bytes_used;
uint16_t bit_count;
Expand Down
3 changes: 2 additions & 1 deletion lib/media/apple/mediaTypeDSK.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
class MediaTypeDSK : public MediaTypeWOZ
{
private:
size_t num_tracks = 0;

void dsk2woz_info();
void dsk2woz_tmap();
bool dsk2woz_tracks(uint8_t *dsk);

public:

virtual mediatype_t mount(FILE *f, uint32_t disksize) override;
mediatype_t mount(FILE *f) {return mount(f, 0);};
// virtual void unmount() override;

// static bool create(FILE *f, uint32_t numBlock);
Expand Down
1 change: 0 additions & 1 deletion lib/media/apple/mediaTypeWOZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class MediaTypeWOZ : public MediaType
virtual bool format(uint16_t *respopnsesize) override { return false; };

virtual mediatype_t mount(FILE *f, uint32_t disksize) override;
mediatype_t mount(FILE *f) {return mount(f, 0);};
virtual void unmount() override;

virtual bool status() override {return (_media_fileh != nullptr);}
Expand Down

0 comments on commit a232440

Please sign in to comment.