x8086NetEmu, an 8086 emulator written in VB.NET

Emulator Status

This section will be updated every time I reach a milestone. That is, each time I’m able to fix some important bug or I implement an important new feature(s).

As soon as the emulator is at a state where I consider it to be “stable enough” and nearly “feature complete”, I will post here its source code.

Again, make sure you check this section often as I will be updating every time I work on the emulator and I’m able to make some progress.

October 9, 2012

As of last month the emulator was FINALLY able to boot from a PC DOS 1.0 floppy!!!!!!!!!!!!!!!!!!!!

x8086NetEmu Boots PC DOS 1.0
Sadly, the emulator still presents an obscure bug which is affecting BASIC.
For some odd reason (and I hope it’s not related to the way I’m updating the flags after emulating an instructions that affects them) the BASIC code fails to work correctly. Take a look at this screenshot to see what I mean:

x8086NetEmu BASIC Bugs

And take a look at this one:

x8086.NET BASIC Bugs

Not matter what I do I cannot seem to be able to correct this issue — actually, none of the bugs that I had to correct to be able to boot into PC DOS 1.0 seemed to affect this bug.
Hopefully, this bug (or bugs) that are affecting BASIC are also the reason why the emulator won’t boot any other OS I’ve tried.

October 10, 2012

Found some issues with the way I was handling invalid reads/writes to protected (ROM) memory.
After fixing this issue (although I still think I have some bugs in the memory handling code), BASIC is now able to load .bas files from a diskette and execute them.

Unfortunately, now that it can run some .bas programs, I’ve found that my CGA emulation sucks!

On the positive side, some more modern DOS versions (such as 3.3 for example) seem to advance a little bit further than before but they still won’t boot and get stuck in a loop “looking for something”…

x8086NetEmu booting NEC-DOS 3.3 in an endless loop

x8086NetEmu booting NEC-DOS 3.3 in an endless loop

I have also noticed something weird. The time in the emulator appears to advance 100 times slower than expected!

x8086NetEmu Time Bug

x8086NetEmu Time Bug

What appears as “milliseconds” should have been “seconds”… what the hell am I doing wrong? Is the scheduler implementation from Retro wrong or did I just implemented it wrong?

October 13, 2012

Well, just as I thought — it was my implementation of Retro’s scheduling.
As it happens I didn’t correctly port the wait() and notify() Java functions.
Initially I interpreted wait() as Thread.Sleep() and that happens to be wrong; the correct interpretation is trough the Monitor synchronization class.
So, now interrupt 0 is fired every ~100us, as per the XT specification.

Moving on, I started working on the Speaker emulation and it appears to be working… kind of. Some frequencies appear to be incorrectly calculated so I decided to work on the emulation of the PIT 8254 and doing so I’ve completely fucked up the emulator! Nothing works anymore!

I’ll post back as soon as I have corrected this regression… I think I’m going to need a version control system so that I can more easily handle changes to the code and keep track of what I did yesterday that is messing things up today ๐Ÿ˜‰

Man!, I’m spending too much time on this project!

December 8, 2012

A couple of days ago I got a Raspberry Pi (Model B rev2.0) for a new project which I’m supposed to start working on right away… but the temptation was too great for me not to try the emulator first!

Unfortunately, the current version of mono for Raspbian โ€œwheezyโ€ appears to have a bug involving floating point operations, which renders most projects completely unusable.
This bug is so severe that you cannot use any WinForms-based project as it will fail with a weird exception. This is a very well known issue by the community and I’m hoping they’ll be able to get the required parties to solve it… soon.

So far, when running in the Raspberry Pi, the emulator seems to reach the point where the BIOS clears the screen but appears to get stuck somewhere…

So, because we cannot (yet) use WinForms applications and my CGA implementation works through GDI+, I decided to code an alternative implementation that, instead, works directly with the Console. This means that you can now run the emulator in a console without requiring WinForms!

Here’s a screenshot of the emulator running with mono on a Windows 7 command prompt:

