nepx / halfix

x86 PC emulator that runs both natively and in the browser, via WebAssembly
https://nepx.github.io/halfix-demo/
GNU General Public License v3.0
669 stars 86 forks source link

Emulator/JS communication - stdin, stdout, stderr? #21

Open mweichert opened 3 years ago

mweichert commented 3 years ago

Hi there,

Awesome project!

Is there a way for JS to interact with the emulator via stdin, stdout, or stderr?

I'd like to write to stdin and read stdout via JS.

Thanks! Mike

nepx commented 3 years ago

You can send raw scan codes to the keyboard controller using display_send_scancode. I believe it's exposed to the JS layer. Keep in mind that these are hardware scan codes, not browser key codes -- this list is pretty comprehensive. If you're sending in a string, for instance, you'll have to convert each character to its corresponding scan code.

The screen buffer is just an array of characters. The operating system itself manages the cursor position, scrolling, etc. to simulate a terminal, but the (emulated) hardware treats it as a linear array of characters. There's no way to capture writes to VGA RAM, although you could certainly add a hook somewhere in vga_mem_writeb.

This is an full system emulator -- it emulates the hardware of a standard PC. Unfortunately, it has no concept of stdin, stdout, or stderr because they're abstractions created by the operating system. You're probably looking for application virtualization, which emulates an operating system (letting you take control of these abstractions) instead of hardware. In the long run, it's probably better to invest in one of those (or write your own) than to try to work around these limitations.

If you do want to use this emulator, you have a few options, in order of feasibility:

Sorry if this wasn't the answer you were expecting, but hope this helps, regardless.

mweichert commented 3 years ago

Hi @nepx thanks for your reply. As I got into some of the examples after submitting this issue, what you state above makes sense.

One of the bottlenecks I'm seeing is the filesystem emulation. If my image includes a static binary, will that generally perform better than something that has to read libraries from the filesystem?

nepx commented 3 years ago

The emulator has no concept of files -- it's all sectors loaded from a disk. If I had to guess, the extra overhead of loading all those dynamic libraries would slow things down -- but on the other hand, if the operating system has these shared libraries in memory already, it'll just pull that data from the disk cache. Disk reads are by far the slowest part of the whole emulator, since network latency is typically orders of magnitudes slower than anything else in the emulator.

When in doubt, profile! You might find that one is decidedly faster than the other, or there's no real difference between the two.