Adds support for Pro-DOS images.

This commit is contained in:
Thomas Harte 2018-06-05 20:11:14 -04:00
parent b0577eb459
commit 21e8a281f8
2 changed files with 22 additions and 5 deletions

View File

@ -5,9 +5,14 @@ Usage:
dsk2woz input.dsk output.woz
Reads the contents of the DOS 3.3 disk input.dsk and outputs the WOZ-format file output.woz.
Reads the contents of the disk `input.dsk` and outputs the WOZ-format file `output.woz`.
## Building
There are no dependencies beyond the C standard library. So e.g.
cc dsk2woz.c -o dsk2woz
## DOS 3.3 versus Pro-DOS
Apple II DSK images contain implicitly-ordered sectors; the order depends on whether the image contains a DOS 3.3 image or a Pro-DOS image.
For the purposes of this tool if the file extension of the input disk has a 'p' in it then it is treated as a Pro-DOS image. Otherwise it is treated as a DOS 3.3 image.

View File

@ -1,10 +1,11 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
static uint32_t crc32(const uint8_t *buf, size_t size);
static void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_number);
static void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_number, bool is_prodos);
int main(int argc, char *argv[]) {
// Announce failure if there are anything other than three arguments.
@ -24,6 +25,17 @@ int main(int argc, char *argv[]) {
const size_t bytes_read = fread(dsk, 1, dsk_image_size, dsk_file);
fclose(dsk_file);
// Determine from the filename whether to use Pro-DOS sector order.
bool has_p = false;
bool has_dot = false;
const char *extension = argv[1] + strlen(argv[1]);
do {
has_p = *extension == 'p';
has_dot = *extension == '.';
--extension;
} while(extension > argv[1] && *extension != '/' && *extension != '.');
const bool is_prodos = has_p && has_dot;
// If the DSK image was too short, announce failure. Some DSK files
// seem empirically to be too long, but it's unclear that the extra
// bytes actually mean anything — they're usually not many.
@ -101,7 +113,7 @@ int main(int argc, char *argv[]) {
// Write out all 35 tracks.
for(int c = 0; c < 35; ++c) {
serialise_track(&woz[output_pointer], &dsk[c * 16 * 256], c);
serialise_track(&woz[output_pointer], &dsk[c * 16 * 256], c, is_prodos);
output_pointer += 6656;
}
#undef set_int32
@ -282,7 +294,7 @@ static void encode_6_and_2(uint8_t *dest, const uint8_t *src) {
}
void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_number) {
void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_number, bool is_prodos) {
size_t track_position = 0; // This is the track position **in bits**.
memset(dest, 0, 6646);
@ -329,7 +341,7 @@ void serialise_track(uint8_t *dest, const uint8_t *src, uint8_t track_number) {
track_position = write_byte(dest, track_position, 0xad);
// Map from this physical sector to a logical sector.
const int logical_sector = (sector == 15) ? 15 : ((sector * 7) % 15);
const int logical_sector = (sector == 15) ? 15 : ((sector * (is_prodos ? 8 : 7)) % 15);
// Sector contents
uint8_t contents[343];