summaryrefslogtreecommitdiff
path: root/src/board_memory.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-26 11:11:46 -0300
committerGabriel Schneider <[email protected]>2026-08-26 11:11:46 -0300
commitfc7d3274c41ebc83911c5a6d1225cecea270cc86 (patch)
treebe6105f3b1600acb308fc346dc4884dff151c056 /src/board_memory.zig
parent27a749d3a2155419fb72bab66b1e78bcd99882ae (diff)
downloadpardes-fc7d3274c41ebc83911c5a6d1225cecea270cc86.tar.gz
pardes-fc7d3274c41ebc83911c5a6d1225cecea270cc86.zip
Fit Hexdump to the board's width, and cut the boot buffer down to addresses
## Eight bytes a row on the P4 `hexdump -C`'s sixteen needs 79 columns: ten for the address, forty-eight of hex, a gap, and eighteen of ASCII gutter. The board drives 56 columns of which seven go to the line numbers, so every row wrapped onto a second display line and the columns stopped lining up - which is the entire value of the layout. Eight fits in 46 and keeps every property that matters, including a gap at the halfway mark, because the eye counts in fours and eights rather than in sixteens. Verified on the die: 0x40000020 32 54 cd ab 00 00 00 00 |2T......| 0x40000030 30 2e 31 00 00 00 00 00 |0.1.....| That is the app descriptor: 0xABCD5432 and the version string, read out of flash by a command typed with no 0x on either argument. ## The boot buffer is shorter, and its addresses are named The first draft opened with four lines of prose explaining that there is no operating system. True, unhelpful, and it cost a third of a fourteen-row window before the first command. One header line earns its place; the rest of the screen is addresses. The two LP registers at the end are now named, because they are named in ESP-IDF's own headers and the names are the interesting part: 0x5011002c is LP_SYSTEM_REG_LP_STORE0, a general-purpose retention register that holds what you put in it, and 0x501101a4 is LP_SYSTEM_REG_RNG_DATA, the hardware random generator. Between them they demonstrate the whole point of a volatile read - one address gives back what was written, the other never gives the same answer twice: Poke 5011002c deadbeef -> 0x5011002c: wrote 0xdeadbeef, reads 0xdeadbeef Peek 5011002c -> 0x5011002c: 0xdeadbeef Peek 501101a4 -> 0x501101a4: 0x0b099791 Peek 501101a4 -> 0x501101a4: 0xfc97f3b7 All four run on the die, all with bare hex. Peek and Poke had not been tested there before this - only Hexdump had, which I had let stand as though it covered all three. snap 95/95, hxdiff 481/0, hxparity 561/0, unit-test, tty/p4/gui.
Diffstat (limited to 'src/board_memory.zig')
-rw-r--r--src/board_memory.zig34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/board_memory.zig b/src/board_memory.zig
index f99fc106..702b130d 100644
--- a/src/board_memory.zig
+++ b/src/board_memory.zig
@@ -296,11 +296,22 @@ pub fn poke(p: *Pardes, id: usize, argument: []const u8) !void {
) catch unreachable);
}
-/// `Hexdump <addr> [len]` — len bytes, 16 to a row, hex columns and an ASCII
-/// gutter, in `hexdump -C`'s layout because that is the one everyone can
-/// already read. BYTE reads, so a partial row at the end of the space is a
-/// short row rather than a refusal, and no alignment is required: this is the
-/// word you reach for when you do not yet know what is there.
+/// Bytes per dumped row, and it is a different number on the board.
+///
+/// `hexdump -C`'s sixteen is the layout everyone can already read, and it needs 79 columns: ten for
+/// the address, forty-eight for the hex, a gap, and the eighteen-column ASCII gutter. The P4 drives
+/// a 56-column grid of which seven go to the line-number gutter, so a sixteen-byte row wraps onto a
+/// second display line and the columns stop lining up - which is the entire value of the layout.
+///
+/// Eight fits in 46 and keeps every property that matters: address on the left, fixed-width hex
+/// columns, ASCII on the right, and a gap at the halfway mark because the eye counts in fours and
+/// eights rather than in sixteens.
+const row_bytes: u32 = if (pardes.platform == .p4) 8 else 16;
+
+/// `Hexdump <addr> [len]` — len bytes, `row_bytes` to a row, hex columns and an ASCII gutter, in
+/// `hexdump -C`'s layout because that is the one everyone can already read. BYTE reads, so a partial
+/// row at the end of the space is a short row rather than a refusal, and no alignment is required:
+/// this is the word you reach for when you do not yet know what is there.
pub fn hexdump(p: *Pardes, id: usize, argument: []const u8) !void {
var it = std.mem.tokenizeAny(u8, argument, " \t\r\n");
const addr = try parseAddr(it.next() orelse return Error.MissingAddress);
@@ -312,15 +323,14 @@ pub fn hexdump(p: *Pardes, id: usize, argument: []const u8) !void {
errdefer out.deinit();
try writeNote(&out.writer, e, requested, "bytes");
var row: u32 = 0;
- while (row < e.count) : (row += 16) {
- const n = @min(@as(u32, 16), e.count - row);
- var bytes: [16]u8 = undefined;
+ while (row < e.count) : (row += row_bytes) {
+ const n = @min(row_bytes, e.count - row);
+ var bytes: [row_bytes]u8 = undefined;
for (0..n) |i| bytes[i] = readByte(addr + row + @as(u32, @intCast(i)));
try out.writer.print("0x{x:0>8} ", .{addr + row});
- for (0..16) |i| {
- // hexdump -C's gap after the eighth column: the eye counts to
- // eight, not to sixteen
- if (i == 8) try out.writer.writeByte(' ');
+ for (0..row_bytes) |i| {
+ // The gap at the halfway mark: the eye counts to four or eight, not to sixteen.
+ if (i == row_bytes / 2) try out.writer.writeByte(' ');
if (i < n)
try out.writer.print(" {x:0>2}", .{bytes[i]})
else