An emulator is a piece of computer software that allows certain programs to
run on a platform (computer architecture and/or operating system) other than
the one they were originally written for. It does this by "emulating", or
reproducing, the behavior of one type of computer on another.
In a technical sense, the Church-Turing thesis implies that any operating
environment can be emulated within any other. In practice, it can be quite
difficult, particularly when the exact behaviour of the system to be
emulated is not documented and has to be deduced through reverse
engineering. It also says nothing about timing constraints; if the emulator
does not perform as quickly as the original hardware, the emulated software
may run much more slowly than it would have on the original hardware.
Most emulators just emulate a hardware architecture—if a specific
operating system is required for the desired software, it must be provided
as well (and may itself be emulated). Both the OS and the software will then
be interpreted by the emulator, rather than being run by native hardware.
Apart from this interpreter for the emulated machine's language, some other
hardware (such as input or output devices) must be provided in virtual form
as well: if writing to a specific memory location should influence the
screen, for example, this will have to be emulated as well.
A popular use of emulators is to run software, often games, written for
hardware that is no longer sold or readily available, such as the Commodore
64 or early Amiga models. Emulating these on modern desktop computers is
usually less cumbersome than relying on the original machine, which may be
inoperational. However, software licensing issues may require emulator
authors to write original software that duplicates the functionality of the
original computer's bootstrap ROM and BIOS.
Developers of software for embedded systems or video game consoles often
design their software on especially accurate emulator called a simulator
before trying it on the real hardware. This is so that software can be
produced and tested before the final hardware exists in large quantities, so
that it can be tested without taking the time to copy the program to the
hardware, or so that it can be debugged at a low level without introducing
the side effects of a debugger.