diff --git a/src/DiskImage.cpp b/src/DiskImage.cpp index 10cbc63..e9ba652 100644 --- a/src/DiskImage.cpp +++ b/src/DiskImage.cpp @@ -151,7 +151,12 @@ void DiskImage::Close() void DiskImage::DumpTrack(unsigned track) { + +#if defined(EXPERIMENTALZERO) + unsigned char* src = &tracks[track << 13]; +#else unsigned char* src = tracks[track]; +#endif unsigned trackLength = trackLengths[track]; DEBUG_LOG("track = %d trackLength = %d\r\n", track, trackLength); for (unsigned index = 0; index < trackLength; ++index) @@ -205,7 +210,11 @@ bool DiskImage::OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsig for (unsigned halfTrackIndex = 0; halfTrackIndex < last_track * 2; ++halfTrackIndex) { unsigned char track = (halfTrackIndex >> 1); +#if defined(EXPERIMENTALZERO) + unsigned char* dest = &tracks[halfTrackIndex << 13]; +#else unsigned char* dest = tracks[halfTrackIndex]; +#endif trackLengths[halfTrackIndex] = SectorsPerTrack[track] * GCR_SECTOR_LENGTH; @@ -800,7 +809,11 @@ bool DiskImage::OpenG64(const FILINFO* fileInfo, unsigned char* diskImage, unsig //DEBUG_LOG("trackLength = %d offset = %d\r\n", trackLength, offset); trackData += 2; trackLengths[track] = trackLength; +#if defined(EXPERIMENTALZERO) + memcpy(&tracks[track << 13], trackData, trackLength); +#else memcpy(tracks[track], trackData, trackLength); +#endif trackUsed[track] = true; //DEBUG_LOG("%d has data\r\n", track); } @@ -899,7 +912,11 @@ bool DiskImage::WriteG64(char* name) gcr_track[0] = (BYTE)(track_len % 256); gcr_track[1] = (BYTE)(track_len / 256); +#if defined(EXPERIMENTALZERO) + memcpy(buffer, &tracks[track << 13], track_len); +#else memcpy(buffer, tracks[track], track_len); +#endif memcpy(gcr_track + 2, buffer, track_len); bytesToWrite = G64_TRACK_MAXLEN + 2; @@ -965,11 +982,19 @@ bool DiskImage::OpenNIB(const FILINFO* fileInfo, unsigned char* diskImage, unsig unsigned char* nibdata = diskImage + (t_index * NIB_TRACK_LENGTH) + 0x100; int align; +#if defined(EXPERIMENTALZERO) + trackLengths[track] = extract_GCR_track(&tracks[track << 13], nibdata, &align + //, ALIGN_GAP + , ALIGN_NONE + , capacity_min[trackDensity[track]], + capacity_max[trackDensity[track]]); +#else trackLengths[track] = extract_GCR_track(tracks[track], nibdata, &align //, ALIGN_GAP , ALIGN_NONE , capacity_min[trackDensity[track]], capacity_max[trackDensity[track]]); +#endif trackUsed[track] = true; @@ -1031,7 +1056,11 @@ bool DiskImage::WriteNIB() { if (trackUsed[track]) { +#if defined(EXPERIMENTALZERO) + if (f_write(&fp, &tracks[track << 13], bytesToWrite, &bytesWritten) != FR_OK || bytesToWrite != bytesWritten) +#else if (f_write(&fp, tracks[track], bytesToWrite, &bytesWritten) != FR_OK || bytesToWrite != bytesWritten) +#endif { DEBUG_LOG("Cannot write track data.\r\n"); } @@ -1250,10 +1279,18 @@ void DiskImage::DecodeBlock(unsigned track, int bitIndex, unsigned char* buf, in unsigned char gcr[5]; unsigned char byte; unsigned char* offset; +#if defined(EXPERIMENTALZERO) + unsigned char* end = &tracks[track << 13] + trackLengths[track]; +#else unsigned char* end = tracks[track] + trackLengths[track]; +#endif shift = bitIndex & 7; +#if defined(EXPERIMENTALZERO) + offset = &tracks[track << 13] + (bitIndex >> 3); +#else offset = tracks[track] + (bitIndex >> 3); +#endif byte = offset[0] << shift; for (i = 0; i < num; i++, buf += 4) @@ -1262,7 +1299,11 @@ void DiskImage::DecodeBlock(unsigned track, int bitIndex, unsigned char* buf, in { offset++; if (offset >= end) +#if defined(EXPERIMENTALZERO) + offset = &tracks[track << 13]; +#else offset = tracks[track]; +#endif if (shift) { @@ -1282,7 +1323,11 @@ void DiskImage::DecodeBlock(unsigned track, int bitIndex, unsigned char* buf, in int DiskImage::FindSync(unsigned track, int bitIndex, int maxBits, int* syncStartIndex) { int readShiftRegister = 0; +#if defined(EXPERIMENTALZERO) + unsigned char byte = tracks[(track << 13) + (bitIndex >> 3)] << (bitIndex & 7); +#else unsigned char byte = tracks[track][bitIndex >> 3] << (bitIndex & 7); +#endif bool prevBitZero = true; while (maxBits--) @@ -1314,7 +1359,11 @@ int DiskImage::FindSync(unsigned track, int bitIndex, int maxBits, int* syncStar bitIndex++; if (bitIndex >= MAX_TRACK_LENGTH * 8) bitIndex = 0; +#if defined(EXPERIMENTALZERO) + byte = tracks[(track << 13)+(bitIndex >> 3)]; +#else byte = tracks[track][bitIndex >> 3]; +#endif } } return -1; diff --git a/src/DiskImage.h b/src/DiskImage.h index 42a2a7a..5dc3adf 100644 --- a/src/DiskImage.h +++ b/src/DiskImage.h @@ -78,19 +78,48 @@ public: bool GetDecodedSector(u32 track, u32 sector, u8* buffer); + inline unsigned char GetNextByte(u32 track, u32 byte) + { +#if defined(EXPERIMENTALZERO) + return tracks[(track << 13) + byte]; +#else + return tracks[track][byte]; +#endif + } + + inline bool GetNextBit(u32 track, u32 byte, u32 bit) { //if (attachedImageSize == 0) // return 0; +#if defined(EXPERIMENTALZERO) + return ((tracks[(track << 13) + byte] >> bit) & 1) != 0; +#else return ((tracks[track][byte] >> bit) & 1) != 0; +#endif } + inline void SetBit(u32 track, u32 byte, u32 bit, bool value) { if (attachedImageSize == 0) return; +#if defined(EXPERIMENTALZERO) + u8 dataOld = tracks[(track << 13) + byte]; + u8 bitMask = 1 << bit; + if (value) + { + TestDirty(track, (dataOld & bitMask) == 0); + tracks[(track << 13) + byte] |= bitMask; + } + else + { + TestDirty(track, (dataOld & bitMask) != 0); + tracks[(track << 13) + byte] &= bitMask; + } +#else u8 dataOld = tracks[track][byte]; u8 bitMask = 1 << bit; if (value) @@ -103,6 +132,7 @@ public: TestDirty(track, (dataOld & bitMask) != 0); tracks[track][byte] &= ~bitMask; } +#endif } static const unsigned char SectorsPerTrack[42]; @@ -160,7 +190,11 @@ public: union { +#if defined(EXPERIMENTALZERO) + unsigned char tracks[HALF_TRACK_COUNT * MAX_TRACK_LENGTH]; +#else unsigned char tracks[HALF_TRACK_COUNT][MAX_TRACK_LENGTH]; +#endif unsigned char tracksD81[HALF_TRACK_COUNT][2][MAX_TRACK_LENGTH]; }; diff --git a/src/Drive.cpp b/src/Drive.cpp index bd3ccd6..e121e49 100644 --- a/src/Drive.cpp +++ b/src/Drive.cpp @@ -662,9 +662,17 @@ void Drive::DriveLoopReadNoFlux() { ResetEncoderDecoder(18 * 16, /*20 * 16*/ 2 * 16); } + if (cycles < UE7Counter) + { + UE7Counter -= cycles; + cyclesLeftForBit -= cycles; + return; + } + cyclesLeftForBit -= UE7Counter; + cycles -= UE7Counter; } - if (UE7Counter == 0x0) // The count carry (bit 4) clocks UF4. + //if (UE7Counter == 0x0) // The count carry (bit 4) clocks UF4. { UE7Counter = 16 - CLOCK_SEL_AB; // A and B inputs of UE7 come from the VIA's CLOCK SEL A/B outputs (ie PB5/6) ie preload the encoder/decoder clock for the current density settings. // The decoder consists of UF4 and UE5A. The ecoder has two outputs, Pin 1 of UE5A is the serial data output and pin 2 of UF4 (output B) is the serial clock output. @@ -749,6 +757,7 @@ void Drive::DriveLoopReadNoCycles() } }; } + void Drive::DriveLoopRead() { unsigned int minCycles; @@ -767,14 +776,9 @@ void Drive::DriveLoopRead() if (cyclesLeftForBit == 0) { - //which is faster? single loop ceil check or the 3 lines below? cyclesForBitErrorCounter -= cyclesPerBitErrorConstant; cyclesLeftForBit = cyclesPerBitInt + (cyclesForBitErrorCounter < cyclesPerBitErrorConstant); - //cyclesForBit -= cyclesPerBit; - //cyclesLeftForBit = ceil(cyclesPerBit - cyclesForBit); - //cyclesForBit += cyclesLeftForBit; - if (GetNextBit()) { ResetEncoderDecoder(18 * 16, /*20 * 16*/ 2 * 16); diff --git a/src/Drive.h b/src/Drive.h index 1ad0933..00646f5 100644 --- a/src/Drive.h +++ b/src/Drive.h @@ -148,12 +148,24 @@ private: ++headBitOffset %= bitsInTrack; return bit; } - + unsigned cachedheadTrackPos = -1; + int cachedbyteOffset = -1; + unsigned char cachedByte = 0; inline bool GetNextBit() { int byteOffset; int bit = AdvanceSectorPositionR(byteOffset); - return diskImage->GetNextBit(headTrackPos, byteOffset, bit); + + //Why is it faster to check both conditions here than to update the cache when moving the head? + if (byteOffset != cachedbyteOffset || cachedheadTrackPos != headTrackPos) + { + cachedByte = diskImage->GetNextByte(headTrackPos, byteOffset); + cachedbyteOffset = byteOffset; + cachedheadTrackPos = headTrackPos; + + } + return ((cachedByte >> bit) & 1) != 0; + //return diskImage->GetNextBit(headTrackPos, byteOffset, bit); } inline void SetNextBit(bool value) diff --git a/src/interrupt.c b/src/interrupt.c index dc8c793..ad5fa08 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -39,7 +39,9 @@ void InterruptSystemInitialize() write32(ARM_IC_IRQ_PENDING_2, read32(ARM_IC_IRQ_PENDING_2)); DataMemBarrier(); -#ifndef EXPERIMENTALZERO +#ifdef EXPERIMENTALZERO + DisableInterrupts(); +#else EnableInterrupts(); #endif } diff --git a/src/interrupt.h b/src/interrupt.h index 0dcfb93..f917ddd 100644 --- a/src/interrupt.h +++ b/src/interrupt.h @@ -9,7 +9,7 @@ extern "C" { #include "bcm2835int.h" #define EnableInterrupts() __asm volatile ("cpsie i") -#define DisableInterrupts() __asm volatile ("cpsid i") +#define DisableInterrupts() __asm volatile ("cpsid ifa, #0x13") typedef void IRQHandler(void* param); diff --git a/src/main.cpp b/src/main.cpp index a601855..91bc238 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -776,7 +776,7 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser) } m6502.Step(); // If the CPU reads or writes to the VIA then clk and data can change - + if (refreshOutsAfterCPUStep) IEC_Bus::RefreshOuts1541(); // Now output all outputs. @@ -829,16 +829,19 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser) prevButtonState = buttonState; - do + do { ctAfter = read32(ARM_SYSTIMER_CLO); - } while (ctAfter == ctBefore); // Sync to the 1MHz clock + } while (ctAfter == ctBefore); // Sync to the 1MHz clock ctBefore = ctAfter; IEC_Bus::ReadEmulationMode1541(); IEC_Bus::RefreshOuts1541(); // Now output all outputs. + + + } return EXIT_UNKNOWN; }