dueker@xenon.arc.nasa.gov (The Code Slinger) (06/25/91)
In article <utoddl.677798586@next1.oit.unc.edu>, utoddl@next1.oit.unc.edu (Todd M. Lewis) writes... -- Woes on attempting to figger out the Blitter deleted -- >Does anybody out there have some advice for--or working examples of--how >to use this wonderful but woefully underdocumented chip for doing block >moves? Any help would be appreciated. > >Thanks, >Todd M. Lewis >utoddl@next1.oit.unc.edu Thomas Rokicki wrote a "Blitter laboratory" called Blitlab, and it's on the Fish disks. I'm not at home or I could tell you which one. Give it a try. It's very good and it's written so's you can experiment in relative safety (an important laboratory necessity). Chris ------------------------------------------------------------------------ "Ah, Benson, you are so mercifully free of the ravages of intellegence!" "Oh, thank you, Master!" - from the movie, TIME BANDITS ------------------------------------------------------------------------ dueker@xenon.arc.nasa.gov | Chris Dueker (The Code Slinger) duke@well.sf.ca.us | Mtn. View, CA (Sillycon Valley!)
utoddl@next1.oit.unc.edu (Todd M. Lewis) (06/25/91)
I've been putting off asking this because I really wanted to figure it out myself, but enough is enough. I have a working program that uses BltMaskBitMapRPort() quite a lot. Since I'm doing the same 10 or so blits over and over I thought I could save some time by doing the blitter register setups once at the beginning, then doing OwnBlitter()/stuff_blit_regs()/DisownBlitter() a la BlitLab when I actually need to blit. The problem is I've had a devil of a time figuring out all the details of how the blitter regs work with various shifts and ascending and descending blit modes. Some of them work as expected, others have obvious problems with modulos, etc. As an educational exercise I have undertaken to write BltMaskBitMapBitMap() with the intent of providing a well-anotated high-level example of how all these things interact and what must be taken into account to get blitter moves to work. Special case blits (like the ones in the program I mentioned) could be easily derived from this general case example. (At least it would be easier than working from the hardware ref. man.) I would hope it could at least save others the hours I've spent on this. So, I'm getting tired of scratching my head and reading the same FM and gazing at the screen trying to figure out why what should work doesn't. Does anybody out there have some advice for--or working examples of--how to use this wonderful but woefully underdocumented chip for doing block moves? Any help would be appreciated. Thanks, Todd M. Lewis utoddl@next1.oit.unc.edu
spence@cbmvax.commodore.com (Spencer Shanson) (06/25/91)
In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: > >I've been putting off asking this because I really wanted to figure it out >myself, but enough is enough. > >I have a working program that uses BltMaskBitMapRPort() quite a lot. Since >I'm doing the same 10 or so blits over and over I thought I could save some >time by doing the blitter register setups once at the beginning, then doing >OwnBlitter()/stuff_blit_regs()/DisownBlitter() a la BlitLab when I actually >need to blit. The problem is I've had a devil of a time figuring out all You are calling WaitBlit() before poking any blitter registers, aren't you? >Thanks, >Todd M. Lewis >utoddl@next1.oit.unc.edu -- --------------------------------------------------------------------------- Spencer Shanson - Amiga Software Engineer | email: spence@commodore.COM | or uunet!cbmvax!spence All opinions expressed are my own, and do not | Bix: sshanson (necessarily) represent those of Commodore. | "Copper? I hardly even | know her!"
chrisg@cbmvax.commodore.com (Chris Green) (06/25/91)
In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: >... >I'm doing the same 10 or so blits over and over I thought I could save some >time by doing the blitter register setups once at the beginning, then doing >OwnBlitter()/stuff_blit_regs()/DisownBlitter() a la BlitLab when I actually >need to blit. The problem is I've had a devil of a time figuring out all You've got the sequence wrong there. You want to: 1. OwnBlitter() 2. calculate initial values to stuff into blit regs 3. WaitBlit() (call the rom one. it deals with blitter bugs, etc.) 4. stuff initial values 5. stuff values for next bitplane, starting blitter 6. calculate values for next bit plane. 7. if more blits then WaitBlit. Goto 5. 8. DisownBlitter(). If you disown the blitter after stuffing the initial register setups, then some other task can get in and changes them before you do the rest of your blit. It is not safe to assume anything about the contents of blitter registers after an OwnBlitter(). -- *-------------------------------------------*---------------------------* |Chris Green - Graphics Software Engineer - chrisg@commodore.COM f | Commodore-Amiga - uunet!cbmvax!chrisg n |My opinions are my own, and do not - killyouridolssonicdeath o |necessarily represent those of my employer.- itstheendoftheworld r *-------------------------------------------*---------------------------d
mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (06/26/91)
In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: [ paraphrased: He wants to drive the blitter to do BlitMaskBitMapRastPort() himself ] >So, I'm getting tired of scratching my head and reading the same FM and >gazing at the screen trying to figure out why what should work doesn't. >Does anybody out there have some advice for--or working examples of--how >to use this wonderful but woefully underdocumented chip for doing block >moves? Any help would be appreciated. > >Thanks, >Todd M. Lewis >utoddl@next1.oit.unc.edu Get ahold of Tom Rokiki's BlitLab from the Fish disks. It is excellent for illustrating how the blitter works. And, by the way, rewriting BMBMPRP() is a great idea. It is a useful general purpose function as is, but it is at least 100 times slower than most software needs it to be. -- **************************************************** * I want games that look like Shadow of the Beast * * but play like Leisure Suit Larry. * ****************************************************
carolyn@cbmvax.commodore.com (Carolyn Scheppner - CATS) (06/27/91)
In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: >[] >need to blit. The problem is I've had a devil of a time figuring out all >the details of how the blitter regs work with various shifts and ascending >and descending blit modes. Some of them work as expected, others have >obvious problems with modulos, etc. >[] Do you have the 1.3 Addison Wesley Amiga Hardware Manual ? That book includes what I call the "Lost Blitter Docs" on how moves and modulos work. In addition, the chapter was reworked and edited by Mr. Blitter himself, Tom Rokicki (author of BlitLab). -- ========================================================================== Carolyn Scheppner -- Tech. Mgr. CATS - Commodore Amiga Technical Support PHONE 215-431-9180 {uunet,rutgers}!cbmvax!carolyn carolyn@commodore.com I am fully operational and all of my circuits are funcTiOnINg pperrf... ==========================================================================
utoddl@next1.oit.unc.edu (Todd M. Lewis) (06/27/91)
Mike Schwartz writes: >In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: > >[ paraphrased: He wants to drive the blitter to do >BlitMaskBitMapRastPort() himself ] Sorry, Mike, that's not what I said. A side effect of what I want to do would be the creation of the routine BltMaskBitMapBitMap(), which currently doesn't exist. But that's not the point. The points are (1) to understand all the nuances of using the blitter to do block moves, and (2) to provide a working piece of example code which incorporates every detail that must be dealt with when using the blitter directly, excluding perhaps dealing with overlapping blits and layers. My reasons are simple and follow the two points above: (1) I'm doing lots of blits over and over and I can make them go faster (I hope) if I precalculate each blit and do the QBlit() tricks, which requires that I understand how the blitter works, and (2) it would be a shame to make sense of all that and not share it with other programmers. Several people have pointed out to me that I left out some steps in my thumbnail description of what I was doing. I didn't mean to be incomplete, but I didn't want to get bogged down at the OwnBlitter/WaitBlit/DisownBlitter level--I want to get bogged down at a much lower level:-) >Get ahold of Tom Rokiki's BlitLab from the Fish disks. It is excellent >for illustrating how the blitter works. Thanks to all who pointed this out, though I mentioned BlitLab in the original article. Tom did his usual great job on that program, and I'm sure it has saved me many hours. I'm using ver. 1.1, BTW. Is that the latest? >And, by the way, rewriting BMBMPRP() is a great idea. It is a useful >general purpose function as is, but it is at least 100 times slower >than most software needs it to be. Have to disagree with you there, at least until I see some data supporting your assertion. BMBMPRP() has to deal with layers, and must set up the blitter without making any assumptions about the blit. The overhead could easily take longer than the blit itself, especially for small (say, the size of a lemming) blits. My guess (I haven't looked at the code) is that BMBMPRP() is just about as optimized as it can get and still work. Incidentally, if I do get a working BltMaskBitMapBitMap(), I can promise you it will be dog slow. Why? Because I intend to make it as clear as possible for people to understand what is involved in blitter settup. In fact, it should not be used. Just knock up a RastPort with a null Layer, set the BitMap ptr to the right place and use BltMaskBitMapRastPort() and save yourself some time and code size. >**************************************************** >* I want games that look like Shadow of the Beast * >* but play like Leisure Suit Larry. * >**************************************************** I want games that play like Lemmings, but where people send me the money! Todd (utoddl@next1.oit.unc.edu) Lewis
mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (06/28/91)
In article <utoddl.678036758@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: > >Mike Schwartz writes: >>In article <utoddl.677798586@next1.oit.unc.edu> utoddl@next1.oit.unc.edu (Todd M. Lewis) writes: >> >>[ paraphrased: He wants to drive the blitter to do >>BlitMaskBitMapRastPort() himself ] > >Sorry, Mike, that's not what I said. A side effect of what I want to do >would be the creation of the routine BltMaskBitMapBitMap(), which currently >doesn't exist. But that's not the point. The points are (1) to understand >all the nuances of using the blitter to do block moves, and (2) to provide >a working piece of example code which incorporates every detail that must >be dealt with when using the blitter directly, excluding perhaps dealing with >overlapping blits and layers. > 1) Get the SOURCE to blitlab. It not only has code to drive the blitter, but it also has 'C' code that emulates the blitter. If you want to reinvent the wheel, go ahead. Tom has already given us a great example of how to use the blitter. Also, AmigaMail contains a few examples as does the Hardware Manual. 2) get blitlab... >My reasons are simple and follow the two points above: (1) I'm doing lots >of blits over and over and I can make them go faster (I hope) if I precalculate >each blit and do the QBlit() tricks, which requires that I understand how >the blitter works, and (2) it would be a shame to make sense of all that >and not share it with other programmers. > 1) Precalculating is a good idea if you want speed, but QBlit makes no sense at all. If you know the size of what you want to blit, it is trivial to code up REAL fast blit routines to blit specific sized items. Also you might want to consider RAW blitting, which has been covered here a few times. Once you do an OwnBlitter(), you can load the values you want into the blitter registers and most of them stay there forever, or until you release the blitter (Qblit forces you to reload the blitter registers over and over). 2) Your desire to share your results is commendable, and I appreciate it. >Several people have pointed out to me that I left out some steps in my >thumbnail description of what I was doing. I didn't mean to be incomplete, >but I didn't want to get bogged down at the OwnBlitter/WaitBlit/DisownBlitter >level--I want to get bogged down at a much lower level:-) > You NEED to be complete, especially when dealing with the blitter the way you want to. Again, if you don't do things correctly, your code will cause havoc to the system. If the OS is using the blitter to scroll a window while you are storing to the blitter registers, you are going to make the blitter store to random memory locations - instant GURU. Also, again, you need to do OwnBlitter() if you want to keep the blitter registers loaded with the numbers you want. Once you set up the blit, you only need to store Source, Destination, and BltSize to start the next plane blit. Any other way, and you will have to load up to 14 registers again and again. You might also consider using blitter NASTY, which makes the blitter go 2x faster. You might also consider using the CPU instead of the blitter if the CPU is an 030 (it is faster that way). >>And, by the way, rewriting BMBMPRP() is a great idea. It is a useful >>general purpose function as is, but it is at least 100 times slower >>than most software needs it to be. > >Have to disagree with you there, at least until I see some data supporting >your assertion. BMBMPRP() has to deal with layers, and must set up the blitter >without making any assumptions about the blit. The overhead could easily take >longer than the blit itself, especially for small (say, the size of a lemming) >blits. My guess (I haven't looked at the code) is that BMBMPRP() is just about >as optimized as it can get and still work. > BMBMRP() is slow no matter how you use it. Try it for yourself and see. Create a bitmap and rastport with NO layers and it still is dog slow. When I first started programming the Amiga 6 years ago, a friend gave me a blit routine he wrote called BlitBitMapPlane(), which was written in 'C'. It took 16 input parameters on the stack (for each plane of a blit no less) and it in turn called an internal blit routine with another 14 parameters on the stack. All that pushing and popping of parameters gets multipled by 5 if you do 32 colors... Anyhow, this terribly inefficient 'C' code was 10 times faster than BMBMRP(). And if you really want to know how to use the system blit routines to do BMBMRP() style blitting, you can do 2 BltBitMap() calls faster than a single BMBMRP() call. >Incidentally, if I do get a working BltMaskBitMapBitMap(), I can promise you it >will be dog slow. Why? Because I intend to make it as clear as possible >for people to understand what is involved in blitter settup. In fact, it should >not be used. Just knock up a RastPort with a null Layer, set the BitMap ptr to >the right place and use BltMaskBitMapRastPort() and save yourself some time and >code size. > You should explore the 2 BltBitMap() calls before you determine how dog slow your code needs to be. You should try 2 BltBitMapRastPort() calls as well, which also runs real fast. I agree you will save yourself programming time and code size if you don't bother to try to make faster code. >>**************************************************** >>* I want games that look like Shadow of the Beast * >>* but play like Leisure Suit Larry. * >>**************************************************** > >I want games that play like Lemmings, but where people send me the money! > >Todd (utoddl@next1.oit.unc.edu) Lewis -- **************************************************** * I want games that look like Shadow of the Beast * * but play like Leisure Suit Larry. * ****************************************************
mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (07/01/91)
In article <PETERM.91Jun30133541@kea.am.dsir.govt.nz> peterm@am.dsir.govt.nz (Peter McGavin) writes: >In article <utoddl.678036758@next1.oit.unc.edu> <mykes.4002@amiga0.SF-Bay.ORG> >Mike Schwartz writes: >>Qblit forces you to reload the blitter registers over and over > >Nope. One call to QBlit() can perform multiple blits, and you need only >reload the registers that change for the 2nd and subsequent blits. See >the description of "function" on page 380 of the 1.3 L&D RKM. > >>Also, again, you need to do OwnBlitter() if you want to keep the blitter >>registers loaded with the numbers you want. > >Again, nope (if you use QBlit() right). > >Furthermore, QBlit() has the advantage of not blocking your task when >someone else already owns the blitter. So it is easier to keep both the >CPU and blitter busy at the same time with QBlit() than with OwnBlitter(). >-- >Peter McGavin. (srwmpnm@wnv.dsir.govt.nz or peterm@am.dsir.govt.nz) No matter what the RKM says, QBlit() doesn't perform as you indicate. It clearly states in my RKM that QSBlit() overrides the QBlit fifo, meaning that your blitter registers could be trashed. It also isn't clear from the RKM whether someone else can do an OwnBlitter() and get the blitter in the midst of QBlitting. In the many areas where the RKM isn't clear like this, CBM seems to indicate that you shouldn't rely on the behavior of the OS routines... In other words, if you assume that the blitter registers are going to be the same as when you last QBlitted a plane, your code might work on YOUR machine with YOUR applications, but not on mine. -- **************************************************** * I want games that look like Shadow of the Beast * * but play like Leisure Suit Larry. * ****************************************************