What makes accurate emulation of old systems a difficult task? Unicorn Meta Zoo #1: Why another podcast? Announcing the arrival of Valued Associate #679: Cesar ManaraWhat are the laws concerning emulation in the US?NES cartridge ROM emulation with Arduino or Pi?How old-computer emulators work?What are all the known file extensions for Atari 8-bit disk/tape/cartridge images?Is emulation ultimately the future of retro computing?How to do I/O with emulation code?Are there runnable Multics systems available?Retro emulation with perfect V-syncWhat systems had the lowest resolution ever that still allowed games to be made?Operating systems which have non-x86 instruction set architecture
When do you need buffers/drivers on buses in a microprocessor design?
Will I lose my paid in full property
What is the best way to deal with NPC-NPC combat?
What's the difference between using dependency injection with a container and using a service locator?
How do I check if a string is entirely made of the same substring?
Putting Ant-Man on house arrest
What is purpose of DB Browser(dbbrowser.aspx) under admin tool?
Protagonist's race is hidden - should I reveal it?
Is Bran literally the world's memory?
A Paper Record is What I Hamper
What to do with someone that cheated their way through university and a PhD program?
How much of a wave function must reside inside event horizon for it to be consumed by the black hole?
Can we hide a text first in a picture and then hide that image again in one more image?
How long after the last departure shall the airport stay open for an emergency return?
Is it acceptable to use working hours to read general interest books?
Is it possible to cast 2x Final Payment while sacrificing just one creature?
How would this chord from "Rocket Man" be analyzed?
Are these square matrices always diagonalisable?
How can I wire a 9-position switch so that each position turns on one more LED than the one before?
Scheduling based problem
What is the least dense liquid under normal conditions?
First instead of 1 when referencing
What is the term for a person whose job is to place products on shelves in stores?
How do I prove this combinatorial identity
What makes accurate emulation of old systems a difficult task?
Unicorn Meta Zoo #1: Why another podcast?
Announcing the arrival of Valued Associate #679: Cesar ManaraWhat are the laws concerning emulation in the US?NES cartridge ROM emulation with Arduino or Pi?How old-computer emulators work?What are all the known file extensions for Atari 8-bit disk/tape/cartridge images?Is emulation ultimately the future of retro computing?How to do I/O with emulation code?Are there runnable Multics systems available?Retro emulation with perfect V-syncWhat systems had the lowest resolution ever that still allowed games to be made?Operating systems which have non-x86 instruction set architecture
Thanks to a lot of passionate and skilled people, we can emulate pretty much any retro platform today.
For most people they perform well enough, but in fact, a substantial amount of these emulators are hardly accurate when compared to the original hardware they are trying to emulate.
While some of them accurately emulate the target platform, it generally comes with a huge performance penalty, making this a never ending quest to perfect emulation.
My question is the following:
What makes accurate emulation of some old systems a difficult thing, if not impossible?
Obviously this is a fairly broad topic with potentially infinite answers, so let me know if and how the question could be improved to be a good fit for the website.
emulation
add a comment |
Thanks to a lot of passionate and skilled people, we can emulate pretty much any retro platform today.
For most people they perform well enough, but in fact, a substantial amount of these emulators are hardly accurate when compared to the original hardware they are trying to emulate.
While some of them accurately emulate the target platform, it generally comes with a huge performance penalty, making this a never ending quest to perfect emulation.
My question is the following:
What makes accurate emulation of some old systems a difficult thing, if not impossible?
Obviously this is a fairly broad topic with potentially infinite answers, so let me know if and how the question could be improved to be a good fit for the website.
emulation
add a comment |
Thanks to a lot of passionate and skilled people, we can emulate pretty much any retro platform today.
For most people they perform well enough, but in fact, a substantial amount of these emulators are hardly accurate when compared to the original hardware they are trying to emulate.
While some of them accurately emulate the target platform, it generally comes with a huge performance penalty, making this a never ending quest to perfect emulation.
My question is the following:
What makes accurate emulation of some old systems a difficult thing, if not impossible?
Obviously this is a fairly broad topic with potentially infinite answers, so let me know if and how the question could be improved to be a good fit for the website.
emulation
Thanks to a lot of passionate and skilled people, we can emulate pretty much any retro platform today.
For most people they perform well enough, but in fact, a substantial amount of these emulators are hardly accurate when compared to the original hardware they are trying to emulate.
While some of them accurately emulate the target platform, it generally comes with a huge performance penalty, making this a never ending quest to perfect emulation.
My question is the following:
What makes accurate emulation of some old systems a difficult thing, if not impossible?
Obviously this is a fairly broad topic with potentially infinite answers, so let me know if and how the question could be improved to be a good fit for the website.
emulation
emulation
edited 5 hours ago
Aybe
asked 5 hours ago
AybeAybe
8721619
8721619
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Almost all computer systems have multiple different devices operating in parallel. For example, the CPU is typically running parallel to the video generation hardware.
This can be very difficult to emulate accurately, as interactions between different devices require that the emulation of each device proceeds in sync with the rest. Each device may be running on a different clock, and it becomes necessary to accurately emulate things like bus contention and DMA slot allocation.
There is also the issue of simply knowing how the original system actually behaves. Even now emulator developers are still finding new behaviours of classic hardware such as the Amiga and C64. Documentation is usually incomplete and back when those machines were popular developers would experiment with using the hardware in unintended ways, with results that were undocumented and sometimes not even consistent across revisions of the same machine.
Analogue processes are also very difficult to emulate accurately. For example, the way the Amiga generates sound uses pulse-width modulation and multiple analogue filters. Such systems can be measured and modelled but producing an accurate reproduction digitally is tricky. It gets even worse when you consider systems that had build in speakers or displays, but to sound/look right the properties of those must also be considered.
There are also issues with modern systems that make accurate emulation difficult. Input lag is a major one. Older systems tended to read the keyboard and joystick inputs as simple switches, resulting in very minimal lag. Modern PCs use USB, often with a polling rate of 8ms (the fastest possible for USB1.1). There is also often lag between the PC and the display output, where as older systems had near zero lag between the hardware generating a video signal and it appearing on the monitor.
Monitor refresh rates are also a problem. PC monitors rarely go below 60Hz and graphics cards rarely offer arbitrary refresh rates. Most older machines were either 50Hz (PAL/SECAM) or 59.94Hz (NTSC) so there is a mismatch between one emulated frame and one frame displayed on the host PC. Arcade systems often had odd frame rates such as 57.5Hz too, which even analogue TVs and monitors tend to struggle with.
add a comment |
Speaking from my personal experience of writing a PET emulator, a C64 emulator and a Sinclair Spectrum emulator,, here are the issues I had:
Getting the Speed Right
It's no good just making a processor go as fast as it can because, frequently, application code depends on timing. For old 8-bit machines, it's easy to write an emulator that runs at many times the speed of the original. The trouble is that has a knock on effect. For example, the PET Space Invaders program goes way too fast to be playable. Not that it matters because its key scanning code is similarly speeded up which means when you press a key, your gun is uncontrollable.
The same issue applies to the C64. The interrupt is driven by one of the IO chips which needs to be synchronised to the CPU's clock. This means pressing a key for even a brief time is the same as pressing it for several seconds on a real C64.
So you need to throttle the performance to something like the original speed. Unfortunately, that means having a clock with microsecond accuracy. Such things do not really exist in modern general purpose PC operating systems. Your CPU thread just has to be scheduled out of the processor and it will miss several microseconds probably. One way to get around this is to raise some event every 1/60th of a second (the probable refresh rate of your monitor and handily NTSC TVs) and when the CPU has executed 1/60th of a second's worth of instructions, just make it wait until the event occurs. Unfortunately, that makes doing sound on a PET or a Spectrum difficult because they both rely on the CPU toggling bits in IO registers at the right frequency.
Parallelism
In a real computer, there are several components that all operate concurrently. For example, the C64 has a VIC II chip for the display, a sound chip, some IO chips ands a 6510 and they are all synchronised by the same clock. The easiest way to deal with this is to have a loop in which you execute an instruction in the CPU and then update all the other components with the new clock time. Unfortunately, this is by nature serial and you have to be careful about do complex stuff in case it makes your emulation too slow.
An alternative is to put each component in its own thread, taking advantage of the multiple cores of modern computers, but then you have the problem of synchronisation. All of your components will need to access your emulation of the memory bus and they all need an access to the same copy. So, you might emulate the clock with a boolean that is toggled every 0.5 microseconds (in emulation time, see above) by the CPU. Unfortunately, modern processor cores have caches between themselves and the main memory. If the thread emulating the CPU core toggles a boolean representing the clock, it may only actually be altering the cached version of that variable and the other components won't see it. There are OS functions that allow you to force the cached version of a variable to main memory, but they incur a significant performance penalty. It's about 100 times slower to access main memory than L1 cache.
Documentation
Documentation for old computers can be quite hard to find and may not be detailed enough for constructing an accurate emulator. For example, if you want an accurate Z80 emulation, you need to understand that there is an undocumented "w" register which affects the behaviour of some of the undocumented Z80 instructions. In theory you don't need to care about those, but in practice, some popular game might have used them. The behaviour of the W register has been painstakingly reverse engineered by enthusiasts, but sometimes they get it wrong.
The other problem with old documentation is that it frequently contains errors. A popular book on the 6502 was the Zaks book, Programming the 6502. I remember that my Dad's copy of it was festooned with hand written annotations correcting all the errors that he discovered by bitter experience.
Graphics
Getting the graphics right is pretty hard. I started by just taking a dump of the graphics memory every 1/60th of a second and drawing it in a window. I progressed to doing that in the GPU but it is still not right. C64 programmers were adept at changing the graphics mode on the fly so they could use mixed modes on the screen. Even the Spectrum effect of the rapidly moving stripes in the border when the tape is loading is done by rapid changes to the background colour. You can't just snapshot the state and render it every 60th of a second, you effectively have to know the state at the end of every scan line on the VDU and, in fact, on the C64 I believe it was possible to split the screen vertically by carefully timed mode changes during a scan line. I haven't solved that yet.
Sound
Timing is actually more important as far as sound is concerned than graphics. A film is projected at 24 frames per second and our brains easily fill in the gaps. Try something similar with sound and you'll soon notice. For this reason, a haven't even attempted to emulate sound on the PET or the Spectrum. The C64 should be easier because it had a sound chip that you sent commands to rather than having to toggle an output wire very fast, but I haven't done that bit yet.
Development Tools
You'll need to create test programs for your emulation which means having a development suite. I was lucky in that Z80 and 6502 are both relatively well supported. Other architectures are not so fortunate. Not finding a good toolchain for 68000 stopped me from bothering with that architecture.
add a comment |
In nearly every computer, you have several things going on in parallel, even if it is just code execution on a CPU and screen refresh by the graphics card. In most cases, emulating behaviour of things that happen serially is quite easy, but as soon as you have to synchronize parallel actions, emulation gets difficult.
I once hacked on a gameboy emulator, and one of the performance limiting factors of the video emulation was that games do change video controller parameters during scan-out, e.g. to change the background color between the score bar and the game screen, or change the start offset of the screen scanout to have a fixed score bar above or below a scrolling game screen. This means that in the general case, you have to draw each scanline separately and take in account the current video parameters to scan it correctly, even though the graphics chip works with 8x8 tiles and (if the software would not change parameters) you could generate 8 lines at once with less overhead.
In many cases, changing video parameters is actively synchronized in CPU code, either by using a scan-line match interrupt (but possibly not on the game boy, I forgot whether it has a scan-line interrupt) or by polling the "current scanline register". In these cases, the emulator can provide synchronization by fudging values in the current scanline register to "probe" what value the software is waiting for, or by knowing the first scanline to apply the parameters from the interrupt configuration, but in some cases, programmers just counted CPU cycles, so the emulator needs to know how much scan lines elapsed between the latest synchronization and the current point in time.
New contributor
add a comment |
There has been a drift in the goals of video game emulators over the past decade or two. At first, getting emulated software to run at all was a major success, and was often done with simplified kludges and hacks. As the resources available to emulators has improved, the focus has moved more toward accurate reconstruction of what the original does. But why is that difficult to do?
Well, if software was written to follow a standard API and use documented system calls at all times, things would be fairly straightforward: just design a modern implementation of that API, and everything should work fine. But that's clearly not the case.
Sometimes these standardised interfaces don't meet the needs of programmers. Perhaps the functionality they want isn't provided (e.g. the PC BIOS's primitive graphics handling routines). Or maybe the "official" method is too slow for you, and you need to get the very fastest performance possible. This is often the case with computer games, which are of course the type of software that is most popular, emulation-wise.
At this point, the programmer would typically bypass the API, and address the hardware directly itself. And this is where the problems start.* As by trial and error programmers will find, use, and rely on hardware behaviour that may not have been intended or known of by the system's designers.
To accurately emulate a piece of hardware (for example a graphics processor or I/O chip) you need to know what it does, and how it does it. If you're using an off-the-shelf component, such as a 6522 VIA (I/O chip), then there will be some public documentation available. But if the programmer has found some undocumented functionality (or the system designer has written the operating system according to how the physical hardware behaves, and not documented it exhaustively themselves) then there's no easy way for emulator writers to know how the game+system actually works.
One approach is to use a black-box method. You give some input to a physical system, and see what output you get. But that's limited to your ability to think of all possible relevant situations, and going off to test them all.
Another is to open the chip up (a process known as decapping) and photograph the transistors on the die, layer by layer. If you use these images to reconstruct the "circuit diagram" of the chip, you could manufacture your own duplicate chip, or simulate it in software. The resources required to decap a chip are significant, as you need to shave off tiny layers of the packaging, or use acids to eat away at it, before using a specialist camera to photograph the tiny die at high resolution. And once that's done, you have a jigsaw that consists of thousands upon thousands (or even millions) of transistors that need to be traced out and joined up.
Once you know the exact structure of the chip you're trying to emulate, you then need to simulate the behaviour of every transistor in the chip. And, depending on the accuracy you're trying to achieve, you might eventually be attempting to simulate the behaviour of electrons themselves. At this small scale, we're into the territory of quantum behaviour, too.
At which point the question rises: how accurate do you want your emulator to be?
*These problems affect backward compatibility as well as emulation. If you write code that bypasses the OS and addresses the sound chip directly, then it may not work if the manufacturer uses a different sound chip in the next model, or simply moves it to a different memory location.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "648"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f10828%2fwhat-makes-accurate-emulation-of-old-systems-a-difficult-task%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Almost all computer systems have multiple different devices operating in parallel. For example, the CPU is typically running parallel to the video generation hardware.
This can be very difficult to emulate accurately, as interactions between different devices require that the emulation of each device proceeds in sync with the rest. Each device may be running on a different clock, and it becomes necessary to accurately emulate things like bus contention and DMA slot allocation.
There is also the issue of simply knowing how the original system actually behaves. Even now emulator developers are still finding new behaviours of classic hardware such as the Amiga and C64. Documentation is usually incomplete and back when those machines were popular developers would experiment with using the hardware in unintended ways, with results that were undocumented and sometimes not even consistent across revisions of the same machine.
Analogue processes are also very difficult to emulate accurately. For example, the way the Amiga generates sound uses pulse-width modulation and multiple analogue filters. Such systems can be measured and modelled but producing an accurate reproduction digitally is tricky. It gets even worse when you consider systems that had build in speakers or displays, but to sound/look right the properties of those must also be considered.
There are also issues with modern systems that make accurate emulation difficult. Input lag is a major one. Older systems tended to read the keyboard and joystick inputs as simple switches, resulting in very minimal lag. Modern PCs use USB, often with a polling rate of 8ms (the fastest possible for USB1.1). There is also often lag between the PC and the display output, where as older systems had near zero lag between the hardware generating a video signal and it appearing on the monitor.
Monitor refresh rates are also a problem. PC monitors rarely go below 60Hz and graphics cards rarely offer arbitrary refresh rates. Most older machines were either 50Hz (PAL/SECAM) or 59.94Hz (NTSC) so there is a mismatch between one emulated frame and one frame displayed on the host PC. Arcade systems often had odd frame rates such as 57.5Hz too, which even analogue TVs and monitors tend to struggle with.
add a comment |
Almost all computer systems have multiple different devices operating in parallel. For example, the CPU is typically running parallel to the video generation hardware.
This can be very difficult to emulate accurately, as interactions between different devices require that the emulation of each device proceeds in sync with the rest. Each device may be running on a different clock, and it becomes necessary to accurately emulate things like bus contention and DMA slot allocation.
There is also the issue of simply knowing how the original system actually behaves. Even now emulator developers are still finding new behaviours of classic hardware such as the Amiga and C64. Documentation is usually incomplete and back when those machines were popular developers would experiment with using the hardware in unintended ways, with results that were undocumented and sometimes not even consistent across revisions of the same machine.
Analogue processes are also very difficult to emulate accurately. For example, the way the Amiga generates sound uses pulse-width modulation and multiple analogue filters. Such systems can be measured and modelled but producing an accurate reproduction digitally is tricky. It gets even worse when you consider systems that had build in speakers or displays, but to sound/look right the properties of those must also be considered.
There are also issues with modern systems that make accurate emulation difficult. Input lag is a major one. Older systems tended to read the keyboard and joystick inputs as simple switches, resulting in very minimal lag. Modern PCs use USB, often with a polling rate of 8ms (the fastest possible for USB1.1). There is also often lag between the PC and the display output, where as older systems had near zero lag between the hardware generating a video signal and it appearing on the monitor.
Monitor refresh rates are also a problem. PC monitors rarely go below 60Hz and graphics cards rarely offer arbitrary refresh rates. Most older machines were either 50Hz (PAL/SECAM) or 59.94Hz (NTSC) so there is a mismatch between one emulated frame and one frame displayed on the host PC. Arcade systems often had odd frame rates such as 57.5Hz too, which even analogue TVs and monitors tend to struggle with.
add a comment |
Almost all computer systems have multiple different devices operating in parallel. For example, the CPU is typically running parallel to the video generation hardware.
This can be very difficult to emulate accurately, as interactions between different devices require that the emulation of each device proceeds in sync with the rest. Each device may be running on a different clock, and it becomes necessary to accurately emulate things like bus contention and DMA slot allocation.
There is also the issue of simply knowing how the original system actually behaves. Even now emulator developers are still finding new behaviours of classic hardware such as the Amiga and C64. Documentation is usually incomplete and back when those machines were popular developers would experiment with using the hardware in unintended ways, with results that were undocumented and sometimes not even consistent across revisions of the same machine.
Analogue processes are also very difficult to emulate accurately. For example, the way the Amiga generates sound uses pulse-width modulation and multiple analogue filters. Such systems can be measured and modelled but producing an accurate reproduction digitally is tricky. It gets even worse when you consider systems that had build in speakers or displays, but to sound/look right the properties of those must also be considered.
There are also issues with modern systems that make accurate emulation difficult. Input lag is a major one. Older systems tended to read the keyboard and joystick inputs as simple switches, resulting in very minimal lag. Modern PCs use USB, often with a polling rate of 8ms (the fastest possible for USB1.1). There is also often lag between the PC and the display output, where as older systems had near zero lag between the hardware generating a video signal and it appearing on the monitor.
Monitor refresh rates are also a problem. PC monitors rarely go below 60Hz and graphics cards rarely offer arbitrary refresh rates. Most older machines were either 50Hz (PAL/SECAM) or 59.94Hz (NTSC) so there is a mismatch between one emulated frame and one frame displayed on the host PC. Arcade systems often had odd frame rates such as 57.5Hz too, which even analogue TVs and monitors tend to struggle with.
Almost all computer systems have multiple different devices operating in parallel. For example, the CPU is typically running parallel to the video generation hardware.
This can be very difficult to emulate accurately, as interactions between different devices require that the emulation of each device proceeds in sync with the rest. Each device may be running on a different clock, and it becomes necessary to accurately emulate things like bus contention and DMA slot allocation.
There is also the issue of simply knowing how the original system actually behaves. Even now emulator developers are still finding new behaviours of classic hardware such as the Amiga and C64. Documentation is usually incomplete and back when those machines were popular developers would experiment with using the hardware in unintended ways, with results that were undocumented and sometimes not even consistent across revisions of the same machine.
Analogue processes are also very difficult to emulate accurately. For example, the way the Amiga generates sound uses pulse-width modulation and multiple analogue filters. Such systems can be measured and modelled but producing an accurate reproduction digitally is tricky. It gets even worse when you consider systems that had build in speakers or displays, but to sound/look right the properties of those must also be considered.
There are also issues with modern systems that make accurate emulation difficult. Input lag is a major one. Older systems tended to read the keyboard and joystick inputs as simple switches, resulting in very minimal lag. Modern PCs use USB, often with a polling rate of 8ms (the fastest possible for USB1.1). There is also often lag between the PC and the display output, where as older systems had near zero lag between the hardware generating a video signal and it appearing on the monitor.
Monitor refresh rates are also a problem. PC monitors rarely go below 60Hz and graphics cards rarely offer arbitrary refresh rates. Most older machines were either 50Hz (PAL/SECAM) or 59.94Hz (NTSC) so there is a mismatch between one emulated frame and one frame displayed on the host PC. Arcade systems often had odd frame rates such as 57.5Hz too, which even analogue TVs and monitors tend to struggle with.
answered 4 hours ago
useruser
4,596921
4,596921
add a comment |
add a comment |
Speaking from my personal experience of writing a PET emulator, a C64 emulator and a Sinclair Spectrum emulator,, here are the issues I had:
Getting the Speed Right
It's no good just making a processor go as fast as it can because, frequently, application code depends on timing. For old 8-bit machines, it's easy to write an emulator that runs at many times the speed of the original. The trouble is that has a knock on effect. For example, the PET Space Invaders program goes way too fast to be playable. Not that it matters because its key scanning code is similarly speeded up which means when you press a key, your gun is uncontrollable.
The same issue applies to the C64. The interrupt is driven by one of the IO chips which needs to be synchronised to the CPU's clock. This means pressing a key for even a brief time is the same as pressing it for several seconds on a real C64.
So you need to throttle the performance to something like the original speed. Unfortunately, that means having a clock with microsecond accuracy. Such things do not really exist in modern general purpose PC operating systems. Your CPU thread just has to be scheduled out of the processor and it will miss several microseconds probably. One way to get around this is to raise some event every 1/60th of a second (the probable refresh rate of your monitor and handily NTSC TVs) and when the CPU has executed 1/60th of a second's worth of instructions, just make it wait until the event occurs. Unfortunately, that makes doing sound on a PET or a Spectrum difficult because they both rely on the CPU toggling bits in IO registers at the right frequency.
Parallelism
In a real computer, there are several components that all operate concurrently. For example, the C64 has a VIC II chip for the display, a sound chip, some IO chips ands a 6510 and they are all synchronised by the same clock. The easiest way to deal with this is to have a loop in which you execute an instruction in the CPU and then update all the other components with the new clock time. Unfortunately, this is by nature serial and you have to be careful about do complex stuff in case it makes your emulation too slow.
An alternative is to put each component in its own thread, taking advantage of the multiple cores of modern computers, but then you have the problem of synchronisation. All of your components will need to access your emulation of the memory bus and they all need an access to the same copy. So, you might emulate the clock with a boolean that is toggled every 0.5 microseconds (in emulation time, see above) by the CPU. Unfortunately, modern processor cores have caches between themselves and the main memory. If the thread emulating the CPU core toggles a boolean representing the clock, it may only actually be altering the cached version of that variable and the other components won't see it. There are OS functions that allow you to force the cached version of a variable to main memory, but they incur a significant performance penalty. It's about 100 times slower to access main memory than L1 cache.
Documentation
Documentation for old computers can be quite hard to find and may not be detailed enough for constructing an accurate emulator. For example, if you want an accurate Z80 emulation, you need to understand that there is an undocumented "w" register which affects the behaviour of some of the undocumented Z80 instructions. In theory you don't need to care about those, but in practice, some popular game might have used them. The behaviour of the W register has been painstakingly reverse engineered by enthusiasts, but sometimes they get it wrong.
The other problem with old documentation is that it frequently contains errors. A popular book on the 6502 was the Zaks book, Programming the 6502. I remember that my Dad's copy of it was festooned with hand written annotations correcting all the errors that he discovered by bitter experience.
Graphics
Getting the graphics right is pretty hard. I started by just taking a dump of the graphics memory every 1/60th of a second and drawing it in a window. I progressed to doing that in the GPU but it is still not right. C64 programmers were adept at changing the graphics mode on the fly so they could use mixed modes on the screen. Even the Spectrum effect of the rapidly moving stripes in the border when the tape is loading is done by rapid changes to the background colour. You can't just snapshot the state and render it every 60th of a second, you effectively have to know the state at the end of every scan line on the VDU and, in fact, on the C64 I believe it was possible to split the screen vertically by carefully timed mode changes during a scan line. I haven't solved that yet.
Sound
Timing is actually more important as far as sound is concerned than graphics. A film is projected at 24 frames per second and our brains easily fill in the gaps. Try something similar with sound and you'll soon notice. For this reason, a haven't even attempted to emulate sound on the PET or the Spectrum. The C64 should be easier because it had a sound chip that you sent commands to rather than having to toggle an output wire very fast, but I haven't done that bit yet.
Development Tools
You'll need to create test programs for your emulation which means having a development suite. I was lucky in that Z80 and 6502 are both relatively well supported. Other architectures are not so fortunate. Not finding a good toolchain for 68000 stopped me from bothering with that architecture.
add a comment |
Speaking from my personal experience of writing a PET emulator, a C64 emulator and a Sinclair Spectrum emulator,, here are the issues I had:
Getting the Speed Right
It's no good just making a processor go as fast as it can because, frequently, application code depends on timing. For old 8-bit machines, it's easy to write an emulator that runs at many times the speed of the original. The trouble is that has a knock on effect. For example, the PET Space Invaders program goes way too fast to be playable. Not that it matters because its key scanning code is similarly speeded up which means when you press a key, your gun is uncontrollable.
The same issue applies to the C64. The interrupt is driven by one of the IO chips which needs to be synchronised to the CPU's clock. This means pressing a key for even a brief time is the same as pressing it for several seconds on a real C64.
So you need to throttle the performance to something like the original speed. Unfortunately, that means having a clock with microsecond accuracy. Such things do not really exist in modern general purpose PC operating systems. Your CPU thread just has to be scheduled out of the processor and it will miss several microseconds probably. One way to get around this is to raise some event every 1/60th of a second (the probable refresh rate of your monitor and handily NTSC TVs) and when the CPU has executed 1/60th of a second's worth of instructions, just make it wait until the event occurs. Unfortunately, that makes doing sound on a PET or a Spectrum difficult because they both rely on the CPU toggling bits in IO registers at the right frequency.
Parallelism
In a real computer, there are several components that all operate concurrently. For example, the C64 has a VIC II chip for the display, a sound chip, some IO chips ands a 6510 and they are all synchronised by the same clock. The easiest way to deal with this is to have a loop in which you execute an instruction in the CPU and then update all the other components with the new clock time. Unfortunately, this is by nature serial and you have to be careful about do complex stuff in case it makes your emulation too slow.
An alternative is to put each component in its own thread, taking advantage of the multiple cores of modern computers, but then you have the problem of synchronisation. All of your components will need to access your emulation of the memory bus and they all need an access to the same copy. So, you might emulate the clock with a boolean that is toggled every 0.5 microseconds (in emulation time, see above) by the CPU. Unfortunately, modern processor cores have caches between themselves and the main memory. If the thread emulating the CPU core toggles a boolean representing the clock, it may only actually be altering the cached version of that variable and the other components won't see it. There are OS functions that allow you to force the cached version of a variable to main memory, but they incur a significant performance penalty. It's about 100 times slower to access main memory than L1 cache.
Documentation
Documentation for old computers can be quite hard to find and may not be detailed enough for constructing an accurate emulator. For example, if you want an accurate Z80 emulation, you need to understand that there is an undocumented "w" register which affects the behaviour of some of the undocumented Z80 instructions. In theory you don't need to care about those, but in practice, some popular game might have used them. The behaviour of the W register has been painstakingly reverse engineered by enthusiasts, but sometimes they get it wrong.
The other problem with old documentation is that it frequently contains errors. A popular book on the 6502 was the Zaks book, Programming the 6502. I remember that my Dad's copy of it was festooned with hand written annotations correcting all the errors that he discovered by bitter experience.
Graphics
Getting the graphics right is pretty hard. I started by just taking a dump of the graphics memory every 1/60th of a second and drawing it in a window. I progressed to doing that in the GPU but it is still not right. C64 programmers were adept at changing the graphics mode on the fly so they could use mixed modes on the screen. Even the Spectrum effect of the rapidly moving stripes in the border when the tape is loading is done by rapid changes to the background colour. You can't just snapshot the state and render it every 60th of a second, you effectively have to know the state at the end of every scan line on the VDU and, in fact, on the C64 I believe it was possible to split the screen vertically by carefully timed mode changes during a scan line. I haven't solved that yet.
Sound
Timing is actually more important as far as sound is concerned than graphics. A film is projected at 24 frames per second and our brains easily fill in the gaps. Try something similar with sound and you'll soon notice. For this reason, a haven't even attempted to emulate sound on the PET or the Spectrum. The C64 should be easier because it had a sound chip that you sent commands to rather than having to toggle an output wire very fast, but I haven't done that bit yet.
Development Tools
You'll need to create test programs for your emulation which means having a development suite. I was lucky in that Z80 and 6502 are both relatively well supported. Other architectures are not so fortunate. Not finding a good toolchain for 68000 stopped me from bothering with that architecture.
add a comment |
Speaking from my personal experience of writing a PET emulator, a C64 emulator and a Sinclair Spectrum emulator,, here are the issues I had:
Getting the Speed Right
It's no good just making a processor go as fast as it can because, frequently, application code depends on timing. For old 8-bit machines, it's easy to write an emulator that runs at many times the speed of the original. The trouble is that has a knock on effect. For example, the PET Space Invaders program goes way too fast to be playable. Not that it matters because its key scanning code is similarly speeded up which means when you press a key, your gun is uncontrollable.
The same issue applies to the C64. The interrupt is driven by one of the IO chips which needs to be synchronised to the CPU's clock. This means pressing a key for even a brief time is the same as pressing it for several seconds on a real C64.
So you need to throttle the performance to something like the original speed. Unfortunately, that means having a clock with microsecond accuracy. Such things do not really exist in modern general purpose PC operating systems. Your CPU thread just has to be scheduled out of the processor and it will miss several microseconds probably. One way to get around this is to raise some event every 1/60th of a second (the probable refresh rate of your monitor and handily NTSC TVs) and when the CPU has executed 1/60th of a second's worth of instructions, just make it wait until the event occurs. Unfortunately, that makes doing sound on a PET or a Spectrum difficult because they both rely on the CPU toggling bits in IO registers at the right frequency.
Parallelism
In a real computer, there are several components that all operate concurrently. For example, the C64 has a VIC II chip for the display, a sound chip, some IO chips ands a 6510 and they are all synchronised by the same clock. The easiest way to deal with this is to have a loop in which you execute an instruction in the CPU and then update all the other components with the new clock time. Unfortunately, this is by nature serial and you have to be careful about do complex stuff in case it makes your emulation too slow.
An alternative is to put each component in its own thread, taking advantage of the multiple cores of modern computers, but then you have the problem of synchronisation. All of your components will need to access your emulation of the memory bus and they all need an access to the same copy. So, you might emulate the clock with a boolean that is toggled every 0.5 microseconds (in emulation time, see above) by the CPU. Unfortunately, modern processor cores have caches between themselves and the main memory. If the thread emulating the CPU core toggles a boolean representing the clock, it may only actually be altering the cached version of that variable and the other components won't see it. There are OS functions that allow you to force the cached version of a variable to main memory, but they incur a significant performance penalty. It's about 100 times slower to access main memory than L1 cache.
Documentation
Documentation for old computers can be quite hard to find and may not be detailed enough for constructing an accurate emulator. For example, if you want an accurate Z80 emulation, you need to understand that there is an undocumented "w" register which affects the behaviour of some of the undocumented Z80 instructions. In theory you don't need to care about those, but in practice, some popular game might have used them. The behaviour of the W register has been painstakingly reverse engineered by enthusiasts, but sometimes they get it wrong.
The other problem with old documentation is that it frequently contains errors. A popular book on the 6502 was the Zaks book, Programming the 6502. I remember that my Dad's copy of it was festooned with hand written annotations correcting all the errors that he discovered by bitter experience.
Graphics
Getting the graphics right is pretty hard. I started by just taking a dump of the graphics memory every 1/60th of a second and drawing it in a window. I progressed to doing that in the GPU but it is still not right. C64 programmers were adept at changing the graphics mode on the fly so they could use mixed modes on the screen. Even the Spectrum effect of the rapidly moving stripes in the border when the tape is loading is done by rapid changes to the background colour. You can't just snapshot the state and render it every 60th of a second, you effectively have to know the state at the end of every scan line on the VDU and, in fact, on the C64 I believe it was possible to split the screen vertically by carefully timed mode changes during a scan line. I haven't solved that yet.
Sound
Timing is actually more important as far as sound is concerned than graphics. A film is projected at 24 frames per second and our brains easily fill in the gaps. Try something similar with sound and you'll soon notice. For this reason, a haven't even attempted to emulate sound on the PET or the Spectrum. The C64 should be easier because it had a sound chip that you sent commands to rather than having to toggle an output wire very fast, but I haven't done that bit yet.
Development Tools
You'll need to create test programs for your emulation which means having a development suite. I was lucky in that Z80 and 6502 are both relatively well supported. Other architectures are not so fortunate. Not finding a good toolchain for 68000 stopped me from bothering with that architecture.
Speaking from my personal experience of writing a PET emulator, a C64 emulator and a Sinclair Spectrum emulator,, here are the issues I had:
Getting the Speed Right
It's no good just making a processor go as fast as it can because, frequently, application code depends on timing. For old 8-bit machines, it's easy to write an emulator that runs at many times the speed of the original. The trouble is that has a knock on effect. For example, the PET Space Invaders program goes way too fast to be playable. Not that it matters because its key scanning code is similarly speeded up which means when you press a key, your gun is uncontrollable.
The same issue applies to the C64. The interrupt is driven by one of the IO chips which needs to be synchronised to the CPU's clock. This means pressing a key for even a brief time is the same as pressing it for several seconds on a real C64.
So you need to throttle the performance to something like the original speed. Unfortunately, that means having a clock with microsecond accuracy. Such things do not really exist in modern general purpose PC operating systems. Your CPU thread just has to be scheduled out of the processor and it will miss several microseconds probably. One way to get around this is to raise some event every 1/60th of a second (the probable refresh rate of your monitor and handily NTSC TVs) and when the CPU has executed 1/60th of a second's worth of instructions, just make it wait until the event occurs. Unfortunately, that makes doing sound on a PET or a Spectrum difficult because they both rely on the CPU toggling bits in IO registers at the right frequency.
Parallelism
In a real computer, there are several components that all operate concurrently. For example, the C64 has a VIC II chip for the display, a sound chip, some IO chips ands a 6510 and they are all synchronised by the same clock. The easiest way to deal with this is to have a loop in which you execute an instruction in the CPU and then update all the other components with the new clock time. Unfortunately, this is by nature serial and you have to be careful about do complex stuff in case it makes your emulation too slow.
An alternative is to put each component in its own thread, taking advantage of the multiple cores of modern computers, but then you have the problem of synchronisation. All of your components will need to access your emulation of the memory bus and they all need an access to the same copy. So, you might emulate the clock with a boolean that is toggled every 0.5 microseconds (in emulation time, see above) by the CPU. Unfortunately, modern processor cores have caches between themselves and the main memory. If the thread emulating the CPU core toggles a boolean representing the clock, it may only actually be altering the cached version of that variable and the other components won't see it. There are OS functions that allow you to force the cached version of a variable to main memory, but they incur a significant performance penalty. It's about 100 times slower to access main memory than L1 cache.
Documentation
Documentation for old computers can be quite hard to find and may not be detailed enough for constructing an accurate emulator. For example, if you want an accurate Z80 emulation, you need to understand that there is an undocumented "w" register which affects the behaviour of some of the undocumented Z80 instructions. In theory you don't need to care about those, but in practice, some popular game might have used them. The behaviour of the W register has been painstakingly reverse engineered by enthusiasts, but sometimes they get it wrong.
The other problem with old documentation is that it frequently contains errors. A popular book on the 6502 was the Zaks book, Programming the 6502. I remember that my Dad's copy of it was festooned with hand written annotations correcting all the errors that he discovered by bitter experience.
Graphics
Getting the graphics right is pretty hard. I started by just taking a dump of the graphics memory every 1/60th of a second and drawing it in a window. I progressed to doing that in the GPU but it is still not right. C64 programmers were adept at changing the graphics mode on the fly so they could use mixed modes on the screen. Even the Spectrum effect of the rapidly moving stripes in the border when the tape is loading is done by rapid changes to the background colour. You can't just snapshot the state and render it every 60th of a second, you effectively have to know the state at the end of every scan line on the VDU and, in fact, on the C64 I believe it was possible to split the screen vertically by carefully timed mode changes during a scan line. I haven't solved that yet.
Sound
Timing is actually more important as far as sound is concerned than graphics. A film is projected at 24 frames per second and our brains easily fill in the gaps. Try something similar with sound and you'll soon notice. For this reason, a haven't even attempted to emulate sound on the PET or the Spectrum. The C64 should be easier because it had a sound chip that you sent commands to rather than having to toggle an output wire very fast, but I haven't done that bit yet.
Development Tools
You'll need to create test programs for your emulation which means having a development suite. I was lucky in that Z80 and 6502 are both relatively well supported. Other architectures are not so fortunate. Not finding a good toolchain for 68000 stopped me from bothering with that architecture.
answered 1 hour ago
JeremyPJeremyP
5,33012030
5,33012030
add a comment |
add a comment |
In nearly every computer, you have several things going on in parallel, even if it is just code execution on a CPU and screen refresh by the graphics card. In most cases, emulating behaviour of things that happen serially is quite easy, but as soon as you have to synchronize parallel actions, emulation gets difficult.
I once hacked on a gameboy emulator, and one of the performance limiting factors of the video emulation was that games do change video controller parameters during scan-out, e.g. to change the background color between the score bar and the game screen, or change the start offset of the screen scanout to have a fixed score bar above or below a scrolling game screen. This means that in the general case, you have to draw each scanline separately and take in account the current video parameters to scan it correctly, even though the graphics chip works with 8x8 tiles and (if the software would not change parameters) you could generate 8 lines at once with less overhead.
In many cases, changing video parameters is actively synchronized in CPU code, either by using a scan-line match interrupt (but possibly not on the game boy, I forgot whether it has a scan-line interrupt) or by polling the "current scanline register". In these cases, the emulator can provide synchronization by fudging values in the current scanline register to "probe" what value the software is waiting for, or by knowing the first scanline to apply the parameters from the interrupt configuration, but in some cases, programmers just counted CPU cycles, so the emulator needs to know how much scan lines elapsed between the latest synchronization and the current point in time.
New contributor
add a comment |
In nearly every computer, you have several things going on in parallel, even if it is just code execution on a CPU and screen refresh by the graphics card. In most cases, emulating behaviour of things that happen serially is quite easy, but as soon as you have to synchronize parallel actions, emulation gets difficult.
I once hacked on a gameboy emulator, and one of the performance limiting factors of the video emulation was that games do change video controller parameters during scan-out, e.g. to change the background color between the score bar and the game screen, or change the start offset of the screen scanout to have a fixed score bar above or below a scrolling game screen. This means that in the general case, you have to draw each scanline separately and take in account the current video parameters to scan it correctly, even though the graphics chip works with 8x8 tiles and (if the software would not change parameters) you could generate 8 lines at once with less overhead.
In many cases, changing video parameters is actively synchronized in CPU code, either by using a scan-line match interrupt (but possibly not on the game boy, I forgot whether it has a scan-line interrupt) or by polling the "current scanline register". In these cases, the emulator can provide synchronization by fudging values in the current scanline register to "probe" what value the software is waiting for, or by knowing the first scanline to apply the parameters from the interrupt configuration, but in some cases, programmers just counted CPU cycles, so the emulator needs to know how much scan lines elapsed between the latest synchronization and the current point in time.
New contributor
add a comment |
In nearly every computer, you have several things going on in parallel, even if it is just code execution on a CPU and screen refresh by the graphics card. In most cases, emulating behaviour of things that happen serially is quite easy, but as soon as you have to synchronize parallel actions, emulation gets difficult.
I once hacked on a gameboy emulator, and one of the performance limiting factors of the video emulation was that games do change video controller parameters during scan-out, e.g. to change the background color between the score bar and the game screen, or change the start offset of the screen scanout to have a fixed score bar above or below a scrolling game screen. This means that in the general case, you have to draw each scanline separately and take in account the current video parameters to scan it correctly, even though the graphics chip works with 8x8 tiles and (if the software would not change parameters) you could generate 8 lines at once with less overhead.
In many cases, changing video parameters is actively synchronized in CPU code, either by using a scan-line match interrupt (but possibly not on the game boy, I forgot whether it has a scan-line interrupt) or by polling the "current scanline register". In these cases, the emulator can provide synchronization by fudging values in the current scanline register to "probe" what value the software is waiting for, or by knowing the first scanline to apply the parameters from the interrupt configuration, but in some cases, programmers just counted CPU cycles, so the emulator needs to know how much scan lines elapsed between the latest synchronization and the current point in time.
New contributor
In nearly every computer, you have several things going on in parallel, even if it is just code execution on a CPU and screen refresh by the graphics card. In most cases, emulating behaviour of things that happen serially is quite easy, but as soon as you have to synchronize parallel actions, emulation gets difficult.
I once hacked on a gameboy emulator, and one of the performance limiting factors of the video emulation was that games do change video controller parameters during scan-out, e.g. to change the background color between the score bar and the game screen, or change the start offset of the screen scanout to have a fixed score bar above or below a scrolling game screen. This means that in the general case, you have to draw each scanline separately and take in account the current video parameters to scan it correctly, even though the graphics chip works with 8x8 tiles and (if the software would not change parameters) you could generate 8 lines at once with less overhead.
In many cases, changing video parameters is actively synchronized in CPU code, either by using a scan-line match interrupt (but possibly not on the game boy, I forgot whether it has a scan-line interrupt) or by polling the "current scanline register". In these cases, the emulator can provide synchronization by fudging values in the current scanline register to "probe" what value the software is waiting for, or by knowing the first scanline to apply the parameters from the interrupt configuration, but in some cases, programmers just counted CPU cycles, so the emulator needs to know how much scan lines elapsed between the latest synchronization and the current point in time.
New contributor
New contributor
answered 5 hours ago
Michael KarcherMichael Karcher
1134
1134
New contributor
New contributor
add a comment |
add a comment |
There has been a drift in the goals of video game emulators over the past decade or two. At first, getting emulated software to run at all was a major success, and was often done with simplified kludges and hacks. As the resources available to emulators has improved, the focus has moved more toward accurate reconstruction of what the original does. But why is that difficult to do?
Well, if software was written to follow a standard API and use documented system calls at all times, things would be fairly straightforward: just design a modern implementation of that API, and everything should work fine. But that's clearly not the case.
Sometimes these standardised interfaces don't meet the needs of programmers. Perhaps the functionality they want isn't provided (e.g. the PC BIOS's primitive graphics handling routines). Or maybe the "official" method is too slow for you, and you need to get the very fastest performance possible. This is often the case with computer games, which are of course the type of software that is most popular, emulation-wise.
At this point, the programmer would typically bypass the API, and address the hardware directly itself. And this is where the problems start.* As by trial and error programmers will find, use, and rely on hardware behaviour that may not have been intended or known of by the system's designers.
To accurately emulate a piece of hardware (for example a graphics processor or I/O chip) you need to know what it does, and how it does it. If you're using an off-the-shelf component, such as a 6522 VIA (I/O chip), then there will be some public documentation available. But if the programmer has found some undocumented functionality (or the system designer has written the operating system according to how the physical hardware behaves, and not documented it exhaustively themselves) then there's no easy way for emulator writers to know how the game+system actually works.
One approach is to use a black-box method. You give some input to a physical system, and see what output you get. But that's limited to your ability to think of all possible relevant situations, and going off to test them all.
Another is to open the chip up (a process known as decapping) and photograph the transistors on the die, layer by layer. If you use these images to reconstruct the "circuit diagram" of the chip, you could manufacture your own duplicate chip, or simulate it in software. The resources required to decap a chip are significant, as you need to shave off tiny layers of the packaging, or use acids to eat away at it, before using a specialist camera to photograph the tiny die at high resolution. And once that's done, you have a jigsaw that consists of thousands upon thousands (or even millions) of transistors that need to be traced out and joined up.
Once you know the exact structure of the chip you're trying to emulate, you then need to simulate the behaviour of every transistor in the chip. And, depending on the accuracy you're trying to achieve, you might eventually be attempting to simulate the behaviour of electrons themselves. At this small scale, we're into the territory of quantum behaviour, too.
At which point the question rises: how accurate do you want your emulator to be?
*These problems affect backward compatibility as well as emulation. If you write code that bypasses the OS and addresses the sound chip directly, then it may not work if the manufacturer uses a different sound chip in the next model, or simply moves it to a different memory location.
add a comment |
There has been a drift in the goals of video game emulators over the past decade or two. At first, getting emulated software to run at all was a major success, and was often done with simplified kludges and hacks. As the resources available to emulators has improved, the focus has moved more toward accurate reconstruction of what the original does. But why is that difficult to do?
Well, if software was written to follow a standard API and use documented system calls at all times, things would be fairly straightforward: just design a modern implementation of that API, and everything should work fine. But that's clearly not the case.
Sometimes these standardised interfaces don't meet the needs of programmers. Perhaps the functionality they want isn't provided (e.g. the PC BIOS's primitive graphics handling routines). Or maybe the "official" method is too slow for you, and you need to get the very fastest performance possible. This is often the case with computer games, which are of course the type of software that is most popular, emulation-wise.
At this point, the programmer would typically bypass the API, and address the hardware directly itself. And this is where the problems start.* As by trial and error programmers will find, use, and rely on hardware behaviour that may not have been intended or known of by the system's designers.
To accurately emulate a piece of hardware (for example a graphics processor or I/O chip) you need to know what it does, and how it does it. If you're using an off-the-shelf component, such as a 6522 VIA (I/O chip), then there will be some public documentation available. But if the programmer has found some undocumented functionality (or the system designer has written the operating system according to how the physical hardware behaves, and not documented it exhaustively themselves) then there's no easy way for emulator writers to know how the game+system actually works.
One approach is to use a black-box method. You give some input to a physical system, and see what output you get. But that's limited to your ability to think of all possible relevant situations, and going off to test them all.
Another is to open the chip up (a process known as decapping) and photograph the transistors on the die, layer by layer. If you use these images to reconstruct the "circuit diagram" of the chip, you could manufacture your own duplicate chip, or simulate it in software. The resources required to decap a chip are significant, as you need to shave off tiny layers of the packaging, or use acids to eat away at it, before using a specialist camera to photograph the tiny die at high resolution. And once that's done, you have a jigsaw that consists of thousands upon thousands (or even millions) of transistors that need to be traced out and joined up.
Once you know the exact structure of the chip you're trying to emulate, you then need to simulate the behaviour of every transistor in the chip. And, depending on the accuracy you're trying to achieve, you might eventually be attempting to simulate the behaviour of electrons themselves. At this small scale, we're into the territory of quantum behaviour, too.
At which point the question rises: how accurate do you want your emulator to be?
*These problems affect backward compatibility as well as emulation. If you write code that bypasses the OS and addresses the sound chip directly, then it may not work if the manufacturer uses a different sound chip in the next model, or simply moves it to a different memory location.
add a comment |
There has been a drift in the goals of video game emulators over the past decade or two. At first, getting emulated software to run at all was a major success, and was often done with simplified kludges and hacks. As the resources available to emulators has improved, the focus has moved more toward accurate reconstruction of what the original does. But why is that difficult to do?
Well, if software was written to follow a standard API and use documented system calls at all times, things would be fairly straightforward: just design a modern implementation of that API, and everything should work fine. But that's clearly not the case.
Sometimes these standardised interfaces don't meet the needs of programmers. Perhaps the functionality they want isn't provided (e.g. the PC BIOS's primitive graphics handling routines). Or maybe the "official" method is too slow for you, and you need to get the very fastest performance possible. This is often the case with computer games, which are of course the type of software that is most popular, emulation-wise.
At this point, the programmer would typically bypass the API, and address the hardware directly itself. And this is where the problems start.* As by trial and error programmers will find, use, and rely on hardware behaviour that may not have been intended or known of by the system's designers.
To accurately emulate a piece of hardware (for example a graphics processor or I/O chip) you need to know what it does, and how it does it. If you're using an off-the-shelf component, such as a 6522 VIA (I/O chip), then there will be some public documentation available. But if the programmer has found some undocumented functionality (or the system designer has written the operating system according to how the physical hardware behaves, and not documented it exhaustively themselves) then there's no easy way for emulator writers to know how the game+system actually works.
One approach is to use a black-box method. You give some input to a physical system, and see what output you get. But that's limited to your ability to think of all possible relevant situations, and going off to test them all.
Another is to open the chip up (a process known as decapping) and photograph the transistors on the die, layer by layer. If you use these images to reconstruct the "circuit diagram" of the chip, you could manufacture your own duplicate chip, or simulate it in software. The resources required to decap a chip are significant, as you need to shave off tiny layers of the packaging, or use acids to eat away at it, before using a specialist camera to photograph the tiny die at high resolution. And once that's done, you have a jigsaw that consists of thousands upon thousands (or even millions) of transistors that need to be traced out and joined up.
Once you know the exact structure of the chip you're trying to emulate, you then need to simulate the behaviour of every transistor in the chip. And, depending on the accuracy you're trying to achieve, you might eventually be attempting to simulate the behaviour of electrons themselves. At this small scale, we're into the territory of quantum behaviour, too.
At which point the question rises: how accurate do you want your emulator to be?
*These problems affect backward compatibility as well as emulation. If you write code that bypasses the OS and addresses the sound chip directly, then it may not work if the manufacturer uses a different sound chip in the next model, or simply moves it to a different memory location.
There has been a drift in the goals of video game emulators over the past decade or two. At first, getting emulated software to run at all was a major success, and was often done with simplified kludges and hacks. As the resources available to emulators has improved, the focus has moved more toward accurate reconstruction of what the original does. But why is that difficult to do?
Well, if software was written to follow a standard API and use documented system calls at all times, things would be fairly straightforward: just design a modern implementation of that API, and everything should work fine. But that's clearly not the case.
Sometimes these standardised interfaces don't meet the needs of programmers. Perhaps the functionality they want isn't provided (e.g. the PC BIOS's primitive graphics handling routines). Or maybe the "official" method is too slow for you, and you need to get the very fastest performance possible. This is often the case with computer games, which are of course the type of software that is most popular, emulation-wise.
At this point, the programmer would typically bypass the API, and address the hardware directly itself. And this is where the problems start.* As by trial and error programmers will find, use, and rely on hardware behaviour that may not have been intended or known of by the system's designers.
To accurately emulate a piece of hardware (for example a graphics processor or I/O chip) you need to know what it does, and how it does it. If you're using an off-the-shelf component, such as a 6522 VIA (I/O chip), then there will be some public documentation available. But if the programmer has found some undocumented functionality (or the system designer has written the operating system according to how the physical hardware behaves, and not documented it exhaustively themselves) then there's no easy way for emulator writers to know how the game+system actually works.
One approach is to use a black-box method. You give some input to a physical system, and see what output you get. But that's limited to your ability to think of all possible relevant situations, and going off to test them all.
Another is to open the chip up (a process known as decapping) and photograph the transistors on the die, layer by layer. If you use these images to reconstruct the "circuit diagram" of the chip, you could manufacture your own duplicate chip, or simulate it in software. The resources required to decap a chip are significant, as you need to shave off tiny layers of the packaging, or use acids to eat away at it, before using a specialist camera to photograph the tiny die at high resolution. And once that's done, you have a jigsaw that consists of thousands upon thousands (or even millions) of transistors that need to be traced out and joined up.
Once you know the exact structure of the chip you're trying to emulate, you then need to simulate the behaviour of every transistor in the chip. And, depending on the accuracy you're trying to achieve, you might eventually be attempting to simulate the behaviour of electrons themselves. At this small scale, we're into the territory of quantum behaviour, too.
At which point the question rises: how accurate do you want your emulator to be?
*These problems affect backward compatibility as well as emulation. If you write code that bypasses the OS and addresses the sound chip directly, then it may not work if the manufacturer uses a different sound chip in the next model, or simply moves it to a different memory location.
answered 1 hour ago
KazKaz
2,631945
2,631945
add a comment |
add a comment |
Thanks for contributing an answer to Retrocomputing Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f10828%2fwhat-makes-accurate-emulation-of-old-systems-a-difficult-task%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown