From f32a27ff15aaa651aba2b7a2af73edae79d4fd30 Mon Sep 17 00:00:00 2001 From: BlackMark Date: Sun, 19 Jul 2026 14:55:01 +0200 Subject: [PATCH] tsb: use the named register surface Direct register access now reads through the named surface (hw::mcusr::wdrf.test(), hw::ucsr0b::write(...)) instead of the string form, matching how libavr itself is written. Zero-overhead: pure 740 B, tricks 658 B, asm 508 B unchanged, all byte-identical across modes, protocol green. Co-Authored-By: Claude Opus 4.8 --- tsb/tsb_asm.cpp | 11 +++++------ tsb/tsb_pure.cpp | 2 +- tsb/tsb_tricks.cpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tsb/tsb_asm.cpp b/tsb/tsb_asm.cpp index 02e2054..854c4c1 100644 --- a/tsb/tsb_asm.cpp +++ b/tsb/tsb_asm.cpp @@ -237,10 +237,9 @@ void write_config() // Minimal 115200 8N1 bring-up: 8N1 is the UCSR0C reset value, so only U2X0, // UBRR0 (16 at 16 MHz → 2.1 % error) and the RX/TX enables need writing — the // driver's avr::init also programs UCSR0C. - avr::hw::reg<"UCSR0A">::write(avr::hw::field<"UCSR0A", "U2X0">{}(1).value); - avr::hw::reg<"UBRR0">::write16(16); - avr::hw::reg<"UCSR0B">::write(static_cast(avr::hw::field<"UCSR0B", "RXEN0">{}(1).value | - avr::hw::field<"UCSR0B", "TXEN0">{}(1).value)); + avr::hw::ucsr0a::write(avr::hw::ucsr0a::u2x0(1).value); + avr::hw::ubrr0::write16(16); + avr::hw::ucsr0b::write(avr::hw::ucsr0b::rxen0(1), avr::hw::ucsr0b::txen0(1)); // The password gate that the canonical loader carries (compare host bytes // against the config page, hang on mismatch) is dropped here: it is optional @@ -250,8 +249,8 @@ void write_config() std::uint8_t knocks = 0; std::uint16_t idle = 0xFFFF; while (knocks < 3) { - if (avr::hw::reg<"UCSR0A">::read() & avr::hw::field<"UCSR0A", "RXC0">{}(1).value) - knocks = avr::hw::reg<"UDR0">::read() == '@' ? knocks + 1 : 0; + if (avr::hw::ucsr0a::rxc0.test()) + knocks = avr::hw::udr0::read() == '@' ? knocks + 1 : 0; else if (--idle == 0) appjump(); } diff --git a/tsb/tsb_pure.cpp b/tsb/tsb_pure.cpp index bc8004d..b26cb64 100644 --- a/tsb/tsb_pure.cpp +++ b/tsb/tsb_pure.cpp @@ -201,7 +201,7 @@ void write_config() { // A bootloader may be entered by a watchdog reset; the reference loader // hands straight back to the application in that case rather than run. - if (avr::hw::field<"MCUSR", "WDRF">::test()) + if (avr::hw::mcusr::wdrf.test()) appjump(); avr::init(); diff --git a/tsb/tsb_tricks.cpp b/tsb/tsb_tricks.cpp index 35e7913..d6f1c90 100644 --- a/tsb/tsb_tricks.cpp +++ b/tsb/tsb_tricks.cpp @@ -185,7 +185,7 @@ void write_config() [[noreturn]] void run() { - if (avr::hw::reg<"MCUSR">::read() & avr::hw::field<"MCUSR", "WDRF">{}(1).value) + if (avr::hw::mcusr::read() & avr::hw::mcusr::wdrf(1).value) appjump(); avr::init();