home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
new
/
dev
/
src
/
c2p
/
cpu+blitter
/
c2p8_test.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-01
|
8KB
|
391 lines
// set tabs to 4
#define WIDTH 320 // MUST be a multiple of 32
#define HEIGHT 200
struct TagItem TagArray[] = {
SA_Interleaved, FALSE, // c2p8 does NOT work on interleaved screens
// can add other tags here
TAG_DONE,0
};
struct ExtNewScreen NewScreenStructure = {
0,0,
WIDTH,HEIGHT,
8, // depth
0,1,
NULL,
CUSTOMSCREEN+SCREENQUIET+NS_EXTENDED,
NULL,
NULL,
NULL,
NULL,
(struct TagItem *)&TagArray
};
struct NewWindow NewWindowStructure1 = {
0,0,
WIDTH,HEIGHT,
0,1,
NULL,
SIMPLE_REFRESH+BORDERLESS+NOCAREREFRESH,
NULL,
NULL,
NULL,
NULL,
NULL,
5,5,
WIDTH,HEIGHT,
CUSTOMSCREEN
};
// external function prototypes -----------------
void __asm c2p8_init ( register __a0 UBYTE *chunky, // pointer to chunky data
register __a1 UBYTE *chunky_cmp, // pointer to chunky comparison buffer
register __a2 PLANEPTR *planes, // pointer to planes
register __d0 ULONG signals1, // 1 << sigbit1
register __d1 ULONG signals2, // 1 << sigbit2
register __d2 ULONG pixels, // WIDTH * HEIGHT
register __d3 ULONG offset, // byte offset into plane
register __d4 UBYTE *buff2, // Chip buffer (size = width*height)
register __d5 UBYTE *buff3, // Chip buffer (size = width*height)
register __a3 struct GfxBase *GfxBase);
void __asm c2p8_go(void);
// internal function prototypes -----------------
long get_timer(void);
void free_timer(void);
long get_signals(void);
void free_signals(void);
long get_chunky_mem(void);
void free_chunky_mem(void);
void init_chunky(void);
long get_window(void);
void free_window(void);
// library bases --------------------------------
struct DosLibrary *DOSBase;
struct IntuitionBase *IntuitionBase;
struct ExecBase *SysBase;
struct GfxBase *GfxBase;
struct Library *TimerBase;
struct Library *MathIeeeDoubBasBase;
// timer related variables ----------------------
struct timerequest timerio_m;
struct EClockVal time0_m;
struct EClockVal time1_m;
struct timerequest *timerio = &timerio_m;
struct EClockVal *time0 = &time0_m;
struct EClockVal *time1 = &time1_m;
ULONG timerclosed = TRUE;
double micros_per_eclock; // Length of EClock tick in microseconds
// window related variables ---------------------
struct RastPort *RP;
struct Screen *s;
struct Window *w;
// chunky data and c2p8() related variables -----
UBYTE *chunky; // chunky data (preferably in fast ram)
UBYTE *chunky_cmp; // chunky data comparison buffer (preferably in fast ram)
UBYTE *buff2; // blitter buffer (chip ram)
UBYTE *buff3; // blitter buffer (chip ram)
long sigbit1 = -1; // used by c2p8()
long sigbit2 = -1; // used by c2p8()
#define nokick "This needs Kickstart 3.0!\n"
#define REPEAT_COUNT 10
long __saveds main(void)
{
int count;
double micros, sum_micros;
SysBase = *(struct ExecBase **)4;
if(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library",33))
{
// check what kickstart version we are using
// inform the user and exit if lower than 39
if( DOSBase->dl_lib.lib_Version < 39)
{
Write(Output(), nokick, sizeof(nokick) );
CloseLibrary( (struct Library *) DOSBase);
return(0);
}
// if compiling with 68020+ code, exit before we crash
// a 68000 machine
#ifdef _M68020
if(! ( SysBase->AttnFlags & AFF_68020) )
{
Printf("This version needs at least a 68020!\n");
return(0);
}
#endif
if(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",39))
if(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",39))
{
if( get_timer() )
if( get_window() )
if( get_chunky_mem() )
if( get_signals() )
{
Printf ("\nWidth = %ld, Height = %ld, Depth = 8\n\n",WIDTH, HEIGHT );
sum_micros = 0.0;
// initialize c2p converter
c2p8_init ( chunky,
chunky_cmp,
&RP->BitMap->Planes[0],
1 << sigbit1,
1 << sigbit2,
WIDTH * HEIGHT,
0,
buff2,
buff3,
GfxBase);
// fill the chunky buffer with a distinct pattern and a triangle
init_chunky();
// time each c2p call and average it out over 10 calls
for (count = 0; count < REPEAT_COUNT; count++)
{
Forbid();
ReadEClock(time0);
c2p8_go(); // Convert chunky buffer to planar
// only writes to the screen if the chunky
// buffer has changed since last time.
// Only converts the changed data
ReadEClock (time1);
Permit();
micros = (time1->ev_lo - time0->ev_lo) * micros_per_eclock;
sum_micros += micros;
Printf (" %8ld : %9ld µs\n", count, (long)micros);
}
Printf ("\nMean time = %9ld microseconds\n\n", (long)(sum_micros / REPEAT_COUNT) );
}
free_signals(); // wait for c2p8 to finish before
// freeing memory or closing screens
free_chunky_mem();
free_window();
free_timer();
CloseLibrary((struct Library *)GfxBase);
}
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
CloseLibrary((struct Library *)DOSBase);
}
return(0);
}
// open timer.device and the math library -------
long get_timer(void)
{
long ok = 0;
if(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library",33))
if( ! (timerclosed = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerio, 0)))
{
TimerBase = (struct Library *)timerio->tr_node.io_Device;
micros_per_eclock = 1000000.0 / (double)ReadEClock (time0);
ok = 1;
}
return(ok);
}
void free_timer(void)
{
if(!timerclosed)
CloseDevice( (struct IORequest *) timerio);
if(MathIeeeDoubBasBase)
CloseLibrary(MathIeeeDoubBasBase);
}
// get signals necessary for c2p8() -------------
long get_signals(void)
{
long ok = 0;
if(-1 != (sigbit1 = AllocSignal(-1)))
{
SetSignal (1 << sigbit1, 1 << sigbit1); // Initial state is "finished"
if(-1 != (sigbit2 = AllocSignal(-1)))
{
SetSignal (1 << sigbit2, 1 << sigbit2); // Initial state is "finished"
ok = 1;
}
}
return(ok);
}
void free_signals(void)
{
if(sigbit1 != -1)
{
Wait (1 << sigbit1); // wait for last c2p8 to finish pass 3
FreeSignal(sigbit1);
sigbit1 = -1;
}
if(sigbit2 != -1)
{
Wait (1 << sigbit2); // wait for last c2p8 to finish totally
FreeSignal(sigbit2);
sigbit2 = -1;
}
}
// get memory for chunky buffer, chunky comparsion buffer
// and two blitter buffers needed by c2p8() -----
long get_chunky_mem(void)
{
long ok = 0, size = WIDTH * HEIGHT;
if( chunky = AllocVec(size, MEMF_CLEAR+MEMF_ANY))
if( chunky_cmp = AllocVec(size, MEMF_CLEAR+MEMF_ANY))
if( buff2 = AllocVec(size, MEMF_CLEAR+MEMF_CHIP))
if( buff3 = AllocVec(size, MEMF_CLEAR+MEMF_CHIP))
{
ok = 1;
}
return(ok);
}
void free_chunky_mem(void)
{
if(buff3)
FreeVec(buff3);
if(buff2)
FreeVec(buff2);
if(chunky_cmp)
FreeVec(chunky_cmp);
if(chunky)
FreeVec(chunky);
}
// Write a distinctive pattern to chunky buffer and a triangle
#define write_pixel(x,y,p) (chunky[y * WIDTH + x] = p )
void init_chunky(void)
{
int i, j;
UBYTE *p;
p = chunky;
for (j = 0; j < HEIGHT; j++)
for (i = 0; i < WIDTH; i++)
*p++ = (i + j) & 255;
// Draw a triangle to check orientation
for (i = 50; i < 150; i++)
{
write_pixel (i, 150, i);
write_pixel (i+120, 150, i);
write_pixel (50, i, i);
write_pixel (170, i, i);
write_pixel (i, i, i);
write_pixel (i+120, i, i);
}
}
// open a screen and a window -------------------
long get_window(void)
{
long ok = 0;
if(s = OpenScreen( (struct NewScreen *) &NewScreenStructure))
{
NewWindowStructure1.Screen = s;
if(w = OpenWindow(&NewWindowStructure1))
{
RP = w->RPort;
ok = 1;
}
}
return(ok);
}
void free_window(void)
{
if(w) CloseWindow(w);
if(s) CloseScreen(s);
}