mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-15 09:30:16 +00:00
Refactor to load whole disk image into memory
This commit is contained in:
parent
b496d771f6
commit
d46a62a4dd
59
src/disk.c
59
src/disk.c
@ -29,6 +29,9 @@ extern uint8_t slot6_rom[256];
|
||||
|
||||
drive_t disk6;
|
||||
|
||||
static uint8_t disk_a[NIB_SIZE] = { 0 };
|
||||
static uint8_t disk_b[NIB_SIZE] = { 0 };
|
||||
|
||||
static int stepper_phases = 0; // state bits for stepper magnet phases 0-3
|
||||
static int skew_table_6_po[16] = { 0x00,0x08,0x01,0x09,0x02,0x0A,0x03,0x0B, 0x04,0x0C,0x05,0x0D,0x06,0x0E,0x07,0x0F }; // ProDOS order
|
||||
static int skew_table_6_do[16] = { 0x00,0x07,0x0E,0x06,0x0D,0x05,0x0C,0x04, 0x0B,0x03,0x0A,0x02,0x09,0x01,0x08,0x0F }; // DOS order
|
||||
@ -410,6 +413,7 @@ static void denibblize_track(const uint8_t * const src, int drive, uint8_t * con
|
||||
++offset;
|
||||
if (offset >= disk6.disk[drive].track_width) {
|
||||
offset = 0;
|
||||
LOG("WARNING : wrapping trackimage ... trk:%d sct:%d [0]:0x%02X", (disk6.disk[drive].phase >> 1), sector, trackimage[offset]);
|
||||
}
|
||||
}
|
||||
assert(sector >= 0 && sector < 16 && "invalid previous nibblization");
|
||||
@ -545,14 +549,21 @@ GLUE_C_READ(disk_read_write_byte)
|
||||
|
||||
if (!disk6.disk[disk6.drive].track_valid) {
|
||||
assert(!disk6.disk[disk6.drive].track_dirty);
|
||||
if (!load_track_data(disk6.drive, disk6.disk[disk6.drive].track_image)) {
|
||||
ERRLOG("OOPS, problem loading track data");
|
||||
// TODO FIXME ... methinks we shouldn't need to reload, but :
|
||||
// * testing shows different intermediate results (SIXBITNIBS, etc)
|
||||
// * could be instability between the {de,}nibblize routines
|
||||
const uintptr_t niboff = NIB_TRACK_SIZE * (disk6.disk[disk6.drive].phase >> 1);
|
||||
size_t track_width = load_track_data(disk6.drive, disk6.disk[disk6.drive].whole_image+niboff);
|
||||
if (track_width != disk6.disk[disk6.drive].track_width) {
|
||||
////ERRLOG_THROTTLE("OOPS, problem loading track data");
|
||||
break;
|
||||
}
|
||||
disk6.disk[disk6.drive].track_valid = true;
|
||||
disk6.disk[disk6.drive].run_byte = 0;
|
||||
}
|
||||
|
||||
uintptr_t track_idx = NIB_TRACK_SIZE * (disk6.disk[disk6.drive].phase >> 1);
|
||||
track_idx += disk6.disk[disk6.drive].run_byte;
|
||||
if (disk6.ddrw) {
|
||||
if (disk6.disk[disk6.drive].is_protected) {
|
||||
value = 0x00;
|
||||
@ -570,7 +581,7 @@ GLUE_C_READ(disk_read_write_byte)
|
||||
fprintf(test_write_fp, "%02X", disk6.disk_byte);
|
||||
}
|
||||
#endif
|
||||
disk6.disk[disk6.drive].track_image[disk6.disk[disk6.drive].run_byte] = disk6.disk_byte;
|
||||
disk6.disk[disk6.drive].whole_image[track_idx] = disk6.disk_byte;
|
||||
disk6.disk[disk6.drive].track_dirty = true;
|
||||
} else {
|
||||
|
||||
@ -584,7 +595,7 @@ GLUE_C_READ(disk_read_write_byte)
|
||||
}
|
||||
}
|
||||
|
||||
value = disk6.disk[disk6.drive].track_image[disk6.disk[disk6.drive].run_byte];
|
||||
value = disk6.disk[disk6.drive].whole_image[track_idx];
|
||||
#if DISK_TRACING
|
||||
if (test_read_fp) {
|
||||
fprintf(test_read_fp, "%02X", value);
|
||||
@ -652,7 +663,8 @@ GLUE_C_READ(disk_read_phase)
|
||||
|
||||
if (direction) {
|
||||
if (disk6.disk[disk6.drive].track_dirty) {
|
||||
save_track_data(disk6.disk[disk6.drive].track_image, disk6.drive);
|
||||
const uintptr_t niboff = NIB_TRACK_SIZE * (disk6.disk[disk6.drive].phase >> 1);
|
||||
save_track_data(disk6.disk[disk6.drive].whole_image+niboff, disk6.drive);
|
||||
}
|
||||
disk6.disk[disk6.drive].track_valid = false;
|
||||
disk6.disk[disk6.drive].phase += direction;
|
||||
@ -759,6 +771,7 @@ void disk6_init(void) {
|
||||
|
||||
disk6.disk[0].phase = disk6.disk[1].phase = 0;
|
||||
disk6.disk[0].track_valid = disk6.disk[1].track_valid = 0;
|
||||
disk6.disk[0].track_dirty = disk6.disk[1].track_dirty = 0;
|
||||
disk6.motor_time = (struct timespec){ 0 };
|
||||
disk6.motor_off = 1;
|
||||
disk6.drive = 0;
|
||||
@ -847,6 +860,39 @@ const char *disk6_insert(int drive, const char * const raw_file_name, int readon
|
||||
break;
|
||||
}
|
||||
|
||||
// read entire disk image into memory
|
||||
disk6.disk[drive].whole_image = (drive==0) ? &disk_a[0] : &disk_b[0];
|
||||
disk6.disk[drive].track_width = 0;
|
||||
if (disk6.disk[drive].nibblized) {
|
||||
disk6.disk[drive].track_width = NIB_TRACK_SIZE;
|
||||
}
|
||||
|
||||
for (unsigned int trk=0, off=0; trk<NUM_TRACKS; trk++, off+=NIB_TRACK_SIZE) {
|
||||
disk6.disk[drive].phase = (trk<<1); // HACK : load_track_data()/nibblize_track() expects this set properly
|
||||
size_t track_width = load_track_data(drive, disk6.disk[drive].whole_image+off);
|
||||
if (disk6.disk[drive].nibblized) {
|
||||
assert(track_width == NIB_TRACK_SIZE);
|
||||
} else {
|
||||
assert(track_width <= NIB_TRACK_SIZE);
|
||||
#if CONFORMANT_TRACKS
|
||||
if (track_width != NI2_TRACK_SIZE) {
|
||||
ERRLOG("Invalid dsk image creation...");
|
||||
}
|
||||
#endif
|
||||
if (!disk6.disk[drive].track_width) {
|
||||
disk6.disk[drive].track_width = track_width;
|
||||
} else {
|
||||
assert((disk6.disk[drive].track_width == track_width) && "track width should match for all tracks");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close disk image file if readonly
|
||||
if (readonly) {
|
||||
#warning TODO FIXME : close the disk image file here and refactor to support it (checks for .fp == NULL are invalid) ...
|
||||
// ...
|
||||
}
|
||||
|
||||
disk6.disk[drive].phase = 0;
|
||||
} while (0);
|
||||
|
||||
@ -861,7 +907,8 @@ void disk6_flush(int drive) {
|
||||
|
||||
if (disk6.disk[drive].track_dirty) {
|
||||
LOG("WARNING : flushing previous session for drive (%d)...", drive+1);
|
||||
save_track_data(disk6.disk[drive].track_image, drive);
|
||||
const uintptr_t niboff = NIB_TRACK_SIZE * (disk6.disk[drive].phase >> 1);
|
||||
save_track_data(disk6.disk[drive].whole_image+niboff, drive);
|
||||
}
|
||||
|
||||
TEMP_FAILURE_RETRY(fflush(disk6.disk[drive].fp));
|
||||
|
@ -52,8 +52,9 @@
|
||||
#define _GZLEN (sizeof(DISK_EXT_GZ)-1)
|
||||
|
||||
typedef struct diskette_t {
|
||||
uint8_t track_image[NIB_TRACK_SIZE];
|
||||
char *file_name;
|
||||
FILE *fp;
|
||||
uint8_t *whole_image;
|
||||
bool nibblized;
|
||||
bool is_protected;
|
||||
bool track_valid;
|
||||
@ -62,7 +63,6 @@ typedef struct diskette_t {
|
||||
long track_width;
|
||||
int phase;
|
||||
int run_byte;
|
||||
FILE *fp;
|
||||
} diskette_t;
|
||||
|
||||
typedef struct drive_t {
|
||||
|
@ -624,6 +624,13 @@ TEST test_disk_bytes_savehello_po() {
|
||||
|
||||
#define NOSPACE_SHA1 "2EA4D4B9F1C6797E476CD0FE59970CC243263B16"
|
||||
#define EXPECTED_OOS_DSK_SHA "D5C5A3FFB43F3C55E1C9E4ABD8580322415E9CE0"
|
||||
#if CONFORMANT_TRACKS
|
||||
# define EXPECTED_OOS_DSK_TRACE_FILE_SIZE 4386397
|
||||
# define EXPECTED_OOS_DSK_TRACE_SHA "2451ED08296637220614B1DE2C5AE11AB97ED173"
|
||||
#else
|
||||
# define EXPECTED_OOS_DSK_TRACE_FILE_SIZE 4386354
|
||||
# define EXPECTED_OOS_DSK_TRACE_SHA "FB1BFF7D1535D30810EED9FD1D98CC054FB6FB1A"
|
||||
#endif
|
||||
TEST test_outofspace_dsk() {
|
||||
test_setup_boot_disk(BLANK_DSK, 0);
|
||||
BOOT_TO_DOS();
|
||||
@ -631,6 +638,15 @@ TEST test_outofspace_dsk() {
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] != TEST_FINISHED);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0x00);
|
||||
|
||||
srandom(0);
|
||||
const char *homedir = HOMEDIR;
|
||||
char *disk = NULL;
|
||||
asprintf(&disk, "%s/a2_oos_dsk_test.txt", homedir);
|
||||
if (disk) {
|
||||
unlink(disk);
|
||||
c_begin_disk_trace_6(NULL, disk);
|
||||
}
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x0;
|
||||
EAT_UP_DISK_SPACE();
|
||||
test_type_input("POKE7987,255:REM TRIGGER DEBUGGER\r");
|
||||
@ -640,6 +656,34 @@ TEST test_outofspace_dsk() {
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
ASSERT_SHA(NOSPACE_SHA1);
|
||||
|
||||
c_end_disk_trace_6();
|
||||
|
||||
do {
|
||||
uint8_t md[SHA_DIGEST_LENGTH];
|
||||
char mdstr0[(SHA_DIGEST_LENGTH*2)+1];
|
||||
|
||||
FILE *fp = fopen(disk, "r");
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long expectedSize = ftell(fp);
|
||||
ASSERT(expectedSize == EXPECTED_OOS_DSK_TRACE_FILE_SIZE);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
unsigned char *buf = malloc(EXPECTED_OOS_DSK_TRACE_FILE_SIZE);
|
||||
if (fread(buf, 1, EXPECTED_OOS_DSK_TRACE_FILE_SIZE, fp) != EXPECTED_OOS_DSK_TRACE_FILE_SIZE) {
|
||||
ASSERT(false);
|
||||
}
|
||||
fclose(fp); fp = NULL;
|
||||
SHA1(buf, EXPECTED_OOS_DSK_TRACE_FILE_SIZE, md);
|
||||
FREE(buf);
|
||||
|
||||
sha1_to_str(md, mdstr0);
|
||||
ASSERT(strcmp(mdstr0, EXPECTED_OOS_DSK_TRACE_SHA) == 0);
|
||||
} while(0);
|
||||
|
||||
unlink(disk);
|
||||
FREE(disk);
|
||||
|
||||
REBOOT_TO_DOS();
|
||||
c_debugger_go();
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
Loading…
x
Reference in New Issue
Block a user