Add machine code monitor#358
Conversation
… files: home/F2 (start of file) and end/F8 (end of file)
|
Looks quite good. I was able to build the U64 target. As soon as I have set up my U64 again (still in a box from a Commodore party), I will test it out. I can see you are on the right track also with separating the editor by type. Have you been able to figure out what happens with files larger than 26K? |
|
Thanks Gideon! Please also have a look at the other PR I raised which, unlike the one here, is ready to be merged as it had a much smaller focus, namely to introduce a hex viewer for files rather than the C64's RAM. The issue I had on that other PR with not being able to open files larger than 26KiB is already resolved. It was probably due to memory exhaustion caused by duplicating the required buffer space. The new approach simply uses the single source of truth buffer into which the file is read, then on the fly creates its hex representation as the hex viewer traverses the buffer. Thus, only a small additional buffer for the current view window is needed. I also did some low level byte to hex conversion (rather than relying on I am facing a few issues with this PR here and I described them in the PR overview at the bottom. Maybe you have an idea how to resolve them. Many thanks! |
|
A full machine code monitor like the one in VICE would be great to have. |
|
Would quite like this feature actually, missed a monitor sorely on developing my own recent project targettiing the U64. So ended up by debugging using full memory dumps (and doing PC based comparisons and analysis using a PC based hex editor) A VICE like monitor via the Ultimate UI would be awesome. |
Not to mention, supporting the C128's MMU from an app running on the UII+(L) is probably not possible, because the MMU is invisible for DMA.. So such a monitor would be of limited use for the C128... but for a C64 with UII+ it would still be quite usefull. The biggest challenge I see is supporting changing the contents of $01, as it is also hidden from DMA, tho I think this is far less of a limitation for the c64. |
|
Hi Chris, In the last months I have been primarily busy with the Ultimate64 Elite-II, so I had very little time to address activities from other users. I understand that this is discouraging, sorry about that. The good news is that I have put a bit of effort in CI/CD through github, which means that changes in a PR will be automatically built and result in an update package. Until now that's only available in the u64ii branch, but I'll merge all my changes there towards master shortly. |
|
Hi @GideonZ , that's excellent news. Thanks a lot for investing time into this. It will drastically simplify raising PRs. Some time ago, I wrote a hex viewer for viewing non-textual files in hexadecimal - an extension of the already existing text viewer in the context sensitive menu - see https://github.com/GideonZ/1541ultimate/tree/chrisgleissner-feature/320-hex. It works great on my U64. You didn't merge it back when I wrote it cause it only built for the U64 and I could not try it on any other devices as I only own a U64. If I get this to build with your new CI/CD pipeline, would you consider merging it? Also, I emailed you two months ago about extending this hex viewer into a hex editor so one could also edit the file. This in turn could then be extended towards the machine code monitor described in this ticket. Thanks |
There was a problem hiding this comment.
Pull request overview
This draft PR expands Ultimate 64 developer tooling (peek/poke + a RAM “monitor” hex view) and introduces a new “managed Temp” mechanism that routes temporary artifacts into configurable Temp subfolders and optionally enforces an auto-cleanup limit, with supporting tests and validation scripts.
Changes:
- Add managed Temp file APIs in
FileManager(category-based paths, optional/Temp/cache/<category>routing, and auto-cleanup enforcement). - Add Ultimate 64 developer actions for Peek/Poke/Monitor and U64 memory access helpers (including freeze-menu handling).
- Add test coverage + on-device scripts to validate temp auto-cleanup behavior and PRG boot-cart display-name trimming.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/io/temp-auto-cleanup/temp-auto-cleanup-test.sh | End-to-end device validator for temp auto-cleanup behavior (FTP/REST driven). |
| tools/io/temp-auto-cleanup/temp-auto-cleanup-perf-test.py | Latency/throughput probe for managed temp uploads under different settings. |
| tools/io/prg-load-path-trim-test.sh | Device validator for boot-cart display-name trimming via PRG runner endpoints. |
| software/wifi/raw_c3/main/dump_hex.c | Formatting-only normalization of an ESP32-side hex dump utility. |
| software/userinterface/userinterface.h | Adds UI config IDs for Temp Auto Cleanup/Subfolders; defines store ID constant. |
| software/userinterface/userinterface.cc | Applies Temp settings to FileManager during UI configuration effectuation. |
| software/userinterface/hex_editor.cc | Uses shared dump-hex helpers for rendering hex rows. |
| software/userinterface/editor.h | Introduces AssEditor class declaration (assembly/disassembly editor placeholder). |
| software/userinterface/editor.cc | Adjusts text line-break behavior; minor draw() signature change. |
| software/userinterface/ass_editor.cc | Adds initial AssEditor implementation (currently erroneous draw binding). |
| software/u64/u64_machine.h | Adds U64-specific peek()/poke() and helpers around memory access. |
| software/u64/u64_machine.cc | Implements peek/poke and refactors memory access sequencing with freeze support. |
| software/u64/u64_config.h | Adds action slots for peek/monitor. |
| software/u64/u64_config.cc | Adds Developer menu actions: Peek, Poke, Monitor (RAM hex viewer). |
| software/test/filesys/test_mounts.cc | Removes redundant TempfileWriter::temp_count test definition. |
| software/system/dump_hex.h | Exposes new buffer-format helpers dump_hex_byte/word. |
| software/system/dump_hex.c | Implements dump_hex_byte/word; tightens const-correctness. |
| software/network/socket_dma.cc | Routes socket-uploaded disk images through managed temp storage. |
| software/network/assembly.cc | Removes redundant TempfileWriter::temp_count test definition. |
| software/io/c64/c64_subsys.cc | Trims boot-cart display name to last 13 chars with leading “...”. |
| software/io/c64/c64.h | Adds virtual peek()/poke() to the machine abstraction. |
| software/filesystem/filesystem_a64.cc | Uses managed temp paths/dirs for A64 cached downloads. |
| software/filemanager/tests/temp_auto_cleanup_test.cpp | New unit test suite for managed temp routing + auto-cleanup semantics. |
| software/filemanager/tests/Makefile | Adds a standalone build/run target for the new temp-auto-cleanup tests. |
| software/filemanager/filemanager.h | Adds managed temp tracking structures, settings, and new temp APIs. |
| software/filemanager/filemanager.cc | Implements managed temp pathing, tracking, cleanup enforcement, and hooks into open/close/rename/delete. |
| software/api/routes.cc | Removes redundant TempfileWriter::temp_count definition. |
| software/api/attachment_writer.h | Uses FileManager::create_temp_file() for multipart uploads (managed temp). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
From what I can tell currently none (monitor isn't in the developer menu, but didn't try if I can start it with c=+o). |
|
Thanks @bvl1999 . Yeah, that is the problem with not owning a certain device; it makes development for it difficult. I will see if there is an easy way to at least activate the monitor so you can select it in the menu, but as it is already feature complete for Ultimate 64 devices, I think full support for U2 could then be a next step after merge. |
@chrisgleissner Or before merge with a bit of help from the mighty guru... ;-) |
I did a brief review of the code (tho before your last changes). Currently there are a number of U64 specific things in there.
Beyond that I didn't see things which wouldn't work on the UII/UII+. So, with a few changes, and with some restriction on functionality, this could totally work on a UII+ As to integration, no idea if you already did any of this, but I have 2 suggestions:
Last but not least, somehow u64_config.cc and u64_config.h ended up with dos line endings, the rest of your code has unix line endings like everything else in the repo. Bart. |
Correct. This ROM is not available in the /flash/roms directly on the cartridges. Including it in the ROM is OK for the C64U (is in fact already there), but not for the U64 / U64E2. What you could do instead is a DMA read of the cartridge ROM ;-) This will work on all machines / carts.
You can't fix this through DMA unfortunately. This will neither work on the U64/U64E2/C64U. DMA access to locations 0 and 1 will always go to RAM, never to the CPU's PIO.
Agreed.
Agreed. We must even consider renaming u64_config to u64_hw_config. This module shall only contain code that is U64 specific and is related to the configuration of the hardware (-registers) that configure the operation of the C64/U64 specific hardware.
@bvl1999 The repo has different line endings, unfortunately, because some code is legacy from when I was still developing under Windows (before 2016). Git can be configured to store text files always with unix line endings, regardless of what your editor does. Would this be a solution for the future? |
I'm not sure I understand what you wrote here. Character rom on a C64/128 is not typically visible, and without changing either $01 on a C64, or both the mmu and $01 on a C128, you can't 'DMA' from there. And $01 as well as the MMU for the C128 can't be read/written using DMA. Unless you run some software on the machine itself which sets up a memory map in which chargen rom is visible for DMA. But maybe I am missing something here?
I think this is unfixable for the cartridges without running code on the cpu. And that code would be either C64 or C128 specific, or have to detect the machine type, as this also works differently on the 64 and 128 (where the memory map is mostly determined by the mmu, and only somewhat by $01, and neither mmu or $01 are visible for DMA). So, for a UII(+) version, I rather consider this a limitation which cannot be addressed in a good way.
Sure. I just noticed the named files have unix line endings in the main repo, but not in this branch. It is a bit annoying to read, but no big deal really. Bart. |
|
Thanks for your very insightful comments. Here some follow-up remarks:
Today I did some final fixes to the Load / Save functionality to ensure it neatly integrates with the rest of the file picker (not yet pushed) and I am fixing the G (Go) command. Once that is done, it's ready for promoting the PR from Draft status. Best wishes |
Thing is, when I look in Gideon's version of the repository, those files have 'unix' line endings. Gideon's suggestion to 'auto enforce' 'unix line endings' might work, until for some reason someone includes a dos/windows specific file of course. Regardless, I agree, it would be better to go through the entire repo at some point and fix all the cases where dos/windows line endings are used.
I'm totally fine with that name, simple and clear... but eventually, it is Gideon's call!
I understand your take on this. My primary concern here is to not introduce avoidable things which would make it impossible to also implement this for the cartridges without that being a conscious decision. As to the C64 Ultimate firmware, keep this in mind: the C64U firmware is currently not open source, and that means your code can't just move there, without your explicit permission or signing over the copyright. From what you write, I assume you'd be willing to permit this, but I think it is good to not completely ignore the formalities of the GPL in this.
From what I saw, you are using machine->get_cpu_port() to get around this, which works on the U64, but won't work on the UII/UII+.
Thank you very much for all your work on this, I am sure this contribution will be valued by many a developer. Bart. |
|
Thanks @bvl1999 , Yeah, I am totally fine for all the code that I submit to this repo to be used for the Commodore 64 U firmware. To be perfectly honest, the prospect of making it to that repo is the sole reason why I started contributing a lot recently. There is currently no direct way to contribute to the C64U firmware, so this is my next best route. Also, and this is totally unrelated, but have you seen Spiffy's take on the C64U firmware being also GPL v3 since it is unlikely all of its many authors signed a dual license agreement. I am not sure this can be discussed as part of this PR, but it is an open question I've had ever since reading this. In terms of adding U2+ support, I would be very happy for this PR to be merged to Many thanks for all your constructive feedback, it is much appreciated. I hope to promote the PR from Draft status either later today or tomorrow. Just final clean-up, and addressing the comment you left earlier about relocation. Best wishes |
I am aware of that, but I think that discussion is a bit too big for this PR. I just wanted to make sure you are aware of this aspect, and permit such use. |
|
I have pushed all my changes (including the relocation to a new folder, introduction of This has undergone my usual testing and I also added a video walk-through. There are also extensive unit tests as well as an E2E Python-based test that interacts with the deployed machine monitor via Telnet. Many thanks for considering a merge. Best wishes |
|
Yay! This is a C128 in 128 mode with UII+
Nice work @chrisgleissner ! |
|
Hi @bvl1999 , That is excellent, thanks for the good news! You may like two new features I added: bookmarks and polling. I think especially the latter could become very handy when watching the I/O area. I also added a short video link at the top of this PR to demonstrate them. Best wishes |
Nice. but... do you ever sleep??? (hides) |
|
So, found one curious behavior with the UII+ on a C64 or C128 in 64 mode. It makes sense when you realize how the freezer works, and might be hard to avoid. Anyway, because the cartridge puts the system in ultimax mode, the system roms at a000 and e000 are not accessible, and nor is the ram below it, what you get looks like disconnected address space. When using telnet instead of the local interface, you do get to see whatever is currently there based on the CPU's banking configuration. This doesn't happen on a C128 in 128 mode because it ignores the cartridge trying to use ultimax mode, and you always get the view of memory configured in the mmu. It has its own peculiarity tho, because dma is used for reading/writing memory, the monitor will see the ram bank configured in $d506 and not the one in $d500. Also, the mmu and vdc registers are invisible to dma, so those can't be viewed or polled. I imagine it might be possible to switch out of ultimax mode for the dma read/write, but don't know, @GideonZ would that work? |

Add C64 Machine Code Monitor
Addresses #151
This PR adds a machine code monitor for Ultimate 64–based devices. It includes a dedicated UI, a U64-aware memory backend, and 6510 disassembly support.
This PR has been tested on:
Video Walkthrough
Entry Points
Developer -> Machine Code Monitor(overlay and freeze modes)Features
Banking
RAM,BASIC,CHAR,IO,KERNALSession Handling
Backend
Testing
Keyboard Shortcuts
General
CBM+O: Open monitorXorCBM+O: Exit monitorF3or?: Toggle helpPage UporF1: Navigate one page upPage DownorF7: Navigate one page downPlease note that interacting with the machine code monitor often requires switching the two user interface modes (freeze and overlay):
To simplify this UI switch, I added a new keyboard shortcut accessible from the menu:
CBM+I: Toggles the User Interface Mode and exits the menu (akin to Joystick toggle)Views
M: MemoryA: AssemblyB: BinaryI: ASCIIV: Screen Code viewO: CPU bank optionsShift-O: VIC bank optionsP: Toggle polling; great for observing live changes in UI Overlay modeEdit Mode
E: EditCBM+E: Exit editRUN/STOPorESC: Exit edit mode or monitorCopy / Paste
R: Mark region start/endCBM-C: CopyCBM-V: PasteBookmarks
Bookmarks allow for storing up to 10 different regions (and user-preferred view settings for them).
This allows for very quick jumping to high value memory regions.
0...9: Recall bookmarkCBM-0...CBM-9: Set bookmarkCBM-B: Open bookmarks listDelete
The DEL key behaviour depends on the view and is always enabled, even if not in Edit mode:
NOP, moves cursor forward00, moves cursor forward0(shown as.), moves cursor forward (NOT YET IMPLEMENTED)View-Specific
Assembly
U: Toggle undocumented opcodesBinary
W: Set width, 1-4 bytes. Use 1 byte for charset editing and 3 bytes for sprites.Freeze
Z: Freeze in overlay modeMemory Commands
ASCII and Screen Code edit modes must be exited before using memory commands, to avoid ambiguity.
J: Jump to addressF: Fill memory rangeT: Transfer memory rangeC: Compare memory rangesH: Hunt for byte sequenceN: Evaluate numberRETURNwrites the selected value to the current address in the active memory view.ESCcloses without writing.Execution Commands
G: Go, executing the program at the specified address.Disk Commands
L: Load file to RAM. Choose PRG header address or absolute target address; optional file offset and length supported.S: Save RAM to file:Files can be loaded from / saved to either U64 filesystem files, or alternatively files within C64 disk files such as .d64 files.
Screenshots
Developer Menu
The machine code monitor can be opened in one of two ways:
CBM+O. (O as in mOnitor; the m shortcut is already taken)F5-D-M-Enter. In other words, via the Action Menu's "Developer" sub-menu, as seen in the screenshot below.Freeze Mode
The "Freeze Mode" is used if the user selects
Interface Type = Freezein theUser Interface Settingsof the menu.The freeze mode is largely identical to the overlay mode discussed below, but it does not have access to the BASIC nor KERNAL regions. Instead, it views the memory beneath them.
Help Menu
Hex Mode
Assembly Mode
The following steps take us to this screenshot
$1000with theT E000-FFFF,1000command (only works in Overlay UI Mode since Kernal not visible in Freeze UI mode)E(dit) modeSTFrom here, the user would normally continue as follows:
Binary Mode
Useful for viewing/editing the character set (as shown here) or sprites. Configurable width of 1 to 4 bytes per row.
ASCII Mode
Please note that the character set used by the UI does not include all characters of the standard C64 character set, so this is a best effort rendering.
Screen Code Mode
As mentioned under "ASCII mode", this is best effort rendering.
Evaluate Number
See the Hexadecimal / Decimal / Binary / ASCII / ScreenCode representation of the value at the current cursor position.
Save and Load
This section demonstrates how a byte range is saved, then loaded again. This relies on the standard Ultimate 64 file picker.
From U64...
...To C64U...
... And Back Again.
Overlay Mode
The overlay mode allows for full visibility of the C64's RAM, including BASIC and Kernal.
By default, the C64 is not frozen. However, if desired, its freeze status can be toggled via the
Zshortcut. Great for examining memory without the C64 changing it.Please excuse the image quality; the overlay is not visible in U64's video stream, thus I had to take photos. These are somewhat outdated as the code has moved on. For the latest code state, see the Freeze mode screenshots.
Disassembly Mode
Jump to Address
Fill Region
Limitations
$0001latch is not directly observable there, so the selected bank is treated as authoritative.