Auto: focas-f4c — pmc_wrpmcrng with bit-level RMW

Closes #270
This commit is contained in:
Joseph Doherty
2026-04-26 05:15:52 -04:00
parent 0c967af645
commit 54c09d4d5d
17 changed files with 837 additions and 101 deletions

View File

@@ -91,6 +91,44 @@ internal class FakeFocasClient : IFocasClient
return Task.FromResult(status);
}
/// <summary>
/// Plan PR F4-c (issue #270) — typed PMC range-write entry point. Records
/// the call in <see cref="PmcRangeWriteLog"/> and applies the bytes to
/// <see cref="PmcByteRanges"/> at <c>(letter, pathId)</c> so a subsequent
/// <see cref="ReadPmcRangeAsync"/> sees the updated bytes (round-trip
/// shape). Status looked up by the canonical PMC address (e.g. <c>R100</c>)
/// of the first byte if seeded; otherwise Good.
/// </summary>
public List<(string Letter, int PathId, int StartByte, byte[] Bytes)> PmcRangeWriteLog { get; } = new();
public virtual Task<uint> WritePmcRangeAsync(
string letter, int pathId, int startByte, byte[] bytes, CancellationToken ct)
{
if (ThrowOnWrite) throw Exception ?? new InvalidOperationException();
var copy = bytes.ToArray();
PmcRangeWriteLog.Add((letter, pathId, startByte, copy));
// Persist into PmcByteRanges so subsequent range reads see the write — this
// mirrors the simulator round-trip the integration tests check.
var key = (letter.ToUpperInvariant(), pathId);
if (!PmcByteRanges.TryGetValue(key, out var src))
{
src = new byte[startByte + copy.Length];
PmcByteRanges[key] = src;
}
else if (src.Length < startByte + copy.Length)
{
var grown = new byte[startByte + copy.Length];
Array.Copy(src, 0, grown, 0, src.Length);
src = grown;
PmcByteRanges[key] = src;
}
Array.Copy(copy, 0, src, startByte, copy.Length);
// Status seeded by canonical PMC address of the first byte (no bit index).
var canonical = $"{letter.ToUpperInvariant()}{startByte}";
var status = WriteStatuses.TryGetValue(canonical, out var sx) ? sx : FocasStatusMapper.Good;
return Task.FromResult(status);
}
public List<(int number, int axis, FocasDataType type)> DiagnosticReads { get; } = new();
public virtual Task<(object? value, uint status)> ReadDiagnosticAsync(