Start using VFS/filestream functions

This commit is contained in:
twinaphex committed 2021-11-06 17:15:23 +01:00
1 parent 009e5a779b
commit 770313ba24
12 files changed
+1611 -1584

No files matched your search

+2
View File
@@ -21,6 +21,8 @@ SOURCES_C := \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c
+1068 -931
View File
File diff suppressed because it is too large. Load diff
+6 -4
View File
@@ -24,6 +24,8 @@
#include <stdio.h>
#include <vector>
#include <streams/file_stream.h>
#include "IEC.h"
/*
@@ -123,7 +125,7 @@ private:
virtual void new_cmd(const uint8 *name, int name_len, const uint8 *comma);
virtual void validate_cmd(void);
FILE *the_file; // File pointer for image file
RFILE *the_file; // File pointer for image file
image_file_desc desc; // Image file descriptor
bool write_protected; // Flag: image file write-protected
@@ -143,12 +145,12 @@ private:
// Check whether file with given header (64 bytes) and size looks like one
// of the file types supported by this module
extern bool IsImageFile(const char *path, const uint8 *header, long size);
bool IsImageFile(const char *path, const uint8 *header, int64_t size);
// Read directory of disk image file into (empty) c64_dir_entry vector
extern bool ReadImageDirectory(const char *path, std::vector<c64_dir_entry> &vec);
bool ReadImageDirectory(const char *path, std::vector<c64_dir_entry> &vec);
// Create new blank disk image file
extern bool CreateImageFile(const char *path);
bool CreateImageFile(const char *path);
#endif
+138 -133
View File
@@ -45,24 +45,23 @@
#include "CPU1541.h"
#include "Prefs.h"
/* Number of tracks/sectors */
#define NUM_TRACKS 35
#define NUM_SECTORS 683
// Number of tracks/sectors
const int NUM_TRACKS = 35;
const int NUM_SECTORS = 683;
// Size of GCR encoded data
/* Size of GCR encoded data */
const int GCR_SECTOR_SIZE = 1+10+9+1+325+8; // SYNC Header Gap SYNC Data Gap (should be 5 SYNC bytes each)
const int GCR_TRACK_SIZE = GCR_SECTOR_SIZE * 21; // Each track in gcr_data has 21 sectors
const int GCR_DISK_SIZE = GCR_TRACK_SIZE * NUM_TRACKS;
const int GCR_TRACK_SIZE = GCR_SECTOR_SIZE * 21; // Each track in gcr_data has 21 sectors
const int GCR_DISK_SIZE = GCR_TRACK_SIZE * NUM_TRACKS;
// Job return codes
const int RET_OK = 1; // No error
const int RET_NOT_FOUND = 2; // Block not found
const int RET_NOT_READY = 15; // Drive not ready
/* Job return codes */
#define RET_OK 1 /* No error */
#define RET_NOT_FOUND 2 /* Block not found */
#define RET_NOT_READY 15 /* Drive not ready */
// Number of sectors of each track
const int num_sectors[36] = {
/* Number of sectors of each track */
const int num_sectors[36] =
{
0,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
19,19,19,19,19,19,19,
@@ -71,14 +70,26 @@ const int num_sectors[36] = {
};
// Sector offset of start of track in .d64 file
const int sector_offset[36] = {
0,
0,21,42,63,84,105,126,147,168,189,210,231,252,273,294,315,336,
357,376,395,414,433,452,471,
490,508,526,544,562,580,
598,615,632,649,666
const int sector_offset[36] =
{
0,
0,21,42,63,84,105,126,147,168,189,210,231,252,273,294,315,336,
357,376,395,414,433,452,471,
490,508,526,544,562,580,
598,615,632,649,666
};
/* Forward declarations */
extern "C" {
RFILE* rfopen(const char *path, const char *mode);
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
int64_t rftell(RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
int64_t rfwrite(void const* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
}
/*
* Constructor: Open .d64 file if processor-level 1541
@@ -87,13 +98,13 @@ const int sector_offset[36] = {
Job1541::Job1541(uint8 *ram1541) : ram(ram1541)
{
the_file = NULL;
the_file = NULL;
gcr_data = gcr_ptr = gcr_track_start = new uint8[GCR_DISK_SIZE];
gcr_track_end = gcr_track_start + GCR_TRACK_SIZE;
gcr_data = gcr_ptr = gcr_track_start = new uint8[GCR_DISK_SIZE];
gcr_track_end = gcr_track_start + GCR_TRACK_SIZE;
current_halftrack = 2;
disk_changed = true;
disk_changed = true;
if (ThePrefs.Emul1541Proc)
open_d64_file(ThePrefs.DrivePath[0]);
@@ -111,10 +122,7 @@ Job1541::~Job1541()
}
/*
* Preferences may have changed
*/
/* Preferences may have changed */
void Job1541::NewPrefs(Prefs *prefs)
{
// 1541 emulation turned off?
@@ -126,69 +134,74 @@ void Job1541::NewPrefs(Prefs *prefs)
open_d64_file(prefs->DrivePath[0]);
// .d64 file name changed?
else if (strcmp(ThePrefs.DrivePath[0], prefs->DrivePath[0])) {
close_d64_file();
open_d64_file(prefs->DrivePath[0]);
disk_changed = true;
}
else if (strcmp(ThePrefs.DrivePath[0], prefs->DrivePath[0]))
{
close_d64_file();
open_d64_file(prefs->DrivePath[0]);
disk_changed = true;
}
}
/*
* Open .d64 file
*/
/* Open .d64 file */
void Job1541::open_d64_file(char *filepath)
{
long size;
uint8 magic[4];
uint8 bam[256];
// Clear GCR buffer
/* Clear GCR buffer */
memset(gcr_data, 0x55, GCR_DISK_SIZE);
// Try opening the file for reading/writing first, then for reading only
/* Try opening the file for reading/writing first,
then for reading only */
write_protected = false;
the_file = fopen(filepath, "rb+");
if (the_file == NULL) {
write_protected = true;
the_file = fopen(filepath, "rb");
}
if (the_file != NULL) {
the_file = rfopen(filepath, "rb+");
if (!the_file)
{
write_protected = true;
the_file = rfopen(filepath, "rb");
}
if (the_file)
{
// Check length
rfseek(the_file, 0, SEEK_END);
if ((size = rftell(the_file)) < NUM_SECTORS * 256)
{
rfclose(the_file);
the_file = NULL;
return;
}
// Check length
fseek(the_file, 0, SEEK_END);
if ((size = ftell(the_file)) < NUM_SECTORS * 256) {
fclose(the_file);
the_file = NULL;
return;
}
// x64 image?
rfseek(the_file, 0, SEEK_SET);
rfread(&magic, 4, 1, the_file);
if ( magic[0] == 0x43
&& magic[1] == 0x15
&& magic[2] == 0x41
&& magic[3] == 0x64)
image_header = 64;
else
image_header = 0;
// x64 image?
fseek(the_file, 0, SEEK_SET);
fread(&magic, 4, 1, the_file);
if (magic[0] == 0x43 && magic[1] == 0x15 && magic[2] == 0x41 && magic[3] == 0x64)
image_header = 64;
else
image_header = 0;
// Preset error info (all sectors no error)
memset(error_info, 1, NUM_SECTORS);
// Preset error info (all sectors no error)
memset(error_info, 1, NUM_SECTORS);
// Load sector error info from .d64 file, if present
if (!image_header && size == NUM_SECTORS * 257)
{
rfseek(the_file, NUM_SECTORS * 256, SEEK_SET);
rfread(&error_info, NUM_SECTORS, 1, the_file);
}
// Load sector error info from .d64 file, if present
if (!image_header && size == NUM_SECTORS * 257) {
fseek(the_file, NUM_SECTORS * 256, SEEK_SET);
fread(&error_info, NUM_SECTORS, 1, the_file);
};
// Read BAM and get ID
read_sector(18, 0, bam);
id1 = bam[162];
id2 = bam[163];
// Read BAM and get ID
read_sector(18, 0, bam);
id1 = bam[162];
id2 = bam[163];
// Create GCR encoded disk data from image
disk2gcr();
}
// Create GCR encoded disk data from image
disk2gcr();
}
}
@@ -198,10 +211,10 @@ void Job1541::open_d64_file(char *filepath)
void Job1541::close_d64_file(void)
{
if (the_file != NULL) {
fclose(the_file);
the_file = NULL;
}
if (!the_file)
return;
rfclose(the_file);
the_file = NULL;
}
@@ -227,23 +240,24 @@ void Job1541::WriteSector(void)
void Job1541::FormatTrack(void)
{
int track = ram[0x51];
// Get new ID
uint8 buf[256];
int sector;
int track = ram[0x51];
/* Get new ID */
uint8 bufnum = ram[0x3d];
id1 = ram[0x12 + bufnum];
id2 = ram[0x13 + bufnum];
// Create empty block
uint8 buf[256];
/* Create empty block */
memset(buf, 1, 256);
buf[0] = 0x4b;
// Write block to all sectors on track
for(int sector=0; sector<num_sectors[track]; sector++) {
write_sector(track, sector, buf);
sector2gcr(track, sector);
}
for(sector=0; sector<num_sectors[track]; sector++)
{
write_sector(track, sector, buf);
sector2gcr(track, sector);
}
// Clear error info (all sectors no error)
if (track == 35)
@@ -265,8 +279,8 @@ bool Job1541::read_sector(int track, int sector, uint8 *buffer)
if ((offset = offset_from_ts(track, sector)) < 0)
return false;
fseek(the_file, offset + image_header, SEEK_SET);
fread(buffer, 256, 1, the_file);
rfseek(the_file, offset + image_header, SEEK_SET);
rfread(buffer, 256, 1, the_file);
return true;
}
@@ -279,13 +293,12 @@ bool Job1541::read_sector(int track, int sector, uint8 *buffer)
bool Job1541::write_sector(int track, int sector, uint8 *buffer)
{
int offset;
// Convert track/sector to byte offset in file
/* Convert track/sector to byte offset in file */
if ((offset = offset_from_ts(track, sector)) < 0)
return false;
fseek(the_file, offset + image_header, SEEK_SET);
fwrite(buffer, 256, 1, the_file);
rfseek(the_file, offset + image_header, SEEK_SET);
rfwrite(buffer, 256, 1, the_file);
return true;
}
@@ -320,9 +333,7 @@ const uint16 gcr_table[16] = {
void Job1541::gcr_conv4(uint8 *from, uint8 *to)
{
uint16 g;
g = (gcr_table[*from >> 4] << 5) | gcr_table[*from & 15];
uint16 g = (gcr_table[*from >> 4] << 5) | gcr_table[*from & 15];
*to++ = g >> 2;
*to = (g << 6) & 0xc0;
from++;
@@ -349,9 +360,11 @@ void Job1541::gcr_conv4(uint8 *from, uint8 *to)
void Job1541::sector2gcr(int track, int sector)
{
int i;
uint8 block[256];
uint8 buf[4];
uint8 *p = gcr_data + (track-1) * GCR_TRACK_SIZE + sector * GCR_SECTOR_SIZE;
uint8 *p = gcr_data + (track-1) * GCR_TRACK_SIZE
+ sector * GCR_SECTOR_SIZE;
read_sector(track, sector, block);
@@ -380,14 +393,15 @@ void Job1541::sector2gcr(int track, int sector)
sum ^= buf[3] = block[2];
gcr_conv4(buf, p);
p += 5;
for (int i=3; i<255; i+=4) {
sum ^= buf[0] = block[i];
sum ^= buf[1] = block[i+1];
sum ^= buf[2] = block[i+2];
sum ^= buf[3] = block[i+3];
gcr_conv4(buf, p);
p += 5;
}
for (i = 3; i < 255; i += 4)
{
sum ^= buf[0] = block[i];
sum ^= buf[1] = block[i+1];
sum ^= buf[2] = block[i+2];
sum ^= buf[3] = block[i+3];
gcr_conv4(buf, p);
p += 5;
}
sum ^= buf[0] = block[255];
buf[1] = sum; // Checksum
buf[2] = 0;
@@ -399,64 +413,55 @@ void Job1541::sector2gcr(int track, int sector)
void Job1541::disk2gcr(void)
{
int track, sector;
// Convert all tracks and sectors
for (int track=1; track<=NUM_TRACKS; track++)
for(int sector=0; sector<num_sectors[track]; sector++)
for (track = 1; track <= NUM_TRACKS; track++)
for(sector = 0; sector < num_sectors[track]; sector++)
sector2gcr(track, sector);
}
/*
* Move R/W head out (lower track numbers)
*/
/* Move R/W head out (lower track numbers) */
void Job1541::MoveHeadOut(void)
{
if (current_halftrack == 2)
return;
current_halftrack--;
gcr_ptr = gcr_track_start = gcr_data + ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_ptr = gcr_track_start = gcr_data + ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_track_end = gcr_track_start + num_sectors[current_halftrack >> 1] * GCR_SECTOR_SIZE;
}
/*
* Move R/W head in (higher track numbers)
*/
/* Move R/W head in (higher track numbers) */
void Job1541::MoveHeadIn(void)
{
if (current_halftrack == NUM_TRACKS*2)
return;
current_halftrack++;
gcr_ptr = gcr_track_start = gcr_data + ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_ptr = gcr_track_start = gcr_data + ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_track_end = gcr_track_start + num_sectors[current_halftrack >> 1] * GCR_SECTOR_SIZE;
}
/*
* Get state
*/
/* Get state */
void Job1541::GetState(Job1541State *state)
{
state->current_halftrack = current_halftrack;
state->gcr_ptr = gcr_ptr - gcr_data;
state->write_protected = write_protected;
state->disk_changed = disk_changed;
state->gcr_ptr = gcr_ptr - gcr_data;
state->write_protected = write_protected;
state->disk_changed = disk_changed;
}
/*
* Set state
*/
/* Set state */
void Job1541::SetState(Job1541State *state)
{
current_halftrack = state->current_halftrack;
gcr_ptr = gcr_data + state->gcr_ptr;
gcr_track_start = gcr_data + ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_track_end = gcr_track_start + num_sectors[current_halftrack >> 1] * GCR_SECTOR_SIZE;
write_protected = state->write_protected;
disk_changed = state->disk_changed;
gcr_ptr = gcr_data + state->gcr_ptr;
gcr_track_start = gcr_data
+ ((current_halftrack >> 1) - 1) * GCR_TRACK_SIZE;
gcr_track_end = gcr_track_start
+ num_sectors[current_halftrack >> 1] * GCR_SECTOR_SIZE;
write_protected = state->write_protected;
disk_changed = state->disk_changed;
}
+12 -13
View File
@@ -21,7 +21,7 @@
#ifndef _1541JOB_H
#define _1541JOB_H
#include <stdio.h>
#include <streams/file_stream.h>
class MOS6502_1541;
class Prefs;
@@ -56,7 +56,7 @@ private:
void disk2gcr(void);
uint8 *ram; // Pointer to 1541 RAM
FILE *the_file; // File pointer for .d64 file
RFILE *the_file; // File pointer for .d64 file
int image_header; // Length of .d64/.x64 file header
uint8 id1, id2; // ID of disk
@@ -87,14 +87,12 @@ struct Job1541State {
inline bool Job1541::SyncFound(void)
{
if (*gcr_ptr == 0xff)
return true;
else {
gcr_ptr++; // Rotate disk
if (gcr_ptr == gcr_track_end)
gcr_ptr = gcr_track_start;
return false;
}
if (*gcr_ptr == 0xff)
return true;
gcr_ptr++; /* Rotate disk */
if (gcr_ptr == gcr_track_end)
gcr_ptr = gcr_track_start;
return false;
}
@@ -117,11 +115,12 @@ inline uint8 Job1541::ReadGCRByte(void)
inline uint8 Job1541::WPState(void)
{
if (disk_changed) { // Disk change -> WP sensor strobe
if (disk_changed) // Disk change -> WP sensor strobe
{
disk_changed = false;
return write_protected ? 0x10 : 0;
} else
return write_protected ? 0 : 0x10;
}
return write_protected ? 0 : 0x10;
}
#endif
+148 -145
View File
@@ -160,55 +160,52 @@ class ScopedSignalBlocker {
sigset_t old_set_;
};
static FILE* __tmpfile_dir(const char* tmp_dir) {
char buf[PATH_MAX];
int path_length = snprintf(buf, sizeof(buf), "%s/tmp.XXXXXXXXXX", tmp_dir);
if (path_length >= sizeof(buf)) {
return NULL;
}
int fd;
{
ScopedSignalBlocker ssb;
fd = mkstemp2(buf);
if (fd == -1) {
static FILE* __tmpfile_dir(const char* tmp_dir)
{
int fd, old_errno;
char buf[PATH_MAX];
ScopedSignalBlocker ssb;
struct stat sb;
FILE *fp = NULL;
int path_length = snprintf(buf, sizeof(buf), "%s/tmp.XXXXXXXXXX", tmp_dir);
if (path_length >= sizeof(buf))
return NULL;
}
// Unlink the file now so that it's removed when closed.
unlink(buf);
fd = mkstemp2(buf);
if (fd == -1)
return NULL;
// Can we still use the file now it's unlinked?
// File systems without hard link support won't have the usual Unix semantics.
struct stat sb;
int rc = fstat(fd, &sb);
if (rc == -1) {
int old_errno = errno;
// Unlink the file now so that it's removed when closed.
unlink(buf);
// Can we still use the file now it's unlinked?
// File systems without hard link support won't have the usual Unix semantics.
int rc = fstat(fd, &sb);
if (rc == -1)
{
old_errno = errno;
close(fd);
errno = old_errno;
errno = old_errno;
return NULL;
}
}
}
// Turn the file descriptor into a FILE*.
FILE* fp = fdopen(fd, "w+");
if (fp != NULL) {
return fp;
}
// Turn the file descriptor into a FILE*.
fp = fdopen(fd, "w+");
if (fp)
return fp;
// Failure. Clean up. We already unlinked, so we just need to close.
int old_errno = errno;
close(fd);
errno = old_errno;
return NULL;
// Failure. Clean up. We already unlinked, so we just need to close.
old_errno = errno;
close(fd);
errno = old_errno;
return NULL;
}
FILE* tmpfile2() {
FILE* tmpfile2(void)
{
FILE* fp = __tmpfile_dir("/data/data/com.retroarch/tmp");
if (fp == NULL) {
fp = __tmpfile_dir(P_tmpdir);
}
if (!fp)
return __tmpfile_dir(P_tmpdir);
return fp;
}
@@ -222,42 +219,36 @@ static bool parse_t64_file(FILE *f, std::vector<c64_dir_entry> &vec, char *dir_t
static bool parse_lynx_file(FILE *f, std::vector<c64_dir_entry> &vec, char *dir_title);
static bool parse_p00_file(FILE *f, std::vector<c64_dir_entry> &vec, char *dir_title);
/*
* Constructor: Prepare emulation
*/
ArchDrive::ArchDrive(IEC *iec, const char *filepath) : Drive(iec), the_file(NULL)
{
for (int i=0; i<16; i++)
unsigned i;
for (i = 0; i < 16; i++)
file[i] = NULL;
Reset();
// Open archive file
/* Open archive file */
if (change_arch(filepath))
Ready = true;
}
/*
* Destructor
*/
/* Destructor */
ArchDrive::~ArchDrive()
{
// Close archive file
if (the_file) {
close_all_channels();
fclose(the_file);
}
if (the_file)
{
close_all_channels();
fclose(the_file);
}
Ready = false;
}
/*
* Open the archive file
*/
/* Open the archive file */
bool ArchDrive::change_arch(const char *path)
{
FILE *new_file;
@@ -271,33 +262,41 @@ bool ArchDrive::change_arch(const char *path)
uint8 header[64];
fread(header, 1, 64, new_file);
bool parsed_ok = false;
if (is_t64_header(header)) {
archive_type = TYPE_T64;
parsed_ok = parse_t64_file(new_file, file_info, dir_title);
} else if (is_lynx_header(header)) {
archive_type = TYPE_LYNX;
parsed_ok = parse_lynx_file(new_file, file_info, dir_title);
} else if (is_p00_header(header)) {
archive_type = TYPE_P00;
parsed_ok = parse_p00_file(new_file, file_info, dir_title);
}
if (is_t64_header(header))
{
archive_type = TYPE_T64;
parsed_ok = parse_t64_file(new_file, file_info, dir_title);
}
else if (is_lynx_header(header))
{
archive_type = TYPE_LYNX;
parsed_ok = parse_lynx_file(new_file, file_info, dir_title);
}
else if (is_p00_header(header))
{
archive_type = TYPE_P00;
parsed_ok = parse_p00_file(new_file, file_info, dir_title);
}
if (!parsed_ok) {
fclose(new_file);
if (the_file) {
close_all_channels();
fclose(the_file);
the_file = NULL;
}
return false;
}
if (!parsed_ok)
{
fclose(new_file);
if (the_file)
{
close_all_channels();
fclose(the_file);
the_file = NULL;
}
return false;
}
// Close old archive if open, and set new file
if (the_file) {
close_all_channels();
fclose(the_file);
the_file = NULL;
}
if (the_file)
{
close_all_channels();
fclose(the_file);
the_file = NULL;
}
the_file = new_file;
return true;
}
@@ -314,40 +313,40 @@ uint8 ArchDrive::Open(int channel, const uint8 *name, int name_len)
set_error(ERR_OK);
// Channel 15: Execute file name as command
if (channel == 15) {
execute_cmd(name, name_len);
return ST_OK;
}
if (channel == 15)
{
execute_cmd(name, name_len);
return ST_OK;
}
// Close previous file if still open
if (file[channel]) {
fclose(file[channel]);
file[channel] = NULL;
}
if (file[channel])
{
fclose(file[channel]);
file[channel] = NULL;
}
if (name[0] == '#') {
set_error(ERR_NOCHANNEL);
return ST_OK;
}
if (name[0] == '#')
{
set_error(ERR_NOCHANNEL);
return ST_OK;
}
if (the_file == NULL) {
set_error(ERR_NOTREADY);
return ST_OK;
}
if (!the_file)
{
set_error(ERR_NOTREADY);
return ST_OK;
}
if (name[0] == '$')
return open_directory(channel, name + 1, name_len - 1);
return open_file(channel, name, name_len);
}
/*
* Open file
*/
/* Open file */
uint8 ArchDrive::open_file(int channel, const uint8 *name, int name_len)
{
bool writing;
uint8 plain_name[NAMEBUF_LENGTH];
int plain_name_len;
int mode = FMODE_READ;
@@ -362,7 +361,7 @@ uint8 ArchDrive::open_file(int channel, const uint8 *name, int name_len)
type = FTYPE_PRG;
}
bool writing = (mode == FMODE_WRITE || mode == FMODE_APPEND);
writing = (mode == FMODE_WRITE || mode == FMODE_APPEND);
// Wildcards are only allowed on reading
if (writing && (strchr((const char *)plain_name, '*') || strchr((const char *)plain_name, '?'))) {
@@ -423,13 +422,14 @@ uint8 ArchDrive::open_file(int channel, const uint8 *name, int name_len)
// Return true if name 'n' matches pattern 'p'
static bool match(const uint8 *p, int p_len, const uint8 *n)
{
while (p_len-- > 0) {
if (*p == '*') // Wildcard '*' matches all following characters
return true;
if ((*p != *n) && (*p != '?')) // Wildcard '?' matches single character
return false;
p++; n++;
}
while (p_len-- > 0)
{
if (*p == '*') // Wildcard '*' matches all following characters
return true;
if ((*p != *n) && (*p != '?')) // Wildcard '?' matches single character
return false;
p++; n++;
}
return *n == 0;
}
@@ -437,10 +437,11 @@ static bool match(const uint8 *p, int p_len, const uint8 *n)
bool ArchDrive::find_first_file(const uint8 *pattern, int pattern_len, int &num)
{
std::vector<c64_dir_entry>::const_iterator i, end = file_info.end();
for (i = file_info.begin(), num = 0; i != end; i++, num++) {
if (match(pattern, pattern_len, (uint8 *)i->name))
return true;
}
for (i = file_info.begin(), num = 0; i != end; i++, num++)
{
if (match(pattern, pattern_len, (uint8 *)i->name))
return true;
}
return false;
}
@@ -451,19 +452,22 @@ bool ArchDrive::find_first_file(const uint8 *pattern, int pattern_len, int &num)
uint8 ArchDrive::open_directory(int channel, const uint8 *pattern, int pattern_len)
{
uint8 *t;
// Special treatment for "$0"
if (pattern[0] == '0' && pattern_len == 1) {
pattern++;
pattern_len--;
}
if (pattern[0] == '0' && pattern_len == 1)
{
pattern++;
pattern_len--;
}
// Skip everything before the ':' in the pattern
uint8 *t = (uint8 *)memchr(pattern, ':', pattern_len);
if (t) {
t++;
pattern_len -= t - pattern;
pattern = t;
}
t = (uint8 *)memchr(pattern, ':', pattern_len);
if (t)
{
t++;
pattern_len -= t - pattern;
pattern = t;
}
#if defined(ANDROID) || defined(__ANDROID__)
// Create temporary file
@@ -719,8 +723,7 @@ static bool is_t64_header(const uint8 *header)
|| memcmp(header, "C64 tape image", 14) == 0
|| memcmp(header, "C64S tape image", 15) == 0)
return true;
else
return false;
return false;
}
static bool is_lynx_header(const uint8 *header)
@@ -894,26 +897,26 @@ static bool parse_p00_file(FILE *f, std::vector<c64_dir_entry> &vec, char *dir_t
bool ReadArchDirectory(const char *path, std::vector<c64_dir_entry> &vec)
{
// Open file
FILE *f = fopen(path, "rb");
if (f) {
// Open file
FILE *f = fopen(path, "rb");
if (f)
{
// Read header
uint8 header[64];
fread(header, 1, sizeof(header), f);
// Read header
uint8 header[64];
fread(header, 1, sizeof(header), f);
// Determine archive type and parse archive
bool result = false;
char dir_title[16];
if (is_t64_header(header))
result = parse_t64_file(f, vec, dir_title);
else if (is_lynx_header(header))
result = parse_lynx_file(f, vec, dir_title);
else if (is_p00_header(header))
result = parse_p00_file(f, vec, dir_title);
// Determine archive type and parse archive
bool result = false;
char dir_title[16];
if (is_t64_header(header))
result = parse_t64_file(f, vec, dir_title);
else if (is_lynx_header(header))
result = parse_lynx_file(f, vec, dir_title);
else if (is_p00_header(header))
result = parse_p00_file(f, vec, dir_title);
fclose(f);
return result;
} else
return false;
fclose(f);
return result;
}
return false;
}
+78 -69
View File
@@ -18,8 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/time.h> /* TODO/FIXME - get rid of gettimeofday */
#include <libretro.h>
#include "sysdeps.h"
@@ -48,17 +46,29 @@ bool IsFrodoSC = true;
bool IsFrodoSC = false;
#endif
/* Forward declarations */
extern "C" {
RFILE* rfopen(const char *path, const char *mode);
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
int64_t rftell(RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
int64_t rfwrite(void const* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
int rfgetc(RFILE* stream);
int rfputc(int character, RFILE * stream);
int rfprintf(RFILE * stream, const char * format, ...);
}
extern retro_input_state_t input_state_cb;
#ifndef NO_LIBCO
extern cothread_t mainThread;
extern cothread_t emuThread;
#endif
extern int pauseg,retro_quit;
extern void pause_select();
extern void pause_select(void);
extern int SHOWKEY;
static struct timeval tv_start;
/*
* Constructor: Allocate objects and memory
*/
@@ -277,14 +287,14 @@ void C64::PatchKernal(bool fast_reset, bool emul_1541_proc)
/* Save RAM contents */
void C64::SaveRAM(char *filename)
{
FILE *f;
if (!(f = fopen(filename, "wb")))
RFILE *f;
if (!(f = rfopen(filename, "wb")))
return;
fwrite((void*)RAM, 1, 0x10000, f);
fwrite((void*)Color, 1, 0x400, f);
rfwrite((void*)RAM, 1, 0x10000, f);
rfwrite((void*)Color, 1, 0x400, f);
if (ThePrefs.Emul1541Proc)
fwrite((void*)RAM1541, 1, 0x800, f);
fclose(f);
rfwrite((void*)RAM1541, 1, 0x800, f);
rfclose(f);
}
/*
@@ -294,7 +304,7 @@ void C64::SaveRAM(char *filename)
* 1: OK
* -1: Instruction not completed
*/
int C64::SaveCPUState(FILE *f)
int C64::SaveCPUState(RFILE *f)
{
int i;
MOS6510State state;
@@ -303,9 +313,9 @@ int C64::SaveCPUState(FILE *f)
if (!state.instruction_complete)
return -1;
i = fwrite(RAM, 0x10000, 1, f);
i += fwrite(Color, 0x400, 1, f);
i += fwrite((void*)&state, sizeof(state), 1, f);
i = rfwrite(RAM, 0x10000, 1, f);
i += rfwrite(Color, 0x400, 1, f);
i += rfwrite((void*)&state, sizeof(state), 1, f);
return i == 3;
}
@@ -315,12 +325,12 @@ int C64::SaveCPUState(FILE *f)
* Load CPU state from snapshot
*/
bool C64::LoadCPUState(FILE *f)
bool C64::LoadCPUState(RFILE *f)
{
MOS6510State state;
int i = fread(RAM, 0x10000, 1, f);
i += fread(Color, 0x400, 1, f);
i += fread((void*)&state, sizeof(state), 1, f);
int i = rfread(RAM, 0x10000, 1, f);
i += rfread(Color, 0x400, 1, f);
i += rfread((void*)&state, sizeof(state), 1, f);
if (i == 3)
{
@@ -339,7 +349,7 @@ bool C64::LoadCPUState(FILE *f)
* -1: Instruction not completed
*/
int C64::Save1541State(FILE *f)
int C64::Save1541State(RFILE *f)
{
int i;
MOS6502State state;
@@ -348,8 +358,8 @@ int C64::Save1541State(FILE *f)
if (!state.idle && !state.instruction_complete)
return -1;
i = fwrite(RAM1541, 0x800, 1, f);
i += fwrite((void*)&state, sizeof(state), 1, f);
i = rfwrite(RAM1541, 0x800, 1, f);
i += rfwrite((void*)&state, sizeof(state), 1, f);
return i == 2;
}
@@ -358,11 +368,11 @@ int C64::Save1541State(FILE *f)
* Load 1541 state from snapshot
*/
bool C64::Load1541State(FILE *f)
bool C64::Load1541State(RFILE *f)
{
MOS6502State state;
int i = fread(RAM1541, 0x800, 1, f);
i += fread((void*)&state, sizeof(state), 1, f);
int i = rfread(RAM1541, 0x800, 1, f);
i += rfread((void*)&state, sizeof(state), 1, f);
if (i == 2)
{
@@ -377,11 +387,11 @@ bool C64::Load1541State(FILE *f)
* Save VIC state to snapshot
*/
bool C64::SaveVICState(FILE *f)
bool C64::SaveVICState(RFILE *f)
{
MOS6569State state;
TheVIC->GetState(&state);
return fwrite((void*)&state, sizeof(state), 1, f) == 1;
return rfwrite((void*)&state, sizeof(state), 1, f) == 1;
}
@@ -389,10 +399,10 @@ bool C64::SaveVICState(FILE *f)
* Load VIC state from snapshot
*/
bool C64::LoadVICState(FILE *f)
bool C64::LoadVICState(RFILE *f)
{
MOS6569State state;
if (fread((void*)&state, sizeof(state), 1, f) == 1)
if (rfread((void*)&state, sizeof(state), 1, f) == 1)
{
TheVIC->SetState(&state);
return true;
@@ -405,11 +415,11 @@ bool C64::LoadVICState(FILE *f)
* Save SID state to snapshot
*/
bool C64::SaveSIDState(FILE *f)
bool C64::SaveSIDState(RFILE *f)
{
MOS6581State state;
TheSID->GetState(&state);
return fwrite((void*)&state, sizeof(state), 1, f) == 1;
return rfwrite((void*)&state, sizeof(state), 1, f) == 1;
}
@@ -417,10 +427,10 @@ bool C64::SaveSIDState(FILE *f)
* Load SID state from snapshot
*/
bool C64::LoadSIDState(FILE *f)
bool C64::LoadSIDState(RFILE *f)
{
MOS6581State state;
if (fread((void*)&state, sizeof(state), 1, f) == 1)
if (rfread((void*)&state, sizeof(state), 1, f) == 1)
{
TheSID->SetState(&state);
return true;
@@ -433,14 +443,14 @@ bool C64::LoadSIDState(FILE *f)
* Save CIA states to snapshot
*/
bool C64::SaveCIAState(FILE *f)
bool C64::SaveCIAState(RFILE *f)
{
MOS6526State state;
TheCIA1->GetState(&state);
if (fwrite((void*)&state, sizeof(state), 1, f) == 1)
if (rfwrite((void*)&state, sizeof(state), 1, f) == 1)
{
TheCIA2->GetState(&state);
return fwrite((void*)&state, sizeof(state), 1, f) == 1;
return rfwrite((void*)&state, sizeof(state), 1, f) == 1;
}
return false;
}
@@ -450,13 +460,13 @@ bool C64::SaveCIAState(FILE *f)
* Load CIA states from snapshot
*/
bool C64::LoadCIAState(FILE *f)
bool C64::LoadCIAState(RFILE *f)
{
MOS6526State state;
if (fread((void*)&state, sizeof(state), 1, f) == 1)
if (rfread((void*)&state, sizeof(state), 1, f) == 1)
{
TheCIA1->SetState(&state);
if (fread((void*)&state, sizeof(state), 1, f) == 1)
if (rfread((void*)&state, sizeof(state), 1, f) == 1)
{
TheCIA2->SetState(&state);
return true;
@@ -470,11 +480,11 @@ bool C64::LoadCIAState(FILE *f)
* Save 1541 GCR state to snapshot
*/
bool C64::Save1541JobState(FILE *f)
bool C64::Save1541JobState(RFILE *f)
{
Job1541State state;
TheJob1541->GetState(&state);
return fwrite((void*)&state, sizeof(state), 1, f) == 1;
return rfwrite((void*)&state, sizeof(state), 1, f) == 1;
}
@@ -482,10 +492,10 @@ bool C64::Save1541JobState(FILE *f)
* Load 1541 GCR state from snapshot
*/
bool C64::Load1541JobState(FILE *f)
bool C64::Load1541JobState(RFILE *f)
{
Job1541State state;
if (fread((void*)&state, sizeof(state), 1, f) == 1)
if (rfread((void*)&state, sizeof(state), 1, f) == 1)
{
TheJob1541->SetState(&state);
return true;
@@ -521,19 +531,19 @@ bool C64::Load1541JobState(FILE *f)
void C64::SaveSnapshot(char *filename)
{
FILE *f;
RFILE *f;
uint8 flags;
uint8 delay;
int stat;
if (!(f = fopen(filename, "wb")))
if (!(f = rfopen(filename, "wb")))
return;
fprintf(f, "%s%c", SNAPSHOT_HEADER, 10);
fputc(0, f); // Version number 0
rfprintf(f, "%s%c", SNAPSHOT_HEADER, 10);
rfputc(0, f); // Version number 0
flags = 0;
if (ThePrefs.Emul1541Proc)
flags |= SNAPSHOT_1541;
fputc(flags, f);
rfputc(flags, f);
SaveVICState(f);
SaveSIDState(f);
SaveCIAState(f);
@@ -549,16 +559,16 @@ void C64::SaveSnapshot(char *filename)
delay++;
}
} while (stat == -1);
fputc(delay, f); // Number of cycles the
rfputc(delay, f); // Number of cycles the
// saved CPUC64 lags behind the previous chips
#else
SaveCPUState(f);
fputc(0, f); // No delay
rfputc(0, f); // No delay
#endif
if (ThePrefs.Emul1541Proc)
{
fwrite(ThePrefs.DrivePath[0], 256, 1, f);
rfwrite(ThePrefs.DrivePath[0], 256, 1, f);
#ifdef FRODO_SC
delay = 0;
do
@@ -569,14 +579,14 @@ void C64::SaveSnapshot(char *filename)
delay++;
}
} while (stat == -1);
fputc(delay, f);
rfputc(delay, f);
#else
Save1541State(f);
fputc(0, f); // No delay
rfputc(0, f); // No delay
#endif
Save1541JobState(f);
}
fclose(f);
rfclose(f);
}
@@ -586,8 +596,8 @@ void C64::SaveSnapshot(char *filename)
bool C64::LoadSnapshot(char *filename)
{
FILE *f;
if ((f = fopen(filename, "rb")))
RFILE *f;
if ((f = rfopen(filename, "rb")))
{
uint8 delay, i;
char Header[] = SNAPSHOT_HEADER;
@@ -597,7 +607,7 @@ bool C64::LoadSnapshot(char *filename)
and so forth utterly fail here. */
while (*b > 32)
{
if ((c = fgetc(f)) != *b++)
if ((c = rfgetc(f)) != *b++)
{
b = NULL;
break;
@@ -613,15 +623,15 @@ bool C64::LoadSnapshot(char *filename)
#endif
while (c != 10)
c = fgetc(f); // Shouldn't be necessary
if (fgetc(f) != 0)
c = rfgetc(f); // Shouldn't be necessary
if (rfgetc(f) != 0)
{
fclose(f);
rfclose(f);
return false;
}
flags = fgetc(f);
flags = rfgetc(f);
#ifndef FRODO_SC
vicptr = ftell(f);
vicptr = rftell(f);
#endif
error |= !LoadVICState(f);
@@ -629,7 +639,7 @@ bool C64::LoadSnapshot(char *filename)
error |= !LoadCIAState(f);
error |= !LoadCPUState(f);
delay = fgetc(f); // Number of cycles the 6510 is ahead of the previous chips
delay = rfgetc(f); // Number of cycles the 6510 is ahead of the previous chips
#ifdef FRODO_SC
// Make the other chips "catch up" with the 6510
for (i=0; i<delay; i++)
@@ -643,7 +653,7 @@ bool C64::LoadSnapshot(char *filename)
{
Prefs *prefs = new Prefs(ThePrefs);
// First switch on emulation
error |= (fread(prefs->DrivePath[0], 256, 1, f)
error |= (rfread(prefs->DrivePath[0], 256, 1, f)
!= 1);
prefs->Emul1541Proc = true;
NewPrefs(prefs);
@@ -653,7 +663,7 @@ bool C64::LoadSnapshot(char *filename)
// Then read the context
error |= !Load1541State(f);
delay = fgetc(f);
delay = rfgetc(f);
// Number of cycles
// the 6502 is ahead of the previous chips
#ifdef FRODO_SC
@@ -679,11 +689,11 @@ bool C64::LoadSnapshot(char *filename)
}
#ifndef FRODO_SC
fseek(f, vicptr, SEEK_SET);
rfseek(f, vicptr, SEEK_SET);
LoadVICState(f); // Load VIC data twice
// in SL (is REALLY necessary sometimes!)
#endif
fclose(f);
rfclose(f);
if (error)
{
@@ -692,7 +702,7 @@ bool C64::LoadSnapshot(char *filename)
}
return true;
}
fclose(f);
rfclose(f);
}
return false;
}
@@ -712,7 +722,6 @@ void C64::c64_ctor1(void)
void C64::c64_ctor2(void)
{
gettimeofday(&tv_start, NULL);
}
+23 -19
View File
@@ -23,14 +23,18 @@
#include <stdio.h>
// Sizes of memory areas
const int C64_RAM_SIZE = 0x10000;
const int COLOR_RAM_SIZE = 0x400;
const int BASIC_ROM_SIZE = 0x2000;
#include <streams/file_stream.h>
/* TODO/FIXME - most if not all the file I/O should eventually be removed */
/* Sizes of memory areas */
const int C64_RAM_SIZE = 0x10000;
const int COLOR_RAM_SIZE = 0x400;
const int BASIC_ROM_SIZE = 0x2000;
const int KERNAL_ROM_SIZE = 0x2000;
const int CHAR_ROM_SIZE = 0x1000;
const int DRIVE_RAM_SIZE = 0x800;
const int DRIVE_ROM_SIZE = 0x4000;
const int CHAR_ROM_SIZE = 0x1000;
const int DRIVE_RAM_SIZE = 0x800;
const int DRIVE_ROM_SIZE = 0x4000;
// false: Frodo, true: FrodoSC
@@ -62,18 +66,18 @@ public:
void SaveRAM(char *filename);
void SaveSnapshot(char *filename);
bool LoadSnapshot(char *filename);
int SaveCPUState(FILE *f);
int Save1541State(FILE *f);
bool Save1541JobState(FILE *f);
bool SaveVICState(FILE *f);
bool SaveSIDState(FILE *f);
bool SaveCIAState(FILE *f);
bool LoadCPUState(FILE *f);
bool Load1541State(FILE *f);
bool Load1541JobState(FILE *f);
bool LoadVICState(FILE *f);
bool LoadSIDState(FILE *f);
bool LoadCIAState(FILE *f);
int SaveCPUState(RFILE *f);
int Save1541State(RFILE *f);
bool Save1541JobState(RFILE *f);
bool SaveVICState(RFILE *f);
bool SaveSIDState(RFILE *f);
bool SaveCIAState(RFILE *f);
bool LoadCPUState(RFILE *f);
bool Load1541State(RFILE *f);
bool Load1541JobState(RFILE *f);
bool LoadVICState(RFILE *f);
bool LoadSIDState(RFILE *f);
bool LoadCIAState(RFILE *f);
uint8 *RAM, *Basic, *Kernal,
*Char, *Color; // C64
+76 -70
View File
@@ -41,6 +41,8 @@
* Sent before the last byte, not after it.
*/
#include <streams/file_stream.h>
#include "sysdeps.h"
#include "IEC.h"
@@ -51,15 +53,15 @@
#include "Display.h"
#include "main.h"
// IEC command codes
/* IEC command codes */
enum
{
CMD_DATA = 0x60, // Data transfer
CMD_CLOSE = 0xe0, // Close channel
CMD_OPEN = 0xf0 // Open channel
CMD_DATA = 0x60, /* Data transfer */
CMD_CLOSE = 0xe0, /* Close channel */
CMD_OPEN = 0xf0 /* Open channel */
};
// IEC ATN codes
/* IEC ATN codes */
enum
{
ATN_LISTEN = 0x20,
@@ -68,38 +70,43 @@ enum
ATN_UNTALK = 0x50
};
/* Forward declarations */
extern "C" {
RFILE* rfopen(const char *path, const char *mode);
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
int64_t rftell(RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
}
/*
* Constructor: Initialize variables
*/
/* Constructor: Initialize variables */
Drive *IEC::create_drive(const char *path)
{
int type;
// Mount host directory
if (IsDirectory(path))
return new FSDrive(this, path);
if (IsDirectory(path))
return new FSDrive(this, path);
// Not a directory, check for mountable file type
if (IsMountableFile(path, type))
{
// Not a directory, check for mountable file type
int type;
if (IsMountableFile(path, type))
{
if (type == FILE_IMAGE)
// Mount disk image
return new ImageDrive(this, path);
// Mount archive type file
return new ArchDrive(this, path);
}
}
if (type == FILE_IMAGE)
// Mount disk image
return new ImageDrive(this, path);
// Mount archive type file
return new ArchDrive(this, path);
}
return NULL;
}
IEC::IEC(C64Display *display) : the_display(display)
{
int i;
// Create drives 8..11
/* Create drives 8..11 */
for (i=0; i<4; i++)
drive[i] = NULL; // Important because UpdateLEDs is called from the drive constructors (via set_error)
drive[i] = NULL; /* Important because UpdateLEDs
is called from the drive
constructors (via set_error) */
if (!ThePrefs.Emul1541Proc)
{
@@ -107,18 +114,17 @@ IEC::IEC(C64Display *display) : the_display(display)
drive[i] = create_drive(ThePrefs.DrivePath[i]);
}
listener_active = talker_active = false;
listener_active = false;
talker_active = false;
listening = false;
}
/*
* Destructor: Delete drives
*/
/* Destructor: Delete drives */
IEC::~IEC()
{
for (int i=0; i<4; i++)
int i;
for (i=0; i<4; i++)
delete drive[i];
}
@@ -129,8 +135,9 @@ IEC::~IEC()
void IEC::Reset(void)
{
for (int i=0; i<4; i++)
if (drive[i] != NULL && drive[i]->Ready)
int i;
for (i = 0; i < 4; i++)
if (drive[i] && drive[i]->Ready)
drive[i]->Reset();
UpdateLEDs();
@@ -145,13 +152,18 @@ void IEC::Reset(void)
void IEC::NewPrefs(Prefs *prefs)
{
// Delete and recreate all changed drives
for (int i=0; i<4; i++)
int i;
/* Delete and recreate all changed drives */
for (i=0; i<4; i++)
{
if (strcmp(ThePrefs.DrivePath[i], prefs->DrivePath[i]) || ThePrefs.Emul1541Proc != prefs->Emul1541Proc)
if ( strcmp(ThePrefs.DrivePath[i],
prefs->DrivePath[i])
|| ThePrefs.Emul1541Proc != prefs->Emul1541Proc)
{
delete drive[i];
drive[i] = NULL; // Important because UpdateLEDs is called from drive constructors (via set_error())
drive[i] = NULL; /* Important because UpdateLEDs
is called from drive
constructors (via set_error()) */
if (!prefs->Emul1541Proc)
drive[i] = create_drive(prefs->DrivePath[i]);
}
@@ -161,21 +173,20 @@ void IEC::NewPrefs(Prefs *prefs)
}
/*
* Update drive LED display
*/
/* Update drive LED display */
void IEC::UpdateLEDs(void)
{
if (drive[0] != NULL && drive[1] != NULL && drive[2] != NULL && drive[3] != NULL)
the_display->UpdateLEDs(drive[0]->LED, drive[1]->LED, drive[2]->LED, drive[3]->LED);
if (
drive[0] != NULL
&& drive[1] != NULL
&& drive[2] != NULL
&& drive[3] != NULL)
the_display->UpdateLEDs(drive[0]->LED,
drive[1]->LED, drive[2]->LED, drive[3]->LED);
}
/*
* Output one byte
*/
/* Output one byte */
uint8 IEC::Out(uint8 byte, bool eoi)
{
if (listener_active)
@@ -189,10 +200,7 @@ uint8 IEC::Out(uint8 byte, bool eoi)
}
/*
* Output one byte with ATN (Talk/Listen/Untalk/Unlisten)
*/
/* Output one byte with ATN (Talk/Listen/Untalk/Unlisten) */
uint8 IEC::OutATN(uint8 byte)
{
received_cmd = sec_addr = 0; // Command is sent with secondary address
@@ -393,7 +401,6 @@ uint8 IEC::sec_talk(void)
return ST_OK;
}
/*
* Byte after Open command: Store character in file name, open file on EOI
*/
@@ -417,11 +424,7 @@ uint8 IEC::open_out(uint8 byte, bool eoi)
return ST_OK;
}
/*
* Write byte to channel
*/
/* Write byte to channel */
uint8 IEC::data_out(uint8 byte, bool eoi)
{
return listener->Write(sec_addr, byte, eoi);
@@ -493,8 +496,8 @@ void Drive::set_error(int error, int track, int sector)
{
// Write error message to buffer
sprintf(error_buf, Errors_1541[error], track, sector);
error_ptr = error_buf;
error_len = strlen(error_buf);
error_ptr = error_buf;
error_len = strlen(error_buf);
current_error = error;
// Set drive condition
@@ -515,6 +518,7 @@ void Drive::set_error(int error, int track, int sector)
void Drive::parse_file_name(const uint8 *src, int src_len, uint8 *dest, int &dest_len, int &mode, int &type, int &rec_len, bool convert_charset)
{
uint8 *q;
// If the string contains a ':', the file name starts after that
const uint8 *p = (const uint8 *)memchr(src, ':', src_len);
if (p)
@@ -527,7 +531,7 @@ void Drive::parse_file_name(const uint8 *src, int src_len, uint8 *dest, int &des
// Transfer file name upto ','
dest_len = 0;
uint8 *q = dest;
q = dest;
while (*p != ',' && src_len-- > 0)
{
if (convert_charset)
@@ -940,17 +944,18 @@ void petscii2ascii(char *dest, const uint8 *src, int n)
bool IsMountableFile(const char *path, int &type)
{
// Read header and determine file size
int64_t size;
/* Read header and determine file size */
uint8 header[64];
memset(header, 0, sizeof(header));
FILE *f = fopen(path, "rb");
RFILE *f = rfopen(path, "rb");
if (!f)
return false;
fseek(f, 0, SEEK_END);
long size = ftell(f);
fseek(f, 0, SEEK_SET);
fread(header, 1, sizeof(header), f);
fclose(f);
rfseek(f, 0, SEEK_END);
size = rftell(f);
rfseek(f, 0, SEEK_SET);
rfread(header, 1, sizeof(header), f);
rfclose(f);
if (IsImageFile(path, header, size))
{
@@ -967,11 +972,12 @@ bool IsMountableFile(const char *path, int &type)
/*
* Read directory of mountable disk image or archive file into c64_dir_entry vector,
* Read directory of mountable disk image
* or archive file into c64_dir_entry vector,
* returns false on error
*/
bool ReadDirectory(const char *path, int type, std::vector<c64_dir_entry> &vec)
bool ReadDirectory(const char *path, int type,
std::vector<c64_dir_entry> &vec)
{
vec.clear();
switch (type)
+37 -45
View File
@@ -26,6 +26,14 @@
#include <unistd.h> /* getcwd */
#endif
#include <sys/stat.h>
#include <file/file_path.h>
#include <streams/file_stream.h>
#include "Version.h"
#include "core-log.h"
#ifndef NO_LIBCO
#include "libco.h"
#endif
#include "sysdeps.h"
@@ -34,12 +42,28 @@
#include "Display.h"
#include "Prefs.h"
// Global variables
C64 *TheC64 = NULL; // Global C64 object
char AppDirPath[1024]; // Path of application directory
/* Forward declarations */
int init_graphics(void);
extern "C" {
RFILE* rfopen(const char *path, const char *mode);
int64_t rftell(RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
}
#ifndef NO_LIBCO
extern cothread_t mainThread;
extern cothread_t emuThread;
#endif
// ROM file names
/* Global variables */
C64 *TheC64 = NULL; /* Global C64 object */
char AppDirPath[1024]; /* Path of application directory */
char Frodo::device_path[256] = "";
Frodo *the_app;
/* ROM file names */
#ifndef DATADIR
#define DATADIR
#endif
@@ -49,25 +73,22 @@ char AppDirPath[1024]; // Path of application directory
#define CHAR_ROM_FILE DATADIR "Char ROM"
#define DRIVE_ROM_FILE DATADIR "1541 ROM"
// Builtin ROMs
/* Builtin ROMs */
#include "Basic_ROM.h"
#include "Kernal_ROM.h"
#include "Char_ROM.h"
#include "1541_ROM.h"
/*
* Load C64 ROM files
*/
/* Load C64 ROM files */
bool Frodo::load_rom(const char *which, const char *path,
uint8 *where, size_t size, const uint8 *builtin)
{
FILE *f = fopen(path, "rb");
RFILE *f = rfopen(path, "rb");
if (f)
{
size_t actual = fread(where, 1, size, f);
fclose(f);
size_t actual = (size_t)rfread(where, 1, size, f);
rfclose(f);
if (actual == size)
return true;
}
@@ -93,26 +114,6 @@ void Frodo::load_rom_files()
memcpy(TheC64->ROM1541, builtin_drive_rom, DRIVE_ROM_SIZE);
}
/*
* main_x.i - Main program, X specific stuff
*
* Frodo (C) 1994-1997,2002 Christian Bauer
*/
#include "Version.h"
#include "core-log.h"
#ifndef NO_LIBCO
#include "libco.h"
extern cothread_t mainThread;
extern cothread_t emuThread;
#endif
extern int init_graphics(void);
Frodo *the_app;
char Frodo::device_path[256] = "";
/*
* Create application object and start it
@@ -154,20 +155,14 @@ Frodo::Frodo()
}
/*
* Process command line arguments
*/
/* Process command line arguments */
void Frodo::ArgvReceived(int argc, char **argv)
{
if (argc == 2)
strncpy(device_path, argv[1], 255);
}
/*
* Arguments processed, run emulation
*/
/* Arguments processed, run emulation */
void Frodo::ReadyToRun(void)
{
#if defined (__vita__) || defined(__psp__)
@@ -194,12 +189,9 @@ void Frodo::ReadyToRun(void)
#endif
}
/*
* Determine whether path name refers to a directory
*/
/* Determine whether path name refers to a directory */
bool IsDirectory(const char *path)
{
struct stat st;
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
return path_is_directory(path);
}
+23 -151
View File
@@ -23,20 +23,24 @@
#include <errno.h>
#include <string.h>
#include <zlib.h>
#include <file/file_path.h>
#include <streams/file_stream.h>
#include "utype.h"
#if defined(WIN32) && !defined(_VCWIN_)
#include <winsock2.h>
#endif
#include "dialog.h"
#include "file.h"
#include "zip.h"
#if defined(WIN32)
#define ftello ftell
#endif
/* Forward declarations */
extern "C" {
RFILE* rfopen(const char *path, const char *mode);
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
int64_t rftell(RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
}
/*-----------------------------------------------------------------------*/
/**
@@ -100,7 +104,7 @@ static bool File_IsRootFileName(const char *pszFileName)
if (pszFileName[0] == PATHSEP)
return true;
#ifdef WIN32
#ifdef _WIN32
if (pszFileName[1] == ':')
return true;
#endif
@@ -172,10 +176,9 @@ Uint8 *File_Read(const char *pszFileName, long *pFileSize, const char * const pp
/* Is it a gzipped file? */
if (File_DoesFileExtensionMatch(filepath, ".gz"))
{
gzFile hGzFile;
/* Open and read gzipped file */
hGzFile = gzopen(filepath, "rb");
if (hGzFile != NULL)
gzFile hGzFile = gzopen(filepath, "rb");
if (hGzFile)
{
/* Find size of file: */
do
@@ -203,21 +206,19 @@ Uint8 *File_Read(const char *pszFileName, long *pFileSize, const char * const pp
}
else /* It is a normal file */
{
FILE *hDiskFile;
/* Open and read normal file */
hDiskFile = fopen(filepath, "rb");
if (hDiskFile != NULL)
RFILE *hDiskFile = rfopen(filepath, "rb");
if (hDiskFile)
{
/* Find size of file: */
fseek(hDiskFile, 0, SEEK_END);
FileSize = ftell(hDiskFile);
fseek(hDiskFile, 0, SEEK_SET);
rfseek(hDiskFile, 0, SEEK_END);
FileSize = rftell(hDiskFile);
rfseek(hDiskFile, 0, SEEK_SET);
/* Read in... */
pFile = (Uint8*)malloc(FileSize);
if (pFile)
FileSize = fread(pFile, 1, FileSize, hDiskFile);
fclose(hDiskFile);
FileSize = rfread(pFile, 1, FileSize, hDiskFile);
rfclose(hDiskFile);
}
}
free(filepath);
@@ -229,79 +230,6 @@ Uint8 *File_Read(const char *pszFileName, long *pFileSize, const char * const pp
return pFile; /* Return to where read in/allocated */
}
/*-----------------------------------------------------------------------*/
/**
* Save file to disk, return FALSE if errors
*/
bool File_Save(const char *pszFileName, const Uint8 *pAddress, size_t Size, bool bQueryOverwrite)
{
bool bRet = false;
/* Check if need to ask user if to overwrite */
if (bQueryOverwrite)
{
/* If file exists, ask if OK to overwrite */
if (!File_QueryOverwrite(pszFileName))
return false;
}
/* Normal file or gzipped file? */
if (File_DoesFileExtensionMatch(pszFileName, ".gz"))
{
gzFile hGzFile;
/* Create a gzipped file: */
hGzFile = gzopen(pszFileName, "wb");
if (hGzFile != NULL)
{
/* Write data, set success flag */
if (gzwrite(hGzFile, pAddress, Size) == (int)Size)
bRet = true;
gzclose(hGzFile);
}
}
else
{
FILE *hDiskFile;
/* Create a normal file: */
hDiskFile = fopen(pszFileName, "wb");
if (hDiskFile != NULL)
{
/* Write data, set success flag */
if (fwrite(pAddress, 1, Size, hDiskFile) == Size)
bRet = true;
fclose(hDiskFile);
}
}
return bRet;
}
/*-----------------------------------------------------------------------*/
/**
* Return size of file, -1 if error
*/
off_t File_Length(const char *pszFileName)
{
off_t FileSize;
FILE *hDiskFile = fopen(pszFileName, "rb");
if (hDiskFile!=NULL)
{
fseek(hDiskFile, 0, SEEK_END);
FileSize = ftello(hDiskFile);
fseek(hDiskFile, 0, SEEK_SET);
fclose(hDiskFile);
return FileSize;
}
return -1;
}
/*-----------------------------------------------------------------------*/
/**
* Return TRUE if file exists, is readable or writable at least and is not
@@ -309,58 +237,18 @@ off_t File_Length(const char *pszFileName)
*/
bool File_Exists(const char *filename)
{
#ifdef RETRO
if( access( filename, F_OK ) != -1 )
return true;
return false;
#else
struct stat buf;
if ( stat(filename, &buf) == 0
&& (buf.st_mode & (S_IRUSR|S_IWUSR))
&& !(buf.st_mode & S_IFDIR))
{
/* file points to user readable regular file */
return true;
}
return false;
#endif
return path_is_valid(filename);
}
/*-----------------------------------------------------------------------*/
/**
* Return TRUE if directory exists.
*/
bool File_DirExists(const char *path)
{
struct stat buf;
return (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode));
return path_is_directory(path);
}
/*-----------------------------------------------------------------------*/
/**
* Find if file exists, and if so ask user if OK to overwrite
*/
bool File_QueryOverwrite(const char *pszFileName)
{
const char *fmt = NULL;
char *szString = NULL;
bool ret = true;
/* Try and find if file exists */
if (File_Exists(pszFileName))
{
fmt = "File '%s' exists, overwrite?";
/* File does exist, are we OK to overwrite? */
szString = (char*)malloc(strlen(pszFileName) + strlen(fmt) + 1);
sprintf(szString, fmt, pszFileName);
ret = DlgAlert_Query(szString);
free(szString);
}
return ret;
}
/*-----------------------------------------------------------------------*/
/**
* Try filename with various extensions and check if file exists
@@ -503,22 +391,6 @@ void File_ShrinkName(char *pDestFileName, const char *pSrcFileName, int maxlen)
}
/*-----------------------------------------------------------------------*/
/**
* Wrapper for File_MakeAbsoluteName() which special-cases stdin/out/err
* named files and empty file name. The given buffer should be opened
* with File_Open() and closed with File_Close() if this function is used!
* (On Linux one can use /dev/stdout etc, this is intended for other OSes)
*/
void File_MakeAbsoluteSpecialName(char *path)
{
if (path[0] &&
strcmp(path, "stdin") != 0 &&
strcmp(path, "stdout") != 0 &&
strcmp(path, "stderr") != 0)
File_MakeAbsoluteName(path);
}
/*-----------------------------------------------------------------------*/
/**
* Create a clean absolute file name from a (possibly) relative file name.
-4
View File
@@ -20,16 +20,12 @@ extern bool File_DoesFileExtensionMatch(const char *pszFileName, const char *psz
extern const char *File_RemoveFileNameDrive(const char *pszFileName);
extern bool File_DoesFileNameEndWithSlash(char *pszFileName);
extern Uint8 *File_Read(const char *pszFileName, long *pFileSize, const char * const ppszExts[]);
extern bool File_Save(const char *pszFileName, const Uint8 *pAddress, size_t Size, bool bQueryOverwrite);
extern off_t File_Length(const char *pszFileName);
extern bool File_Exists(const char *pszFileName);
extern bool File_DirExists(const char *psDirName);
extern bool File_QueryOverwrite(const char *pszFileName);
extern char* File_FindPossibleExtFileName(const char *pszFileName,const char * const ppszExts[]);
extern void File_SplitPath(const char *pSrcFileName, char *pDir, char *pName, char *Ext);
extern char* File_MakePath(const char *pDir, const char *pName, const char *pExt);
extern void File_ShrinkName(char *pDestFileName, const char *pSrcFileName, int maxlen);
extern void File_MakeAbsoluteSpecialName(char *pszFileName);
extern void File_MakeAbsoluteName(char *pszFileName);
extern void File_MakeValidPathName(char *pPathName);
extern void File_PathShorten(char *path, int dirs);