Annotation of uae/docs/README.PROGRAMMERS, revision 1.1.1.2

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.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.