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 68020 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. - Improve the Kickstart replacement to boot more demos. - 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 has to be mounted manually with Kick 1.3. The problem seems to be that we don't have a handler for it. I _think_ what we need is the seglist of the standard filesystem handler. Problem is, DOS hasn't been started when the devices are initialized and so we can't get to the DosBase->RootNode->FileHandlerSeg pointer, and then there is the confusing matter of BCPL GlobVecs and other weird stuff... - 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. Not _really_ necessary, I think: Surprisingly, and unlike 8 bit computer software, Amiga programs usually seem to make use only of documented hardware features. - Figure out a diskfile format that supports every possible non-standard format. - Implement 68551 MMU. I have docs now. Not among the most necessary things. - Implement AGA support. Some bits and pieces exist. - 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] - 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 and Emacs Lisp - 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...