mil@mendel.acc.Virginia.EDU (Maria I. Lasaga) (08/24/90)
Can anyone tell me why the following code bombs? Any clues would be appreciated. Essentially, I am trying to switch between the main and alternate video buffers of an SE. (I know that newer Mac models don't have this option, but I need to use it for a very specific application.) I am trying to get around using assembly language because I haven't used it in a while and am a bit rusty, and because I don't have the time to relearn it. (IM III-20 suggests how one might alternate between the main and alternate video buffers in assembly language, but I can't make sense of it.) So here's the code that bombs. The machine just freezes. I assume I am overwriting parts of memory I shouldn't, but I don't get how I am doing this: var offscreen: grafport; mypointer: ptr; mybitmap: bitmap; myaddress: longint; begin {--offscreen bitmap created here--} eraserect(theport^.portrect); { clearing the area of memory... } myaddress := $727; {starting location for alternate memory buffer on SE} mybitmap.baseaddr := @myaddresvkcPmybitmap.rowbytes := offscreen.portbits.rowbytes; mybitmap.bounds := offscreen.portbits.bounds; copybits(offscreen.portbits, mybitmap, offscreen.portrect, offscreen.portrect, srccopy, nil); {copies an image previously drawn in an offscreen portrect} myaddress := $824; {supposedly the location of the global variable,} {ScrnBase, that holds the address of the main screen } {buffer. } mypointer := @myaddress; mypointer^ := $727; {Attempt to set ScrnBase to the address of the } {alternate screen buffer.} end; ----------------------------------------------------------------------- Maria I. Lasaga Dept. of Psychology Gilmer Hall University of Virginia Charlottesville, Virginia 22903 mil@virginia.bitnet -----------------------------------------------------------------------
mil@mendel.acc.Virginia.EDU (Maria I. Lasaga) (08/24/90)
(Sorry. Noise on the line messed up the code in the previous listing.) Can anyone tell me why the following code bombs? Any clues would be appreciated. Essentially, I am trying to switch between the main and alternate video buffers of an SE. (I know that newer Mac models don't have this option, but I need to use it for a very specific application.) I am trying to get around using assembly language because I haven't used it in a while and am a bit rusty, and because I don't have the time to relearn it. (IM III-20 suggests how one might alternate between the main and alternate video buffers in assembly language, but I can't make sense of it.) So here's the code that bombs. The machine just freezes. I assume I am overwriting parts of memory I shouldn't, but I don't get how I am doing this: var oldport: grafptr; offscreen: grafport; mypointer: ptr; mybitmap: bitmap; myaddress: longint; begin {--offscreen bitmap created here--} eraserect(theport^.portrect); { clearing the area of memory... } myaddress := $727; {starting location for alternate memory buffer on SE} mybitmap.baseaddr := @myaddress; mybitmap.rowbytes := offscreen.portbits.rowbytes; mybitmap.bounds := offscreen.portbits.bounds; copybits(offscreen.portbits, mybitmap, offscreen.portrect, offscreen.portrect, srccopy, nil); {copies an image previously drawn in an offscreen portrect} myaddress := $824; {supposedly the location of the global variable,} {ScrnBase, that holds the address of the main screen } {buffer. } mypointer := @myaddress; mypointer^ := $727; {Attempt to set ScrnBase to the address of the } {alternate screen buffer.} end; ----------------------------------------------------------------------- Maria I. Lasaga Dept. of Psychology Gilmer Hall University of Virginia Charlottesville, Virginia 22903 mil@virginia.bitnet -----------------------------------------------------------------------
jackiw@cs.swarthmore.edu (Nick Jackiw) (08/24/90)
mil@mendel.acc.Virginia.EDU (Maria I. Lasaga) writes: > Can anyone tell me why the following code bombs? Any clues > would be appreciated. DISCLAIMER: I've never played with ScrnBase and don't, off the top of my head, know how to do it. The following observations are "clues"--not answers. > > var > oldport: grafptr; > offscreen: grafport; > mypointer: ptr; "Ptr" is defined in the Memory Manager as ^SignedByte. You are trying to stuff either a word or a longword into myPointer. Depending on your compiler, you may just be sticking the low-order byte of this word or longword into myPointer^. Try instead declaring myPointer as either ^longint or ^integer, depending on whether you want to write four bytes or two. > mybitmap: bitmap; > myaddress: longint; > > begin > > {--offscreen bitmap created here--} > > > eraserect(theport^.portrect); { clearing the area of memory... } > > myaddress := $727; {starting location for alternate memory buffer on SE} > mybitmap.baseaddr := @myaddress; I highly doubt that location $727 is the base address of an alternate memory buffer. Why? Because a B&W 9" screen is about 20K worth of data, and the area between $727 and $727+20K is filled with important low-memory globals. Not exactly information you want to be drawing pictures over. Could location $727 *contain* the address of the alternate screen buffer? If so, you'll want to set myBitmap.baseAddr to longintPtr($727)^, instead of to $727 itself. > mybitmap.rowbytes := offscreen.portbits.rowbytes; > mybitmap.bounds := offscreen.portbits.bounds; > copybits(offscreen.portbits, mybitmap, > offscreen.portrect, offscreen.portrect, srccopy, nil); > > {copies an image previously drawn in an offscreen portrect} > > myaddress := $824; {supposedly the location of the global variable,} > {ScrnBase, that holds the address of the main screen } > {buffer. } > > mypointer := @myaddress; > mypointer^ := $727; {Attempt to set ScrnBase to the address of the } > {alternate screen buffer.} > end; This stuff is wrong for the above reasons. You're setting location $824 to value $727, and I suspect you want to set location $824 to value of location $727. If not, as soon as you write data, the 20K following location $727 is going to be scrambled--including, of course, location $824. Hope this puts you on the right track. -- ------------------------ Nick Jackiw jackiw@cs.swarthmore.edu "Just break out the Visual Geometry Project jackiw@swarthmr.bitnet rum so we seem natural!" Swarthmore College, PA 19081-1397 -F. Franklin
hawley@adobe.COM (Steve Hawley) (08/24/90)
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