-
Notifications
You must be signed in to change notification settings - Fork 57
Emulator Architecture
(...work in progress...)
(continued in Emulator Architecture Part 2)
Here is an collection of information explaining why the Newton OS is such a great operating system, and why emulation and simulation could be solved so elegantly in Einstein: Newton Architecture
In order to run, Einstein requires a ROM dump from a real Newton. We cannot provide you this ROM file, but you can generate one from your own hardware if you own a Newton. The ROM file is expected to be exactly 8 megabytes in size. Most development is being done with the version 717006 ROM.
Einstein.rex is a Newton ROM extension, built with the Newton developer tools in much the same way as you would build a ROM patch for an actual Newton. It provides glue code to re-route hardware dependencies to the virtual emulator hardware. Einstein loads the REx file from disk and applies it to the vanilla ROM when the emulator first starts up.
The flash file simulates the on-board flash memory of an actual Newton. It is created and initialized the first time the emulator is run. The file is eight megabytes in size, consisting of two "banks" of four megabytes each. The TFlash class provides the interface to the flash memory. The TFlash object is "owned" by TMemory, which is in turn owned by TEmulator.
On OS X, the flash file is created in ~/Library/Application Support/Einstein Platform
Einstein creates a file (usually named 717006.img, assuming you're using the 717006 ROM) the first time it runs. This 16 MB file mirrors the SImage structure defined in the code. The first 8 MB are a copy of the ROM dump. The next 8 MB contain a copy of the REX file (padded out to 8 MB with zeros). The ROM and REX images are byte-swapped on little-endian host OSes as they are written to the file. At the end of the file is some metadata used by Einstein.
Patches are then applied to this "cooked" ROM image, so that the original ROM image remains unmodified.
TEmulator is the primary class that runs the emulation. TEmulator encapsulates all of the other hardware abstractions in Einstein, including display hardware, sound hardware, CPU, memory, serial ports, etc. Once properly created and initialized, TEmulator's Run() method is dispatched on its own thread and drives the main loop of the emulator.
In addition to TEmulator's thread, TInterruptManager::Run() executes in its own thread, as does TNetworkManager::Run().
The serial port manager provides interfaces for each of the N2 platform's four serial ports:
- The external serial port,
extr
- connected to the interconnect port's serial pins - The infrared serial port,
infr
- connected to the IrDA transceiver - The built-in serial port,
tblt
- The modem serial port,
mdem
- connected to a PCMCIA serial/modem card, if inserted
In practice, only extr
has platform drivers.
The sound manager provides an interface to the host OS's sound hardware. It receives raw sound buffers from the emulator and routes them to the host OS for playback, as well as accepting sound input.
TNullSoundManager is a direct subclass that provides no sound input/output capabilities.
On OS X and iOS, TSoundManager is subclassed by TBufferedSoundManager which is in turn subclassed by TCoreAudioSoundManager.
On Linux, PulseAudio is used via the TPulseAudioSoundManager subclass of TBufferedSoundManager.
For other platforms, the open source portaudio library is used via the TPortAudioSoundManager subclass of TBufferedSoundManager.
TScreenManager is an abstract base class that handles display screen output and pen/keyboard input in a host-agnostic way. Each target platform has its own subclass for handling this:
-
TIOSScreenManager
for iOS -
TAndroidScreenManager
for Android -
TCocoaScreenManager
for OS X -
TX11ScreenManager
for Linux or, theoretically, anything with an X11 server (OS X) -
TFLScreenManager
uses the FLTK GUI toolkit, so is used for Linux and Windows. -
TSDLScreenManager
also exists.
TScreenManager supplies basic bitmap blitting functions designed to work in any of the emulated Newton's screen orientations. It is up to the subclass to display the emulated Newton's bitmap.
Subclasses of TScreenManager also convey pen and key inputs from the host OS back to the emulator.
TScreenManager receives calls from the emulator when the emulated Newton has a power button, backlight toggle, screen reorientation, or contrast change event.
The emulator thread spends most of its life in the Run() method of the JIT (currently TJITGeneric).
The emulator performs just-in-time (JIT) translation of the Newton's ARM CPU instruction set to host-native instructions. JIT is performed in units of pages (1K) as the emulator follows the Newton CPU's program counter (PC). A cache of translated pages is kept in memory to boost performance.
The JIT has two steps: first, ARM instructions are converted into an internal bytecode for performance reasons. While emulation is running, the bytecode is interpreted and dispatched to host-native code. For example, the ARM instruction "mov r0, r1" is ultimately dispatched to a native function called JIT_mov_r0_r1()