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!!!!!!!!!!!!!!!!!!!!
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:
And take a look at this one:
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”…
I have also noticed something weird. The time in the emulator appears to advance 100 times slower than expected!
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:
Well, drunk as I am, I have finally been able to determine the issue with BASIC!
Consider this code:
Dim b1 As Byte = 1
Dim x1 As Integer = b1 << 16 ' x1 = 1 Dim b2 As Integer = 1 Dim x2 As Integer = b2 >> 16 ' x2 = 65536
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!
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.
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.
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 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.
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)
Update 2017/3/9: Latest releases are now available on GitHub under Releases