From de64006303deda0c5d4fbba3c5a67c57539b2443 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Sun, 1 Jan 2017 19:35:33 -0500 Subject: [PATCH] Fixes #116 Support .po files --- src/Makefile | 4 ++-- src/dsk.c | 37 ++++++++++++++++++++++++++++++------- src/dsk.h | 6 +++++- src/utl.c | 35 +++++++++++++++++++++++++++++++++++ src/utl.h | 30 ++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 src/utl.c create mode 100644 src/utl.h diff --git a/src/Makefile b/src/Makefile index c27ad59..d9fb437 100644 --- a/src/Makefile +++ b/src/Makefile @@ -25,7 +25,7 @@ CFLAGS=-std=gnu11 -O3 -Wall -Wextra -Werror -Wno-unused-parameter LDFLAGS=-g -L/usr/local/lib EWM_EXECUTABLE=ewm -EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c two.c scr.c dsk.c chr.c alc.c one.c tty.c +EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c two.c scr.c dsk.c chr.c alc.c one.c tty.c utl.c EWM_OBJECTS=$(EWM_SOURCES:.c=.o) EWM_LIBS=-lSDL2 @@ -35,7 +35,7 @@ CPU_TEST_OBJECTS=$(CPU_TEST_SOURCES:.c=.o) CPU_TEST_LIBS= SCR_TEST_EXECUTABLE=scr_test -SCR_TEST_SOURCES=cpu.c ins.c mem.c fmt.c two.c scr.c dsk.c chr.c alc.c scr_test.c +SCR_TEST_SOURCES=cpu.c ins.c mem.c fmt.c two.c scr.c dsk.c chr.c alc.c utl.c scr_test.c SCR_TEST_OBJECTS=$(SCR_TEST_SOURCES:.c=.o) SCR_TEST_LIBS=-lSDL2 diff --git a/src/dsk.c b/src/dsk.c index 6de11a5..9a99aa9 100644 --- a/src/dsk.c +++ b/src/dsk.c @@ -29,6 +29,7 @@ #include "mem.h" #include "cpu.h" +#include "utl.h" #include "dsk.h" // @@ -292,8 +293,12 @@ static uint8_t dsk_fourxfour_lo(uint8_t v) { return (v & 0b01010101) | 0b10101010; } -static uint8_t dsk_sector_ordering[EWM_DSK_SECTORS] = { - 0x0,0xD,0xB,0x9,0x7,0x5,0x3,0x1,0xE,0xC,0xA,0x8,0x6,0x4,0x2,0xF +static uint8_t dsk_sector_ordering_do[EWM_DSK_SECTORS] = { + 0x00,0x0d,0x0b,0x09,0x07,0x05,0x03,0x01,0x0e,0x0c,0x0a,0x08,0x06,0x04,0x02,0x0f +}; + +static uint8_t dsk_sector_ordering_po[EWM_DSK_SECTORS] = { + 0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x01,0x03,0x05,0x07,0x09,0x0b,0x0d,0x0f }; static uint8_t *dsk_convert_sector(struct ewm_dsk_t *dsk, struct ewm_dsk_drive_t *drive, int track_idx, int sector_idx, uint8_t *src, uint8_t *dst) { @@ -385,18 +390,20 @@ static uint8_t *dsk_convert_sector(struct ewm_dsk_t *dsk, struct ewm_dsk_drive_t return dst; } -static struct ewm_dsk_track_t dsk_convert_track(struct ewm_dsk_t *disk, struct ewm_dsk_drive_t *drive, uint8_t *data, int track_idx) { +static struct ewm_dsk_track_t dsk_convert_track(struct ewm_dsk_t *disk, struct ewm_dsk_drive_t *drive, uint8_t *data, int track_idx, int type) { struct ewm_dsk_track_t track; track.length = dsk_native_track_length(track_idx); track.data = malloc(track.length); + uint8_t *sector_ordering = (type == EWM_DSK_TYPE_DO) ? dsk_sector_ordering_do : dsk_sector_ordering_po; + uint8_t *dst = track.data; for (int sector_idx = 0; sector_idx < EWM_DSK_SECTORS; sector_idx++) { int _s = 15 - sector_idx; uint8_t *src = data + (track_idx * EWM_DSK_SECTORS * EWM_DSK_SECTOR_SIZE) // Start of track_idx + (_s * EWM_DSK_SECTOR_SIZE); // Start of sector_idx - dst = dsk_convert_sector(disk, drive, track_idx, dsk_sector_ordering[_s], src, dst); + dst = dsk_convert_sector(disk, drive, track_idx, sector_ordering[_s], src, dst); } return track; @@ -421,7 +428,8 @@ struct ewm_dsk_t *ewm_dsk_create(struct cpu_t *cpu) { return dsk; } -int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, void *data, size_t length) { +int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, void *data, size_t length, int type) { + assert(type == EWM_DSK_TYPE_DO || type == EWM_DSK_TYPE_PO); assert(index < 2); assert(length == (EWM_DSK_TRACKS * EWM_DSK_SECTORS * EWM_DSK_SECTOR_SIZE)); @@ -444,13 +452,28 @@ int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, v drive->dirty = false; for (int t = 0; t < EWM_DSK_TRACKS; t++) { - drive->tracks[t] = dsk_convert_track(dsk, drive, data, t); + drive->tracks[t] = dsk_convert_track(dsk, drive, data, t, type); } return 0; } +static int ewm_dsk_type_from_path(char *path) { + if (ewm_utl_endswith(path, ".dsk") || ewm_utl_endswith(path, ".do")) { + return EWM_DSK_TYPE_DO; + } + if (ewm_utl_endswith(path, ".po")) { + return EWM_DSK_TYPE_PO; + } + return EWM_DSK_TYPE_UNKNOWN; +} + int ewm_dsk_set_disk_file(struct ewm_dsk_t *dsk, uint8_t drive, bool readonly, char *path) { + int type = ewm_dsk_type_from_path(path); + if (type == EWM_DSK_TYPE_UNKNOWN) { + return -1; + } + int fd = open(path, O_RDONLY); if (fd == -1) { return -1; @@ -475,7 +498,7 @@ int ewm_dsk_set_disk_file(struct ewm_dsk_t *dsk, uint8_t drive, bool readonly, c close(fd); - int result = ewm_dsk_set_disk_data(dsk, drive, readonly, data, file_info.st_size); + int result = ewm_dsk_set_disk_data(dsk, drive, readonly, data, file_info.st_size, type); free(data); return result; diff --git a/src/dsk.h b/src/dsk.h index 221dc2c..e0ae176 100644 --- a/src/dsk.h +++ b/src/dsk.h @@ -62,9 +62,13 @@ struct ewm_dsk_t { int skip; }; +#define EWM_DSK_TYPE_UNKNOWN (-1) +#define EWM_DSK_TYPE_DO (0) +#define EWM_DSK_TYPE_PO (1) + int ewm_dsk_init(struct ewm_dsk_t *dsk, struct cpu_t *cpu); struct ewm_dsk_t *ewm_dsk_create(struct cpu_t *cpu); -int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, void *data, size_t length); +int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, void *data, size_t length, int type); int ewm_dsk_set_disk_file(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, char *path); #endif diff --git a/src/utl.c b/src/utl.c new file mode 100644 index 0000000..b5202cb --- /dev/null +++ b/src/utl.c @@ -0,0 +1,35 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Stefan Arentz - http://github.com/st3fan/ewm +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include +#include + +#include "utl.h" + +bool ewm_utl_endswith(char *s, char *suffix) { + if (s != NULL && suffix != NULL) { + if (strlen(suffix) <= strlen(s)) { + return strcmp(s + strlen(s) - strlen(suffix), suffix) == 0; + } + } + return false; +} diff --git a/src/utl.h b/src/utl.h new file mode 100644 index 0000000..57d2324 --- /dev/null +++ b/src/utl.h @@ -0,0 +1,30 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Stefan Arentz - http://github.com/st3fan/ewm +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef EWM_UTL_H +#define EWM_UTL_H + +#include + +bool ewm_utl_endswith(char *s, char *suffix); + +#endif // EWM_UTL_H