mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-14 14:29:33 +00:00
working on merging
This commit is contained in:
parent
8443e08114
commit
a15ac7c3c8
|
@ -22,6 +22,7 @@
|
||||||
#include "scsi_controller.h"
|
#include "scsi_controller.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cassert>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "shared/piscsi_exceptions.h"
|
#include "shared/piscsi_exceptions.h"
|
||||||
|
#include "disk_image/disk_image_handle_factory.h"
|
||||||
|
#include "disk_image/disk_track_cache.h"
|
||||||
#include "scsi_command_util.h"
|
#include "scsi_command_util.h"
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -81,7 +83,7 @@ void Disk::Dispatch(scsi_command cmd)
|
||||||
|
|
||||||
void Disk::SetUpCache(off_t image_offset, bool raw)
|
void Disk::SetUpCache(off_t image_offset, bool raw)
|
||||||
{
|
{
|
||||||
cache = make_unique<DiskCache>(GetFilename(), size_shift_count, static_cast<uint32_t>(GetBlockCount()), image_offset);
|
cache = DiskImageHandleFactory::CreateDiskImageHandle(GetFilename(), size_shift_count, static_cast<uint32_t>(GetBlockCount()), image_offset);
|
||||||
cache->SetRawMode(raw);
|
cache->SetRawMode(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
|
|
||||||
#include "shared/scsi.h"
|
#include "shared/scsi.h"
|
||||||
#include "device_factory.h"
|
#include "device_factory.h"
|
||||||
#include "disk_track.h"
|
// #include "disk_track.h"
|
||||||
#include "disk_cache.h"
|
// #include "disk_cache.h"
|
||||||
|
#include "disk_image/disk_image_handle.h"
|
||||||
#include "interfaces/scsi_block_commands.h"
|
#include "interfaces/scsi_block_commands.h"
|
||||||
#include "storage_device.h"
|
#include "storage_device.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -32,7 +33,7 @@ class Disk : public StorageDevice, private ScsiBlockCommands
|
||||||
{
|
{
|
||||||
enum access_mode { RW6, RW10, RW16, SEEK6, SEEK10 };
|
enum access_mode { RW6, RW10, RW16, SEEK6, SEEK10 };
|
||||||
|
|
||||||
unique_ptr<DiskCache> cache;
|
unique_ptr<DiskImageHandle> cache;
|
||||||
|
|
||||||
// The supported configurable sector sizes, empty if not configurable
|
// The supported configurable sector sizes, empty if not configurable
|
||||||
unordered_set<uint32_t> sector_sizes;
|
unordered_set<uint32_t> sector_sizes;
|
||||||
|
|
|
@ -1,192 +0,0 @@
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// X68000 EMULATOR "XM6"
|
|
||||||
//
|
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
|
||||||
// Copyright (C) 2014-2020 GIMONS
|
|
||||||
//
|
|
||||||
// XM6i
|
|
||||||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
|
||||||
// Copyright (C) 2010 Y.Sugahara
|
|
||||||
//
|
|
||||||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
|
||||||
// Comments translated to english by akuker.
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "disk_track.h"
|
|
||||||
#include "disk_cache.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cassert>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
DiskCache::DiskCache(const string& path, int size, uint32_t blocks, off_t imgoff)
|
|
||||||
: sec_path(path), sec_size(size), sec_blocks(blocks), imgoffset(imgoff)
|
|
||||||
{
|
|
||||||
assert(blocks > 0);
|
|
||||||
assert(imgoff >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskCache::Save() const
|
|
||||||
{
|
|
||||||
// Save valid tracks
|
|
||||||
return none_of(cache.begin(), cache.end(), [this](const cache_t& c)
|
|
||||||
{ return c.disktrk != nullptr && !c.disktrk->Save(sec_path); });
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<DiskTrack> DiskCache::GetTrack(uint32_t block)
|
|
||||||
{
|
|
||||||
// Update first
|
|
||||||
UpdateSerialNumber();
|
|
||||||
|
|
||||||
// Calculate track (fixed to 256 sectors/track)
|
|
||||||
int track = block >> 8;
|
|
||||||
|
|
||||||
// Get track data
|
|
||||||
return Assign(track);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskCache::ReadSector(vector<uint8_t>& buf, uint32_t block)
|
|
||||||
{
|
|
||||||
shared_ptr<DiskTrack> disktrk = GetTrack(block);
|
|
||||||
if (disktrk == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the track data to the cache
|
|
||||||
return disktrk->ReadSector(buf, block & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskCache::WriteSector(const vector<uint8_t>& buf, uint32_t block)
|
|
||||||
{
|
|
||||||
shared_ptr<DiskTrack> disktrk = GetTrack(block);
|
|
||||||
if (disktrk == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the data to the cache
|
|
||||||
return disktrk->WriteSector(buf, block & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Track Assignment
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
shared_ptr<DiskTrack> DiskCache::Assign(int track)
|
|
||||||
{
|
|
||||||
assert(sec_size != 0);
|
|
||||||
assert(track >= 0);
|
|
||||||
|
|
||||||
// First, check if it is already assigned
|
|
||||||
for (cache_t& c : cache) {
|
|
||||||
if (c.disktrk && c.disktrk->GetTrack() == track) {
|
|
||||||
// Track match
|
|
||||||
c.serial = serial;
|
|
||||||
return c.disktrk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, check for empty
|
|
||||||
for (size_t i = 0; i < cache.size(); i++) {
|
|
||||||
if (cache[i].disktrk == nullptr) {
|
|
||||||
// Try loading
|
|
||||||
if (Load(static_cast<int>(i), track, nullptr)) {
|
|
||||||
// Success loading
|
|
||||||
cache[i].serial = serial;
|
|
||||||
return cache[i].disktrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load failed
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, find the youngest serial number and delete it
|
|
||||||
|
|
||||||
// Set index 0 as candidate c
|
|
||||||
uint32_t s = cache[0].serial;
|
|
||||||
size_t c = 0;
|
|
||||||
|
|
||||||
// Compare candidate with serial and update to smaller one
|
|
||||||
for (size_t i = 0; i < cache.size(); i++) {
|
|
||||||
assert(cache[i].disktrk);
|
|
||||||
|
|
||||||
// Compare and update the existing serial
|
|
||||||
if (cache[i].serial < s) {
|
|
||||||
s = cache[i].serial;
|
|
||||||
c = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save this track
|
|
||||||
if (!cache[c].disktrk->Save(sec_path)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete this track
|
|
||||||
shared_ptr<DiskTrack> disktrk = cache[c].disktrk;
|
|
||||||
cache[c].disktrk.reset();
|
|
||||||
|
|
||||||
if (Load(static_cast<int>(c), track, disktrk)) {
|
|
||||||
// Successful loading
|
|
||||||
cache[c].serial = serial;
|
|
||||||
return cache[c].disktrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load failed
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Load cache
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool DiskCache::Load(int index, int track, shared_ptr<DiskTrack> disktrk)
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < static_cast<int>(cache.size()));
|
|
||||||
assert(track >= 0);
|
|
||||||
assert(cache[index].disktrk == nullptr);
|
|
||||||
|
|
||||||
// Get the number of sectors on this track
|
|
||||||
int sectors = sec_blocks - (track << 8);
|
|
||||||
assert(sectors > 0);
|
|
||||||
if (sectors > 0x100) {
|
|
||||||
sectors = 0x100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a disk track
|
|
||||||
if (disktrk == nullptr) {
|
|
||||||
disktrk = make_shared<DiskTrack>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize disk track
|
|
||||||
disktrk->Init(track, sec_size, sectors, cd_raw, imgoffset);
|
|
||||||
|
|
||||||
// Try loading
|
|
||||||
if (!disktrk->Load(sec_path)) {
|
|
||||||
// Failure
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocation successful, work set
|
|
||||||
cache[index].disktrk = disktrk;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiskCache::UpdateSerialNumber()
|
|
||||||
{
|
|
||||||
// Update and do nothing except 0
|
|
||||||
serial++;
|
|
||||||
if (serial != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear serial of all caches
|
|
||||||
for (cache_t& c : cache) {
|
|
||||||
c.serial = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// X68000 EMULATOR "XM6"
|
|
||||||
//
|
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
|
||||||
// Copyright (C) 2014-2020 GIMONS
|
|
||||||
//
|
|
||||||
// XM6i
|
|
||||||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
|
||||||
//
|
|
||||||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
|
||||||
// Comments translated to english by akuker.
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class DiskCache
|
|
||||||
{
|
|
||||||
// Number of tracks to cache
|
|
||||||
static const int CACHE_MAX = 16;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Internal data definition
|
|
||||||
using cache_t = struct {
|
|
||||||
shared_ptr<DiskTrack> disktrk; // Disk Track
|
|
||||||
uint32_t serial; // Serial
|
|
||||||
};
|
|
||||||
|
|
||||||
DiskCache(const string&, int, uint32_t, off_t = 0);
|
|
||||||
~DiskCache() = default;
|
|
||||||
|
|
||||||
void SetRawMode(bool b) { cd_raw = b; } // CD-ROM raw mode setting
|
|
||||||
|
|
||||||
// Access
|
|
||||||
bool Save() const; // Save and release all
|
|
||||||
bool ReadSector(vector<uint8_t>&, uint32_t); // Sector Read
|
|
||||||
bool WriteSector(const vector<uint8_t>&, uint32_t); // Sector Write
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Internal Management
|
|
||||||
shared_ptr<DiskTrack> Assign(int);
|
|
||||||
shared_ptr<DiskTrack> GetTrack(uint32_t);
|
|
||||||
bool Load(int index, int track, shared_ptr<DiskTrack>);
|
|
||||||
void UpdateSerialNumber();
|
|
||||||
|
|
||||||
// Internal data
|
|
||||||
array<cache_t, CACHE_MAX> cache = {}; // Cache management
|
|
||||||
uint32_t serial = 0; // Last serial number
|
|
||||||
string sec_path; // Path
|
|
||||||
int sec_size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
|
||||||
int sec_blocks; // Blocks per sector
|
|
||||||
bool cd_raw = false; // CD-ROM RAW mode
|
|
||||||
off_t imgoffset; // Offset to actual data
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,275 +0,0 @@
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// X68000 EMULATOR "XM6"
|
|
||||||
//
|
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
|
||||||
// Copyright (C) 2014-2020 GIMONS
|
|
||||||
//
|
|
||||||
// XM6i
|
|
||||||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
|
||||||
// Copyright (C) 2010 Y.Sugahara
|
|
||||||
//
|
|
||||||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
|
||||||
// Comments translated to english by akuker.
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "shared/log.h"
|
|
||||||
#include "disk_track.h"
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
DiskTrack::~DiskTrack()
|
|
||||||
{
|
|
||||||
// Release memory, but do not save automatically
|
|
||||||
free(dt.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiskTrack::Init(int track, int size, int sectors, bool raw, off_t imgoff)
|
|
||||||
{
|
|
||||||
assert(track >= 0);
|
|
||||||
assert((sectors > 0) && (sectors <= 0x100));
|
|
||||||
assert(imgoff >= 0);
|
|
||||||
|
|
||||||
// Set Parameters
|
|
||||||
dt.track = track;
|
|
||||||
dt.size = size;
|
|
||||||
dt.sectors = sectors;
|
|
||||||
dt.raw = raw;
|
|
||||||
|
|
||||||
// Not initialized (needs to be loaded)
|
|
||||||
dt.init = false;
|
|
||||||
|
|
||||||
// Not Changed
|
|
||||||
dt.changed = false;
|
|
||||||
|
|
||||||
// Offset to actual data
|
|
||||||
dt.imgoffset = imgoff;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskTrack::Load(const string& path)
|
|
||||||
{
|
|
||||||
// Not needed if already loaded
|
|
||||||
if (dt.init) {
|
|
||||||
assert(dt.buffer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
|
||||||
off_t offset = ((off_t)dt.track << 8);
|
|
||||||
if (dt.raw) {
|
|
||||||
assert(dt.size == 11);
|
|
||||||
offset *= 0x930;
|
|
||||||
offset += 0x10;
|
|
||||||
} else {
|
|
||||||
offset <<= dt.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add offset to real image
|
|
||||||
offset += dt.imgoffset;
|
|
||||||
|
|
||||||
// Calculate length (data size of this track)
|
|
||||||
const int length = dt.sectors << dt.size;
|
|
||||||
|
|
||||||
// Allocate buffer memory
|
|
||||||
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
|
||||||
|
|
||||||
if (dt.buffer == nullptr) {
|
|
||||||
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
|
||||||
LOGWARN("posix_memalign failed")
|
|
||||||
}
|
|
||||||
dt.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dt.buffer == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reallocate if the buffer length is different
|
|
||||||
if (dt.length != static_cast<uint32_t>(length)) {
|
|
||||||
free(dt.buffer);
|
|
||||||
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
|
||||||
LOGWARN("posix_memalign failed")
|
|
||||||
}
|
|
||||||
dt.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize and clear changemap
|
|
||||||
dt.changemap.resize(dt.sectors);
|
|
||||||
fill(dt.changemap.begin(), dt.changemap.end(), false);
|
|
||||||
|
|
||||||
ifstream in(path, ios::binary);
|
|
||||||
if (in.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dt.raw) {
|
|
||||||
// Split Reading
|
|
||||||
for (int i = 0; i < dt.sectors; i++) {
|
|
||||||
in.seekg(offset);
|
|
||||||
if (in.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
in.read((char *)&dt.buffer[i << dt.size], 1 << dt.size);
|
|
||||||
if (in.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next offset
|
|
||||||
offset += 0x930;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Continuous reading
|
|
||||||
in.seekg(offset);
|
|
||||||
if (in.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
in.read((char *)dt.buffer, length);
|
|
||||||
if (in.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set a flag and end normally
|
|
||||||
dt.init = true;
|
|
||||||
dt.changed = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskTrack::Save(const string& path)
|
|
||||||
{
|
|
||||||
// Not needed if not initialized
|
|
||||||
if (!dt.init) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not needed unless changed
|
|
||||||
if (!dt.changed) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to write
|
|
||||||
assert(dt.buffer);
|
|
||||||
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
|
||||||
|
|
||||||
// Writing in RAW mode is not allowed
|
|
||||||
assert(!dt.raw);
|
|
||||||
|
|
||||||
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
|
||||||
off_t offset = ((off_t)dt.track << 8);
|
|
||||||
offset <<= dt.size;
|
|
||||||
|
|
||||||
// Add offset to real image
|
|
||||||
offset += dt.imgoffset;
|
|
||||||
|
|
||||||
// Calculate length per sector
|
|
||||||
const int length = 1 << dt.size;
|
|
||||||
|
|
||||||
ofstream out(path, ios::in | ios::out | ios::binary);
|
|
||||||
if (out.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partial write loop
|
|
||||||
int total;
|
|
||||||
for (int i = 0; i < dt.sectors;) {
|
|
||||||
// If changed
|
|
||||||
if (dt.changemap[i]) {
|
|
||||||
// Initialize write size
|
|
||||||
total = 0;
|
|
||||||
|
|
||||||
out.seekp(offset + ((off_t)i << dt.size));
|
|
||||||
if (out.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consectutive sector length
|
|
||||||
int j;
|
|
||||||
for (j = i; j < dt.sectors; j++) {
|
|
||||||
// end when interrupted
|
|
||||||
if (!dt.changemap[j]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add one sector
|
|
||||||
total += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.write((const char *)&dt.buffer[i << dt.size], total);
|
|
||||||
if (out.fail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To unmodified sector
|
|
||||||
i = j;
|
|
||||||
} else {
|
|
||||||
// Next Sector
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop the change flag and exit
|
|
||||||
fill(dt.changemap.begin(), dt.changemap.end(), false);
|
|
||||||
dt.changed = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskTrack::ReadSector(vector<uint8_t>& buf, int sec) const
|
|
||||||
{
|
|
||||||
assert(sec >= 0 && sec < 0x100);
|
|
||||||
|
|
||||||
// Error if not initialized
|
|
||||||
if (!dt.init) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Error if the number of sectors exceeds the valid number
|
|
||||||
if (sec >= dt.sectors) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy
|
|
||||||
assert(dt.buffer);
|
|
||||||
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
|
||||||
memcpy(buf.data(), &dt.buffer[(off_t)sec << dt.size], (off_t)1 << dt.size);
|
|
||||||
|
|
||||||
// Success
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DiskTrack::WriteSector(const vector<uint8_t>& buf, int sec)
|
|
||||||
{
|
|
||||||
assert((sec >= 0) && (sec < 0x100));
|
|
||||||
assert(!dt.raw);
|
|
||||||
|
|
||||||
// Error if not initialized
|
|
||||||
if (!dt.init) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Error if the number of sectors exceeds the valid number
|
|
||||||
if (sec >= dt.sectors) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate offset and length
|
|
||||||
const int offset = sec << dt.size;
|
|
||||||
const int length = 1 << dt.size;
|
|
||||||
|
|
||||||
// Compare
|
|
||||||
assert(dt.buffer);
|
|
||||||
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
|
||||||
if (memcmp(buf.data(), &dt.buffer[offset], length) == 0) {
|
|
||||||
// Exit normally since it's attempting to write the same thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy, change
|
|
||||||
memcpy(&dt.buffer[offset], buf.data(), length);
|
|
||||||
dt.changemap[sec] = true;
|
|
||||||
dt.changed = true;
|
|
||||||
|
|
||||||
// Success
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// X68000 EMULATOR "XM6"
|
|
||||||
//
|
|
||||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
|
||||||
// Copyright (C) 2014-2020 GIMONS
|
|
||||||
//
|
|
||||||
// XM6i
|
|
||||||
// Copyright (C) 2010-2015 isaki@NetBSD.org
|
|
||||||
//
|
|
||||||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
|
||||||
// Comments translated to english by akuker.
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class DiskTrack
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
int track; // Track Number
|
|
||||||
int size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
|
||||||
int sectors; // Number of sectors(<0x100)
|
|
||||||
uint32_t length; // Data buffer length
|
|
||||||
uint8_t *buffer; // Data buffer
|
|
||||||
bool init; // Is it initilized?
|
|
||||||
bool changed; // Changed flag
|
|
||||||
vector<bool> changemap; // Changed map
|
|
||||||
bool raw; // RAW mode flag
|
|
||||||
off_t imgoffset; // Offset to actual data
|
|
||||||
} dt = {};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DiskTrack() = default;
|
|
||||||
~DiskTrack();
|
|
||||||
DiskTrack(DiskTrack&) = delete;
|
|
||||||
DiskTrack& operator=(const DiskTrack&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
friend class DiskCache;
|
|
||||||
|
|
||||||
void Init(int track, int size, int sectors, bool raw = false, off_t imgoff = 0);
|
|
||||||
bool Load(const string& path);
|
|
||||||
bool Save(const string& path);
|
|
||||||
|
|
||||||
// Read / Write
|
|
||||||
bool ReadSector(vector<uint8_t>&, int) const; // Sector Read
|
|
||||||
bool WriteSector(const vector<uint8_t>& buf, int); // Sector Write
|
|
||||||
|
|
||||||
int GetTrack() const { return dt.track; } // Get track
|
|
||||||
};
|
|
|
@ -11,9 +11,10 @@
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include "disk_image/disk_image_handle.h"
|
#include "disk_image/disk_image_handle.h"
|
||||||
|
|
||||||
DiskImageHandle::DiskImageHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff)
|
DiskImageHandle::DiskImageHandle(const string &path, int size, uint32_t blocks, off_t imgoff)
|
||||||
{
|
{
|
||||||
|
|
||||||
serial = 0;
|
serial = 0;
|
||||||
|
@ -43,7 +44,7 @@ off_t DiskImageHandle::GetTrackOffset(int block)
|
||||||
off_t offset = ((off_t)track_num << 8);
|
off_t offset = ((off_t)track_num << 8);
|
||||||
if (cd_raw)
|
if (cd_raw)
|
||||||
{
|
{
|
||||||
ASSERT(sec_size == 11);
|
assert(sec_size == 11);
|
||||||
offset *= 0x930;
|
offset *= 0x930;
|
||||||
offset += 0x10;
|
offset += 0x10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,26 +13,31 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filepath.h"
|
// #include "filepath.h"
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class DiskImageHandle
|
class DiskImageHandle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DiskImageHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff = 0);
|
DiskImageHandle(const string &path, int size, uint32_t blocks, off_t imgoff = 0);
|
||||||
virtual ~DiskImageHandle();
|
virtual ~DiskImageHandle();
|
||||||
|
|
||||||
void SetRawMode(bool raw) { cd_raw = raw; }; // CD-ROM raw mode setting
|
void SetRawMode(bool raw) { cd_raw = raw; }; // CD-ROM raw mode setting
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
virtual bool Save() = 0; // Save and release all
|
virtual bool Save() = 0; // Save and release all
|
||||||
virtual bool ReadSector(BYTE *buf, int block) = 0; // Sector Read
|
virtual bool ReadSector(vector<uint8_t>& buf, int block) = 0; // Sector Read
|
||||||
virtual bool WriteSector(const BYTE *buf, int block) = 0; // Sector Write
|
virtual bool WriteSector(const vector<uint8_t>& buf, int block) = 0; // Sector Write
|
||||||
virtual bool GetCache(int index, int &track, DWORD &serial) const = 0; // Get cache information
|
virtual bool GetCache(int index, int &track, uint32_t &serial) const = 0; // Get cache information
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool cd_raw = false;
|
bool cd_raw = false;
|
||||||
DWORD serial; // Last serial number
|
uint32_t serial; // Last serial number
|
||||||
Filepath sec_path; // Path
|
string sec_path; // Path
|
||||||
|
|
||||||
int sec_size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
int sec_size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
||||||
int sec_blocks; // Blocks per sector
|
int sec_blocks; // Blocks per sector
|
||||||
|
|
|
@ -12,35 +12,35 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "disk_image/disk_image_handle_factory.h"
|
#include "disk_image/disk_image_handle_factory.h"
|
||||||
#include "log.h"
|
#include "shared/log.h"
|
||||||
#include "disk_image/disk_track_cache.h"
|
#include "disk_image/disk_track_cache.h"
|
||||||
#include "disk_image/mmap_file_handle.h"
|
#include "disk_image/mmap_file_handle.h"
|
||||||
#include "disk_image/posix_file_handle.h"
|
#include "disk_image/posix_file_handle.h"
|
||||||
|
|
||||||
DiskImageHandleType DiskImageHandleFactory::current_access_type = DiskImageHandleType::ePosixFile;
|
DiskImageHandleType DiskImageHandleFactory::current_access_type = DiskImageHandleType::ePosixFile;
|
||||||
|
|
||||||
DiskImageHandle *DiskImageHandleFactory::CreateDiskImageHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff)
|
unique_ptr<DiskImageHandle> DiskImageHandleFactory::CreateDiskImageHandle(const string &path, int size, uint32_t blocks, off_t imgoff)
|
||||||
{
|
{
|
||||||
|
|
||||||
DiskImageHandle *result = NULL;
|
unique_ptr<DiskImageHandle> result = nullptr;
|
||||||
|
|
||||||
if (current_access_type == DiskImageHandleType::eMmapFile)
|
if (current_access_type == DiskImageHandleType::eMmapFile)
|
||||||
{
|
{
|
||||||
LOGINFO("%s Creating MmapFileAccess %s", __PRETTY_FUNCTION__, path.GetPath())
|
LOGINFO("%s Creating MmapFileAccess %s", __PRETTY_FUNCTION__, path.c_str())
|
||||||
result = new MmapFileHandle(path, size, blocks, imgoff);
|
result = make_unique<MmapFileHandle>(path, size, blocks, imgoff);
|
||||||
}
|
}
|
||||||
else if (current_access_type == DiskImageHandleType::eRamCache)
|
else if (current_access_type == DiskImageHandleType::eRamCache)
|
||||||
{
|
{
|
||||||
LOGINFO("%s Creating DiskCache %s", __PRETTY_FUNCTION__, path.GetPath())
|
LOGINFO("%s Creating DiskCache %s", __PRETTY_FUNCTION__, path.c_str())
|
||||||
result = new DiskCache(path, size, blocks, imgoff);
|
result = make_unique<DiskCache>(path, size, blocks, imgoff);
|
||||||
}
|
}
|
||||||
else if (current_access_type == DiskImageHandleType::ePosixFile)
|
else if (current_access_type == DiskImageHandleType::ePosixFile)
|
||||||
{
|
{
|
||||||
LOGINFO("%s Creating PosixFileHandle %s", __PRETTY_FUNCTION__, path.GetPath())
|
LOGINFO("%s Creating PosixFileHandle %s", __PRETTY_FUNCTION__, path.c_str())
|
||||||
result = new PosixFileHandle(path, size, blocks, imgoff);
|
result = make_unique<PosixFileHandle>(path, size, blocks, imgoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == nullptr)
|
||||||
{
|
{
|
||||||
LOGWARN("%s Unable to create the File Access", __PRETTY_FUNCTION__);
|
LOGWARN("%s Unable to create the File Access", __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "disk_image/disk_image_handle.h"
|
#include "disk_image/disk_image_handle.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
enum DiskImageHandleType
|
enum DiskImageHandleType
|
||||||
{
|
{
|
||||||
|
@ -28,7 +29,7 @@ public:
|
||||||
static void SetFileAccessMethod(DiskImageHandleType method) { current_access_type = method; };
|
static void SetFileAccessMethod(DiskImageHandleType method) { current_access_type = method; };
|
||||||
static DiskImageHandleType GetFileAccessMethod() { return current_access_type; };
|
static DiskImageHandleType GetFileAccessMethod() { return current_access_type; };
|
||||||
|
|
||||||
static DiskImageHandle *CreateDiskImageHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff = 0);
|
static unique_ptr<DiskImageHandle> CreateDiskImageHandle(const string &path, int size, uint32_t blocks, off_t imgoff = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static DiskImageHandleType current_access_type;
|
static DiskImageHandleType current_access_type;
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "os.h"
|
#include <fstream>
|
||||||
#include "log.h"
|
#include "shared/log.h"
|
||||||
#include "fileio.h"
|
|
||||||
#include "disk_track_cache.h"
|
#include "disk_track_cache.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Disk Track
|
// Disk Track
|
||||||
|
@ -33,13 +34,13 @@ DiskTrack::DiskTrack()
|
||||||
dt.track = 0;
|
dt.track = 0;
|
||||||
dt.size = 0;
|
dt.size = 0;
|
||||||
dt.sectors = 0;
|
dt.sectors = 0;
|
||||||
dt.raw = FALSE;
|
dt.raw = false;
|
||||||
dt.init = FALSE;
|
dt.init = false;
|
||||||
dt.changed = FALSE;
|
dt.changed = false;
|
||||||
dt.length = 0;
|
dt.length = 0;
|
||||||
dt.buffer = NULL;
|
dt.buffer = nullptr;
|
||||||
dt.maplen = 0;
|
dt.maplen = 0;
|
||||||
dt.changemap = NULL;
|
dt.changemap = nullptr;
|
||||||
dt.imgoffset = 0;
|
dt.imgoffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,11 +57,11 @@ DiskTrack::~DiskTrack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskTrack::Init(int track, int size, int sectors, BOOL raw, off_t imgoff)
|
void DiskTrack::Init(int track, int size, int sectors, bool raw, off_t imgoff)
|
||||||
{
|
{
|
||||||
ASSERT(track >= 0);
|
assert(track >= 0);
|
||||||
ASSERT((sectors > 0) && (sectors <= 0x100));
|
assert((sectors > 0) && (sectors <= 0x100));
|
||||||
ASSERT(imgoff >= 0);
|
assert(imgoff >= 0);
|
||||||
|
|
||||||
// Set Parameters
|
// Set Parameters
|
||||||
dt.track = track;
|
dt.track = track;
|
||||||
|
@ -69,28 +70,28 @@ void DiskTrack::Init(int track, int size, int sectors, BOOL raw, off_t imgoff)
|
||||||
dt.raw = raw;
|
dt.raw = raw;
|
||||||
|
|
||||||
// Not initialized (needs to be loaded)
|
// Not initialized (needs to be loaded)
|
||||||
dt.init = FALSE;
|
dt.init = false;
|
||||||
|
|
||||||
// Not Changed
|
// Not Changed
|
||||||
dt.changed = FALSE;
|
dt.changed = false;
|
||||||
|
|
||||||
// Offset to actual data
|
// Offset to actual data
|
||||||
dt.imgoffset = imgoff;
|
dt.imgoffset = imgoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskTrack::Load(const Filepath& path)
|
bool DiskTrack::Load(const string& path)
|
||||||
{
|
{
|
||||||
// Not needed if already loaded
|
// Not needed if already loaded
|
||||||
if (dt.init) {
|
if (dt.init) {
|
||||||
ASSERT(dt.buffer);
|
assert(dt.buffer);
|
||||||
ASSERT(dt.changemap);
|
assert(dt.changemap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
||||||
off_t offset = ((off_t)dt.track << 8);
|
off_t offset = ((off_t)dt.track << 8);
|
||||||
if (dt.raw) {
|
if (dt.raw) {
|
||||||
ASSERT(dt.size == 11);
|
assert(dt.size == 11);
|
||||||
offset *= 0x930;
|
offset *= 0x930;
|
||||||
offset += 0x10;
|
offset += 0x10;
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,7 +105,7 @@ bool DiskTrack::Load(const Filepath& path)
|
||||||
int length = dt.sectors << dt.size;
|
int length = dt.sectors << dt.size;
|
||||||
|
|
||||||
// Allocate buffer memory
|
// Allocate buffer memory
|
||||||
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
|
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
||||||
|
|
||||||
if (dt.buffer == NULL) {
|
if (dt.buffer == NULL) {
|
||||||
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
||||||
|
@ -118,7 +119,7 @@ bool DiskTrack::Load(const Filepath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reallocate if the buffer length is different
|
// Reallocate if the buffer length is different
|
||||||
if (dt.length != (DWORD)length) {
|
if (dt.length != (uint32_t)length) {
|
||||||
free(dt.buffer);
|
free(dt.buffer);
|
||||||
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
|
||||||
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__);
|
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__);
|
||||||
|
@ -128,7 +129,7 @@ bool DiskTrack::Load(const Filepath& path)
|
||||||
|
|
||||||
// Reserve change map memory
|
// Reserve change map memory
|
||||||
if (dt.changemap == NULL) {
|
if (dt.changemap == NULL) {
|
||||||
dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL));
|
dt.changemap = (bool *)malloc(dt.sectors * sizeof(bool));
|
||||||
dt.maplen = dt.sectors;
|
dt.maplen = dt.sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,32 +138,33 @@ bool DiskTrack::Load(const Filepath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reallocate if the buffer length is different
|
// Reallocate if the buffer length is different
|
||||||
if (dt.maplen != (DWORD)dt.sectors) {
|
if (dt.maplen != (uint32_t)dt.sectors) {
|
||||||
free(dt.changemap);
|
free(dt.changemap);
|
||||||
dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL));
|
dt.changemap = (bool *)malloc(dt.sectors * sizeof(bool));
|
||||||
dt.maplen = dt.sectors;
|
dt.maplen = dt.sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear changemap
|
// Clear changemap
|
||||||
memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL));
|
memset(dt.changemap, 0x00, dt.sectors * sizeof(bool));
|
||||||
|
|
||||||
// Read from File
|
// Read from File
|
||||||
Fileio fio;
|
fstream fio;
|
||||||
if (!fio.OpenDIO(path, Fileio::ReadOnly)) {
|
fio.open(path.c_str(),ios::in);
|
||||||
|
if(!fio.is_open()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dt.raw) {
|
if (dt.raw) {
|
||||||
// Split Reading
|
// Split Reading
|
||||||
for (int i = 0; i < dt.sectors; i++) {
|
for (int i = 0; i < dt.sectors; i++) {
|
||||||
// Seek
|
// Seek
|
||||||
if (!fio.Seek(offset)) {
|
if (!fio.seekg(offset)) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
if (!fio.Read(&dt.buffer[i << dt.size], 1 << dt.size)) {
|
if (!fio.read(&dt.buffer[i << dt.size], 1 << dt.size)) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,24 +173,24 @@ bool DiskTrack::Load(const Filepath& path)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Continuous reading
|
// Continuous reading
|
||||||
if (!fio.Seek(offset)) {
|
if (!fio.seekg(offset)) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!fio.Read(dt.buffer, length)) {
|
if (!fio.read(dt.buffer, length)) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fio.Close();
|
fio.close();
|
||||||
|
|
||||||
// Set a flag and end normally
|
// Set a flag and end normally
|
||||||
dt.init = TRUE;
|
dt.init = true;
|
||||||
dt.changed = FALSE;
|
dt.changed = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskTrack::Save(const Filepath& path)
|
bool DiskTrack::Save(const string& path)
|
||||||
{
|
{
|
||||||
// Not needed if not initialized
|
// Not needed if not initialized
|
||||||
if (!dt.init) {
|
if (!dt.init) {
|
||||||
|
@ -201,12 +203,12 @@ bool DiskTrack::Save(const Filepath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to write
|
// Need to write
|
||||||
ASSERT(dt.buffer);
|
assert(dt.buffer);
|
||||||
ASSERT(dt.changemap);
|
assert(dt.changemap);
|
||||||
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
|
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
||||||
|
|
||||||
// Writing in RAW mode is not allowed
|
// Writing in RAW mode is not allowed
|
||||||
ASSERT(!dt.raw);
|
assert(!dt.raw);
|
||||||
|
|
||||||
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
// Calculate offset (previous tracks are considered to hold 256 sectors)
|
||||||
off_t offset = ((off_t)dt.track << 8);
|
off_t offset = ((off_t)dt.track << 8);
|
||||||
|
@ -219,8 +221,9 @@ bool DiskTrack::Save(const Filepath& path)
|
||||||
int length = 1 << dt.size;
|
int length = 1 << dt.size;
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
Fileio fio;
|
fstream fio;
|
||||||
if (!fio.Open(path, Fileio::ReadWrite)) {
|
fio.open(path, ios::in | ios::out);
|
||||||
|
if (!fio.is_open()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +236,8 @@ bool DiskTrack::Save(const Filepath& path)
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
if (!fio.Seek(offset + ((off_t)i << dt.size))) {
|
if (!fio.seekg(offset + ((off_t)i << dt.size))) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +254,8 @@ bool DiskTrack::Save(const Filepath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
if (!fio.Write(&dt.buffer[i << dt.size], total)) {
|
if (!fio.write(&dt.buffer[i << dt.size], total)) {
|
||||||
fio.Close();
|
fio.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,18 +268,18 @@ bool DiskTrack::Save(const Filepath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close
|
// Close
|
||||||
fio.Close();
|
fio.close();
|
||||||
|
|
||||||
// Drop the change flag and exit
|
// Drop the change flag and exit
|
||||||
memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL));
|
memset(dt.changemap, 0x00, dt.sectors * sizeof(bool));
|
||||||
dt.changed = FALSE;
|
dt.changed = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskTrack::ReadSector(BYTE *buf, int sec) const
|
bool DiskTrack::ReadSector(vector<uint8_t>& buf, int sec) const
|
||||||
{
|
{
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT((sec >= 0) & (sec < 0x100));
|
assert((sec >= 0) & (sec < 0x100));
|
||||||
|
|
||||||
LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec);
|
LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec);
|
||||||
// Error if not initialized
|
// Error if not initialized
|
||||||
|
@ -290,19 +293,19 @@ bool DiskTrack::ReadSector(BYTE *buf, int sec) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy
|
// Copy
|
||||||
ASSERT(dt.buffer);
|
assert(dt.buffer);
|
||||||
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
|
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
||||||
memcpy(buf, &dt.buffer[(off_t)sec << dt.size], (off_t)1 << dt.size);
|
memcpy(buf.data(), &dt.buffer[(off_t)sec << dt.size], (off_t)1 << dt.size);
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskTrack::WriteSector(const BYTE *buf, int sec)
|
bool DiskTrack::WriteSector(const vector<uint8_t>& buf, int sec)
|
||||||
{
|
{
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT((sec >= 0) & (sec < 0x100));
|
assert((sec >= 0) & (sec < 0x100));
|
||||||
ASSERT(!dt.raw);
|
assert(!dt.raw);
|
||||||
|
|
||||||
// Error if not initialized
|
// Error if not initialized
|
||||||
if (!dt.init) {
|
if (!dt.init) {
|
||||||
|
@ -319,17 +322,17 @@ bool DiskTrack::WriteSector(const BYTE *buf, int sec)
|
||||||
int length = 1 << dt.size;
|
int length = 1 << dt.size;
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
ASSERT(dt.buffer);
|
assert(dt.buffer);
|
||||||
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
|
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
|
||||||
if (memcmp(buf, &dt.buffer[offset], length) == 0) {
|
if (memcmp(buf.data(), &dt.buffer[offset], length) == 0) {
|
||||||
// Exit normally since it's attempting to write the same thing
|
// Exit normally since it's attempting to write the same thing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy, change
|
// Copy, change
|
||||||
memcpy(&dt.buffer[offset], buf, length);
|
memcpy(&dt.buffer[offset], buf.data(), length);
|
||||||
dt.changemap[sec] = TRUE;
|
dt.changemap[sec] = true;
|
||||||
dt.changed = TRUE;
|
dt.changed = true;
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
return true;
|
return true;
|
||||||
|
@ -341,10 +344,10 @@ bool DiskTrack::WriteSector(const BYTE *buf, int sec)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DiskCache::DiskCache(const Filepath& path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
DiskCache::DiskCache(const string& path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
||||||
{
|
{
|
||||||
ASSERT(blocks > 0);
|
assert(blocks > 0);
|
||||||
ASSERT(imgoff >= 0);
|
assert(imgoff >= 0);
|
||||||
|
|
||||||
// Cache work
|
// Cache work
|
||||||
for (int i = 0; i < CacheMax; i++) {
|
for (int i = 0; i < CacheMax; i++) {
|
||||||
|
@ -381,9 +384,9 @@ bool DiskCache::Save()
|
||||||
// Get disk cache information
|
// Get disk cache information
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
bool DiskCache::GetCache(int index, int& track, DWORD& aserial) const
|
bool DiskCache::GetCache(int index, int& track, uint32_t& aserial) const
|
||||||
{
|
{
|
||||||
ASSERT((index >= 0) && (index < CacheMax));
|
assert((index >= 0) && (index < CacheMax));
|
||||||
|
|
||||||
// false if unused
|
// false if unused
|
||||||
if (!cache[index].disktrk) {
|
if (!cache[index].disktrk) {
|
||||||
|
@ -408,9 +411,9 @@ void DiskCache::Clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskCache::ReadSector(BYTE *buf, int block)
|
bool DiskCache::ReadSector(vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
ASSERT(sec_size != 0);
|
assert(sec_size != 0);
|
||||||
|
|
||||||
// Update first
|
// Update first
|
||||||
UpdateSerialNumber();
|
UpdateSerialNumber();
|
||||||
|
@ -428,9 +431,9 @@ bool DiskCache::ReadSector(BYTE *buf, int block)
|
||||||
return disktrk->ReadSector(buf, block & 0xff);
|
return disktrk->ReadSector(buf, block & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskCache::WriteSector(const BYTE *buf, int block)
|
bool DiskCache::WriteSector(const vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
ASSERT(sec_size != 0);
|
assert(sec_size != 0);
|
||||||
|
|
||||||
// Update first
|
// Update first
|
||||||
UpdateSerialNumber();
|
UpdateSerialNumber();
|
||||||
|
@ -455,8 +458,8 @@ bool DiskCache::WriteSector(const BYTE *buf, int block)
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
DiskTrack* DiskCache::Assign(int track)
|
DiskTrack* DiskCache::Assign(int track)
|
||||||
{
|
{
|
||||||
ASSERT(sec_size != 0);
|
assert(sec_size != 0);
|
||||||
ASSERT(track >= 0);
|
assert(track >= 0);
|
||||||
|
|
||||||
// First, check if it is already assigned
|
// First, check if it is already assigned
|
||||||
for (int i = 0; i < CacheMax; i++) {
|
for (int i = 0; i < CacheMax; i++) {
|
||||||
|
@ -487,12 +490,12 @@ DiskTrack* DiskCache::Assign(int track)
|
||||||
// Finally, find the youngest serial number and delete it
|
// Finally, find the youngest serial number and delete it
|
||||||
|
|
||||||
// Set index 0 as candidate c
|
// Set index 0 as candidate c
|
||||||
DWORD s = cache[0].serial;
|
uint32_t s = cache[0].serial;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
// Compare candidate with serial and update to smaller one
|
// Compare candidate with serial and update to smaller one
|
||||||
for (int i = 0; i < CacheMax; i++) {
|
for (int i = 0; i < CacheMax; i++) {
|
||||||
ASSERT(cache[i].disktrk);
|
assert(cache[i].disktrk);
|
||||||
|
|
||||||
// Compare and update the existing serial
|
// Compare and update the existing serial
|
||||||
if (cache[i].serial < s) {
|
if (cache[i].serial < s) {
|
||||||
|
@ -527,13 +530,13 @@ DiskTrack* DiskCache::Assign(int track)
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
bool DiskCache::Load(int index, int track, DiskTrack *disktrk)
|
bool DiskCache::Load(int index, int track, DiskTrack *disktrk)
|
||||||
{
|
{
|
||||||
ASSERT((index >= 0) && (index < CacheMax));
|
assert((index >= 0) && (index < CacheMax));
|
||||||
ASSERT(track >= 0);
|
assert(track >= 0);
|
||||||
ASSERT(!cache[index].disktrk);
|
assert(!cache[index].disktrk);
|
||||||
|
|
||||||
// Get the number of sectors on this track
|
// Get the number of sectors on this track
|
||||||
int sectors = sec_blocks - (track << 8);
|
int sectors = sec_blocks - (track << 8);
|
||||||
ASSERT(sectors > 0);
|
assert(sectors > 0);
|
||||||
if (sectors > 0x100) {
|
if (sectors > 0x100) {
|
||||||
sectors = 0x100;
|
sectors = 0x100;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filepath.h"
|
#include <string>
|
||||||
#include "disk_image/disk_image_handle.h"
|
#include "disk_image/disk_image_handle.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
// Number of tracks to cache
|
// Number of tracks to cache
|
||||||
#define CacheMax 16
|
#define CacheMax 16
|
||||||
|
|
||||||
|
@ -30,13 +32,13 @@ private:
|
||||||
int track; // Track Number
|
int track; // Track Number
|
||||||
int size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
int size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
|
||||||
int sectors; // Number of sectors(<0x100)
|
int sectors; // Number of sectors(<0x100)
|
||||||
DWORD length; // Data buffer length
|
uint32_t length; // Data buffer length
|
||||||
BYTE *buffer; // Data buffer
|
uint8_t *buffer; // Data buffer
|
||||||
BOOL init; // Is it initilized?
|
bool init; // Is it initilized?
|
||||||
BOOL changed; // Changed flag
|
bool changed; // Changed flag
|
||||||
DWORD maplen; // Changed map length
|
uint32_t maplen; // Changed map length
|
||||||
BOOL *changemap; // Changed map
|
bool *changemap; // Changed map
|
||||||
BOOL raw; // RAW mode flag
|
bool raw; // RAW mode flag
|
||||||
off_t imgoffset; // Offset to actual data
|
off_t imgoffset; // Offset to actual data
|
||||||
} dt;
|
} dt;
|
||||||
|
|
||||||
|
@ -47,13 +49,13 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class DiskCache;
|
friend class DiskCache;
|
||||||
|
|
||||||
void Init(int track, int size, int sectors, BOOL raw = FALSE, off_t imgoff = 0);
|
void Init(int track, int size, int sectors, bool raw = false, off_t imgoff = 0) ;
|
||||||
bool Load(const Filepath& path);
|
bool Load(const string& path) ;
|
||||||
bool Save(const Filepath& path);
|
bool Save(const string& path) ;
|
||||||
|
|
||||||
// Read / Write
|
// Read / Write
|
||||||
bool ReadSector(BYTE *buf, int sec) const; // Sector Read
|
bool ReadSector(vector<uint8_t>& buf, int sec) const; // Sector Read
|
||||||
bool WriteSector(const BYTE *buf, int sec); // Sector Write
|
bool WriteSector(const vector<uint8_t>& buf, int sec); // Sector Write
|
||||||
|
|
||||||
int GetTrack() const { return dt.track; } // Get track
|
int GetTrack() const { return dt.track; } // Get track
|
||||||
};
|
};
|
||||||
|
@ -64,18 +66,18 @@ public:
|
||||||
// Internal data definition
|
// Internal data definition
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DiskTrack *disktrk; // Disk Track
|
DiskTrack *disktrk; // Disk Track
|
||||||
DWORD serial; // Serial
|
uint32_t serial; // Serial
|
||||||
} cache_t;
|
} cache_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiskCache(const Filepath& path, int size, uint32_t blocks, off_t imgoff = 0);
|
DiskCache(const string& path, int size, uint32_t blocks, off_t imgoff = 0);
|
||||||
~DiskCache();
|
~DiskCache();
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
bool Save() override; // Save and release all
|
bool Save() override; // Save and release all
|
||||||
bool ReadSector(BYTE *buf, int block) override; // Sector Read
|
bool ReadSector(vector<uint8_t>& buf, int block) override; // Sector Read
|
||||||
bool WriteSector(const BYTE *buf, int block) override; // Sector Write
|
bool WriteSector(const vector<uint8_t>& buf, int block) override; // Sector Write
|
||||||
bool GetCache(int index, int& track, DWORD& serial) const override; // Get cache information
|
bool GetCache(int index, int& track, uint32_t& serial) const override; // Get cache information
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal Management
|
// Internal Management
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "mmap_file_handle.h"
|
#include "mmap_file_handle.h"
|
||||||
#include "log.h"
|
#include "shared/log.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -31,25 +31,25 @@
|
||||||
// Direct file access that will map the file into virtual memory space
|
// Direct file access that will map the file into virtual memory space
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
MmapFileHandle::MmapFileHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
MmapFileHandle::MmapFileHandle(const string &path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
||||||
{
|
{
|
||||||
ASSERT(blocks > 0);
|
assert(blocks > 0);
|
||||||
ASSERT(imgoff >= 0);
|
assert(imgoff >= 0);
|
||||||
|
|
||||||
fd = open(path.GetPath(), O_RDWR);
|
fd = open(path.c_str(), O_RDWR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
LOGWARN("Unable to open file %s. Errno:%d", path.GetPath(), errno)
|
LOGWARN("Unable to open file %s. Errno:%d", path.c_str(), errno)
|
||||||
}
|
}
|
||||||
LOGWARN("%s opened %s", __PRETTY_FUNCTION__, path.GetPath());
|
LOGWARN("%s opened %s", __PRETTY_FUNCTION__, path.c_str())
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (fstat(fd, &sb) < 0)
|
if (fstat(fd, &sb) < 0)
|
||||||
{
|
{
|
||||||
LOGWARN("Unable to run fstat. Errno:%d", errno);
|
LOGWARN("Unable to run fstat. Errno:%d", errno)
|
||||||
}
|
}
|
||||||
printf("Size: %llu\n", (uint64_t)sb.st_size);
|
printf("Size: %zu\n", sb.st_size);
|
||||||
|
|
||||||
LOGWARN("%s mmap-ed file of size: %llu", __PRETTY_FUNCTION__, (uint64_t)sb.st_size);
|
LOGWARN("%s mmap-ed file of size: %zu", __PRETTY_FUNCTION__, sb.st_size)
|
||||||
|
|
||||||
// int x = EACCES;
|
// int x = EACCES;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ MmapFileHandle::MmapFileHandle(const Filepath &path, int size, uint32_t blocks,
|
||||||
int errno_val = errno;
|
int errno_val = errno;
|
||||||
if (memory_block == MAP_FAILED)
|
if (memory_block == MAP_FAILED)
|
||||||
{
|
{
|
||||||
LOGWARN("Unabled to memory map file %s", path.GetPath());
|
LOGWARN("Unabled to memory map file %s", path.c_str());
|
||||||
LOGWARN(" Errno:%d", errno_val);
|
LOGWARN(" Errno:%d", errno_val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,12 @@ MmapFileHandle::~MmapFileHandle()
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MmapFileHandle::ReadSector(BYTE *buf, int block)
|
bool MmapFileHandle::ReadSector(vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
ASSERT(sec_size != 0);
|
assert(sec_size != 0);
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT(block < sec_blocks);
|
assert(block < sec_blocks);
|
||||||
ASSERT(memory_block);
|
assert(memory_block);
|
||||||
|
|
||||||
int sector_size_bytes = (off_t)1 << sec_size;
|
int sector_size_bytes = (off_t)1 << sec_size;
|
||||||
|
|
||||||
|
@ -86,21 +86,21 @@ bool MmapFileHandle::ReadSector(BYTE *buf, int block)
|
||||||
off_t offset = GetTrackOffset(block);
|
off_t offset = GetTrackOffset(block);
|
||||||
offset += GetSectorOffset(block);
|
offset += GetSectorOffset(block);
|
||||||
|
|
||||||
memcpy(buf, &memory_block[offset], sector_size_bytes);
|
memcpy(buf.data(), &memory_block[offset], sector_size_bytes);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MmapFileHandle::WriteSector(const BYTE *buf, int block)
|
bool MmapFileHandle::WriteSector(const vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
|
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT(block < sec_blocks);
|
assert(block < sec_blocks);
|
||||||
ASSERT(memory_block);
|
assert(memory_block);
|
||||||
|
|
||||||
ASSERT((block * sec_size) <= (sb.st_size + sec_size));
|
assert((block * sec_size) <= (sb.st_size + sec_size));
|
||||||
|
|
||||||
memcpy((void *)&memory_block[(block * sec_size)], buf, sec_size);
|
memcpy((void *)&memory_block[(block * sec_size)], buf.data(), sec_size);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,23 +22,24 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filepath.h"
|
#include <string>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "disk_image/disk_image_handle.h"
|
#include "disk_image/disk_image_handle.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class MmapFileHandle : public DiskImageHandle
|
class MmapFileHandle : public DiskImageHandle
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MmapFileHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff = 0);
|
MmapFileHandle(const string &path, int size, uint32_t blocks, off_t imgoff = 0);
|
||||||
~MmapFileHandle();
|
~MmapFileHandle();
|
||||||
|
|
||||||
void SetRawMode(BOOL raw); // CD-ROM raw mode setting
|
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
bool Save() { return true; }; // Save and release all
|
bool Save() { return true; }; // Save and release all
|
||||||
bool ReadSector(BYTE *buf, int block); // Sector Read
|
bool ReadSector(vector<uint8_t>& buf, int block); // Sector Read
|
||||||
bool WriteSector(const BYTE *buf, int block); // Sector Write
|
bool WriteSector(const vector<uint8_t>& buf, int block); // Sector Write
|
||||||
bool GetCache(int index, int &track, DWORD &serial) const { return true; }; // Get cache information
|
bool GetCache(int index, int &track, uint32_t &serial) const { (void)index; (void)track; (void)serial; return true; }; // Get cache information
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *memory_block;
|
const char *memory_block;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "posix_file_handle.h"
|
#include "posix_file_handle.h"
|
||||||
#include "log.h"
|
#include "shared/log.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -20,15 +20,15 @@
|
||||||
// Direct file access that will map the file into virtual memory space
|
// Direct file access that will map the file into virtual memory space
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
PosixFileHandle::PosixFileHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
PosixFileHandle::PosixFileHandle(const string &path, int size, uint32_t blocks, off_t imgoff) : DiskImageHandle(path, size, blocks, imgoff)
|
||||||
{
|
{
|
||||||
ASSERT(blocks > 0);
|
assert(blocks > 0);
|
||||||
ASSERT(imgoff >= 0);
|
assert(imgoff >= 0);
|
||||||
|
|
||||||
fd = open(path.GetPath(), O_RDWR);
|
fd = open(path.c_str(), O_RDWR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
LOGWARN("Unable to open file %s. Errno:%d", path.GetPath(), errno)
|
LOGWARN("Unable to open file %s. Errno:%d", path.c_str(), errno)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
@ -38,7 +38,7 @@ PosixFileHandle::PosixFileHandle(const Filepath &path, int size, uint32_t blocks
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGWARN("%s opened file of size: %llu", __PRETTY_FUNCTION__, (uint64_t)sb.st_size);
|
LOGWARN("%s opened file of size: %zu", __PRETTY_FUNCTION__, sb.st_size);
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
@ -51,17 +51,17 @@ PosixFileHandle::~PosixFileHandle()
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PosixFileHandle::ReadSector(BYTE *buf, int block)
|
bool PosixFileHandle::ReadSector(vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(sec_size != 0);
|
assert(sec_size != 0);
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT(block < sec_blocks);
|
assert(block < sec_blocks);
|
||||||
ASSERT(memory_block);
|
assert(memory_block);
|
||||||
|
|
||||||
size_t sector_size_bytes = (size_t)1 << sec_size;
|
size_t sector_size_bytes = (size_t)1 << sec_size;
|
||||||
|
|
||||||
|
@ -70,27 +70,27 @@ bool PosixFileHandle::ReadSector(BYTE *buf, int block)
|
||||||
offset += GetSectorOffset(block);
|
offset += GetSectorOffset(block);
|
||||||
|
|
||||||
lseek(fd, offset, SEEK_SET);
|
lseek(fd, offset, SEEK_SET);
|
||||||
size_t result = read(fd, buf, sector_size_bytes);
|
size_t result = read(fd, buf.data(), sector_size_bytes);
|
||||||
if (result != sector_size_bytes)
|
if (result != sector_size_bytes)
|
||||||
{
|
{
|
||||||
LOGWARN("%s only read %d bytes but wanted %d ", __PRETTY_FUNCTION__, result, sector_size_bytes);
|
LOGWARN("%s only read %zu bytes but wanted %zu ", __PRETTY_FUNCTION__, result, sector_size_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PosixFileHandle::WriteSector(const BYTE *buf, int block)
|
bool PosixFileHandle::WriteSector(const vector<uint8_t>& buf, int block)
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(buf);
|
assert(buf);
|
||||||
ASSERT(block < sec_blocks);
|
assert(block < sec_blocks);
|
||||||
ASSERT(memory_block);
|
assert(memory_block);
|
||||||
|
|
||||||
ASSERT((block * sec_size) <= (sb.st_size + sec_size));
|
assert((block * sec_size) <= (sb.st_size + sec_size));
|
||||||
|
|
||||||
size_t sector_size_bytes = (size_t)1 << sec_size;
|
size_t sector_size_bytes = (size_t)1 << sec_size;
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@ bool PosixFileHandle::WriteSector(const BYTE *buf, int block)
|
||||||
offset += GetSectorOffset(block);
|
offset += GetSectorOffset(block);
|
||||||
|
|
||||||
lseek(fd, offset, SEEK_SET);
|
lseek(fd, offset, SEEK_SET);
|
||||||
size_t result = write(fd, buf, sector_size_bytes);
|
size_t result = write(fd, buf.data(), sector_size_bytes);
|
||||||
if (result != sector_size_bytes)
|
if (result != sector_size_bytes)
|
||||||
{
|
{
|
||||||
LOGWARN("%s only wrote %d bytes but wanted %d ", __PRETTY_FUNCTION__, result, sector_size_bytes);
|
LOGWARN("%s only wrote %zu bytes but wanted %zu ", __PRETTY_FUNCTION__, result, sector_size_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -11,23 +11,21 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filepath.h"
|
// #include "filepath.h"
|
||||||
#include "disk_image/disk_image_handle.h"
|
#include "disk_image/disk_image_handle.h"
|
||||||
|
|
||||||
class PosixFileHandle : public DiskImageHandle
|
class PosixFileHandle : public DiskImageHandle
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PosixFileHandle(const Filepath &path, int size, uint32_t blocks, off_t imgoff = 0);
|
PosixFileHandle(const string &path, int size, uint32_t blocks, off_t imgoff = 0);
|
||||||
~PosixFileHandle();
|
~PosixFileHandle();
|
||||||
|
|
||||||
void SetRawMode(BOOL raw); // CD-ROM raw mode setting
|
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
bool Save() { return true; }; // Save and release all
|
bool Save() { return true; }; // Save and release all
|
||||||
bool ReadSector(BYTE *buf, int block); // Sector Read
|
bool ReadSector(vector<uint8_t>& buf, int block); // Sector Read
|
||||||
bool WriteSector(const BYTE *buf, int block); // Sector Write
|
bool WriteSector(const vector<uint8_t>& buf, int block); // Sector Write
|
||||||
bool GetCache(int index, int &track, DWORD &serial) const { return true; }; // Get cache information
|
bool GetCache(int index, int &track, uint32_t &serial) const { (void)index; (void)track; (void)serial; return true; }; // Get cache information
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fd;
|
int fd;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user