HNHacker News
TopNewBestAskShowJobs

GloriousCow

246 karma · joined October 1, 2023

submissionscomments
GloriousCow··on MartyPC – A Cycle-Accurate IBM PC/XT Emulator
Did you pick some other video card besides CGA?
GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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.

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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.

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
I am very close to emulating the Covox - I emulate the Disney Sound Source, which is just a Covox with a FIFO
GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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.

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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.

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
Hi, thanks for checking out MartyPC. I'm the developer if there are any questions.
GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
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.

GloriousCow··on MartyPC is a cross-platform emulator of early PCs written in Rust
What keyboard layout are you using? I can't reproduce on a US layout.
GloriousCow··on Executable Emoji
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

GloriousCow··on Executable Emoji
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.
GloriousCow··on Executable Emoji
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.

GloriousCow··on Executable Emoji
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.

GloriousCow··on 80386 microcode disassembled
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.

GloriousCow··on 80386 microcode disassembled
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.

GloriousCow··on 80386 microcode disassembled
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!

GloriousCow··on 80386 microcode disassembled
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.

GloriousCow··on 80386 microcode disassembled
nand2mario has made a Verilog implementation from it. It currently runs DOOM, but some of the more fiddly protected-mode bits prevent it from running full operating systems (besides DOS). I'm sure the bugs will get ironed out eventually.
GloriousCow··on 60fps Video on a CGA? – The GlyphBlaster
Replacing the RAM would probably be straightforward - on the CGA its only 16K, so only twice as big as the font ROM. It's slightly trickier, considering the address lines are row and column multiplexed, and there are eight sockets to tap, and you have to be able to support reading and writing.

The CGA is dumb and re-fetches memory eight times per character row, so what you could do is tie in to HSYNC, so you could basically synthesize three new address lines from the row counter. That would give you a virtual 128K of video memory - a single character cell could then have 8 different sets of foreground and background colors. You could make some pretty impressive composite art with that!

I will likely do this for fun at some point, because I want to see "Never Gonna Give You Up" in the classic magenta & cyan palette, but this is not going to be something that anyone else will likely ever do as the RAM is soldered in - and nobody but Omega-level nerds are going to de-solder eight chips for a meme.

GloriousCow··on Snow - Classic Macintosh emulator
Funny you mention that, I'm actually friends with twvd and we share a discord server and trade UI ideas as we both use the same GUI toolkit. Snow actually uses the disk image library I built for MartyPC.

Inspired is a strong word. I didn't invent the concept of an accurate emulator, although I'm certainly a fan of his approach.

GloriousCow··on A cycle-accurate IBM PC emulator in your web browser
MartyPC brings cycle-accurate IBM PC emulation to your web browser.

Run Area 5150 at 60fps on your phone!

Almost every feature from the desktop version is present if practical:

- View the realtime state of nearly every component of the system. - View live disassembly of CPU instructions. - Edit registers and memory. - Slow down or speed up the system. - Peek on how games draw their graphics with the Memory Visualizer.

GloriousCow··on Hide Photos on Floppies with a Flux Imager
This isn't necessarily a new technique, as black and white art has been put on floppies before: https://github.com/bzotto/picturedsk

But the new wrinkle here is support for grayscale, meaning photos or other grayscale artwork can now be put on a disk.

We can even put the art inside of valid sectors to keep the disk appearing completely normal to casual observation from a host computer.

GloriousCow··on PC Floppy Copy Protection: Xemag Xelok
For the ones that I make to look pretty, the data is colored in buckets of 8 bits, using the bit-count per byte to select a shade in 8 steps from 0-255. So there's at least 8 times less data than you would need. Then it is downsampled 4x to get nice antialiasing, so that is more data loss.

I do have a bit-mode, and if you rendered at high enough resolution you could do it, maybe something like 32k x 32k. But this is a very inefficient way to store a disk image. :)

GloriousCow··on PC Floppy Copy Protection: Xemag Xelok
Or when you win solitaire!
GloriousCow··on PC Floppy Copy Protection: Xemag Xelok
In this post in a series on PC copy floppy protections, we take a look at XEMAG duplication's "Xelok" scheme.

Xelok was quite devious on the Apple II, implementing "fat tracks" that could not be produced with a conventional disk drive. However the PC doesn't allow such tricks, so Xelok appears a bit different on the PC platform.

We take a look at two titles that use it, Sargon III and The Ancient Art of War.

We also take note of a rather amusing bypass for this protection!

GloriousCow··on PC Floppy Copy Protection: Vault Prolok
An investigation into the infamous 80's copy protection scheme PROLOK that involved burning holes on diskettes.

Also included is an interview with Quaid Software founder, Robert McQuaid. Vault sued Quaid Software for producing CopyWrite, a utility that could copy PROLOK protected diskettes.

GloriousCow··on PC Floppy Copy Protection: Softguard Superlok
EA's INTERLOCK protection (Marble Madness) uses deleted address marks.
GloriousCow··on Emulating the Early Macintosh Floppy Drive
An in-depth dive into the Macintosh floppy drive system, including the fascinating IWM (Integrated Woz Machine) custom floppy controller. The level of fidelity to properly emulate the Macintosh disk drive is impressive, and this should be an essential resource to any aspiring Macintosh emulator developers.