VOGONS


x86 emulator

Topic actions

First post, by drsly

User metadata
Rank Newbie
Rank
Newbie

Hi all,

I'm working on a PC emulator project, to learn more about the workings of the hardware.

My goal is to have accurate emulate of a Pentium system circa 1996.

So far I have implemented:
- majority of x86 instruction set (real mode)
- 8259A PIC
- 8253/54 PIT
- 8237 DMA controller
- 8042 keyboard controller
- 82077AA floppy disk controller
- Basic VGA (text mode only)
- still lots more to do, obviously

This is all my own work, based on reading tech datasheets and various sources on the internet. I have a bit of background in C and assembler, though never actually used either in my role as a .Net developer.

Right now I'm able to POST (using Bochs bios image), and load the boot sector from a floppy image, which is great.

Problem I'm having is that the bugs are getting much harder to find. The DOS boot disk I'm testing hangs somewhere after displaying 'Starting MS DOS'. Running the same disk under Bochs debuger, there's 20 million cpu cycles from the prompt until the next screen activity.

If anyone can help, I need ideas on how to test what I've built so far. Maybe something simpler than DOS, or some specialised boot disk image for testing hardware emulation? I'd really like to implement protected more & paging next, but there's really no point doing this until everything else is working!!

In case anyone's interested, the source is at https://bitbucket.org/DrSly/pcemu/src/ (note the master branch isn't the most up to date, see the "dev" branches, currently dev_20190630 is the most recent). You'll need a C compiler, as well as rom images for bios/vga (PM me for details).

Any advice from someone who's done this sort of thing before will be greatly appreciated. Thanks for reading 😀

Reply 1 of 4, by danoon

User metadata
Rank Member
Rank
Member

I would say the easiest way would be to have another emulator that works and modify it to log instructions the same way as your emulator so that you can do a simple diff and see where they differ, but even then you will find it difficult because of timing issues, like interrupts running at different times.

As you probably already know, the easy part is writing the emulator. The hard part is debugging it. I've been debugging mine for a couple of years and I still find issues. There have been bugs that have taken me multiple weeks to find. When it crashes I usually try to find an address that gets run only once before the crash that isn't too far from the crash and start logging from that point on. And if that isn't possible, I might find an address of interest and count how many times it runs before the crash, then in the code turn on logging after it runs x number of times. The longer I spend on a bug the more temp code I write to try to find it and sometimes I end up writing my own custom diff program so that it can ignore chunks of code I know will be different.

The worst bugs are ones that don't crash but cause noticeable problems, like a game draws wrong.

http://www.boxedwine.org/

Reply 2 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'd advice to implement the common log format I and some other emulator developers have made: Common log format

See also(simplified version(without memory transactions): https://sites.google.com/site/capex86/common

It's partly supported in CAPE and IBMulator and fully supported in UniPCemu (disable the extended logging options for compatibility with the current standards).

I'd advice setting the settings in UniPCemu as follows for the most compatible log:
- CPU: 8086/8088
- Clocking mode: IPS
- CPU speed: 300 cycles(so actually running at 300kIPS).
- Use Turbo CPU speed: Disabled
- Debugger log: Always log, even during skipping, common log format
- Debugger state log: Disabled
- Architecture: XT
- Debugger advanced log: Disable advanced logging

That has the most compatibility with the other emulators. Of course the advanced logging can be enabled to add stuff like memory I/O and interrupts etc.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 4, by drsly

User metadata
Rank Newbie
Rank
Newbie

Thanks for the replies.

For now I've used similar debugging methods - I look for an address that's hit only once, and single step from there, comparing the execution against Bochs. I think using Bochs instrumentation plugins to customise it's logging to match mine will make this easier. I also like the idea of a common log format. I'll definitely look into implementing this at some stage.

https://github.com/barotto/test386.asm also helped identify a bug or two.

I can now get to an A> prompt once himem.sys and emm386 are removed from config.sys

Looks like I'll be implementing protected mode soon.

Btw, @superfury, the link from your bitbucket repo, http://www.superfury.tk/ is blocked by my virus scanner. It says "The web page is on the list of websites with potentially dangerous content". Do you know anything about this?

Reply 4 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

Oh, guess I'll have to remove that link. The site has been down for more than about a year by now(mostly due to not refreshing the webhost one every now and then, thus terminating the host.

I'm still reachable here, so luckily that isn't much of an issue. The main app(UniPCemu) has also been moved to the itch.io service, so it hadn't been updated for a long time(still got the server files, databases and settings backed up, so it might still be able to be restored. Although I doubt I will, since it requires manual intervention each month or so to keep it running (due to the host terminating the account without logins for about a month).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io