|
|
1.1 root 1: You can help to make this program better. If you fix bugs or implement new
2: features, I'd be grateful if you send me patches. For a list of interesting
3: projects, and for a brief summary on how UAE works, see below.
4:
5: A few guidelines for anyone who wants to help:
6: - Please contact me first before you implement major new features. Someone
7: else might be doing the same thing already. This has already happened :-(
8: Even if no one else is working on this feature, there might be alternative
9: and better/easier/more elegant ways to do it.
10: - Some coding guidelines.
1.1.1.2 ! root 11: * Avoid GNU C extensions by all means. They make your code non-portable
! 12: (unless you can work around them with a bit of preprocessor magic).
1.1 root 13: * Avoid GNU indentation style by all means. It makes your code unreadable.
14: * Try to indent your code nicely. There are editors like JED, which is
15: available from space.mit.edu:/pub/davis and highly recommendable, that do
16: this for you automatically.
17: * Use eight space tabs, four space tabs make a mess of the code.
18: - If you have access to more than one Unix system, try compiling/running your
1.1.1.2 ! root 19: code on all of these. Remember, UAE is supposed to run on 64 bit machines:
! 20: so don't assume sizeof(char*) == sizeof(int) == sizeof(long)
1.1 root 21: - If you have more than one Kickstart, try your code with each one.
22: - Patches are welcome in any form, but diff -u or diff -c output is preferred.
23: If I get whole source files, the first thing I do is to run diff on it. You
24: can save me some work here (and make my mailbox smaller).
25:
26: Some possible projects, in order of estimated difficulty:
1.1.1.2 ! root 27: - Someone running *BSD on a x86 might want to try using X86.S on such a
! 28: system. It's likely that only configure needs to be modified.
! 29: - Add gamma correction
! 30: - Repair support of the serial interface. Sending data seems to work,
! 31: receiving does not. Maybe this has to be implemented in a completely
! 32: different way (a serial.device? If you do that, don't do it native. At least
! 33: not all of it. Amiga libraries shouldn't be implemented completely native
! 34: in UAE, the parts which are not speed critical should be Amiga native so
! 35: they can call other 68k code safely).
1.1 root 36: - Someone with a 68020 data sheet might check whether all opcodes are
37: decoded correctly and whether all instructions really do what they are
38: supposed to do (I'm pretty sure it's OK by now, but you never know...).
1.1.1.2 ! root 39: - Multi-thread support is there now, it just needs someone to test it on a SMP
! 40: machine and to fix it so it improves speed instead of slowing the thing
! 41: down.
1.1 root 42: - Improve the Kickstart replacement to boot more demos.
43: - Snapshots as in CPE. Will need to collect all the variables containing
44: important information. Fairly easy, but boring. (Use core dumps instead :-)
1.1.1.2 ! root 45: _If_ someone attempts this, please be more clever than the various CPC
! 46: emulators and dump state only at one fixed point in the frame, preferrably
! 47: the vsync point.
1.1 root 48: - Find out why uae.device has to be mounted manually with Kick 1.3.
49: The problem seems to be that we don't have a handler for it. I _think_ what
50: we need is the seglist of the standard filesystem handler. Problem is,
51: DOS hasn't been started when the devices are initialized and so we can't get
52: to the DosBase->RootNode->FileHandlerSeg pointer, and then there is the
53: confusing matter of BCPL GlobVecs and other weird stuff...
1.1.1.2 ! root 54: - Some incompatibilities might be fixed with user-modifiable fudge variables
! 55: the same way it's done in various C64 emulators.
! 56: - With the new display code, it would probably be easier than before to
! 57: implement ECS resolutions - however, a lot of places rely on the OCS timing
! 58: parameters and display sizes.
1.1 root 59: - Figure out a diskfile format that supports every possible non-standard
60: format.
61: - Implement 68551 MMU. I have docs now. Not among the most necessary things.
1.1.1.2 ! root 62: Difficult, at least without using C++ exception handling.
1.1 root 63: - Implement AGA support. Some bits and pieces exist.
64: - Reimplement Amiga OS. (Well-behaved) Amiga programs could then be made
65: to use the X Window System as a "public screen". Of course, not all the
1.1.1.2 ! root 66: OS would have to be re-done, only Intuition/GFX/Layers (which is enough).
! 67: [Started, look at gfxlib.c. The problem is that you need all of Exec native
! 68: first before you can do any non-trivial graphics operation.]
! 69: - Find some extremely clever ways to optimize the smart update methods. Some
! 70: ideas:
! 71: a) Always use memcmpy() to check for bitplane differences. If no differences
! 72: are found, see if BPLxDELAY got modified, if so, scroll.
! 73: Problems:
! 74: * You'd still have to draw a few pixels around the DIW borders. Not very
! 75: hard.
! 76: * Scrolling with memcpy in video memory can be terribly slow (no, I
! 77: shouldn't have bought the cheaper video card with DRAMs)
! 78: * At least every 15 pixels a full update has to be done since the
! 79: bitplane pointers get updated after that. And that's with the slowest
! 80: scrolling - if the playfield scrolls faster, the benefit converges
! 81: against zero.
! 82: You could also do vertical scrolling tests, but similar problems arise -
! 83: where should one check? One line above/below? What about faster
! 84: scrolling? You could use the bitplane pointers as hints, but with
! 85: double/triple buffering this gets problematic, too.
! 86: On the whole, I don't think it would be worth the effort, even if it
! 87: works very well for a few games.
! 88: b) Well, there is no b). If I thought of something I forgot it while
! 89: writing a).
1.1 root 90: - Port it to Java and Emacs Lisp
91: - A formal proof of correctness would be nice.
92:
93:
94: How it works
95:
96: Let's start with the memory emulation. All addressable memory is split into
97: banks of 64K each. Each bank can define custom routines accessing bytes,
98: words, and longwords. All banks that really represent physical memory just
99: define these routines to write/read the specified amount of data to a chunk
1.1.1.2 ! root 100: of memory. This memory area is organized as an array of UBYTEs, which means
1.1 root 101: that those parts of the emulator that want to access memory in a linear
1.1.1.2 ! root 102: fashion can get a (UBYTE *) pointer and use it to circumvent the overhead of
! 103: the put_*() and get_*() calls. That is done, for example, in the
1.1 root 104: pfield_doline() function which handles screen refreshes.
105: Memory banks that represent hardware registers (such as the custom chip bank
106: at 0xDF0000) can trap reads/writes and take any necessary actions.
107: In some places, this scheme is abused: The uae.device and unixfs.device are
108: stored in a segment at 0xF00000 containing a ROMtag structure, so it is
109: recognized at bootup. Since this is a ROM area, writes shouldn't occur
110: normally and are therefore used to trap into emulation routines for these
111: devices.
112:
113: To provide a good emulation of graphical effects, only one thing is vital:
114: Copper and playfield emulation have to be kept absolutely synchronous. If the
115: copper writes to (say) a color register in a specific cycle, the playfield
1.1.1.2 ! root 116: hardware needs to use the new information in the next word of data it
1.1 root 117: processes.
118: UAE 0.1 used to call routines like do_pfield() and do_copper() each time the
119: CPU emulator had finished an instruction. That was one of the reasons why it
120: was so slow. Recent versions try to draw complete scanlines in one piece. This
121: is possible if the copper does not write to any registers affecting the
122: display during that scanline. Therefore, drawing the line is deferred until
1.1.1.2 ! root 123: the last cycle of the line. However, sometimes a register which affects how
! 124: the screen will look is modified before the end of the line (think of copper
! 125: plasmas). That's what "struct decision thisline_decision" is for. It is
! 126: initialized at the start of each line. During the line, whenever a vital
! 127: register is changed, one of the decide_*() functions is called and may modify
! 128: thisline_decision. There are several independent decisions:
! 129: - which DIW should be used
! 130: - where does data fetch start/stop (or is the line in the border altogether)
! 131: - where should sprites be drawn (note: the same sprite can appear more than
! 132: once on one scanline, see Turrican I world 3 levels 1 and 3 for the best
! 133: example)
! 134: - what are the playfield pointers at the start of DDF. Related, what data do
! 135: they point to.
! 136: - what are the playfield modulos at the end of DDF
! 137: - coppermagic with the colors is remembered for later use
! 138: - so is copper magic with the bitplane delay values. I used to think there
! 139: was no useful application for modifying BPLCON1 while data is being
! 140: displayed, but Sanity demos can make Amiga emulator programmers look real
! 141: old.
! 142:
! 143: All of this is remembered while the raster line is processed by the hardware.
! 144: After the line (at hsync), all the decisions are made if they weren't made
! 145: before. At that point the line can be drawn by playfield_draw_line.
! 146: Additionally, all the decisions from the previous displayed frame are saved
! 147: and compared with the new ones, since often lines are not modified between
! 148: frames. This saves a lot of redrawing work.
1.1 root 149:
150: The CPU emulator no longer has to call all sorts of functions after each
151: instruction. Instead, it keeps a list of events that are scheduled (timer
152: interrupts, hsync and vsync events) and their "arrival time". Only the time
153: for the next event is checked after each CPU instruction. If it's higher than
154: the current cycle counter, the CPU can continue to execute.
155:
1.1.1.2 ! root 156: Things that can't be supported with the current "decision" model:
! 157: - Changes in lores/hires mode during one line. Dunno whether that was ever
! 158: used in reality.
! 159: - Changes to the bitplane DMA bit during one line. Hardly useful and not
! 160: likely to be used. [but there is at least two programs which does ugly
! 161: things like that, and there are some hacks in UAE that make those programs
! 162: work (Magic 12 Ray of Hope 2 is one of these demos)]
! 163: - Changes in bitplane data during one line. If programs do this kind of
! 164: thing, it's most likely accidental and the program is broken. Can happen
! 165: with programs that use the blitter incorrectly, like all the Andromeda
! 166: demos.
! 167: - others? (fill in if you can think of anything)
! 168:
! 169: All in all, it's unlikely that this causes compatibility problems. If it does,
! 170: fudge values could be introduced (although that sort of thing gets messy
! 171: quickly).
1.1 root 172:
173: Portability
174:
175: The main thing you need to worry about when porting UAE to a new platform is
176: the OS dependent source file handling all the graphics output. Currently,
177: there are xwin.c, svga.c, mac.c, dos-grx.c, dos-null.c, bebox.cpp and
178: NeXTwin.m. Rewriting one of these to use the features of your operating
179: system should be fairly easy.
180: You might need to worry a little about datatypes. UAE requires that your C
181: compiler supports 8 bit, 16 bit and 32 bit integers, otherwise a MC68000
182: emulation would be not very easy to get right. Some typedefs to hide the
183: actual types used can be found in amiga.h. The CPU emulation is not the only
184: place that makes some potentially non-portable assumptions: The graphics
185: code in custom.c, mainly the pfield_doline() function and its friends, may
186: need some work if you have a really weird architecture.
187: The only thing that's left are some Unixoid assumptions, mainly in
188: filesys.c, but also in debug.c. Put in a few #ifdefs and modify the Makefile
189: if necessary/possible, or make up a dummy unixfs-null.c file that contains
190: stubs.
191: Apart from all that, it's fairly portable...
1.1.1.2 ! root 192:
! 193:
! 194: How the compiler works
! 195:
! 196: .. yet to be written. To be decided, in fact.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.