working on merging

This commit is contained in:
Tony Kuker 2023-01-08 21:39:07 -06:00
parent 8443e08114
commit a15ac7c3c8
17 changed files with 199 additions and 774 deletions

View File

@ -22,6 +22,7 @@
#include "scsi_controller.h"
#include <sstream>
#include <iomanip>
#include <cassert>
#ifdef __linux__
#include <linux/if_tun.h>
#endif

View File

@ -15,6 +15,8 @@
//---------------------------------------------------------------------------
#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 "disk.h"
#include <sstream>
@ -81,7 +83,7 @@ void Disk::Dispatch(scsi_command cmd)
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);
}

View File

@ -17,8 +17,9 @@
#include "shared/scsi.h"
#include "device_factory.h"
#include "disk_track.h"
#include "disk_cache.h"
// #include "disk_track.h"
// #include "disk_cache.h"
#include "disk_image/disk_image_handle.h"
#include "interfaces/scsi_block_commands.h"
#include "storage_device.h"
#include <string>
@ -32,7 +33,7 @@ class Disk : public StorageDevice, private ScsiBlockCommands
{
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
unordered_set<uint32_t> sector_sizes;

View File

@ -1,192 +0,0 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (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;
}
}

View File

@ -1,64 +0,0 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (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
};

View File

@ -1,275 +0,0 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (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;
}

View File

@ -1,59 +0,0 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (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
};

View File

@ -11,9 +11,10 @@
//
//---------------------------------------------------------------------------
#include <cassert>
#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;
@ -43,7 +44,7 @@ off_t DiskImageHandle::GetTrackOffset(int block)
off_t offset = ((off_t)track_num << 8);
if (cd_raw)
{
ASSERT(sec_size == 11);
assert(sec_size == 11);
offset *= 0x930;
offset += 0x10;
}

View File

@ -13,26 +13,31 @@
#pragma once
#include "filepath.h"
// #include "filepath.h"
#include <string>
#include <cstdint>
#include <vector>
using namespace std;
class DiskImageHandle
{
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();
void SetRawMode(bool raw) { cd_raw = raw; }; // CD-ROM raw mode setting
// Access
virtual bool Save() = 0; // Save and release all
virtual bool ReadSector(BYTE *buf, int block) = 0; // Sector Read
virtual bool WriteSector(const BYTE *buf, int block) = 0; // Sector Write
virtual bool GetCache(int index, int &track, DWORD &serial) const = 0; // Get cache information
virtual bool ReadSector(vector<uint8_t>& buf, int block) = 0; // Sector Read
virtual bool WriteSector(const vector<uint8_t>& buf, int block) = 0; // Sector Write
virtual bool GetCache(int index, int &track, uint32_t &serial) const = 0; // Get cache information
protected:
bool cd_raw = false;
DWORD serial; // Last serial number
Filepath sec_path; // Path
uint32_t serial; // 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

View File

@ -12,35 +12,35 @@
//---------------------------------------------------------------------------
#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/mmap_file_handle.h"
#include "disk_image/posix_file_handle.h"
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)
{
LOGINFO("%s Creating MmapFileAccess %s", __PRETTY_FUNCTION__, path.GetPath())
result = new MmapFileHandle(path, size, blocks, imgoff);
LOGINFO("%s Creating MmapFileAccess %s", __PRETTY_FUNCTION__, path.c_str())
result = make_unique<MmapFileHandle>(path, size, blocks, imgoff);
}
else if (current_access_type == DiskImageHandleType::eRamCache)
{
LOGINFO("%s Creating DiskCache %s", __PRETTY_FUNCTION__, path.GetPath())
result = new DiskCache(path, size, blocks, imgoff);
LOGINFO("%s Creating DiskCache %s", __PRETTY_FUNCTION__, path.c_str())
result = make_unique<DiskCache>(path, size, blocks, imgoff);
}
else if (current_access_type == DiskImageHandleType::ePosixFile)
{
LOGINFO("%s Creating PosixFileHandle %s", __PRETTY_FUNCTION__, path.GetPath())
result = new PosixFileHandle(path, size, blocks, imgoff);
LOGINFO("%s Creating PosixFileHandle %s", __PRETTY_FUNCTION__, path.c_str())
result = make_unique<PosixFileHandle>(path, size, blocks, imgoff);
}
if (result == NULL)
if (result == nullptr)
{
LOGWARN("%s Unable to create the File Access", __PRETTY_FUNCTION__);
}

