plasma: ESC P bitmap rows through the feedback endpoint (plasma row)

PlasmaCommands.GraphicsWrite/GraphicsRow port the display firmware graphics
command (ESC P s y x w h, MSB-left); PlasmaDisplay.RowAsync writes a locked
whole-row update; the line protocol gains `plasma row <y> <hex32>`. The
router plasma slot becomes a bounded FIFO queue: rows stream in order (a
frame must not tear), texts still coalesce to the newest, clear flushes, cap
128 with counted drops. Docs updated; 442 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-31 20:45:38 -05:00
co-authored by Claude Fable 5
parent 66c3cbdb57
commit 44b636ddd3
14 changed files with 435 additions and 41 deletions
@@ -184,6 +184,41 @@ public class FeedbackLineParserTests
{
Assert.NotEmpty(ParseError(line));
}
[Fact]
public void PlasmaRow_ParsesRowAndHexData()
{
FeedbackCommand cmd = Parse("plasma row 5 80000000000000000000000000000001");
Assert.Equal(FeedbackCommandKind.PlasmaRow, cmd.Kind);
Assert.Equal(5, cmd.Y);
Assert.NotNull(cmd.Data);
Assert.Equal(16, cmd.Data!.Length);
Assert.Equal(0x80, cmd.Data[0]); // leftmost pixel lit (MSB-first)
Assert.Equal(0x01, cmd.Data[15]);
Assert.All(cmd.Data.Skip(1).Take(14), b => Assert.Equal(0, b));
}
[Fact]
public void PlasmaRow_HexRowNumber_AndMixedCaseHex()
{
FeedbackCommand cmd = Parse("PLASMA ROW 0x1F AaBbCcDdEeFf00112233445566778899");
Assert.Equal(31, cmd.Y);
Assert.Equal(0xAA, cmd.Data![0]);
Assert.Equal(0x99, cmd.Data[15]);
}
[Theory]
[InlineData("plasma row")] // no row
[InlineData("plasma row 5")] // no data
[InlineData("plasma row 32 80000000000000000000000000000001")] // row out of range
[InlineData("plasma row 5 8000")] // too short
[InlineData("plasma row 5 800000000000000000000000000000010A")] // too long
[InlineData("plasma row 5 8000000000000000000000000000000G")] // non-hex char
[InlineData("plasma row 5 80000000000000000000000000000001 x")] // trailing token
public void PlasmaRow_Malformed_ReturnsErrorText(string line)
{
Assert.NotEmpty(ParseError(line));
}
}
public class FeedbackLineBufferTests