Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!rphroy!caen!hellgate.utah.edu!csn!ub!dsinc!bagate!cbmvax!jesup From: jesup@cbmvax.commodore.com (Randell Jesup) Newsgroups: comp.sys.amiga.programmer Subject: Re: Lemmings - a tutorial Part V (last) Message-ID: <20213@cbmvax.commodore.com> Date: 31 Mar 91 06:32:44 GMT References: <23788@well.sf.ca.us> <23837@well.sf.ca.us> <781@tnc.UUCP> Reply-To: jesup@cbmvax.commodore.com (Randell Jesup) Organization: Commodore, West Chester, PA Lines: 183 In article mykes@amiga0.SF-Bay.ORG (Mike Schwartz) writes: >But, a small description of how I do things. I always develop for >an Amiga 500 with 512K of RAM. My 500 has 1Meg and the old Agnus >and 1.2 ROMs. This configuration is guaranteed to give you the >basic features of the vast majority of Amigas around, and I get to >see the game perform exactly as the end user will, including floppy >disk access, the whole time I develop. This is a good thing to do: always have a "standard" machine to test your code on, and we encourage developers to do this. >the machine will boot from the floppy. In any case, the ROM Kernel >loads what is called the boot program from track 0 of the floppy >disk into RAM and does a JSR to it. The standard Amiga OS bootsector >program simply opens dos.library and then does an RTS and the system >continues to boot up into the normal Operating System. You should learn more about the OS... It actually never returns if it opens dos.library. Dos starts the initial process, and then kills the initial task (itself). The initial process continues the boot process. (I'm the person who rewrote the Dos in C and asm.) >a BIOS of sorts. In addition to this 8K of KERNEL code, there is another >12K of floppy disk drivers, because I will not have the operating system >running to read any further data from the floppies. Note that even 2.0 trackdisk is only about 7K long. >Since I am in supervisor mode, there are NO illegal instructions that >can be executed (priviledge violations cause a GURU under the OS). The >User Stack Pointer (USP) also can be used as a quick place to save >an address register (this is 2x faster than a push on the stack). >The upper byte of the status register is available to disable various >levels of interrupts (the INTENA on Paula is just as useful), and >the TRACE bitis available for debugging purposes. Hopefully, if you programmed your game right, you shouldn't have to worry about executing an illegal instruction by mistake (except of course ILLEGAL). Disabling interrupts in the processor is faster than disabling them in Paula, since you don't have to get on the chip bus to do it. >The floppy disk drivers I wrote use a single 10K buffer to handle as >many disk drives (up to 4) that may be configured. The OS routines >will steal 40K if you have 4 drives (10K per drive). Amusing. First, you need more than 10K for a MFM buffer, since the number of bytes (decoded) per track can be as high as 6812, so the MFM buffer must be at LEAST 13624, and you actually want it a bit larger in some cases (we use 15296 - we keep a gaps-worth of NULLs (aaaaaaaa) before the spot where we read, to make writing faster/easier). Sure you don't mean 16K? (Which is what the OS in 1.3 used, though it was a bit more than was needed.) >enhanced performance a few ways. One way is that the blitter is in >nasty mode, so encoding/decoding the MFM data is as fast as possible. Decoding is faster with the processor, if you also are going to check the checksum. Nasty mode will hurt your interrupt response time. Sounds like the classic "optimize the routine within a inch of it's life, and miss the fact that a different algorithm would be twice as fast". BTW, when there's a >2 bitplane (>4 in 320x200/400), running code from the ROMs is faster than from ram, since you don't have to pay the penalty for getting cycles to from the chip bus 9since in your way of programming, all your code ends up in chip ram - annoying for something that could use the extra horsepower, like 3d games. >When data is written to diskette, it is arranged so that NO extra disk >revolutions will be made during readback. This is done by timing >the read and write routines so that by the time a track has been read >in and the head stepped, the next start of track is under the head >and ready to go. Unless your're pulling partial tracks off and using them before the revolution is complete, or unless you're going to write it out again, this makes no difference - and for writing all it saves you is a block-move to eliminate the gap. > The routines also make use of the DSKSYNC capability >of the drives, which the OS routines don't (under 2.0 they probably >do). Yup. Not as big a win as you'd think (I thought it would be a big win, but floppy rotation time swamps almost anything). > The routines use a CIA timer to get perfect timing, no matter >what processor. Try popping the disk out with the disk light on (it >works). Try ejecting the disk in the middle of a load and put it >into a different drive (it works). Try that with the OS and watch >your disk go bad in 1 second, thanks to the disk validator. I guarantee that if you pop a disk while it's writing, it WILL go bad. Even with your code. If it's reading, it may forcefully ask for it back, but it won't go bad. >And what if you >allow multitasking and some CHIP RAM pig program (like DPaint) is already >running? GURU. And you need to test with 4 floppy drives under the OS, >just to make sure the OS hasn't taken more memory than you can allow. You should learn to check allocation returns. It's not hard. There's even a tool for selectively denying memory allocations to stress- test your program that we distribute (written by Bill Hawes to help test 2.0). >Once you start >using the floppy disk hardware directly, for example, you must put >the CIAs back into a state that the OS wants them in. What state is that? >The ROM Kernel manuals LIE. Have fun finding out what page they lie on, >because there is NO index. Sure, the 1.1 RKMs had the CIA allocations backwards. The 1.3 RKMs (which have been out a long time now) had the correct information (and indexes). We told people this. This caused our worst 2.0 compatibility problems, though we solved almost all of them (by dink of truely tricky programming...) >>On the other hand, games like Sim-City and Lemmings have no real use >>for that kind of environment. I agree that the game comes first, >>*BUT* if you don't need total control, *DON'T* take it. >I agree with this 100%. If you don't need to take over the machine, >don't. If you want to push the machine to its limits, there is NO >other way. True. > Let the game come first. If you know you can do the >game in a small amount of RAM and that performance is not an issue, >go ahead and use the OS. In my approach, if I have RAM left over, >I use it for more sounds or instrument samples to make the music >better, or to cache more data from the floppy drives. You don't let the _game_ come first, you put your _implementation_ first. There is a difference. As for your approach, you may find your game didn't need all these tricks, and had ram left over when you're done. But since you programmed yourself into a corner you can't go back and cooperate with the system, so you just look for ways to use up the ram in a more-or-less-useful manner. >Unfortunately, the sales life of a game is about 3 months. Royalties >don't keep trickling in. Good _games_, ones that have a depth beyond flashy graphics, and have replayability, do continue to sell (though they do best when first released, like most authored products). Sure, they do eventually trend towards 0, but by no means do they walk off a cliff for a good game (or even a well-done flashy game). >The OS does have bugs, however. I spent weeks finding them for other >people at EA. Ever hear about the trackdisk bug? It seems that if >you have an external floppy drive and have no disk in it, and do intensive >disk access to the internal drive, it gurus after a random (long) amount >of time. Actually it has nothing to do with internal versus external. This was fixed in one of the 1.3 releases in SetPatch. Note: I don't ever remember seeing a bug report from EA about this (or in fact about almost anything, though some of the people who sell things through EA do report bugs well, and this has changed somewhat for the better in the last few years). Perhaps there was one, it was a while ago, but I don't remember it. Developer support is a 2-way street. >Did you know that LoadRGB4() takes a full 60th of a second on a 68000? No, it merely doesn't take effect until the next vblank (it modifies the copperlist). >How long does MrgCop() take (pick random number). How long does >RethinkDisplay() take (seconds)? How long does BltMaskBitMapRastPort() >take? (1) those are not called all the time, (2) you're exaggerating by a lot. BMBMRP() is not fast because it operates on arbitrary rectangles, and some sets require using the A-channel as a mask. So if you do know the alignments are ok, OwnBlitter() and program it directly. -- Randell Jesup, Keeper of AmigaDos, Commodore Engineering. {uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.commodore.com BIX: rjesup Thus spake the Master Ninjei: "To program a million-line operating system is easy, to change a man's temperament is more difficult." (From "The Zen of Programming") ;-)