home *** CD-ROM | disk | FTP | other *** search
- You can help to make this program better. If you fix bugs or implement new
- features, I'd be grateful if you send me patches. For a list of interesting
- projects, and for a brief summary on how UAE works, see below.
-
- A few guidelines for anyone who wants to help:
- - Please contact me first before you implement major new features. Someone
- else might be doing the same thing already. This has already happened :-(
- Even if no one else is working on this feature, there might be alternative
- and better/easier/more elegant ways to do it.
- - Some coding guidelines.
- * Avoid GNU C extensions by all means. They make your code non-portable.
- * Avoid GNU indentation style by all means. It makes your code unreadable.
- * Try to indent your code nicely. There are editors like JED, which is
- available from space.mit.edu:/pub/davis and highly recommendable, that do
- this for you automatically.
- * Use eight space tabs, four space tabs make a mess of the code.
- - If you have access to more than one Unix system, try compiling/running your
- code on all of these. Remember, UAE is supposed to run on the DEC Alpha: so
- don't assume sizeof(char*) == sizeof(int) == sizeof(long)
- - If you have more than one Kickstart, try your code with each one.
- - Patches are welcome in any form, but diff -u or diff -c output is preferred.
- If I get whole source files, the first thing I do is to run diff on it. You
- can save me some work here (and make my mailbox smaller).
-
- Some possible projects, in order of estimated difficulty:
- - Someone with a 68000 data sheet might check whether all opcodes are
- decoded correctly and whether all instructions really do what they are
- supposed to do (I'm pretty sure it's OK by now, but you never know...).
- - Modify UAE to run in two threads for systems that have more than one CPU.
- I've thought of a way how to do it, but I don't have a multiprocessor board
- to try this. Here's how it works: Start with smart update method #1. This
- method nicely bundles all the data necessary for drawing a scanline into two
- structures: linedescr and line_data. Instead of actually drawing the line
- in the main task, signal the second one to use that information. Synchronize
- the two at the end of a frame to avoid lossage.
- If I haven't overlooked a big problem, it should be trivial.
- Sound output could also be moved into a separate task, but the gain will be
- much smaller.
- - Implement all 68020 instructions/addressing modes.
- - Improve the Kickstart replacement to boot more demos.
- - Write an Amiga program that communicates with UAE and provides a user-
- interface similar to the X Windows one, but from within the emulation.
- - Calculating the flags after each instruction is time consuming and usually
- completely unnecessary. Modify gencpu to generate instructions that don't
- set the flags, and have some code in the central loop to decide which
- set of instructions to use. This means additional overhead, of course,
- which might eat any improvements. [Tried it, hardly a difference, but
- maybe I did it in a stupid way]
- - Translate Kickstart ROM (or any software) to C code with a slightly
- modified gencpu, and link it to the rest of the emulator. Definitely
- possible, maybe illegal. Better don't do that for now.
- - Make a modified gencpu that can generate x86 assembly instead of C. This
- might give a nice speedup. However, the CPU emulation already is the
- fastest part in UAE - screen updates are much more time consuming.
- [Partly done, some __asm__ magic for flag calculations. Bad for performance
- are all the unnecessary register push/pops that the compiler generates.]
- - Improve sound emulation (Find bugs).
- - Snapshots as in CPE. Will need to collect all the variables containing
- important information. Fairly easy, but boring. (Use core dumps instead :-)
- - Find out why uae.device doesn't work with Kick 1.3. Not really important,
- no one in his right mind uses it anyway now there is the unixfs.device
- - Make unixfs.device bootable.
- - The playfield hardware is the only important part of the Amiga that is
- not really well documented in the HRM. Write some test programs that
- do all sorts of weird things with the copper (like turning off bitplane
- DMA during a line, and turning it directly on again: VERY interesting
- result) and try to emulate this perfectly.
- - Figure out a diskfile format that supports every possible non-standard
- format.
- - Translate basic blocks of m68k instructions to intermediate code that is
- interpreted instead of the actual code. Optimize it of course.
- (Not sure whether it would really be faster. But ARDI's Executor does
- a splendid job on translation. This should really help even if the target
- code isn't native).
- - Implement 68551 MMU. I have docs now. Not among the most necessary things.
- - Implement 68882 FPU. Not among the most necessary items, either. (Some docs)
- - Implement AGA support. Maybe some easy parts can be tried first (like 8
- bitplane support). I have sufficient documentation by now.
- - Reimplement Amiga OS. (Well-behaved) Amiga programs could then be made
- to use the X Window System as a "public screen". Of course, not all the
- OS would have to be re-done, only Intuition/GFX. [Started, look at gfxlib.c]
- - Translate instructions on the fly to native code, like Executor does.
- I'll NEVER try that one myself.
- - Find some extremely clever ways to optimize the smart update methods. Maybe
- try to support scrolling. Maybe find a way to update only parts of a line
- (similar to LOW_BANDWIDTH). All such methods would probably be terribly
- complicated, and not easy to get right without sacrificing compatibility.
- Maybe it's not such a good idea.
- - Port it to Java
- - A formal proof of correctness would be nice.
-
- Things I don't really want to do:
- - Full ECS support, with braindamage like Productivity and SuperHires.
-
- How it works
-
- Let's start with the memory emulation. All addressable memory is split into
- banks of 64K each. Each bank can define custom routines accessing bytes,
- words, and longwords. All banks that really represent physical memory just
- define these routines to write/read the specified amount of data to a chunk
- of memory. This memory area is organized as an array of WORDs, which means
- that those parts of the emulator that want to access memory in a linear
- fashion can get a (WORD *) pointer and use it to circumvent the overhead of
- the put_word() and get_word() calls. That is done, for example, in the
- pfield_doline() function which handles screen refreshes.
- Memory banks that represent hardware registers (such as the custom chip bank
- at 0xDF0000) can trap reads/writes and take any necessary actions.
- In some places, this scheme is abused: The uae.device and unixfs.device are
- stored in a segment at 0xF00000 containing a ROMtag structure, so it is
- recognized at bootup. Since this is a ROM area, writes shouldn't occur
- normally and are therefore used to trap into emulation routines for these
- devices.
-
- To provide a good emulation of graphical effects, only one thing is vital:
- Copper and playfield emulation have to be kept absolutely synchronous. If the
- copper writes to (say) a color register in a specific cycle, the playfield
- hardware needs to use the new information in the next word of data it
- processes.
- UAE 0.1 used to call routines like do_pfield() and do_copper() each time the
- CPU emulator had finished an instruction. That was one of the reasons why it
- was so slow. Recent versions try to draw complete scanlines in one piece. This
- is possible if the copper does not write to any registers affecting the
- display during that scanline. Therefore, drawing the line is deferred until
- the last cycle of the line. If the copper writes to a hardware register before
- that, the function pfield_may_need_update() is called and this one determines
- whether it should fall back to the cycle-for-cycle approach. This is very
- rarely needed, mainly for copper-plasma effects and such, and the general case
- is much faster.
-
- The CPU emulator no longer has to call all sorts of functions after each
- instruction. Instead, it keeps a list of events that are scheduled (timer
- interrupts, hsync and vsync events) and their "arrival time". Only the time
- for the next event is checked after each CPU instruction. If it's higher than
- the current cycle counter, the CPU can continue to execute.
-
-
- Portability
-
- The main thing you need to worry about when porting UAE to a new platform is
- the OS dependent source file handling all the graphics output. Currently,
- there are xwin.c, svga.c, mac.c, dos-grx.c, dos-null.c, bebox.cpp and
- NeXTwin.m. Rewriting one of these to use the features of your operating
- system should be fairly easy.
- You might need to worry a little about datatypes. UAE requires that your C
- compiler supports 8 bit, 16 bit and 32 bit integers, otherwise a MC68000
- emulation would be not very easy to get right. Some typedefs to hide the
- actual types used can be found in amiga.h. The CPU emulation is not the only
- place that makes some potentially non-portable assumptions: The graphics
- code in custom.c, mainly the pfield_doline() function and its friends, may
- need some work if you have a really weird architecture.
- The only thing that's left are some Unixoid assumptions, mainly in
- filesys.c, but also in debug.c. Put in a few #ifdefs and modify the Makefile
- if necessary/possible, or make up a dummy unixfs-null.c file that contains
- stubs.
- Apart from all that, it's fairly portable...
-