Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!uunet!decwrl!adobe!hawley From: hawley@adobe.COM (Steve Hawley) Newsgroups: comp.sys.mac.programmer Subject: Re: Help with ScrnBase Message-ID: <5919@adobe.UUCP> Date: 24 Aug 90 15:50:54 GMT References: <1990Aug23.171125.20436@murdoch.acc.Virginia.EDU> Reply-To: hawley@adobe.UUCP (Steve Hawley) Distribution: usa Organization: Adobe Systems Incorporated, Mountain View Lines: 147 In article <1990Aug23.171125.20436@murdoch.acc.Virginia.EDU> mil@mendel.acc.Virginia.EDU (Maria I. Lasaga) writes: > >Can anyone tell me why the following code bombs? Any clues >would be appreciated. Here is some C code I wrote a while ago to do page swapping. I have seen it work on a Mac Plus with 1M & 2M, a Mac SE with 2M and a Mac SE30. It doesn't do any sort of sanity checks for color QD, Mac II family machines or wierdo screen sizes (you want to add all this, trust me) so it will crash unceremoniously under such conditions. It will also not get along well with the MultiFinder (surprise, surprise). You can probably convert it to Pascal: /* PageSwap.h */ #define vPage2 6 #define vBase 0xefe1fe /* from IM III */ #define vBufA (512*15) /* ditto */ /* I wanted the swaps to be 1 instruction macro, not a function call. * You can probably do a similar with an inline Pascal definition. */ #define ScreenOne() asm { BSET #vPage2,vBase+vBufA } #define ScreenTwo() asm { BCLR #vPage2,vBase+vBufA } #define PAGEDIF 0x8000 /* difference between 2 screen pages in memory * This should probably be calculated not defined * so we have a hope of working on big monitors. */ extern GrafPort scrnPort; /* global GrafPort and BitMap */ extern BitMap ScreenMap; extern unsigned int rwords, rbytes, maxv; /* screen dimensions */ /* end of PageSwap.h */ /* PageSwap.c */ #include "PageSwap.h" GrafPort scrnPort; BitMap ScreenMap; unsigned int *page1, *page2; unsigned int rwords, rbytes, maxv; SetUpDouble() { /* code to set up double buffering. Your program will most * certainly crash without this. */ int ref; Handle ahandle; Str255 ApplName; if (CurPageOption != -1) { /* no double buffering, restart me */ GetAppParms(ApplName, &ref, &ahandle); /* who am i? */ Launch(-1, ApplName); /* start me with double buffering */ } else { /* have 2 buffers */ OpenPort(&scrnPort); page1 = (unsigned int *)scrnPort.portBits.baseAddr; /* don't ask me why I did this in assembly language. * It probably seemed like a good idea at the time. */ asm { move.l page1, d0 sub.l #PAGEDIFF, d0 move.l d0, page2 } maxv = scrnPort.portBits.bounds.bottom - scrnPort.portBits.bounds.top; rbytes = scrnPort.portBits.rowBytes; rwords = rbytes/2; ScreenMap = scrnPort.portBits; ScreenMap.baseAddr = (Ptr)page2; } } SwapPages() { /* Flip the pages and set the offscreen map to the invisible one. */ if (ScreenMap.baseAddr == (Ptr)page1) { ScreenOne(); ScreenMap.baseAddr = (Ptr)page2; } else { ScreenTwo(); ScreenMap.baseAddr = (Ptr)page1; } } SetPortBitsToCurrentPage() { /* Let QuickDraw know where we are. I don't do this explicitly, * because you might not want the overhead if you are writing your * own BitBlit code (like I did). */ SetPortBits(&ScreenMap); } MakeMeSane() { /* restore some sanity in the world. */ ScreenOne(); ScreenMap.baseAddr = (Ptr)page1; SetPortBitsToCurrentPage(); } /* end of PageSwap.c */ /* main.c -- some example code */ #include "PageSwap.h" main() { Rect r; InitGraf(&thePort); HideCursor(); SetUpDouble(); SetPortBitsToCurrentPage(); r = ScreenMap.bounds /* hey look! Quickdraw still works! */ PenPat(ltGray); PaintRect(&r); SwapPages(); SetPortBitsToCurrentPage(); PenPat(black); PaintRect(&r); while(!Button()) { SwapPages(); } MakeMeSane(); ShowCursor(); } /* end of main.c */ /* Typos are not my fault! :') */ Steve Hawley hawley@adobe.com -- "I can always telephone, but I can't tell it much." -Roy Blount