summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/fs_oric_jasmin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/fs_oric_jasmin.cpp')
-rw-r--r--src/lib/formats/fs_oric_jasmin.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/lib/formats/fs_oric_jasmin.cpp b/src/lib/formats/fs_oric_jasmin.cpp
new file mode 100644
index 00000000000..13f70ecc258
--- /dev/null
+++ b/src/lib/formats/fs_oric_jasmin.cpp
@@ -0,0 +1,113 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Creation of Apple Oric_Jasmin floppy images
+
+#include "emu.h"
+#include "fs_oric_jasmin.h"
+#include "oric_dsk.h"
+
+// Floppy only, format is 41 tracks, 1/2 heads, 17 sectors.
+// Filesystem has no subdirectories.
+//
+// References are pair of bytes (track + head*41, sector)
+//
+// Track 20 sector 1 has the free bitmap and the volume name
+//
+// offset 3*(track + head*41): bitmap from track, 24 bits LSB first,
+// sector 1 in bit 16, sector 17 in bit 0.
+// 0x01ffff is empty track. Special value
+// 0x800000 marks a full track.
+// offset f6-f7: 0x8080
+// offset f8-ff: volume name, padded with 0x20
+//
+//
+// Track 20 sector 2 has the first directory sector.
+// Directory sector format:
+// offset 00-01: reference to the sector, (0, 0) for the first one
+// offset 02-03: reference to the next sector, (0, 0) on the first sector if it's the end, (ff, 00) for the end of another sector
+// offset 04+ : 14 file entries, 18 bytes each
+// offset 00-01: reference to the first sector of the inode, (ff, xx) when no entry
+// offset 02 : U/L for (U)nlocked or (L)ocked file
+// offset 03-0e: filename.ext, space padiing between filename and '.'
+// offset 0f : S/D for (S)equential (normal) or (D)irect-access files
+// offset 10-11: number of sectors used by the file, including inode, little-endian
+//
+// Inodes:
+// offset 00-01: reference to the next inode sector, (ff, 00) on the last one
+// offset 02-03: loading address for the file on the first sector, ffff otherwise
+// offset 04-05: length of the file in bytes on the first sector, ffff otherwise
+// offset 06+ : reference to data sectors, (ff, ff) when done
+
+void fs_oric_jasmin::enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const
+{
+ if(has(form_factor, variants, floppy_image::FF_3, floppy_image::DSDD))
+ fe.add(this, FLOPPY_ORIC_JASMIN_FORMAT, 356864, "oric_jasmin_ds", "Oric Jasmin dual-sided");
+ if(has(form_factor, variants, floppy_image::FF_3, floppy_image::SSDD))
+ fe.add(this, FLOPPY_ORIC_JASMIN_FORMAT, 178432, "oric_jasmin_ss", "Oric Jasmin single-sided");
+}
+
+std::unique_ptr<filesystem_t> fs_oric_jasmin::mount(fsblk_t &blockdev) const
+{
+ return std::make_unique<impl>(blockdev);
+}
+
+bool fs_oric_jasmin::can_format() const
+{
+ return true;
+}
+
+bool fs_oric_jasmin::can_read() const
+{
+ return false;
+}
+
+bool fs_oric_jasmin::can_write() const
+{
+ return false;
+}
+
+
+void fs_oric_jasmin::impl::format()
+{
+ std::string volume_name = "UNTITLED";
+ m_blockdev.set_block_size(256);
+ u32 blocks = m_blockdev.block_count();
+
+ m_blockdev.fill(0x6c);
+
+ u32 bblk = 20*17;
+ auto fmap = m_blockdev.get(bblk);
+ u32 off = 0;
+ for(u32 blk = 0; blk != blocks; blk += 17) {
+ if(blk == bblk) {
+ fmap.w8(off , 0xff);
+ fmap.w8(off + 1, 0x7f);
+ fmap.w8(off + 2, 0x00);
+ } else {
+ fmap.w8(off , 0xff);
+ fmap.w8(off + 1, 0xff);
+ fmap.w8(off + 2, 0x01);
+ }
+ off += 3;
+ }
+
+ for(u32 blk = blocks; blk != 17*42*2; blk += 17) {
+ fmap.w8(off , 0x00);
+ fmap.w8(off + 1, 0x00);
+ fmap.w8(off + 2, 0x80);
+ off += 3;
+ }
+
+ fmap.w8(0xf6, 0x80);
+ fmap.w8(0xf7, 0x80);
+ fmap.fill(0xf8, 0x20, 8);
+ fmap.wstr(0xf8, volume_name);
+
+ auto bdir = m_blockdev.get(20*17+1);
+ bdir.fill(0xff);
+ bdir.w16l(0, 0x0000);
+ bdir.w16l(2, 0x0000);
+}
+
+const filesystem_manager_type FS_ORIC_JASMIN = &filesystem_manager_creator<fs_oric_jasmin>;;