mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-23 11:31:41 +00:00
Move disk compression routines to disk module
* Makes these routines useable from alternate interfaces, (including tests)
This commit is contained in:
parent
df668f0d6a
commit
e54ce95389
111
src/disk.c
111
src/disk.c
@ -62,6 +62,37 @@ static int translate_table_6[256] = /* Translation table */
|
||||
0x80, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
|
||||
};
|
||||
|
||||
static void cut_gz(char *name) {
|
||||
char *p = name + strlen(name) - 1;
|
||||
p--;
|
||||
p--;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static bool is_gz(const char * const name) {
|
||||
size_t len = strlen( name );
|
||||
|
||||
if (len > 3) {
|
||||
return (strcmp(name+len-3, ".gz") == 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_nib(const char * const name) {
|
||||
size_t len = strlen( name );
|
||||
|
||||
if (is_gz(name)) {
|
||||
len -= 3;
|
||||
}
|
||||
|
||||
if (!strncmp(name + len - 4, ".nib", 4)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_init_6()
|
||||
------------------------------------------------------------------------- */
|
||||
@ -81,6 +112,20 @@ void c_init_6()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INTERFACE_CLASSIC
|
||||
#define ZLIB_SUBMENU_H 7
|
||||
#define ZLIB_SUBMENU_W 40
|
||||
static char zlibmenu[ZLIB_SUBMENU_H][ZLIB_SUBMENU_W+1] =
|
||||
//1. 5. 10. 15. 20. 25. 30. 35. 40.
|
||||
{ "||||||||||||||||||||||||||||||||||||||||",
|
||||
"| |",
|
||||
"| An error occurred when attempting to |",
|
||||
"| handle a compressed disk image: |",
|
||||
"| |",
|
||||
"| |",
|
||||
"||||||||||||||||||||||||||||||||||||||||" };
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_eject_6() - ejects/gzips image file
|
||||
------------------------------------------------------------------------- */
|
||||
@ -88,18 +133,6 @@ void c_init_6()
|
||||
void c_eject_6(int drive) {
|
||||
int ch = -1;
|
||||
|
||||
#define ZLIB_SUBMENU_H 7
|
||||
#define ZLIB_SUBMENU_W 40
|
||||
char zlibmenu[ZLIB_SUBMENU_H][ZLIB_SUBMENU_W+1] =
|
||||
//1. 5. 10. 15. 20. 25. 30. 35. 40.
|
||||
{ "||||||||||||||||||||||||||||||||||||||||",
|
||||
"| |",
|
||||
"| An error occurred when attempting to |",
|
||||
"| compress a disk image: |",
|
||||
"| |",
|
||||
"| |",
|
||||
"||||||||||||||||||||||||||||||||||||||||" };
|
||||
|
||||
if (disk6.disk[drive].compressed)
|
||||
{
|
||||
// foo.dsk -> foo.dsk.gz
|
||||
@ -132,19 +165,46 @@ void c_eject_6(int drive) {
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_new_diskette_6( int drive, char *filename, Tr cmpr, Tr nib )
|
||||
inserts a new disk image into the appropriate drive. assumes
|
||||
privileged user level on entry, sets to the user when using disks.
|
||||
return 1 if we can't open an image file for reading.
|
||||
c_new_diskette_6()
|
||||
inserts a new disk image into the appropriate drive.
|
||||
return 0 on success
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int c_new_diskette_6(int drive, char *file_name, int cmpr, int nib, int force) {
|
||||
int c_new_diskette_6(int drive, const char * const raw_file_name, int force) {
|
||||
struct stat buf;
|
||||
int ch = -1;
|
||||
|
||||
/* uncompress the gziped disk */
|
||||
char *file_name = strdup(raw_file_name);
|
||||
if (is_gz(file_name))
|
||||
{
|
||||
const char* const err = inf(file_name); // foo.dsk.gz -> foo.dsk
|
||||
if (err)
|
||||
{
|
||||
ERRLOG("OOPS: An error occurred when attempting to inflate/load a disk image : %s", err);
|
||||
#ifdef INTERFACE_CLASSIC
|
||||
snprintf(&zlibmenu[4][2], 37, "%s", err);
|
||||
c_interface_print_submenu_centered(zlibmenu[0], ZLIB_SUBMENU_W, ZLIB_SUBMENU_H);
|
||||
while ((ch = c_mygetch(1)) == -1) {
|
||||
// ...
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
if (unlink(file_name)) // temporarily remove .gz file
|
||||
{
|
||||
ERRLOG("OOPS, cannot unlink %s", file_name);
|
||||
}
|
||||
|
||||
cut_gz(file_name);
|
||||
}
|
||||
|
||||
strcpy(disk6.disk[drive].file_name, file_name);
|
||||
disk6.disk[drive].file_name[1023]='\0';
|
||||
disk6.disk[drive].compressed = cmpr;
|
||||
disk6.disk[drive].nibblized = nib;
|
||||
disk6.disk[drive].compressed = true;// always using gz
|
||||
disk6.disk[drive].nibblized = is_nib(file_name);
|
||||
free(file_name);
|
||||
file_name = NULL;
|
||||
|
||||
if (disk6.disk[drive].fp)
|
||||
{
|
||||
fclose(disk6.disk[drive].fp);
|
||||
@ -164,13 +224,13 @@ int c_new_diskette_6(int drive, char *file_name, int cmpr, int nib, int force) {
|
||||
if (!force)
|
||||
{
|
||||
disk6.disk[drive].fp = fopen(disk6.disk[drive].file_name, "r+");
|
||||
disk6.disk[drive].is_protected = 0;
|
||||
disk6.disk[drive].is_protected = false;
|
||||
}
|
||||
|
||||
if ((disk6.disk[drive].fp == NULL) || (force))
|
||||
{
|
||||
disk6.disk[drive].fp = fopen(disk6.disk[drive].file_name, "r");
|
||||
disk6.disk[drive].is_protected = 1; /* disk is write protected! */
|
||||
disk6.disk[drive].is_protected = true; /* disk is write protected! */
|
||||
}
|
||||
|
||||
if (disk6.disk[drive].fp == NULL)
|
||||
@ -204,7 +264,7 @@ unsigned char c_read_nibblized_6_6()
|
||||
if (disk6.disk[disk6.drive].phase_change)
|
||||
{
|
||||
fseek(disk6.disk[disk6.drive].fp, PHASE_BYTES * disk6.disk[disk6.drive].phase, SEEK_SET);
|
||||
disk6.disk[disk6.drive].phase_change = 0;
|
||||
disk6.disk[disk6.drive].phase_change = false;
|
||||
}
|
||||
|
||||
disk6.disk_byte = fgetc(disk6.disk[disk6.drive].fp);
|
||||
@ -402,7 +462,7 @@ void c_write_nibblized_6_6()
|
||||
if (disk6.disk[disk6.drive].phase_change)
|
||||
{
|
||||
fseek(disk6.disk[disk6.drive].fp, PHASE_BYTES * disk6.disk[disk6.drive].phase, SEEK_SET);
|
||||
disk6.disk[disk6.drive].phase_change = 0;
|
||||
disk6.disk[disk6.drive].phase_change = false;
|
||||
}
|
||||
|
||||
fputc(disk6.disk_byte, disk6.disk[disk6.drive].fp);
|
||||
@ -585,7 +645,6 @@ GLUE_C_READ(disk_read_byte)
|
||||
if (disk6.disk[disk6.drive].fp == NULL)
|
||||
{
|
||||
return 0xFF; /* Return FF if there is no disk in drive */
|
||||
|
||||
}
|
||||
|
||||
if (disk6.motor) /* Motor turned on? */
|
||||
@ -636,7 +695,7 @@ GLUE_C_READ(disk_read_phase)
|
||||
disk6.disk[disk6.drive].phase=69;
|
||||
}
|
||||
|
||||
disk6.disk[disk6.drive].phase_change = 1;
|
||||
disk6.disk[disk6.drive].phase_change = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
18
src/disk.h
18
src/disk.h
@ -23,10 +23,10 @@
|
||||
struct diskette
|
||||
{
|
||||
char file_name[1024];
|
||||
int compressed;
|
||||
int nibblized;
|
||||
int is_protected;
|
||||
int phase_change;
|
||||
bool compressed;
|
||||
bool nibblized;
|
||||
bool is_protected;
|
||||
bool phase_change;
|
||||
int sector;
|
||||
long file_size;
|
||||
int phase;
|
||||
@ -50,12 +50,12 @@ struct drive
|
||||
|
||||
extern struct drive disk6;
|
||||
|
||||
void c_init_6();
|
||||
int c_new_diskette_6(int, char*, int, int, int);
|
||||
void c_eject_6(int);
|
||||
void disk_io_initialize(unsigned int slot);
|
||||
void c_init_6();
|
||||
int c_new_diskette_6(int drive, const char * const file_name, int force);
|
||||
void c_eject_6(int drive);
|
||||
void disk_io_initialize(unsigned int slot);
|
||||
|
||||
void disk_read_nop(),
|
||||
void disk_read_nop(),
|
||||
disk_read_phase(),
|
||||
disk_read_motor_off(),
|
||||
disk_read_motor_on(),
|
||||
|
102
src/interface.c
102
src/interface.c
@ -257,57 +257,7 @@ static int c_interface_cut_name(char *name)
|
||||
return is_gz;
|
||||
}
|
||||
|
||||
static void c_interface_cut_gz(char *name)
|
||||
{
|
||||
char *p = name + strlen(name) - 1;
|
||||
|
||||
p--;
|
||||
p--;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
#define GZ_EXT ".gz"
|
||||
#define GZ_EXT_LEN 3
|
||||
#define DISK_EXT1 ".dsk"
|
||||
#define DISK_EXT2 ".nib"
|
||||
#define DISK_EXT3 ".do"
|
||||
#define DISK_EXT_LEN1 4
|
||||
#define DISK_EXT_LEN2 4
|
||||
#define DISK_EXT_LEN3 3
|
||||
|
||||
/* does name end with ".gz" ? */
|
||||
static int c_interface_is_gz(const char *name)
|
||||
{
|
||||
size_t len = strlen( name );
|
||||
|
||||
if (len > GZ_EXT_LEN) /* shouldn't have a file called ".gz"... */
|
||||
{ /*name += len - GZ_EXT_LEN;*/
|
||||
return ((strcmp(name+len-GZ_EXT_LEN, GZ_EXT) == 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* does name end with ".nib{.gz}" */
|
||||
static int c_interface_is_nibblized(const char *name)
|
||||
{
|
||||
size_t len = strlen( name );
|
||||
|
||||
if (c_interface_is_gz(name))
|
||||
{
|
||||
len -= GZ_EXT_LEN;
|
||||
}
|
||||
|
||||
if (!strncmp(name + len - DISK_EXT_LEN2, DISK_EXT2, DISK_EXT_LEN2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int c_interface_disk_select(const struct dirent *e)
|
||||
static int disk_select(const struct dirent *e)
|
||||
{
|
||||
static char cmp[ DISKSIZE ];
|
||||
size_t len;
|
||||
@ -334,24 +284,24 @@ static int c_interface_disk_select(const struct dirent *e)
|
||||
p = e->d_name;
|
||||
len = strlen(p);
|
||||
|
||||
if (len > GZ_EXT_LEN && (!strcmp(p + len - GZ_EXT_LEN, GZ_EXT)))
|
||||
if (len > 3 && (!strcmp(p + len - 3, ".gz")))
|
||||
{
|
||||
len -= GZ_EXT_LEN;
|
||||
len -= 3;
|
||||
}
|
||||
|
||||
if (!strncmp(p + len - DISK_EXT_LEN1, DISK_EXT1, DISK_EXT_LEN1))
|
||||
if (!strncmp(p + len - 4, ".dsk", 4))
|
||||
{
|
||||
return 1; // .dsk
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(p + len - DISK_EXT_LEN2, DISK_EXT2, DISK_EXT_LEN2))
|
||||
if (!strncmp(p + len - 4, ".nib", 4))
|
||||
{
|
||||
return 1; // .nib
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(p + len - DISK_EXT_LEN3, DISK_EXT3, DISK_EXT_LEN3))
|
||||
if (!strncmp(p + len - 3, ".do", 3))
|
||||
{
|
||||
return 1; // .do
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -449,7 +399,7 @@ void c_interface_select_diskette( int drive )
|
||||
while ((ch = c_mygetch(1)) == -1) { }
|
||||
|
||||
/* set to users privilege level for directory access */
|
||||
entries = scandir(disk_path, &namelist, c_interface_disk_select, alphasort);
|
||||
entries = scandir(disk_path, &namelist, disk_select, alphasort);
|
||||
|
||||
if (entries <= 0)
|
||||
{
|
||||
@ -613,13 +563,9 @@ void c_interface_select_diskette( int drive )
|
||||
/* reopen disk, forcing write enabled */
|
||||
if (toupper(ch) == 'W')
|
||||
{
|
||||
if (c_new_diskette_6(
|
||||
drive,
|
||||
temp,
|
||||
disk6.disk[drive].compressed,
|
||||
disk6.disk[drive].nibblized, 0))
|
||||
if (c_new_diskette_6(drive, temp, 0))
|
||||
{
|
||||
DISKERR_SHOWERR("Disk is read and write protected");
|
||||
ERRLOG("Problem loading readonly disk image");
|
||||
c_interface_print_screen( screen );
|
||||
continue;
|
||||
}
|
||||
@ -666,32 +612,12 @@ void c_interface_select_diskette( int drive )
|
||||
break;
|
||||
}
|
||||
|
||||
/* uncompress the gziped disk */
|
||||
if (c_interface_is_gz(temp))
|
||||
{
|
||||
const char* const err = inf(temp); // foo.dsk.gz -> foo.dsk
|
||||
if (err)
|
||||
{
|
||||
DISKERR_SHOWERR(err);
|
||||
c_interface_print_screen( screen );
|
||||
continue;
|
||||
}
|
||||
if (unlink(temp)) // temporarily remove .gz file
|
||||
{
|
||||
ERRLOG("OOPS, cannot unlink %s", temp);
|
||||
}
|
||||
|
||||
c_interface_cut_gz(temp);
|
||||
}
|
||||
|
||||
c_eject_6(drive);
|
||||
c_interface_print_screen( screen );
|
||||
|
||||
if (c_new_diskette_6(
|
||||
drive, temp, 1, c_interface_is_nibblized(temp),
|
||||
(toupper(ch) != 'W')))
|
||||
if (c_new_diskette_6(drive, temp, (toupper(ch) != 'W')))
|
||||
{
|
||||
DISKERR_SHOWERR("Disk is read and write protected");
|
||||
ERRLOG("Problem loading disk image");
|
||||
c_interface_print_screen( screen );
|
||||
continue;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user