x8086NetEmul using the new console video adapter

x8086NetEmul using the new console video adapter

December 30, 2012

Well, drunk as I am, I have finally been able to determine the issue with BASIC!
Consider this code:

This, of course, is to be expected and it’s the correct behavior.
What’s happening is that, in the first case, since b1 is of type byte the shifting of the bit in b1 wraps around the available 8 bits space, twice; resulting in a value of “1”.
In the second case, b2 is large enough so no warping occurs and the variable is able to “withstand” the shifting operation.

What does the value of “65536” (which requires 17 bits) mean to a 16bit CPU?
Well, it means that the result is “-1”. That is a value of “1” with the Sign Flag turned on.

I had originally declared all 8 bit registers (such as AH, AL, BH, BL, etc) as bytes so any logic operation, such as ROR, that produced negative values (or values above 255) generated incorrect results.
Consequently, by simply changing the type definition of the 8 bit register to Integer fixed the problem!

x8086emu_fixed_issue_basic

This version finally resolves “some” of the arithmetic issues that have affected the emulator since its initial implementation

Unfortunately, as it can be seen in the screenshot, the emulator still has some obscure bug that causes it to produce an overflow error when it should be perfectly able to print the number 12345678.

…small steps…

January 4, 2013

I have finally manage to work some more on the CGA emulation. Although it is still far from from perfect, we are now able to render graphics.

x8086 CGA Graphics Mode 4 (320x200 4 colors)

x8086NetEmu CGA Graphics Mode 4 (320×200 4 colors)

At this stage, the CGA emulation supports the seven basic CGA modes:

  • Mode 0: 40×25 B/W
  • Mode 1: 40×25 Color
  • Mode 2: 80×25 Mono
  • Mode 3: 80×25 Color
  • Mode 4: Graphics 320×200 4 colors
  • Mode 5: Graphics 320×200 Mono
  • Mode 6: Graphics 640×200 Mono

I have also implemented support cursor blinking.

Finally, I’ve done quite a lot of code-clean-up which has resulted in a huge performance boost.

Alas, the things that weren’t working ain’t working yet… so it’ll still be some time until I make the code public.

August 20, 2013

I haven’t had much time to work on this project since the last update in January, so all the aforementioned bugs still persist.

But, as per Patrick’s request, I’m making the source code available.
Remember that the code is dirty, a bit unorganized and it does not work correctly.
With the code I’m including the BIOS and BASIC roms plus a PC-DOS 1.0 image, which is the only image the emulator is able to boot.

(Download removed — keep reading)

September 27, 2013 – The Eureka day!

On September 27, at around 5:00pm, I found the last of the “game stopper” bugs that prevented the emulator from being usable.

The culprit?
The flags… again. The way the Sign and Zero flags were being calculated for operations that required subtraction was incorrect. A little adjustment on how these flags are calculated for operations such as DEC, SBB and SUB has solved a problem that has been bugging me since day one!

I have to acknowledge, that, before correcting this bug, Mike Chambers from fake86, helped me discover another serious bug, related to the way some functions were handling 8bit values in 16bit operations. Thanks Mike!

Anyway, although the emulator is now able to boot all the images I’ve been using to test it (including MS-DOS 6.22) and it can run a fair deal of programs, it still appears to have some bugs. Although I’m not 100% sure the bugs are related to the 8086 emulation, I think they are more related to the poorly implemented CGA adapter.

So, now that the emulator is (almost) working, I decided to make several improvements:

  • Performance: This release is up to 4 times faster than any other version. Though there are still are areas that can be improved.
  • CGA Emulation: I finally fixed the way text is rendered making it look much more, well, real.
  • Sound: Although it still has some minor issues, the audio emulation has gotten a lot better.
  • Interrupt Handling: Fixed several bugs that caused the emulator to randomly either crash or freeze when hardware-based interrupts were triggered.
  • WinForms version Improvements: The WinForms version now provides a menu-based UI to manage different aspects of the emulator, including the loading/ejecting of floppy disks.

