Early bail-out of DriveLoopReadNoFlux

A couple of small optimizations that shouldn't make a difference but do such as: Addressing tracks as a single array.  Caching a single byte instead of re-reading the array. (Note that caching 32bits did not improve but actually worsen things). Harsher interrupt disabling. Whitespace changes in main...

Plus, early bail out from DriveLoopReadNoFlux.
This commit is contained in:
Alexander Martinelle 2019-09-10 23:14:34 +02:00
parent 8875c55c25
commit 9b38fc6d32
7 changed files with 117 additions and 13 deletions

View File

@ -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;

View File

@ -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];
};

View File

@ -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);

View File

@ -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)

View File

@ -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
}

View File

@ -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);

View File

@ -832,13 +832,16 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
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;
}