mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-02 03:15:36 +00:00
The SPI NOR model read its image at realize and never wrote back, so the "flash" was a g_malloc buffer: everything the firmware saved -- settings, edited frequencies, channel data -- vanished when the QEMU process exited. That is the "it behaves like RAM" the user reported, and the image on disk still had its original mtime and was byte-identical to what make_flash.py produces. Page-program and sector-erase now mark the image dirty, and it is written out when chip select is released. Flushing there rather than per byte means one file write per settings save instead of thousands, because the firmware's driver holds CS for a whole erase-and-program sequence. Written via a temporary file and rename: an interrupted flush must not leave a truncated image, since that file is the only copy of the radio's state. A short write keeps the previous image rather than replacing it with a partial one. Also flushes from an exit notifier. Deselect covers normal operation, but QMP quit -- which is what the web UI's power off sends -- can arrive with the chip still selected, and the last write would be dropped. tools/test_flash_persist.py covers it end to end on a copy of the image, so it cannot disturb a running session. It asserts specific regions rather than just a changed hash: flash 0x008100 (MR/VFO attributes) and 0x00A100 (settings), which are the two sectors a boot demonstrably writes. Both were 0xFF before and non-0xFF after, and sha256 moved from 933d6974 to 7cdff6ce. Three approaches were tried and abandoned first, all for the same reason: driving the guest from gdb. `call EEPROM_WriteBuffer` and `call SETTINGS_SaveSettings` both hang, because the main loop is running and the called function waits on hardware the debugger has frozen. Observing the file is simpler and closer to what the user actually sees. An earlier version of the test also watched EEPROM offsets instead of flash offsets and reported "same" for every region while persistence was in fact working -- the two address spaces are related by the table in App/driver/eeprom_compat.c, not equal. keypad_test.py still passes, which matters because this file is where deleting three fprintfs once silently removed the keypad.