home *** CD-ROM | disk | FTP | other *** search
- /*
- Test mappings
- */
-
- #include <QDOffscreen.h>
- #include <FixMath.h>
-
- #define pictID 128
- #define kFrameCount 16
-
- void MapCoordinates(short width, short height, short x, short y, short *resultX, short *resultY)
- #define cycleSize (16)
- {
- #define HorizontalSineWave 0
- #define VerticalSineWave 1
- #define Mirror 0
-
- #if Mirror
- *resultX = width - x;
- *resultY = y;
- #endif
-
- #if HorizontalSineWave
- *resultX = x + (2*Frac2Fix(FracSin(y*205887/cycleSize))+32768)/65536;
- *resultY = y;
- #endif
-
- #if VerticalSineWave
- *resultX = x;
- *resultY = y + (2*Frac2Fix(FracSin(x*205887/cycleSize))+32768)/65536;
- #endif
-
- while (*resultX < 0)
- *resultX += width;
- while (*resultY < 0)
- *resultY += height;
-
- *resultX %= width;
- *resultY %= height;
- }
-
- /*
- Generate the addresses for the mapping.
- */
-
- void
- GenerateMappingTable(long *mappingTable, short width, short height, short rowBytes, short frameNumber)
- {
- long *offsetHere;
- short x, y;
-
- offsetHere = mappingTable;
-
- for (y = 0; y < height; ++y) {
- for (x = 0; x < width; ++x)
- {
- short destinationX, destinationY;
-
- MapCoordinates(width, height, x, y, &destinationX, &destinationY);
- *offsetHere++ = (long)destinationY * rowBytes + destinationX;
- }
- }
- }
-
- //
- // Blit the entire bitmap from source to dest
- //
-
- void
- BlitThroughTable(char *sourceBase, char *destinationBase, short height, short width,
- short rowBytes, long *mappingTable)
- {
- short x, y;
- char *sourceRow, *sourceByte;
- long *offsetHere;
-
- offsetHere = mappingTable;
-
- for (y = 0; y < height; ++y)
- {
- sourceRow = sourceBase;
- for (x = 0; x < width; ++x)
- *(destinationBase + *offsetHere++) = *sourceRow++;
- sourceBase += rowBytes;
- }
- }
-
- //
- // Blit the entire bitmap from source to dest using a technique similar to what
- // we'd like to compile.
- //
- // Use 5 destination registers so we can use 16-bit constant offsets in instructions
- // of the form:
- //
- // move.b (sourceRow)+, tableValue(destReg[0..4])
- //
- //
- // Some useful instructions
- // 00000000: 207C 1234 5678 MOVEA.L #$12345678,A0
- // 00000006: 227C 1234 5678 MOVEA.L #$12345678,A1
- // 0000000C: 247C 1234 5678 MOVEA.L #$12345678,A2
- // 00000012: 267C 1234 5678 MOVEA.L #$12345678,A3
- // 00000018: 287C 1234 5678 MOVEA.L #$12345678,A4
- // 0000001E: 2A7C 1234 5678 MOVEA.L #$12345678,A5
- //
- // 00000006: 115D 1234 MOVE.B (A5)+,$1234(A0)
- // 0000000A: 135D 1234 MOVE.B (A5)+,$1234(A1)
- // 0000000E: 155D 1234 MOVE.B (A5)+,$1234(A2)
- // 00000012: 175D 1234 MOVE.B (A5)+,$1234(A3)
- // 00000016: 195D 1234 MOVE.B (A5)+,$1234(A4)
-
- // 00000038: 48E7 00FC MOVEM.L A0-A5,-(A7)
- // 0000003C: 4CDF 3F00 MOVEM.L (A7)+,A0-A5
-
- // 00000040: 4E75 RTS
-
- #define movea_to_a0 0x207c
- #define movea_to_a1 0x227c
- #define movea_to_a2 0x247c
- #define movea_to_a3 0x267c
- #define movea_to_a4 0x287c
- #define movea_to_a5 0x2a7c
-
- #define move_b_a5plus_a0 0x115d
- #define move_b_a5plus_a1 0x135d
- #define move_b_a5plus_a2 0x155d
- #define move_b_a5plus_a3 0x175d
- #define move_b_a5plus_a4 0x195d
-
- #define movem_push_a0_a5 0x48e700fcL
- #define movem_pop_a0_a5 0x4cdf3f00L
-
- #define rts 0x4e75
-
- void
- WriteSomeCode(char *sourceBase, char *destinationBase, short height, short width,
- short rowBytes, long *mappingTable, short *theCode)
- {
- short i, x, y;
- char *sourceRow, *sourceByte;
- long *offsetHere;
-
- char *destRegisters[5];
- long registerRange; // how much of a bitmap chunk each register sees
- long rangeOffset; // where in the chunk each register points
- long targetBitMapSize;
-
- targetBitMapSize = (long) height * (long) rowBytes;
- registerRange = (targetBitMapSize + 20) / 5;
- rangeOffset = (registerRange / 2) & ~3;
-
- for (i = 0; i < 5; i++)
- destRegisters[i] = destinationBase + registerRange * i + rangeOffset;
-
- offsetHere = mappingTable;
-
- // save the registers we trash
- *(*(long **) &theCode)++ = movem_push_a0_a5;
-
- // load the 4 registers
- *(*(short **) &theCode)++ = movea_to_a0;
- *(*(char ***) &theCode)++ = destRegisters[0];
- *(*(short **) &theCode)++ = movea_to_a1;
- *(*(char ***) &theCode)++ = destRegisters[1];
- *(*(short **) &theCode)++ = movea_to_a2;
- *(*(char ***) &theCode)++ = destRegisters[2];
- *(*(short **) &theCode)++ = movea_to_a3;
- *(*(char ***) &theCode)++ = destRegisters[3];
- *(*(short **) &theCode)++ = movea_to_a4;
- *(*(char ***) &theCode)++ = destRegisters[4];
-
- for (y = 0; y < height; ++y)
- {
- sourceRow = sourceBase;
-
- // load the row register
- *(*(short **) &theCode)++ = movea_to_a5;
- *(*(char ***) &theCode)++ = sourceRow;
-
- for (x = 0; x < width; ++x) {
- char *targetByte;
- long registerOffset;
-
- targetByte = destinationBase + *offsetHere++;
-
- for (i = 0; i < 5; i++) {
- registerOffset = targetByte - destRegisters[i];
- if (registerOffset >= -32768 && registerOffset < 32768) {
- switch(i) {
- case 0:
- *(*(short **) &theCode)++ = move_b_a5plus_a0;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 1:
- *(*(short **) &theCode)++ = move_b_a5plus_a1;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 2:
- *(*(short **) &theCode)++ = move_b_a5plus_a2;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 3:
- *(*(short **) &theCode)++ = move_b_a5plus_a3;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 4:
- *(*(short **) &theCode)++ = move_b_a5plus_a4;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- default:
- Debugger();
- break;
- }
- break;
- }
- }
- }
- sourceBase += rowBytes;
- }
- *(*(long **) &theCode)++ = movem_pop_a0_a5;
- *(*(short **) &theCode)++ = rts;
- }
-
- void
- CompileTable(char *sourceBase, char *destinationBase, short height, short width,
- short rowBytes, long *mappingTable)
- {
- short x, y;
-
- char *sourceRow;
-
- for (y = 0; y < height; ++y)
- {
- sourceRow = sourceBase;
- for (x = 0; x < width; ++x)
- *(destinationBase + *mappingTable++) = *sourceRow++;
- sourceBase += rowBytes;
- }
- }
-
- long Microseconds() = 0xA093;
-
- main()
- {
- WindowPtr sourceWindow, destinationWindow;
- Rect sourceRect, destRect;
- Rect frame;
- PicHandle picture;
- GWorldPtr sourceGWorld, destinationGWorld;
- PixMapHandle sourcePix, destinationPix;
- GWorldPtr savedGWorld;
- GDHandle savedGDevice;
- short height, width, rowBytes;
- short x, y;
- long *buffer1, *offsetHere;
- char *sourceBase, *destinationBase;
- long *mappingTable;
- short *theCode;
- long startTime, endTime;
- GrafPtr windowManagerPort;
-
-
- #define PICTURE 1
-
- SetRect(&frame, 0, 0, 640, 480);
- #ifdef PICTURE
- picture = GetPicture(pictID);
- frame = (**picture).picFrame;
- #endif
-
- width = frame.right - frame.left;
- height = frame.bottom - frame.top;
-
- #ifdef PICTURE
- SetRect(&sourceRect, 50, 50, width + 50, height + 50);
- destRect = sourceRect;
- OffsetRect(&destRect, 0, 220);
-
- sourceWindow = NewCWindow(nil,&sourceRect,
- "\pSource", TRUE,
- documentProc, (WindowPtr)(-1), FALSE, 0);
-
- destinationWindow = NewCWindow(nil,&destRect,
- "\pDestination", TRUE,
- documentProc, (WindowPtr)(-1), FALSE, 0);
- #else
-
- // destinationWindow = NewCWindow(nil,&frame,
- // "\pDestination", TRUE,
- // documentProc, (WindowPtr)(-1), FALSE, 0);
- #endif
-
- GetGWorld(&savedGWorld, &savedGDevice);
- NewGWorld(&sourceGWorld,8,&frame,nil,nil,0);
- NewGWorld(&destinationGWorld,8,&frame,nil,nil,0);
- sourcePix = GetGWorldPixMap(sourceGWorld);
- LockPixels(sourcePix);
- SetGWorld(sourceGWorld, nil);
- #ifdef PICTURE
- DrawPicture(picture,&sourceGWorld->portRect);
- #else
- GetWMgrPort(&windowManagerPort);
- CopyBits(&windowManagerPort->portBits, &((GrafPtr)sourceGWorld)->portBits,
- &frame, &frame, srcCopy, nil);
- #endif
- UnlockPixels(sourcePix);
- SetGWorld(savedGWorld, savedGDevice);
-
- sourcePix = GetGWorldPixMap(sourceGWorld);
- destinationPix = GetGWorldPixMap(destinationGWorld);
- rowBytes = (**GetGWorldPixMap(sourceGWorld)).rowBytes & 0x7FFF;
-
- #ifdef PICTURE
- SetPort(sourceWindow);
- LockPixels(sourcePix);
- CopyBits((BitMap *)*sourcePix, &sourceWindow->portBits,
- &sourceGWorld->portRect, &sourceWindow->portRect, srcCopy, nil);
- UnlockPixels(sourcePix);
- #endif
-
- theCode = (short *)NewPtr(4L * width * height + 6 * height + 500L);
- if (theCode == nil)
- Debugger();
-
- mappingTable = (long *)NewPtr(sizeof(long) * (long)width * height);
- if (mappingTable == nil)
- Debugger();
-
- GenerateMappingTable(mappingTable, width, height, rowBytes, x);
-
- LockPixels(sourcePix);
- LockPixels(destinationPix);
-
- sourceBase = (**sourcePix).baseAddr;
- destinationBase = (**destinationPix).baseAddr;
-
- WriteSomeCode(sourceBase, destinationBase, height, width, rowBytes, mappingTable, theCode);
-
- startTime = Microseconds();
- asm {
- movea.l theCode, a0
- jsr (a0) // whee!
- }
- endTime = Microseconds();
-
- UnlockPixels(sourcePix);
- UnlockPixels(destinationPix);
-
- SetPort(destinationWindow);
- CopyBits((BitMap *)*destinationPix, &destinationWindow->portBits,
- &destinationGWorld->portRect, &destinationWindow->portRect, srcCopy, nil);
-
- while (!Button());
- while (Button());
- }
-