View File

@ -14,6 +14,7 @@
#pragma once
#include "disk_image/disk_image_handle.h"
#include <memory>
enum DiskImageHandleType
{
@ -28,7 +29,7 @@ public:
static void SetFileAccessMethod(DiskImageHandleType method) { current_access_type = method; };
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:
static DiskImageHandleType current_access_type;

View File

@ -16,11 +16,12 @@
//
//---------------------------------------------------------------------------
#include "os.h"
#include "log.h"
#include "fileio.h"
#include <fstream>
#include "shared/log.h"
#include "disk_track_cache.h"
using namespace std;
//===========================================================================
//
// Disk Track
@ -33,13 +34,13 @@ DiskTrack::DiskTrack()
dt.track = 0;
dt.size = 0;
dt.sectors = 0;
dt.raw = FALSE;
dt.init = FALSE;
dt.changed = FALSE;
dt.raw = false;
dt.init = false;
dt.changed = false;
dt.length = 0;
dt.buffer = NULL;
dt.buffer = nullptr;
dt.maplen = 0;
dt.changemap = NULL;
dt.changemap = nullptr;
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((sectors > 0) && (sectors <= 0x100));
ASSERT(imgoff >= 0);
assert(track >= 0);
assert((sectors > 0) && (sectors <= 0x100));
assert(imgoff >= 0);
// Set Parameters
dt.track = track;
@ -69,28 +70,28 @@ void DiskTrack::Init(int track, int size, int sectors, BOOL raw, off_t imgoff)
dt.raw = raw;
// Not initialized (needs to be loaded)
dt.init = FALSE;
dt.init = false;
// Not Changed
dt.changed = FALSE;
dt.changed = false;
// Offset to actual data
dt.imgoffset = imgoff;
}
bool DiskTrack::Load(const Filepath& path)
bool DiskTrack::Load(const string& path)
{
// Not needed if already loaded
if (dt.init) {
ASSERT(dt.buffer);
ASSERT(dt.changemap);
assert(dt.buffer);
assert(dt.changemap);
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);
assert(dt.size == 11);
offset *= 0x930;
offset += 0x10;
} else {
@ -104,7 +105,7 @@ bool DiskTrack::Load(const Filepath& path)
int length = dt.sectors << dt.size;
// Allocate buffer memory
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
if (dt.buffer == NULL) {
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
if (dt.length != (DWORD)length) {
if (dt.length != (uint32_t)length) {
free(dt.buffer);
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__);
@ -128,7 +129,7 @@ bool DiskTrack::Load(const Filepath& path)
// Reserve change map memory
if (dt.changemap == NULL) {
dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL));
dt.changemap = (bool *)malloc(dt.sectors * sizeof(bool));
dt.maplen = dt.sectors;
}
@ -137,32 +138,33 @@ bool DiskTrack::Load(const Filepath& path)
}
// Reallocate if the buffer length is different
if (dt.maplen != (DWORD)dt.sectors) {
if (dt.maplen != (uint32_t)dt.sectors) {
free(dt.changemap);
dt.changemap = (BOOL *)malloc(dt.sectors * sizeof(BOOL));
dt.changemap = (bool *)malloc(dt.sectors * sizeof(bool));
dt.maplen = dt.sectors;
}
// Clear changemap
memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL));
memset(dt.changemap, 0x00, dt.sectors * sizeof(bool));
// Read from File
Fileio fio;
if (!fio.OpenDIO(path, Fileio::ReadOnly)) {
fstream fio;
fio.open(path.c_str(),ios::in);
if(!fio.is_open()) {
return false;
}
if (dt.raw) {
// Split Reading
for (int i = 0; i < dt.sectors; i++) {
// Seek
if (!fio.Seek(offset)) {
fio.Close();
if (!fio.seekg(offset)) {
fio.close();
return false;
}
// Read
if (!fio.Read(&dt.buffer[i << dt.size], 1 << dt.size)) {
fio.Close();
if (!fio.read(&dt.buffer[i << dt.size], 1 << dt.size)) {
fio.close();
return false;
}
@ -171,24 +173,24 @@ bool DiskTrack::Load(const Filepath& path)
}
} else {
// Continuous reading
if (!fio.Seek(offset)) {
fio.Close();
if (!fio.seekg(offset)) {
fio.close();
return false;
}
if (!fio.Read(dt.buffer, length)) {
fio.Close();
if (!fio.read(dt.buffer, length)) {
fio.close();
return false;
}
}
fio.Close();
fio.close();
// Set a flag and end normally
dt.init = TRUE;
dt.changed = FALSE;
dt.init = true;
dt.changed = false;
return true;
}
bool DiskTrack::Save(const Filepath& path)
bool DiskTrack::Save(const string& path)
{
// Not needed if not initialized
if (!dt.init) {
@ -201,12 +203,12 @@ bool DiskTrack::Save(const Filepath& path)
}
// Need to write
ASSERT(dt.buffer);
ASSERT(dt.changemap);
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
assert(dt.buffer);
assert(dt.changemap);
assert((dt.sectors > 0) && (dt.sectors <= 0x100));
// Writing in RAW mode is not allowed
ASSERT(!dt.raw);
assert(!dt.raw);
// Calculate offset (previous tracks are considered to hold 256 sectors)
off_t offset = ((off_t)dt.track << 8);
@ -219,8 +221,9 @@ bool DiskTrack::Save(const Filepath& path)
int length = 1 << dt.size;
// Open file
Fileio fio;
if (!fio.Open(path, Fileio::ReadWrite)) {
fstream fio;
fio.open(path, ios::in | ios::out);
if (!fio.is_open()) {
return false;
}
@ -233,8 +236,8 @@ bool DiskTrack::Save(const Filepath& path)
total = 0;
// Seek
if (!fio.Seek(offset + ((off_t)i << dt.size))) {
fio.Close();
if (!fio.seekg(offset + ((off_t)i << dt.size))) {
fio.close();
return false;
}
@ -251,8 +254,8 @@ bool DiskTrack::Save(const Filepath& path)
}
// Write
if (!fio.Write(&dt.buffer[i << dt.size], total)) {
fio.Close();
if (!fio.write(&dt.buffer[i << dt.size], total)) {
fio.close();
return false;
}
@ -265,18 +268,18 @@ bool DiskTrack::Save(const Filepath& path)
}
// Close
fio.Close();
fio.close();
// Drop the change flag and exit
memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL));
dt.changed = FALSE;
memset(dt.changemap, 0x00, dt.sectors * sizeof(bool));
dt.changed = false;
return true;
}
bool DiskTrack::ReadSector(BYTE *buf, int sec) const
bool DiskTrack::ReadSector(vector<uint8_t>& buf, int sec) const
{
ASSERT(buf);
ASSERT((sec >= 0) & (sec < 0x100));
assert(buf);
assert((sec >= 0) & (sec < 0x100));
LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec);
// Error if not initialized
@ -290,19 +293,19 @@ bool DiskTrack::ReadSector(BYTE *buf, int sec) const
}
// Copy
ASSERT(dt.buffer);
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
memcpy(buf, &dt.buffer[(off_t)sec << dt.size], (off_t)1 << dt.size);
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 BYTE *buf, int sec)
bool DiskTrack::WriteSector(const vector<uint8_t>& buf, int sec)
{
ASSERT(buf);
ASSERT((sec >= 0) & (sec < 0x100));
ASSERT(!dt.raw);
assert(buf);
assert((sec >= 0) & (sec < 0x100));
assert(!dt.raw);
// Error if not initialized
if (!dt.init) {
@ -319,17 +322,17 @@ bool DiskTrack::WriteSector(const BYTE *buf, int sec)
int length = 1 << dt.size;
// Compare
ASSERT(dt.buffer);
ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100));
if (memcmp(buf, &dt.buffer[offset], length) == 0) {
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, length);
dt.changemap[sec] = TRUE;
dt.changed = TRUE;
memcpy(&dt.buffer[offset], buf.data(), length);
dt.changemap[sec] = true;
dt.changed = true;
// Success
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(imgoff >= 0);
assert(blocks > 0);
assert(imgoff >= 0);
// Cache work
for (int i = 0; i < CacheMax; i++) {
@ -381,9 +384,9 @@ bool DiskCache::Save()
// 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
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
UpdateSerialNumber();
@ -428,9 +431,9 @@ bool DiskCache::ReadSector(BYTE *buf, int block)
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
UpdateSerialNumber();
@ -455,8 +458,8 @@ bool DiskCache::WriteSector(const BYTE *buf, int block)
//---------------------------------------------------------------------------
DiskTrack* DiskCache::Assign(int track)
{
ASSERT(sec_size != 0);
ASSERT(track >= 0);
assert(sec_size != 0);
assert(track >= 0);
// First, check if it is already assigned
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
// Set index 0 as candidate c
DWORD s = cache[0].serial;
uint32_t s = cache[0].serial;
int c = 0;
// Compare candidate with serial and update to smaller one
for (int i = 0; i < CacheMax; i++) {
ASSERT(cache[i].disktrk);
assert(cache[i].disktrk);
// Compare and update the existing serial
if (cache[i].serial < s) {
@ -527,13 +530,13 @@ DiskTrack* DiskCache::Assign(int track)
//---------------------------------------------------------------------------
bool DiskCache::Load(int index, int track, DiskTrack *disktrk)
{
ASSERT((index >= 0) && (index < CacheMax));
ASSERT(track >= 0);
ASSERT(!cache[index].disktrk);
assert((index >= 0) && (index < CacheMax));
assert(track >= 0);
assert(!cache[index].disktrk);
// Get the number of sectors on this track
int sectors = sec_blocks - (track << 8);
ASSERT(sectors > 0);
assert(sectors > 0);
if (sectors > 0x100) {
sectors = 0x100;
}

View File

@ -17,9 +17,11 @@
#pragma once
#include "filepath.h"
#include <string>
#include "disk_image/disk_image_handle.h"
using namespace std;
// Number of tracks to cache
#define CacheMax 16
@ -30,13 +32,13 @@ private:
int track; // Track Number
int size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)
int sectors; // Number of sectors(<0x100)
DWORD length; // Data buffer length
BYTE *buffer; // Data buffer
BOOL init; // Is it initilized?
BOOL changed; // Changed flag
DWORD maplen; // Changed map length
BOOL *changemap; // Changed map
BOOL raw; // RAW mode flag
uint32_t length; // Data buffer length
uint8_t *buffer; // Data buffer
bool init; // Is it initilized?
bool changed; // Changed flag
uint32_t maplen; // Changed map length
bool *changemap; // Changed map
bool raw; // RAW mode flag
off_t imgoffset; // Offset to actual data
} dt;
@ -47,13 +49,13 @@ public:
private:
friend class DiskCache;
void Init(int track, int size, int sectors, BOOL raw = FALSE, off_t imgoff = 0);
bool Load(const Filepath& path);
bool Save(const Filepath& path);
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(BYTE *buf, int sec) const; // Sector Read
bool WriteSector(const BYTE *buf, int sec); // Sector Write
bool ReadSector(vector<uint8_t>& buf, int sec) const; // Sector Read
bool WriteSector(const vector<uint8_t>& buf, int sec); // Sector Write
int GetTrack() const { return dt.track; } // Get track
};
@ -64,18 +66,18 @@ public:
// Internal data definition
typedef struct {
DiskTrack *disktrk; // Disk Track
DWORD serial; // Serial
uint32_t serial; // Serial
} cache_t;
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();
// Access
bool Save() override; // Save and release all
bool ReadSector(BYTE *buf, int block) override; // Sector Read
bool WriteSector(const BYTE *buf, int block) override; // Sector Write
bool GetCache(int index, int& track, DWORD& serial) const override; // Get cache information
bool ReadSector(vector<uint8_t>& buf, int block) override; // Sector Read
bool WriteSector(const vector<uint8_t>& buf, int block) override; // Sector Write
bool GetCache(int index, int& track, uint32_t& serial) const override; // Get cache information
private:
// Internal Management

View File

@ -21,7 +21,7 @@
//---------------------------------------------------------------------------
#include "mmap_file_handle.h"
#include "log.h"
#include "shared/log.h"
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
@ -31,25 +31,25 @@
// 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(imgoff >= 0);
assert(blocks > 0);
assert(imgoff >= 0);
fd = open(path.GetPath(), O_RDWR);
fd = open(path.c_str(), O_RDWR);
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;
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;
@ -57,7 +57,7 @@ MmapFileHandle::MmapFileHandle(const Filepath &path, int size, uint32_t blocks,
int errno_val = errno;
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);
return;
}
@ -73,12 +73,12 @@ MmapFileHandle::~MmapFileHandle()
sync();
}
bool MmapFileHandle::ReadSector(BYTE *buf, int block)
bool MmapFileHandle::ReadSector(vector<uint8_t>& buf, int block)
{
ASSERT(sec_size != 0);
ASSERT(buf);
ASSERT(block < sec_blocks);
ASSERT(memory_block);
assert(sec_size != 0);
assert(buf);
assert(block < sec_blocks);
assert(memory_block);
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);
offset += GetSectorOffset(block);
memcpy(buf, &memory_block[offset], sector_size_bytes);
memcpy(buf.data(), &memory_block[offset], sector_size_bytes);
return true;
}
bool MmapFileHandle::WriteSector(const BYTE *buf, int block)
bool MmapFileHandle::WriteSector(const vector<uint8_t>& buf, int block)
{
ASSERT(buf);
ASSERT(block < sec_blocks);
ASSERT(memory_block);
assert(buf);
assert(block < sec_blocks);
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;
}

