News for hackers. Stuff that matters.

GloriousCow

Re:MartyPC – A Cycle-Accurate IBM PC/XT Emulator on Wednesday September 16, 2026 @03:34PM (#49731805)
Did you pick some other video card besides CGA?
Thanks. This should be fixed for Tandy 1000 now. On PCjr there is no backslash key, you have to type a backspace using alt + /, so I will need to define a macro that does that for you.

The Tandy 1000 will need its own OSD since the tandy keyboard differs from the Model F in significant ways. You'll notice that if you type shift-backslash on the current model-F based OSD you'll get a 7 instead of the expected |. Because backslash is on numpad 7 on the Tandy.

Dealing with this stuff is tons of fun

feel free to fork MartyPC to build it for your Amiga
yes, swipe up to show a keyboard. this currently only supports the 5150/5160 completely as it is a Model F keyboard and the Tandy/Jr have some differences.
I need to know what keyboard layout you're using. If it is not a standard US keyboard it will need a mapping
DOS has the 'keyb' utility and 'keyboard.sys' to support different layouts, using various code pages.

If you have a CGA card, you're stuck with the code page of the ROM your card came with, which in most cases was code page 437, although a few variants were made.

EGA/VGA had software fonts so other code pages could be loaded.

great emulator and nice guy too. maybe i should ask him if i can use his HDD sounds
they're planned at some point. I need to write a utility or custom controller rig with a pico that can step the head on an MFM drive in patterns i can record, then model stepping to cylinder in the hard disk controller.
The PCjr also famously has no DMA, so things like floppy drive transfers are both extremely slow and somewhat unreliable - the IBM floppy controller is somewhat additionally weird is that they disable interrupts as well. The only way the PCjr knows what the controller is doing is by polling its status register, and there is enough ambiguity that it sets a 555 timer that will reset the FDC and start everything over if things time out.

The combination of these two decisions means its inadvisable to type while your floppy drive is transferring data

I am not the OP of this post, but they're just using my github description. when I first wrote it, Rust was a novel choice for an emulator, and it helped people find examples of emulators written in Rust.

believe it or not I didn't tailor it for the HN meta

It is indeed a Marty McFly reference. The original demo I was trying to run was called 8088 MPH and is full of Back to the Future references.

I was trying to Run Back To The Future, so I figured I'd call my emulator either Marty or McFly.

Unfortunately I found out about the FM Towns later, so I renamed it from Marty to MartyPC so you could google "MartyPC Emulator" properly.

Yeah the OSD is only the Model F and the Tandy has some difference so the OSD keyboard may not work quite right with the Tandy.

I have to make all new pixel-art for a Tandy 1000 keyboard and PCjr keyboard. Fun

I am very close to emulating the Covox - I emulate the Disney Sound Source, which is just a Covox with a FIFO
People will generally get angry no matter what you do. People are also angry it is MIT licensed.

But honestly I wanted to learn the Rust programming language and I thought writing an emulator was a good a project to learn as any.

I have been working on a emulator in C++ in collaboration with a friend, it is also cycle-accurate. It is called XTCE-Blue.

easy - the PCjr keyboard interface.

It is insane because IBM wanted a wireless keyboard. If you're not familiar with the PCjr keyboard, it has two IR transmitters (they are electrically the same, just having two gives you a better transmission path). The PCjr system has an IR receiver.

Now, a normal keyboard cable is a standard two-wire serial protocol with clock and data. Being wireless, you have no clock, so you have to synchronize clocks, or have clock recovery built into the protocol. The PCjr does the former, using the 8253 timer chip.

The keyboard has no way of knowing if the system has received a keystroke, so the system must receive every keystroke - they can't be stored in a fifo, they can't be resent if the CPU missed it.

This rules out the possibility of using system interrupts - so when you type a key on the CPU and the IR receiver gets the start bit - the NMI line is raised, the 8253 is programmed to time the clock bursts from the IR receiver, and the CPU reads out every bit of the scancode.

In software.

What would you say is missing or not working well?
Hi, thanks for checking out MartyPC. I'm the developer if there are any questions.
When I started writing MartyPC over four years ago, writing an emulator in Rust was still somewhat novel. The development of the 'egui' immediate-mode graphics framework made it possible to make one with an advanced interactive debugger.

By mentioning Rust people have been able to more easily find MartyPC as an example of how (or how not to) write an emulator in Rust.

Perhaps the tag as outlived its usefulness, especially if people find it pompous or something. I'm not trying to be Rust cultist, I swear.

When I started this emulator four years ago, this was the first PC emulator written in Rust so it was novel.

I've heard the comments here loud and clear :) You all don't think Rust is novel anymore and I should lose that bit.

What keyboard layout are you using? I can't reproduce on a US layout.
I've built out a full keyboard-remapping system, to support any keyboard layout. I need help building these files.

Are you using DVORAK? If you are willing to help, please open a Github issue with some info about your keyboard, and I'll build support for it.

I haven't implemented the Soundblaster card yet, although it's quite high on my list of things to do.
Re:Executable Emoji on Saturday August 08, 2026 @03:50PM (#49225240)
Thanks for checking this out.

I've uploaded all the binaries to GitHub if you're struggling with copy & paste. There's also a new example in Braille.

https://github.com/dbalsom/executable_unicode

Re:Executable Emoji on Friday August 07, 2026 @03:33PM (#49215246)
For the 'hello' program, you need to use DosBox-X with the 'cpu cputype=8086' parameter. You can use 86Box or MartyPC as well but those take more effort to set up and get the executable onto them.
Re:Executable Emoji on Friday August 07, 2026 @03:32PM (#49215231)
Try copying from the links provided after each emoji block. That goes to my disassembler which should independently verify the md5.

I think blogpspot unfortunately mucks with the emoji.

Re:Executable Emoji on Friday August 07, 2026 @01:52PM (#49213942)
having the emojis survive copy & paste from a browser is surprisingly frustrating. I would have expected there to be well-defined semantics for this, but a lot of things insert variation selectors (U+FE0F) after certain emoji which breaks the code.

It's less to do with browser versions and more to do with websites. Mastodon and unfortunately blogspot seem to mess up the emoji. Fortunately you can click on the disassembly links that go to my disassembler and copy them from there.

Re:80386 Microcode Disassembled on Saturday May 23, 2026 @05:18PM (#48251629)
The actual output of microcode disassembly is just a text file - a line of code for each microcode word, in essentially a a new dialect - a type of static assembly language. reenigne had to invent names for a lot of things, that will now become the official names of these things, unless Intel ever decides to speak up and make corrections.

That language can then be translated into Verilog, and has been.

Re:80386 Microcode Disassembled on Saturday May 23, 2026 @04:55PM (#48251426)
We also had decoded the 386's match-decoder PLA, so we knew roughly the locations of different opcodes were in the microcode itself, which was very helpful. Some opcodes have very specific operands, so would have unique field references. Some forms only operate on EAX/AX, for example, so if you find those instructions you have a hint of how the AX register is encoded as an operand.

Other instructions like PUSHA and POPA are implemented as loops that iterate by incrementing the fields corresponding to registers - and we know in what order they operate.

Bit by bit, relation by relation, you can puzzle out the format of the microcode. Of course, this is glossing over the enormous added complexity of protected-mode operations. This was a herculean effort by reenigne, and I don't think it is hyperbole to call it one of the more impressive human achievements I have witnessed in my lifetime.

Re:80386 Microcode Disassembled on Saturday May 23, 2026 @04:49PM (#48251374)
Intel had given us some clues - they had written somewhere that the 386 had 2560 microcode words. The microcode array has 37 banks - each bank resolves one bit from the 37 bits that comprise a microcode word. But which way to decode them? From top down? Bottom up? Were they interleaved in weird ways?

Documentation from the NEC vs Intel lawsuit ended up documenting the microcode word format for both the 8088 and NEC V20 CPUs, but unfortunately, we were on our own for the 386. But we could take educated guesses - working off the 8088 field format, what additional microcode fields would a 386 add? What fields would expand and how many bits would they need?

We used a lot of python scripts to decode the microcode array into 37-pixel wide, very long bitmaps, in different permutations, to see if any vertical patterns emerged that would hint to us the boundaries of microcode word fields. And some did emerge!

Re:80386 Microcode Disassembled on Saturday May 23, 2026 @04:28PM (#48251148)
I worked a bit on the extraction process so I can chime in here a bit. The first part is to just mark the x,y locations of where all the bits are, generally by the intersection of the rows and columns of the microcode array.

Then you have to classify them as 0's or 1's. Each is visually distinct, a 1 being encoded by the presence of a transistor and a gap in the polysilicon. We didn't have to guess which is which is by the nature of Intel microcode we could assume 0's were much more frequent, so a transistor meant a 1.

There are some automatic tools designed to perform this work via color thresholding, but they didn't work very well here because some of the mosaic was blurry, and a lot of dust had crept in which created false 1 bits.

Instead, we trained a convolutional neural network to classify the extracted bit regions into 0's and 1's. This was overlaid back onto the original mosaic as white or black squares at 50% opacity.

Then we spent several long, tedious days just checking the results for errors. Finally we had the raw 2d array of bits - the next step is to extract the microcode words from the bit array.

Older »