A vibe-coded interactive disassembler for the vintage Mitsubishi M50740-series microcontrollers
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
vcr_rom_m50950f.asmpa sample disassembly project file, if you just want to take a quick peek at what it looks like and fiddle with itasmp - 505.86 kB - 03/19/2026 at 00:24 |
|
|
index.html.txtthe disassembler. you can strip off the .txt extension. just load it in your browser. tested with chrome. feel free to inspect if you're scared. it's html and javascript. the txt extension was added to be compatible with this site's filename restrictionstext/plain - 157.90 kB - 03/15/2026 at 22:05 |
|
|
m50740disassembler-definition.txtMy initial prompt describing the application I'm building: a disassembler!plain - 7.36 kB - 03/15/2026 at 20:34 |
|
The app is realized as a single html file (I asked for that), so one just drops it onto a browser and 'there you are'. And then one drops on a rom image and 'there you go'. I had told Claude that the rom images are likely at the top of the address space because the reset vector requires that, so go ahead with an initial guess of that minus the size of the binary as being the load address. There is a list of processors to choose from. I didn't recognize these numbers, and I didn't know at the time which it was from, so I left it as the basic '740 for starters.
Upon loading, it creates segments for the rom, and for the ram and special function registers. It puts labels on whatever it knows about (this is not magical -- it's a property of the CPU selection). Any of the vectors are assumed to point to code (especially reset) and those are put in the disassembly queue. Once finished setting up, the queue is set to processing. As mentioned, this consists of plucking an address from the queue and disassembling until a terminating instruction is found, then plucking the next until done. The disassembly action itself can enqueue more work, but eventually it will stop.
After loading looks like:
So there are segments create for the ROM but also any on-chip RAM and the memory mapped peripherals. Here we can see the initial disassembly found references into the RAM region and added labels for such. There's not a lot because disassembly stopped pretty soon. This chip has a minimal CPU (based on 6502) and there's a fair amount of computed goto that the simple disassembler heuristic can't follow into. So the human needs to help it, and that's part of the motivation for the interactive aspect. You could say this app is powered by Natural Intelligence integration. And we're gonna need it.
Scrutinizing, I can see there is a claim of a zero page of 256 bytes. I know the '740 only has 96 bytes of ram total. Not 256. Collapsing the segments so I can see the summary better:
There is also a stack section?! And *no* special function registers? Scrolling to the end of rom:
Hmm, I know this can't be right because the reset vector is in the last position. And 'nmi'? Wut? OK, time to look at the code. It was relatively straightforward; I'll not go too far into details except to show this representative bit:
return {
"M740": { label:"M740 (generic)", sfrs:{}, vectors:[
v(0xFFFA,"vec_nmi", "nmi"),
v(0xFFFC,"vec_reset","reset"),
v(0xFFFE,"vec_irq", "irq"),
], regions: regions_zp_stack },
"M37450": { label:"M37450 / 7450", sfrs:sfr_37450, vectors:vec_37450, regions:regions_37450 },
"M37451": { label:"M37451 / 7451", sfrs:sfr_37451, vectors:vec_37450, regions:regions_37450 },
"M3802": { label:"M3802", sfrs:sfr_3802, vectors:vec_3802, regions:regions_3802 },
"M3807": { label:"M3807", sfrs:sfr_3807, vectors:vec_3807, regions:regions_3802 },
"M3886": { label:"M3886", sfrs:sfr_3886, vectors:vec_3886, regions:regions_3802 },
"M50734": { label:"M50734", sfrs:sfr_50734, vectors:vec_50734, regions:regions_50734 },
};
OK, so that is the source of madness. I can manually fix that well enough, but let me check.
> where did the list of vectors come from? they don't seem to match the data sheet. would it be easier for me to fix them manually? ● These came from my training data — I constructed them from general knowledge of the M740 family, not a specific datasheet, so they may well be wrong in name, address, or count. Yes, editing them directly would be easiest. They're at lines 760–799 in index.html. Each entry is just: ...
Well OK then! I suppose I should still be pleased that I got a working application. I just need to manage my expectations that I will need to QA it -- especially if obscure facts are involved. I can do that, but it would have been nice for it to warn me beforehand of...
Read more »I spent some time compiling my thoughts into a text file named 'm50740disassembler-definition.txt' describing the application. It can take me an hour or more to gather and articulate my thoughts. It's a little humbling because once that's done Claude generates the code for the project in a few minutes. I feel so obsolete!
I have put 'm50740disassembler-definition.txt' in the files section so you can see how I write that. It's pretty long so I didn't want to post it inline. It's pretty easy and free-form. I have found that you really do not have to baby talk Claude. It has encyclopedic knowledge. The first few sentences are:
Create a single page web application that is a disassembler for the Mitsubishi M50740 series microcontrollers from the 1980's. The application should support drag-dropping of binary images, and disassembly projects. A disassembly project will consists of lines of disassembly. Each line will consist of address, hex instruction bytes, address label, mnemonic, and comment. Comment is freely editable. Address label is editable, but needs to be globally unique to the project. The mnemonic is ...
The full text is about 8 KiB, and if I paste that into a word processor app it's about 2.5 pages.
One thing to know is that Claude is very eager. It will blythely make code changes based upon your observations, so be ready for that. There is a thing called 'plan mode' entered with the command /plan. This causes it to hold off on making changes, letting you have a back-and-forth with it until you feel good about letting it go. Know that once you let it go, it will be out of plan mode, so if you want to do things a little more slowly you should keep an eye on that. At the bottom of the repl will be an indication of if you are still in plan mode.
Since I was ready, I prompted Claude "there is a project definition in the file named 'm50740disassembler-definition.txt'; let us start work on that'.
Claude read it and did research on the web about the processor and all manner of other things like downloading files to read more closely.
When you're doing this, Claude is very timid about running tools on your system and will stop and ask for permission to do so. So you need to baby sit the repl or it will just sit there waiting for you to approve. Many things will allow you to say 'approve for this session', but not everything.
Eventually I got through all the approval and it reported it had a thorough understanding and then it set to work. It worked for quite a while! It worked for 22 minutes 30 seconds. And then it was done. It had produced a single page HTML/JavaScript app. You just load the file in your browser -- there's no server backend. And from there you can drop rom dumps on the work area, and specify the starting address to map that to (it will make a sane guess) and the processor variant. Those things will let it know about the special function registers, the reset and other vectors, and tweaks to the instruction set. It doesn't really disassemble until told do, but it knows the various vectors are a starting point to code, so it queues those items immediately, and gives the locations sane names.
Disassembly is driven by a work queue which are just start addresses. Each opcode has a flag that indicates whether that instruction should terminate disassembly or not. Most don't, but things like 'ret' and whatnot do. This is to help avoid disassembling non-code and having to clean it up later. Then as it proceeds, the opcodes also have another flag indicating whether the operand is a code address itself, e.g. a JSR references a code target address, and is non-terminating (since the subroutine is expected to return). JMP references a code target address, but is terminating because there's no assurance that what follows is indeed code --...
Read more »Claude code is some sort of nodejs application, and the installer will take care of all the dependency installation fairly nicely for what otherwise seems kinda kludgey by my standards. But then I crinkle my nose at most anything that's not a single statically linked executable, so my standards are peculiar. It wires into the path and you invoke it from the command line with 'claude'. Then you're in a REPL. You speak to it conversationally.
Claude generally like to work in a directory for a project, so go ahead and create one for whatever your project is, and the activate Claude from the command line there. It will ask you if you trust it, and then it will remember whatever you talk about in the context of that directory (and subdirs).
Claude runs all sorts of tools while helping you. It might use docker -- I don't really know, but I do know it is especially happy if you have python, because it will gleefully write one-off scripts to do things like rummage around the file system or make gnarly mass edits. (Oh, Claude is great at creating python tools for you if you need such. I use it a lot for things like 'take this JSON and extract these items and then format it into a Postgres SQL script for bulk importing into a table having this structure, mapping the fields like this'. It does thing like that nearly instantly and frankly with more robust code that I would have written for a one-off.) So the second thing I do is create a Python virtual environment in that that work directory. I be sure to 'activate' that virtual environment before invoking claude so that it has access to python scoped to that project.
You'll probably want a version control system. Claude understands git well. I like to use Fossil SCM for my personal projects. Claude knows of it but won't do commits and whatnot for you. So you have to do that yourself when you want.
Claude will eagerly rummage around that section of the tree to figure out what is going on. If you have any text files, it will read them. So I usually start with a text file describing what I'm going to be doing. It really doesn't matter what you call it because Claude will figure out that it's your project definition by itself. You can use the '/init' command to create a Claude.md that is a separate summary that claude uses to keep on track. I usually do that after I've made a few exchanges about what I'm going to do first, though.
When you first invoke Claude it will want you to 'login' to your account. This is done by launching a browser where you'll do the actual login. If you have multiple claude accounts (I have a separate one for real life work; here I'm using my personal one), you can use /logout, and then /login to switch accounts. The account login seems to be global to the system -- not local to the project -- so you'll probably want to set your user name distinctly via the 'setting' on the web interface to make sure the usage is being charged to the correct entity.
Speaking of usage, you can see that down in 'settings' on the web page. You can also use /usage in the repl. Sometimes it hangs in the repl. I don't know why. The web page auto-updates, so I usually have a tab open to that and then I can just check it at a glance to see how my token usage is going and when the next window opens.
So the next thing is to start the project conversation.
I have been working with my friend [Eric Hertz] for some years now on various project usually involving him find esoteric/vintage hardware and me disassembling the firmware. One recent one is M-740 Reverse-Engineering And Hacking Adventures, and the target device is a delightfully quirky 'typewriter' that is actually a plotter (Type-O-Graph). It's brains consist of two Mitsubishi microcontrollers in the M50740 family. The chip is mask-programmed. A separate activity is going on exploiting a mode intended for developers that, if it works, should allow us to get a rom dump. Rather than cutting up on that precious device, Eric found that Lo! and Behold! he had another piece of junk that used a controller in the same family, and that one was not nearly as precious, so he could test out the rom dumping idea on that before committing to surgery on the Type-O-Graph. He had success, and I now have a rom dump. But no disassembler.
Generating disassembly is a pretty straightforward translation of bytes to mnemonics, and that will get you a text file. However, for reverse-engineering it is more useful to have something interactive. A static disassembler will happily go off and disassemble data, and then you have to start another pass, perhaps manually merging, and heaven help you if you've commented or labelled anything because you can kiss all that goodbye.
There exist commercial and free tools for this, such as IDA and Ghidra. I don't know if those support the M-740 line -- it is quite old, though based on 6502. But I thought "Why not try out this vibe coding thing, and make a bespoke too. See how far you can get with that." And so I did. Figuring that someone else might like to know what the experience is like (I don't think the world will beat a path to my door for a M740 disassembler), I decided to blog it here for posterity to see how I did it. Maybe it will inspire someone in their own endeavours.
I have a Claude Code 'Pro' account, which means that I pay USD $20/month. (If I paid a year in advance it's a little cheaper, but I didn't/don't know if I will stick with it.) For that real money you get 'tokens' -- whatever those are. There are caps on token use. There is a window of 5 hours that you can exhaust before the next window replenishes, and there is a weekly cap that accumulates all those windows usage and then you have to wait to the week's end before that replenishes. So it's about USD $5/week-ish to use it all the way up to the cap. Beyond that you just have to wait, but now you can put it into 'extra-usage' which is a pay-go system. I don't know what that costs -- I'll try to live within my means.
So let's see what USD $5 will get you. It scarcely gets you a sandwich where I am.
Create an account to leave a comment. Already have an account? Log In.
Become a member to follow this project and never miss any updates
About Us Contact Hackaday.io Give Feedback Terms of Use Privacy Policy Hackaday API Do not sell or share my personal information
ziggurat29
mateusz.kolanski
Brandon
chris jones