View File

@ -22,23 +22,24 @@
#pragma once
#include "filepath.h"
#include <string>
#include <sys/stat.h>
#include "disk_image/disk_image_handle.h"
using namespace std;
class MmapFileHandle : public DiskImageHandle
{
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();
void SetRawMode(BOOL raw); // CD-ROM raw mode setting
// Access
bool Save() { return true; }; // Save and release all
bool ReadSector(BYTE *buf, int block); // Sector Read
bool WriteSector(const BYTE *buf, int block); // Sector Write
bool GetCache(int index, int &track, DWORD &serial) const { return true; }; // Get cache information
bool ReadSector(vector<uint8_t>& buf, int block); // Sector Read
bool WriteSector(const vector<uint8_t>& buf, int block); // Sector Write
bool GetCache(int index, int &track, uint32_t &serial) const { (void)index; (void)track; (void)serial; return true; }; // Get cache information
private:
const char *memory_block;

View File

@ -10,7 +10,7 @@
//---------------------------------------------------------------------------
#include "posix_file_handle.h"
#include "log.h"
#include "shared/log.h"
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
@ -20,15 +20,15 @@
// 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(imgoff >= 0);
assert(blocks > 0);
assert(imgoff >= 0);
fd = open(path.GetPath(), O_RDWR);
fd = open(path.c_str(), O_RDWR);
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;
}
struct stat sb;
@ -38,7 +38,7 @@ PosixFileHandle::PosixFileHandle(const Filepath &path, int size, uint32_t blocks
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;
}
@ -51,17 +51,17 @@ PosixFileHandle::~PosixFileHandle()
sync();
}
bool PosixFileHandle::ReadSector(BYTE *buf, int block)
bool PosixFileHandle::ReadSector(vector<uint8_t>& buf, int block)
{
if (!initialized)
{
return false;
}
ASSERT(sec_size != 0);
ASSERT(buf);
ASSERT(block < sec_blocks);
ASSERT(memory_block);
assert(sec_size != 0);
assert(buf);
assert(block < sec_blocks);
assert(memory_block);
size_t sector_size_bytes = (size_t)1 << sec_size;
@ -70,27 +70,27 @@ bool PosixFileHandle::ReadSector(BYTE *buf, int block)
offset += GetSectorOffset(block);
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)
{
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;
}
bool PosixFileHandle::WriteSector(const BYTE *buf, int block)
bool PosixFileHandle::WriteSector(const vector<uint8_t>& buf, int block)
{
if (!initialized)
{
return false;
}
ASSERT(buf);
ASSERT(block < sec_blocks);
ASSERT(memory_block);
assert(buf);
assert(block < sec_blocks);
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;
@ -98,10 +98,10 @@ bool PosixFileHandle::WriteSector(const BYTE *buf, int block)
offset += GetSectorOffset(block);
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)
{
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;

View File

@ -11,23 +11,21 @@
#pragma once
#include "filepath.h"
// #include "filepath.h"
#include "disk_image/disk_image_handle.h"
class PosixFileHandle : public DiskImageHandle
{
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();
void SetRawMode(BOOL raw); // CD-ROM raw mode setting
// Access
bool Save() { return true; }; // Save and release all
bool ReadSector(BYTE *buf, int block); // Sector Read
bool WriteSector(const BYTE *buf, int block); // Sector Write
bool GetCache(int index, int &track, DWORD &serial) const { return true; }; // Get cache information
bool ReadSector(vector<uint8_t>& buf, int block); // Sector Read
bool WriteSector(const vector<uint8_t>& buf, int block); // Sector Write
bool GetCache(int index, int &track, uint32_t &serial) const { (void)index; (void)track; (void)serial; return true; }; // Get cache information
private:
int fd;