As I mentioned earlier, there are still tons of things to do… but for now, go ahead and play with this VB.NET – based 8086 emulator. Have fun!

Remember to post in the comments below any questions, suggestions you may have and if you find a bug, please, share it!

October 2, 2013

Fixed many more bugs… which allow the emulator to boot Minix 1.5.
At this moment, the emulator will boot every single image I have thrown at it (except for Mininx 2.0).
Also, I have finished implementing support for hard disks. I was able to perform a clean install of DOS 6.22 without a hitch.

Unfortunately, while playing with MS DOS 6.22 I discovered another bug which affects QBasic, Edit and Microsoft Diagnostics.
However, the equivalent of these programs for FreeDOS are working perfectly.

Defrag also refuses to work, complaining that it cannot be run under a multi-tasking environment. Go figure.

I was also able to install Windows 1.01, but it doesn’t work; I think it’s all because of the same bug that is affecting QBasic, Edit and the others.

Finally, I’ve changed the default font used by the emulator so it looks more like a real CGA display.

Defrag Fail

Update: I just confirmed that the emulator works under MacOS X 10.8.4 (using Mono) and, quite surprisingly, the console version also works on the Raspberry Pi!

I’ll post the new code tomorrow…

October 4, 2013

Here’s the promised download link.

This version includes some major improvements, although it appears that it still has a major bug which prevents it from working correctly.
Hopefully, the bug is no longer related to the CPU flags… ๐Ÿ˜‰

Download x8086NetEmu (with Source Code and several floppy/hard disk images)

x8086NetEmu Source Code + Binaries 0.2 [8.5 MB]

Update 2017/3/9: Latest releases are now available on GitHub under Releases

