Compare commits
11 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4925b3453a | ||
|
|
ee266ee6e2 | ||
|
|
01c0dba6ff | ||
|
|
c3bbf2e55f | ||
|
|
69ea975f5c | ||
|
|
de1fa12ad6 | ||
|
|
7118f6cf40 | ||
|
|
281b3c2f86 | ||
|
|
82f8bbda20 | ||
|
|
c6c32d09ce | ||
|
|
cb757ba8f0 |
10 changed files with 57 additions and 60 deletions
6
Makefile
6
Makefile
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
export FW_VER := 1.0
|
export FW_VER := 1.3
|
||||||
|
|
||||||
PROJ := FlashFloppy
|
PROJ := FlashFloppy
|
||||||
VER := v$(FW_VER)
|
VER := v$(FW_VER)
|
||||||
|
|
@ -30,7 +30,7 @@ gotek: all
|
||||||
|
|
||||||
HXC_FF_URL := https://www.github.com/keirf/HxC_FF_File_Selector
|
HXC_FF_URL := https://www.github.com/keirf/HxC_FF_File_Selector
|
||||||
HXC_FF_URL := $(HXC_FF_URL)/releases/download
|
HXC_FF_URL := $(HXC_FF_URL)/releases/download
|
||||||
HXC_FF_VER := v1.75-ff
|
HXC_FF_VER := v5-FF
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
rm -rf flashfloppy-*
|
rm -rf flashfloppy-*
|
||||||
|
|
@ -52,6 +52,8 @@ dist:
|
||||||
rm -rf index.html
|
rm -rf index.html
|
||||||
unzip -q HxC_Compat_Mode-$(HXC_FF_VER).zip
|
unzip -q HxC_Compat_Mode-$(HXC_FF_VER).zip
|
||||||
mv HxC_Compat_Mode flashfloppy-$(VER)
|
mv HxC_Compat_Mode flashfloppy-$(VER)
|
||||||
|
mkdir -p flashfloppy-$(VER)/scripts
|
||||||
|
cp -a scripts/edsk* flashfloppy-$(VER)/scripts/
|
||||||
zip -r flashfloppy-$(VER).zip flashfloppy-$(VER)
|
zip -r flashfloppy-$(VER).zip flashfloppy-$(VER)
|
||||||
|
|
||||||
mrproper: clean
|
mrproper: clean
|
||||||
|
|
|
||||||
65
README.md
65
README.md
|
|
@ -1,44 +1,27 @@
|
||||||
# FlashFloppy
|
# FlashFloppy
|
||||||
|
|
||||||
A retro floppy emulator for the ubiquitous Gotek hardware.
|
A retro floppy emulator for the ubiquitous Gotek hardware.
|
||||||
- Directly supports a wide range of image formats:
|
- Directly supports a [wide range of image formats][Image-Formats]
|
||||||
- ADF (Commodore Amiga)
|
- [Flexible track layout][Track-Layouts] for Raw Sector Images
|
||||||
- ADM, ADL, ADF, DSD, SSD (Acorn DFS and ADFS)
|
- [Extremely configurable][FF.CFG-Configuration-File]
|
||||||
- D81 (Commodore 64 1581)
|
|
||||||
- DSK (Amstrad CPC, Spectrum +3, Sam Coupe, Microbee)
|
|
||||||
- FDI, HDM (NEC PC-98)
|
|
||||||
- IMG, IMA, DSK (IBM MFM Raw Sector)
|
|
||||||
- JVC, DSK (Tandy Color Computer 'CoCo')
|
|
||||||
- MBD (Spectrum MB02)
|
|
||||||
- MGT (Spectrum DISCiPLE/+D)
|
|
||||||
- OPD (Spectrum Opus Discovery)
|
|
||||||
- SDU (SAB Diskette Utility)
|
|
||||||
- ST (Atari ST)
|
|
||||||
- TRD (Spectrum TR-DOS)
|
|
||||||
- V9T9, DSK (TI-99/4A)
|
|
||||||
- VDK (Dragon)
|
|
||||||
- HFE, HFEv3 (Universal)
|
|
||||||
- Pre-configured track layouts for Raw Sector Images:
|
|
||||||
- Akai (S01, S20, S950), Korg, SC (Prophet 3000)
|
|
||||||
- Casio (FZ-1)
|
|
||||||
- DEC (RX33, RX50)
|
|
||||||
- Ensoniq (ASR, TS, etc)
|
|
||||||
- Fluke (9100)
|
|
||||||
- General Music (S2, S3, S2R)
|
|
||||||
- Kaypro
|
|
||||||
- Memotech
|
|
||||||
- MSX
|
|
||||||
- Nascom (1, 2)
|
|
||||||
- NEC PC-98
|
|
||||||
- UKNC, DVK (Soviet PDP-11)
|
|
||||||
- IBM PC and many others
|
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
- [**Download FlashFloppy**](https://github.com/keirf/FlashFloppy/wiki/Downloads)
|
- [**Download FlashFloppy**][Downloads]
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
- [**Read the GitHub Wiki**](https://github.com/keirf/FlashFloppy/wiki)
|
- [**Read the GitHub Wiki**](https://github.com/keirf/FlashFloppy/wiki)
|
||||||
|
|
||||||
|
## Donations
|
||||||
|
|
||||||
|
FlashFloppy is a labour of love: working on it takes a **lot** of time
|
||||||
|
and effort. The development of new features, plus maintenance, bug
|
||||||
|
fixing, testing, release preparations and so on is a huge undertaking;
|
||||||
|
and that ignores non-development tasks such as writing documentation
|
||||||
|
and community management.
|
||||||
|
|
||||||
|
If you would like to **support FlashFloppy's development**, please see
|
||||||
|
the [**Donations page**][Donations].
|
||||||
|
|
||||||
## Redistribution
|
## Redistribution
|
||||||
|
|
||||||
Most code is public domain; the rest is MIT/BSD or Open Source friendly
|
Most code is public domain; the rest is MIT/BSD or Open Source friendly
|
||||||
|
|
@ -55,16 +38,8 @@ file on your selling page. For example:
|
||||||
- FlashFloppy is free software. For more information see the
|
- FlashFloppy is free software. For more information see the
|
||||||
[license](COPYING).
|
[license](COPYING).
|
||||||
|
|
||||||
## Donations
|
[Image-Formats]: https://github.com/keirf/FlashFloppy/wiki/Image-Formats
|
||||||
|
[Track-Layouts]: https://github.com/keirf/FlashFloppy/wiki/Track-Layouts
|
||||||
Although FlashFloppy is Free Software, some people have expressed a
|
[FF.CFG-Configuration-File]: https://github.com/keirf/FlashFloppy/wiki/FF.CFG-Configuration-File
|
||||||
wish to make a donation for using and distributing it. If this
|
[Downloads]: https://github.com/keirf/FlashFloppy/wiki/Downloads
|
||||||
includes you please feel free to make that donation to a charity of your
|
[Donations]: https://github.com/keirf/FlashFloppy/wiki/Donations
|
||||||
choice. Money sent directly to me is donated to
|
|
||||||
[Macmillan Cancer Support](https://www.macmillan.org.uk/donate)
|
|
||||||
in the UK.
|
|
||||||
|
|
||||||
A couple of redistributors have chosen to donate 1GBP/1EUR to charity
|
|
||||||
for each unit they sell. I appreciate this lovely gesture but as with
|
|
||||||
end-user donations it is entirely at their discretion. FlashFloppy
|
|
||||||
will always be Free.
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,17 @@
|
||||||
** Keir Fraser <keir.xen@gmail.com>
|
** Keir Fraser <keir.xen@gmail.com>
|
||||||
************************************
|
************************************
|
||||||
|
|
||||||
|
** v1.3 - 26 May 2019
|
||||||
|
- Indexed mode: Fix for *.ST images
|
||||||
|
- MFM generation: Fix small error for DSK and IMG
|
||||||
|
|
||||||
|
** v1.2 - 14 April 2019
|
||||||
|
- OLED: Fix horizontal offset on SH1106 128x32 displays
|
||||||
|
- Update HxC Compat to v5-FF
|
||||||
|
|
||||||
|
** v1.1 - 14 March 2019
|
||||||
|
- FF.CFG: Fix parsing of comma-separated values
|
||||||
|
|
||||||
** v1.0 - 4 February 2019
|
** v1.0 - 4 February 2019
|
||||||
- Game/demo AutoSwap-disks feature
|
- Game/demo AutoSwap-disks feature
|
||||||
- No manual disk swapping, at all!
|
- No manual disk swapping, at all!
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ def main(argv):
|
||||||
sides = int(x[3])
|
sides = int(x[3])
|
||||||
tsz = in_dat[52:256]
|
tsz = in_dat[52:256]
|
||||||
populated = 0
|
populated = 0
|
||||||
|
ext = False
|
||||||
|
if x[0].startswith("EXTENDED CPC DSK File\r\nDisk-Info\r\n"):
|
||||||
|
print("Extended DSK")
|
||||||
|
ext = True
|
||||||
|
else:
|
||||||
|
assert x[0].startswith("MV - CPCEMU")
|
||||||
|
print("Standard DSK")
|
||||||
while tsz:
|
while tsz:
|
||||||
x = struct.unpack("B", tsz[:1])
|
x = struct.unpack("B", tsz[:1])
|
||||||
if int(x[0]) != 0:
|
if int(x[0]) != 0:
|
||||||
|
|
@ -42,6 +49,8 @@ def main(argv):
|
||||||
tot_dlen = 0
|
tot_dlen = 0
|
||||||
while sinfo and nr != 0:
|
while sinfo and nr != 0:
|
||||||
(c,h,r,n,s1,s2,alen) = struct.unpack("<BBBBBBH", sinfo[:8])
|
(c,h,r,n,s1,s2,alen) = struct.unpack("<BBBBBBH", sinfo[:8])
|
||||||
|
if not ext:
|
||||||
|
alen = 128<<n
|
||||||
sdat = in_dat[:alen]
|
sdat = in_dat[:alen]
|
||||||
in_dat = in_dat[alen:]
|
in_dat = in_dat[alen:]
|
||||||
tot_dlen += alen
|
tot_dlen += alen
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ static int isvalid(char c)
|
||||||
return (((c >= 'A') && (c <= 'Z'))
|
return (((c >= 'A') && (c <= 'Z'))
|
||||||
|| ((c >= 'a') && (c <= 'z'))
|
|| ((c >= 'a') && (c <= 'z'))
|
||||||
|| ((c >= '0') && (c <= '9'))
|
|| ((c >= '0') && (c <= '9'))
|
||||||
|| ((c == '-')));
|
|| (c == '-') || (c == ','));
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_next_opt(struct opts *opts)
|
int get_next_opt(struct opts *opts)
|
||||||
|
|
|
||||||
|
|
@ -561,9 +561,9 @@ static unsigned int oled_start_i2c(uint8_t *buf)
|
||||||
static const uint8_t ssd1306_addr_cmds[] = {
|
static const uint8_t ssd1306_addr_cmds[] = {
|
||||||
0x20, 0, /* horizontal addressing mode */
|
0x20, 0, /* horizontal addressing mode */
|
||||||
0x21, 0, 127, /* column address range: 0-127 */
|
0x21, 0, 127, /* column address range: 0-127 */
|
||||||
0x22, 0, /*3*//* page address range: 0-3 */
|
0x22, 0, /*?*//* page address range: 0-? */
|
||||||
}, sh1106_addr_cmds[] = {
|
}, sh1106_addr_cmds[] = {
|
||||||
0x02, 0x10, /* column address: 2 */
|
0x10 /* column address high nibble is zero */
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t dynamic_cmds[4], *dc = dynamic_cmds;
|
uint8_t dynamic_cmds[4], *dc = dynamic_cmds;
|
||||||
|
|
@ -572,6 +572,8 @@ static unsigned int oled_start_i2c(uint8_t *buf)
|
||||||
/* Set up the display address range. */
|
/* Set up the display address range. */
|
||||||
if (ff_cfg.display_type & DISPLAY_sh1106) {
|
if (ff_cfg.display_type & DISPLAY_sh1106) {
|
||||||
p += oled_queue_cmds(p, sh1106_addr_cmds, sizeof(sh1106_addr_cmds));
|
p += oled_queue_cmds(p, sh1106_addr_cmds, sizeof(sh1106_addr_cmds));
|
||||||
|
/* Column address: 0 or 2 (seems 128x64 displays are shifted by 2). */
|
||||||
|
*dc++ = (oled_height == 64) ? 0x02 : 0x00;
|
||||||
/* Page address: according to oled_row. */
|
/* Page address: according to oled_row. */
|
||||||
*dc++ = 0xb0 + oled_row;
|
*dc++ = 0xb0 + oled_row;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ static bool_t mfm_read_track(struct image *im)
|
||||||
uint8_t *buf = rd->p;
|
uint8_t *buf = rd->p;
|
||||||
uint16_t *bc_b = bc->p;
|
uint16_t *bc_b = bc->p;
|
||||||
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
||||||
uint16_t pr = 0, crc;
|
uint16_t pr, crc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Generate some MFM if there is space in the raw-bitcell ring buffer. */
|
/* Generate some MFM if there is space in the raw-bitcell ring buffer. */
|
||||||
|
|
@ -282,6 +282,7 @@ static bool_t mfm_read_track(struct image *im)
|
||||||
if (bc_space < im->da.dam_sz)
|
if (bc_space < im->da.dam_sz)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
pr = be16toh(bc_b[(bc_p-1) & bc_mask]);
|
||||||
#define emit_raw(r) ({ \
|
#define emit_raw(r) ({ \
|
||||||
uint16_t _r = (r); \
|
uint16_t _r = (r); \
|
||||||
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ static bool_t dsk_read_track(struct image *im)
|
||||||
uint8_t *buf = (uint8_t *)rd->p + 512; /* skip DIB/TIB */
|
uint8_t *buf = (uint8_t *)rd->p + 512; /* skip DIB/TIB */
|
||||||
uint16_t *bc_b = bc->p;
|
uint16_t *bc_b = bc->p;
|
||||||
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
||||||
uint16_t pr = 0, crc;
|
uint16_t pr, crc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (tib->nr_secs && (rd->prod == rd->cons)) {
|
if (tib->nr_secs && (rd->prod == rd->cons)) {
|
||||||
|
|
@ -320,6 +320,7 @@ static bool_t dsk_read_track(struct image *im)
|
||||||
bc_mask = bc_len - 1;
|
bc_mask = bc_len - 1;
|
||||||
bc_space = bc_len - (uint16_t)(bc_p - bc_c);
|
bc_space = bc_len - (uint16_t)(bc_p - bc_c);
|
||||||
|
|
||||||
|
pr = be16toh(bc_b[(bc_p-1) & bc_mask]);
|
||||||
#define emit_raw(r) ({ \
|
#define emit_raw(r) ({ \
|
||||||
uint16_t _r = (r); \
|
uint16_t _r = (r); \
|
||||||
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
||||||
|
|
|
||||||
|
|
@ -1207,7 +1207,7 @@ static bool_t mfm_read_track(struct image *im)
|
||||||
uint8_t *buf = rd->p;
|
uint8_t *buf = rd->p;
|
||||||
uint16_t *bc_b = bc->p;
|
uint16_t *bc_b = bc->p;
|
||||||
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
uint32_t bc_len, bc_mask, bc_space, bc_p, bc_c;
|
||||||
uint16_t pr = 0, crc;
|
uint16_t pr, crc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
img_fetch_data(im);
|
img_fetch_data(im);
|
||||||
|
|
@ -1219,6 +1219,7 @@ static bool_t mfm_read_track(struct image *im)
|
||||||
bc_mask = bc_len - 1;
|
bc_mask = bc_len - 1;
|
||||||
bc_space = bc_len - (uint16_t)(bc_p - bc_c);
|
bc_space = bc_len - (uint16_t)(bc_p - bc_c);
|
||||||
|
|
||||||
|
pr = be16toh(bc_b[(bc_p-1) & bc_mask]);
|
||||||
#define emit_raw(r) ({ \
|
#define emit_raw(r) ({ \
|
||||||
uint16_t _r = (r); \
|
uint16_t _r = (r); \
|
||||||
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
bc_b[bc_p++ & bc_mask] = htobe16(_r & ~(pr << 15)); \
|
||||||
|
|
|
||||||
|
|
@ -1294,13 +1294,8 @@ indexed_mode:
|
||||||
idx *= 10;
|
idx *= 10;
|
||||||
idx += *p++ - '0';
|
idx += *p++ - '0';
|
||||||
}
|
}
|
||||||
/* Expect a 4-digit number range 0-999 followed by a period. */
|
/* Expect a 4-digit number range 0-999. */
|
||||||
if ((i != 4) || (*p++ != '.') || (idx > 999))
|
if ((i != 4) || (idx > 999))
|
||||||
continue;
|
|
||||||
/* Expect 3-char extension followed by nul. */
|
|
||||||
for (i = 0; (i < 3) && *p; i++, p++)
|
|
||||||
continue;
|
|
||||||
if ((i != 3) || (*p != '\0'))
|
|
||||||
continue;
|
continue;
|
||||||
/* A file type we support? */
|
/* A file type we support? */
|
||||||
if (!image_valid(&fs->fp))
|
if (!image_valid(&fs->fp))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue