diff --git a/disks/blank.nib.gz b/disks/blank.nib.gz index 06fefc48..3360a910 100644 Binary files a/disks/blank.nib.gz and b/disks/blank.nib.gz differ diff --git a/src/disk.c b/src/disk.c index 34f66f79..5ee62b9f 100644 --- a/src/disk.c +++ b/src/disk.c @@ -488,12 +488,11 @@ static inline void animate_disk_track_sector(void) { // ---------------------------------------------------------------------------- // Emulator hooks -GLUE_C_READ(disk_read_write_byte) -{ - uint8_t value = 0xFF; // U5 needs this set to "Journey Onward" +static void _disk_readWriteByte(void) { do { if (disk6.disk[disk6.drive].fd < 0) { ////ERRLOG_THROTTLE("OOPS, attempt to read byte from NULL image in drive (%d)", disk6.drive+1); + disk6.disk_byte = 0xFF; break; } @@ -505,6 +504,7 @@ GLUE_C_READ(disk_read_write_byte) size_t track_width = load_track_data(disk6.drive); if (track_width != disk6.disk[disk6.drive].track_width) { ////ERRLOG_THROTTLE("OOPS, problem loading track data"); + disk6.disk_byte = 0xFF; break; } disk6.disk[disk6.drive].track_valid = true; @@ -515,13 +515,11 @@ GLUE_C_READ(disk_read_write_byte) track_idx += disk6.disk[disk6.drive].run_byte; if (disk6.ddrw) { if (disk6.disk[disk6.drive].is_protected) { - value = 0x00; break; // Do not write if diskette is write protected } if (disk6.disk_byte < 0x96) { ////ERRLOG_THROTTLE("OOPS, attempting to write a non-nibblized byte"); - value = 0x00; break; } @@ -535,20 +533,20 @@ GLUE_C_READ(disk_read_write_byte) disk6.disk[disk6.drive].track_dirty = true; } else { - if (disk6.motor_off) { // ??? + if (disk6.motor_off) { // !!! FIXME TODO ... introduce a proper spin-down, cribbing from AppleWin if (disk6.motor_off > 99) { ////ERRLOG_THROTTLE("OOPS, potential disk motor issue"); - value = 0x00; + disk6.disk_byte = 0xFF; break; } else { disk6.motor_off++; } } - value = disk6.disk[disk6.drive].whole_image[track_idx]; + disk6.disk_byte = disk6.disk[disk6.drive].whole_image[track_idx]; #if DISK_TRACING if (test_read_fp) { - fprintf(test_read_fp, "%02X", value); + fprintf(test_read_fp, "%02X", disk6.disk_byte); } #endif } @@ -574,12 +572,9 @@ GLUE_C_READ(disk_read_write_byte) } } #endif - - return value; } -GLUE_C_READ(disk_read_phase) -{ +static void _disk6_phaseChange(uint16_t ea) { ea &= 0xFF; int phase = (ea>>1)&3; int phase_bit = (1 << phase); @@ -643,57 +638,104 @@ GLUE_C_READ(disk_read_phase) animate_disk_track_sector(); } - - return ea == 0xE0 ? 0xFF : floating_bus_hibit(1); } -GLUE_C_READ(disk_read_motor_off) -{ +static void _disk6_motorControl(uint16_t ea) { clock_gettime(CLOCK_MONOTONIC, &disk6.motor_time); - disk6.motor_off = 1; - return floating_bus_hibit(1); + int turnOn = (ea & 0x1); + disk6.motor_off = turnOn ? 0 : 1; } -GLUE_C_READ(disk_read_motor_on) -{ - clock_gettime(CLOCK_MONOTONIC, &disk6.motor_time); - disk6.motor_off = 0; - return floating_bus_hibit(1); +static void _disk6_driveSelect(uint16_t ea) { + int driveB = (ea & 0x1); + disk6.drive = driveB ? 1 : 0; } -GLUE_C_READ(disk_read_select_a) -{ - disk6.drive = 0; - return floating_bus(); +static void _disk_readLatch(void) { + if (!disk6.motor_off && !disk6.ddrw) { + // UNIMPLEMENTED : phase 1 on forces write protect in the Disk II drive (UTA2E page 9-7) + if (disk6.disk[disk6.drive].is_protected) { + disk6.disk_byte |= 0x80; + } else { + disk6.disk_byte &= 0x7F; + } + } } -GLUE_C_READ(disk_read_select_b) -{ - disk6.drive = 1; - return floating_bus(); +static void _disk_modeSelect(uint16_t ea) { + disk6.ddrw = (ea & 0x1); } -GLUE_C_READ(disk_read_latch) +GLUE_C_READ(disk6_ioRead) { - return disk6.drive; + uint8_t sw = ea & 0xf; + if (sw <= 0x7) { // C0E0 - C0E7 + _disk6_phaseChange(ea); + } else { + switch (sw) { + case 0x8: // C0E8 + case 0x9: // C0E9 + _disk6_motorControl(ea); + break; + case 0xA: // C0EA + case 0xB: // C0EB + _disk6_driveSelect(ea); + break; + case 0xC: // C0EC + _disk_readWriteByte(); + break; + case 0xD: // C0ED + _disk_readLatch(); + break; + case 0xE: // C0EE + case 0xF: // C0EF + _disk_modeSelect(ea); + break; + default: + assert(false && "all cases should be handled"); + break; + } + } + + // Even addresses returns the latch (UTA2E Table 9.1) + return (ea & 1) ? floating_bus() : disk6.disk_byte; } -GLUE_C_READ(disk_read_prepare_in) +GLUE_C_WRITE(disk6_ioWrite) { - disk6.ddrw = 0; - return floating_bus_hibit(disk6.disk[disk6.drive].is_protected); -} + uint8_t sw = ea & 0xf; + if (sw < 0x7) { // C0E0 - C0E7 + _disk6_phaseChange(ea); + } else { + switch (sw) { + case 0x8: // C0E8 + case 0x9: // C0E9 + _disk6_motorControl(ea); + break; + case 0xA: // C0EA + case 0xB: // C0EB + _disk6_driveSelect(ea); + break; + case 0xC: // C0EC + _disk_readWriteByte(); + break; + case 0xD: // C0ED + // _disk_readLatch(); -- do not call on write + break; + case 0xE: // C0EE + case 0xF: // C0EF + _disk_modeSelect(ea); + break; + default: + assert(false && "all cases should be handled"); + break; + } + } -GLUE_C_READ(disk_read_prepare_out) -{ - disk6.ddrw = 1; - return floating_bus_hibit(1); -} - -GLUE_C_WRITE(disk_write_latch) -{ - disk6.disk_byte = b; - //return b; + // NOTE : any address writes the latch via sequencer LD command (74LS323 datasheet) + if (disk6.ddrw) { + disk6.disk_byte = b; + } } // ---------------------------------------------------------------------------- @@ -708,24 +750,12 @@ void disk6_init(void) { // disk softswitches // 0xC0Xi : X = slot 0x6 + 0x8 == 0xE - cpu65_vmem_r[0xC0E0] = cpu65_vmem_r[0xC0E2] = cpu65_vmem_r[0xC0E4] = cpu65_vmem_r[0xC0E6] = disk_read_phase; - cpu65_vmem_r[0xC0E1] = cpu65_vmem_r[0xC0E3] = cpu65_vmem_r[0xC0E5] = cpu65_vmem_r[0xC0E7] = disk_read_phase; - - cpu65_vmem_r[0xC0E8] = disk_read_motor_off; - cpu65_vmem_r[0xC0E9] = disk_read_motor_on; - cpu65_vmem_r[0xC0EA] = disk_read_select_a; - cpu65_vmem_r[0xC0EB] = disk_read_select_b; - cpu65_vmem_r[0xC0EC] = disk_read_write_byte; - cpu65_vmem_r[0xC0ED] = disk_read_latch; - cpu65_vmem_r[0xC0EE] = disk_read_prepare_in; - cpu65_vmem_r[0xC0EF] = disk_read_prepare_out; for (unsigned int i = 0xC0E0; i < 0xC0F0; i++) { - cpu65_vmem_w[i] = cpu65_vmem_r[i]; + cpu65_vmem_r[i] = disk6_ioRead; + cpu65_vmem_w[i] = disk6_ioWrite; } - cpu65_vmem_w[0xC0ED] = disk_write_latch; - stepper_phases = 0; disk6.disk[0].phase = disk6.disk[1].phase = 0; diff --git a/src/test/testdisk.c b/src/test/testdisk.c index c1f73812..f8c936ed 100644 --- a/src/test/testdisk.c +++ b/src/test/testdisk.c @@ -92,7 +92,7 @@ TEST test_boot_disk_bytes() { } #define EXPECTED_DISK_TRACE_NIB_FILE_SIZE 147368 -#define EXPECTED_DISK_TRACE_NIB_SHA "DE92EABF6C9747353E9C8A367706D70E520CC2C1" +#define EXPECTED_DISK_TRACE_NIB_SHA "1716FE7E79068D85F4EEF3CFEB28EAE8D512E592" TEST test_boot_disk_bytes_nib() { test_setup_boot_disk(BLANK_NIB, 0); srandom(0); @@ -424,7 +424,7 @@ TEST test_disk_bytes_savehello_dsk() { #define EXPECTED_DISKWRITE_TRACE_NIB_FILE_SIZE 2409 #define EXPECTED_DISKWRITE_TRACE_NIB_SHA "332EA76D8BCE45ACA6F805B978E6A3327386ABD6" -#define EXPECTED_BSAVE_NIB_SHA "94193718A6B610AE31B5ABE7058416B321968CA1" +#define EXPECTED_BSAVE_NIB_SHA "D894560D1061008FFA9F0BC08B163AC7086A7C0E" TEST test_disk_bytes_savehello_nib() { test_setup_boot_disk(BLANK_NIB, 0); BOOT_TO_DOS(); @@ -723,7 +723,7 @@ TEST test_outofspace_dsk() { PASS(); } -#define EXPECTED_OOS_NIB_SHA "8B91A71F6D52E1151D9DB4DB2E2B4B9C2FB5393C" +#define EXPECTED_OOS_NIB_SHA "D1C404E55811C47CF105D08D536EBBEEC7AA7F51" TEST test_outofspace_nib() { test_setup_boot_disk(BLANK_NIB, 0); BOOT_TO_DOS(); @@ -1307,7 +1307,7 @@ TEST test_data_stability_dsk() { } #define EXPECTED_STABILITY_NIB_FILE_SIZE 232960 -#define EXPECTED_STABILITY_NIB_SHA "94193718A6B610AE31B5ABE7058416B321968CA1" +#define EXPECTED_STABILITY_NIB_SHA "D894560D1061008FFA9F0BC08B163AC7086A7C0E" TEST test_data_stability_nib() { diff --git a/src/test/testtrace.c b/src/test/testtrace.c index 2ac90d45..2b892a99 100644 --- a/src/test/testtrace.c +++ b/src/test/testtrace.c @@ -124,8 +124,8 @@ TEST test_boot_sound() { // Mockingboard tracing #define NSCT_DSK "NSCT.dsk.gz" -#define NSCT_TRACE_SHA "35C58FEEB70E76FC31CEB55DB4C830B471B48AE3" // WARNING unstable if tests changed before this ... -#define NSCT_SAMPS_SHA "C48AFC2ABFECC98CECB8A5B63E2261181195E1B2" +#define NSCT_TRACE_SHA "FA2FE78A273405E2B129E46FD13F1CB0C56F8D53" +#define NSCT_SAMPS_SHA "DF9686D4835B0E55480BE25CB0A065C85A6963DE" #define NSCT_TRACE_TARGET_SIZ (512 * 65536) // 2^25 #define NSCT_SAMPS_TARGET_SIZ (2048 * 65536) // 2^27 TEST test_mockingboard_1() { @@ -169,6 +169,10 @@ TEST test_mockingboard_1() { uint8_t md[SHA_DIGEST_LENGTH]; char mdstr0[(SHA_DIGEST_LENGTH*2)+1]; + mb_traceEnd(); + truncate(mbTraceFile, NSCT_TRACE_TARGET_SIZ); + truncate(mbSampsFile, NSCT_SAMPS_TARGET_SIZ); + // verify trace file do { unsigned char *buf = MALLOC(NSCT_TRACE_TARGET_SIZ); @@ -196,7 +200,6 @@ TEST test_mockingboard_1() { break; } while (1); c_debugger_set_timeout(0); - mb_traceEnd(); unlink(mbTraceFile); FREE(mbTraceFile); @@ -211,11 +214,11 @@ TEST test_mockingboard_1() { // ---------------------------------------------------------------------------- // CPU tracing -// This test is majorly abusive ... it creates an ~800MB file in $HOME +// This test is majorly abusive ... it creates an ~900MB file in $HOME // ... but if it's correct, you're fairly assured the cpu/vm is working =) #if ABUSIVE_TESTS -#define EXPECTED_CPU_TRACE_FILE_SIZE 889495849 -#define EXPECTED_CPU_TRACE_SHA "5D16B61156B82960E668A8FA2C5DB931471524FE" +#define EXPECTED_CPU_TRACE_FILE_SIZE 889495699 +#define EXPECTED_CPU_TRACE_SHA "ADFF915FF3B8F15428DD89580DBE21CDF71B7E39" TEST test_boot_disk_cputrace() { const char *homedir = HOMEDIR; char *output = NULL; @@ -259,8 +262,8 @@ TEST test_boot_disk_cputrace() { } #endif -#define EXPECTED_CPUTRACE_HELLO_FILE_SIZE 118170553 -#define EXPECTED_CPUTRACE_HELLO_SHA "3BE4CFC3CFDBFED83FAF29EB0C8A004D20964461" +#define EXPECTED_CPUTRACE_HELLO_FILE_SIZE 118170437 +#define EXPECTED_CPUTRACE_HELLO_SHA "D5BF7650E51404F3358C9C4CBBEBAA191E53AD72" TEST test_cputrace_hello_dsk() { test_setup_boot_disk(BLANK_DSK, 0); @@ -310,7 +313,7 @@ TEST test_cputrace_hello_dsk() { } #define EXPECTED_CPUTRACE_HELLO_NIB_FILE_SIZE 14153921 -#define EXPECTED_CPUTRACE_HELLO_NIB_SHA "AC3787B7AE7422DD88AA414989B059F13BBF1674" +#define EXPECTED_CPUTRACE_HELLO_NIB_SHA "B09F85206E964487378C5B62EA26626A6E8159F1" TEST test_cputrace_hello_nib() { test_setup_boot_disk(BLANK_NIB, 0); @@ -412,8 +415,8 @@ TEST test_cputrace_hello_po() { // ---------------------------------------------------------------------------- // VM tracing -#define EXPECTED_VM_TRACE_FILE_SIZE 2832136 -#define EXPECTED_VM_TRACE_SHA "E39658183FF87974D8538B38B772A193C6C3276C" +#define EXPECTED_VM_TRACE_FILE_SIZE 2383449 +#define EXPECTED_VM_TRACE_SHA "0B387CBF4342CC24E0B9D2DA37AF517FD75DF467" TEST test_boot_disk_vmtrace() { const char *homedir = HOMEDIR; char *disk = NULL; @@ -458,8 +461,8 @@ TEST test_boot_disk_vmtrace() { PASS(); } -#define EXPECTED_VM_TRACE_NIB_FILE_SIZE 2931400 -#define EXPECTED_VM_TRACE_NIB_SHA "5ED6270A7A9CC523D9BAB07E08B74394C3386A32" +#define EXPECTED_VM_TRACE_NIB_FILE_SIZE 2470474 +#define EXPECTED_VM_TRACE_NIB_SHA "0256D57E561FE301588B1FC081F04D20AA870789" TEST test_boot_disk_vmtrace_nib() { test_setup_boot_disk(BLANK_NIB, 0); @@ -507,7 +510,7 @@ TEST test_boot_disk_vmtrace_nib() { } #define EXPECTED_VM_TRACE_PO_FILE_SIZE EXPECTED_VM_TRACE_FILE_SIZE -#define EXPECTED_VM_TRACE_PO_SHA "EDBE060984FC1BAA30C2633B791AF49BA89112AE" +#define EXPECTED_VM_TRACE_PO_SHA "3AE332028B37DE1DD0F967C095800E28D5DC6DB7" TEST test_boot_disk_vmtrace_po() { test_setup_boot_disk(BLANK_PO, 0);