PAGE: 1 2 3 4

  • Patrick VDW

    Hello,

    Me again… sorry for that, but perhaps now I’m in the right blog.

    Is it possible to send me the x8086NetEmu source please? I’m trying to “understand” a minimal PC (e.g. BIOS, CPU, Memory, some devices and then booting do DOS 1) so your code would help me enormously…

    You can send it to: pat_vdw@yahoo.co.uk

    Many many thanks in advance!

    Patrick VDW

    • Hi Patrick,

      I will be posting the sources for the emulator in a couple of days.
      I’m trying to fix a couple of bugs before I post it.

      • Patrick VDW

        Hello,

        What a quick answer: you just made my day!

        Many thanks!!

        Patrick

        • Patrick, I’ve just posted a link to the source code and binaries.
          You’ll find it under the “August 20, 2013” update heading.

          • Patrick VDW

            Hello,

            I have them. Again: many many thanks…

            If you ever want to visit Belgium, give me a note and I’ll buy you some good Belgian beer!!

            Kind regards
            Patrick

          • That sounds awesome!
            I’d love to visit Belgium!!! ๐Ÿ˜‰

  • Mike Chambers

    This looks interesting, but I’m having a problem running it. All I can get out of it is SlimDX errors. I’ve got the runtime installed, but the program refuses to run. I tried it on both my main desktop, and on my netbook. Same issue. (BTW, I’m the writer of fake86)

    I’m interested in seeing how an 8086 emulator written in VB.NET actually performs. I wrote one in VB6 just for fun about a year ago. I’ve never seen one in classic VB6, and thought it would be kind of funny. It runs really badly. (of course)

    • Hi Mike.
      First of all, congratulations on your fake86 — it is simply amazing. I’ve used some of your own code (from an old release) to develop several of the low level CPU emulation in x8086NetEmu.

      Now, as for the problem you’re having.
      I’m not sure what could be causing that… and, honestly, I thought I had included everything in the ZIP file so that anyone could re-compile it.

      I will now re-build the ZIP archive and make sure everything is included.

      I’ll post back when the new ZIP archive is available.

    • Mike, me again…
      I have just updated the ZIP file and I can confirm that it now includes all the necessary files to compile.

      Please (please!) let me know of any bugs you find ๐Ÿ˜‰

      • Mike Chambers

        Excellent! Thanks.

        I believe I know why you can’t boot newer versions of DOS. You haven’t implemented group 5 opcodes. Looks like you’re sending ops FEh and FFh to the group 4 handler, but FFh is group 5. It handles mostly indirect calling and jumping.

        When I first started writing my emulator, I had bugs in group 5. Once I fixed it, it booted DOS 6.22! ๐Ÿ™‚

        It’s probably the source of a lot of your problems.

        • Unfortunately, that wasn’t the problem as the Group5 is already implemented inside the Group4 function…

          What I did find, debugging my code vs yours is that at some point the code that is loaded from the boot disk is offset by one byte in my code.

          So the whole set of instructions are not at the correct location (IP).

          I honestly don’t even know where to start looking for this one!

          • Mike Chambers

            Are you taking into account that the INC/DEC in group 4 are byte operations, but in group 5 they are word ops?

          • Yes.
            Anyway, I think I have found the problem…or at least, one of them.

            Just so you know, it is related to your “signext” function…

            I’ll let you know if implementing it solves the problem(s).

          • Mike Chambers

            Good luck! It will be fun to play around in it if it can boot a newer DOS. Maybe even run some games…

          • That’s the idea ๐Ÿ˜‰

            One question through.
            Since type casting in VB.NET doesn’t really work as in c++, would you say that my interpretation of your signext function is correct?

            v = v And &HFF
            If (v And &H80) 0 Then v = &HFF00 Or v
            Return v

            Basically, I first convert the value into a byte and then, if the byte is signed I OR it with FF00

            It appears to work on some cases, but not all…

          • Holy cr…
            It just booted 6.22!!!

            Unfortunately, it crashes right away.
            Guess I’m still missing a couple of “tweaks”.

            (Sorry for the multiple posts — I got a bit carried away)

          • Mike Chambers

            Yeah, that should work. Good job getting 6.22 kind of working! Does the program hard crash or do you mean DOS just goes nuts or stops responding or something?

          • After the command prompt appears, if you try to type any commands it either shows a “bad command or argument error”, crashes (cpu enters loop cycle), or halts the CPU.

          • FINALLY FOUND THE DREADED BUG!!!!

            I’ll post a detailed description of the problem later… but for now, here’s the x8086NetEmu running QBasic from DOS 6

          • Mike Chambers

            NICE job!! Haha, this looks cool. Will download and play with it.

          • Mike Chambers

            Alright, yeah it works pretty nicely now for the most part. Great! I played Space Commander a bit, which was perfect. The only problem I had was that often the keys would repeat when I pressed them. Also, I can’t compile the source again because it’s looking for the Binary and ConsoleCrayon stuff in a hardcoded path on C: like before. Good work though.

  • Mike Chambers

    I see you say you can’t run MINIX 2.0. Fake86 won’t boot those floppies past the boot monitor either. Download the “DOSMINIX” package of version 2.0.2. and try booting the MINIX.MNX hard drive image directly. That boots in Fake86. Hit escape when it gets to the monitor and type this:

    hd=bios
    save
    boot

    …and see how that works for you.

    • No. It doesn’t boot from that image either.

      I know I still have a serious bug since most of DOS 6.22 utilities such as edit.exe and qbasic.exe, for example, won’t work on x8086NetEmu, yet they work perfectly fine under fake86.

      The funny thing is that the DOS 6.22 image I’m using boots just fine with x8086NetEmu but freezes with fake86…

      Anyway, thanks for pointing me to DOSMINIX.
      Hopefully, that bug that prevents x8086NetEmu from booting it is also related to the issue I’m having with most of the DOS 6.22 programs.

      • Mike Chambers

        Did you make install DOS on that image that fake86 locks up on from inside your emulator? If so, maybe you’re not using the same head and SPT values that I am for a hard drive image. That could cause it. That may even cause that MINIX image to be reading in the wrong sectors. It *may* explain your divide error crash. It’s a possibility anyway. Does your DOS image work in QEMU?

    • With the image you suggested, the emulator doesn’t do anything… CS:IP jump to some invalid address and it freezes.

      However, I have a Minix 2.0.2 image, which x8086NetEmu has never been able to boot, but it does display a boot prompt.

      So, after the prompt, I followed your instructions and this is what I’m getting:

      • Mike Chambers

        Well it’s getting there at least, lots of progress. It’s so hard to debug this stuff! Could be the divide code, but could also have nothing to do with it whatsoever lol. So much fun.

        • ha haha ha…

          The fact that the program is reporting a divide error could just come from a poorly implemented DAA opcode. Who knows!

          Anyway, the fact that fake86 can boot that image (although I haven’t tried it yet), might help me figure out what’s going on.

          Oh… and I’m “pretty sure” that all routines in Group 3 (including DIV) are properly implemented; otherwise, the emulator wouldn’t be able to even boot DOS 2.x

          That said… I could be just plain wrong. Just as you said: this is so freaking hard to debug!

          …but it’s fun…;)

    • Mike, when you have the time, could you please check why fake86 is not booting the “MS-DOS 6.22.IMA” image I’m using?

      To obtain it, just download the latest version of the x8086NetEmu.

      It baffles me that fake86 is so MUCH MORE complete than x8086NetEmu and yet, it fails to pass executing cd1.sys from the image’s config.sys.

      I mean, at this point, I’m just looking at the way we have implemented some of the most complex opcodes (such as those from Group 2).
      I don’t know… maybe if you can find some bug in your code, might help me find a dozen in mine ๐Ÿ˜‰

      • Mike Chambers

        I didn’t notice this message before. I just saw your next message. I’ll have a look and see if I can figure that out. Too bad you don’t have a forum here, it would be easier to talk than these messages.

        • Yes, this messaging system is really annoying.
          I do have a forum, but it’s on the “commercial” web site — I’ll do some research and see if there’s a simple forum system for WordPress.

        • The forums are now available!

          Here’s a direct link to the x8086NetEmu’s forum:
          http://whenimbored.xfx.net/forums/forum/software-discussion/x8086netemu/

          • Mike Chambers

            Great! It won’t let me start any threads though, it says I need to be logged in but I don’t see any special log in or register links for the forum part. Maybe I’m overlooking it.

          • Click the “Log In” link on the right hand side (bluish section) and select “Register”.

            Registering on the blog is the same thing as registering on the forums.

            I wish the forums could support OpenID… but unfortunately, it doesn’t.

      • Mike Chambers

        Okay, figured it out. CD1.SYS first of all is trying to execute some 386 opcodes. It’s trying to use op 66h which is operand-size prefix. It’s trying to execute some 32-bit operations, but that’s not exactly why it’s hanging.

        If I change my port read function to return 00h instead of FFh on a port that is not connected to anything, it continues to the DOS prompt as your emu does.

        However, I verified on my real IBM XT that the correct behavior is to hang at “BANANA”. FFh is actually what should be returned for a port not connected to anything (open-bus). This is verified further by the fact that when I return 00h, the BIOS reports a bunch of hardware that I’m not actually emulating. Joystick, extra serial ports, etc.

        If you fix that open-bus read value, yours should also hang in the same place. The proper solution is to just take that device driver out of config.sys.

        • Mike, do you know the port number that is being queried?
          As far as I know, I always return 0xFF for ports that the emulator does not support.

          • Mike Chambers

            It’s reading CFCh and CFDh. Not sure what else it might be.

          • That’s weird…
            I can confirm that the emulator is returning 0xFF for all unsupported port addresses, including 0xCFC and 0xCFD.

  • Pingback: x8086NetEmu for Linux, Mac OS X and Raspberry Pi | When I'm BoredWhen I'm Bored()

  • Pingback: VB.NET and its broken data types | When I'm BoredWhen I'm Bored()

  • Pingback: Factorial calculation algorithms - When I'm Bored()