/**
 * Sky driver dma support
 *
 * Copyright (c) Criterion Software Limited
 */

/************************************************************************
 * File: Sweet Emotion                                                  *
 *                                                                      *
 * Dma handler, interupts, etc.                                         *
 ************************************************************************/

#include <string.h>
#include "batypes.h"
#include "balibtyp.h"
#include "dmamacros.h"
#include "gs.h"

#ifdef GSB
#include "gsbapi.h"
#endif /* GSB */

#ifdef GSB
#define MAXFLIPS 1
#else /* GSB */
#define MAXFLIPS 3
#endif /* GSB */

int sweMaxFlips = MAXFLIPS;
/* If required, use this to get the TRC ExitHandler exit requirement */
#define EIEXIT

#if (defined(EIEXIT))
#define EXITHANDLER()   ExitHandler()
#endif /* (defined(EIEXIT)) */

#if (!defined(EXITHANDLER))
#define EXITHANDLER()   /* No op */
#endif /* (!defined(EXITHANDLER)) */

/*
 * Warning: Alot of vars are nonstatic so I can see them in the debugger
 * At present we don't recover gracefully from memory failure
 * I'm using source chain, even though it can be clearly seen that I could
 * use normal DMA. Hopefully when we start to do more interesting stuff
 * this will be useful. It also allows user packets to be of more interesting
 * and flexible forms
 * If this is defined, put a digit in the top right of the number of VSYNC
 */

/* times between flips */
#define VISTIMEx

/* If VISTIME is defined, measure time spent between begin/end camera */

#define COLOURDMAx

#ifdef COLOURDMA
static volatile long dmacolour=0;
#endif /* COLOURDMA */

/* Requires TIMER be defined */
#define DRIVETIME

/* Define to flush SPR on each close pkt */
#define SYNCSPRx

#ifdef USEDIRECT

/* Use this define to choose between direct uncache and uncache accel */
#if 0

/* Uncached */
#define DIRECTOFFSET (0x20000000)

/* #define DIRECTOFFSET 0x00000000 */
#else

/* Uncached accelerated */
#define DIRECTOFFSET (0x30000000)
#endif
#endif /* USEDIRECT */

/* Dumps lots of stuff to stdout */
#define TRACEx

/* Don't use interupts */
#define SYNCx

/* Procratinate */
#define PROCRASx

/* Big dump chain */
#define DUMPDETAILx
#define DUMPDETAILFOLLOWCALLSx

/* ship render state via VIF 1 */
#define VIF1RENDER

/* Don't wait for VSync on frame flips */
#ifdef GSB
/* In theory we can define this for more efficiency under GSB */
#define TEARx
#else /* GSB */
#define TEARx
#endif /* GSB */

/* If we have runtime tear things are a bit more complex */
#define RUNTIMETEARx

#ifdef RUNTIMETEAR
int sweTear=0;
#endif /* RUNTIMETEAR */

/* Enable a 1/16th bus clk counter [9.375MHz] uses timer 1.
 * Causes an interrupt every 7ms */
#if defined(PROFILE) || defined(PG) || defined(RWMETRICS)
#define TIMER
#define TIMERHIREZ
#else /* PROFILE || PG || RWMETRICS */
#define TIMERx

/* if TIMER is defined, if TIMERHIREZ is defined use bus clk/150MHz.
 * This will cause an interupt every 0.4ms so don't use it unless you have to */
#define TIMERHIREZx
#endif /* PROFILE || PG || RWMETRICS */

/* So we can get marketing numbers, accumulate time spent by dma and render */
#define DMATIMEx

/* Notch out TIEs */
#define NOTIE

#ifdef DMATIME
unsigned long       sweDmaRunTime = 0;
static unsigned long sweDmaTimer = 0;
#endif /* DMATIME */


#include <eekernel.h>
#include <libgraph.h>
#include <libdma.h>

#include "badevice.h"
#include "bamemory.h"
#include "baraster.h"
#include "dmaalloc.h"
#include "devprofile.h"
#include "basky.h"

#ifdef PG
#ifdef PGA
#include "skygmon.h"
#endif /* PGA */
#include "/usr/local/sce/ee/gcc/src/gprof/gmon_out.h"
#include "sifdev.h"
#endif /* PG */

#include "badma.h"

#undef RWPENTER
#define RWPENTER(_func) /* No op; DMA can lead to debug call stack confusion */

#undef RWPEXIT
#define RWPEXIT(_func)  /* No op; DMA can lead to debug call stack confusion */

#ifdef SWEASYNC
static RwBool sweAsyncInProgress = FALSE;
int sweNumAsyncDispatched;
RwBool sweDontFlushRefs = FALSE;

/* define to get sync but reordered dispatch */
#define NONASYNCTESTx
#define NONASYNCTEST2x

#ifdef NONASYNCTEST2
#ifndef NONASYNCTEST
#error "If NONASYNCTEST2 then NONASYNCTEST is required"
#endif /* NONASYNCTEST */
#endif /* NONASYNCTEST2 */

#endif /* SWEASYNC */

static const char rcsid[] __RWUNUSED__ =
  "@@(#)$Id: badma.c,v 1.133 2001/10/03 15:23:50 rabin Exp $";

#define SWE_CHAIN_BLOCK (128)

/* Local packet builder support: */
#define SWE_LPS_NONE 0
#ifndef SWE_LPS_CONT
#define SWE_LPS_CONT 1
#endif /* SWE_LPS_CONT */
#ifndef SWE_LPS_PRIM
#define SWE_LPS_PRIM 2
#endif /* SWE_LPS_PRIM */
#ifndef SWE_LPS_NOFIXUP
#define SWE_LPS_NOFIXUP 0x80000000
#endif /* SWE_LPS_NOFIXUP */

/* We define the max size and check for inconsistency */
#ifndef SWE_LPS_MAX_PACKET_SIZE
#define SWE_LPS_MAX_PACKET_SIZE 1022
#else /* !SWE_LPS_MAX_PACKET_SIZE */
#if (SWE_LPS_MAX_PACKET_SIZE != 1022)
#error "Definitions of SWE_LPS_MAX_PACKET_SIZE in badma.{c,h} conflict"
#endif
#endif /* !SWE_LPS_MAX_PACKET_SIZE */
#define SWE_LPS_MAX_BLOCK 2000

static int          sweOwnVBON;
#if 0
static int          sweOwnVIF0;
#endif
static int          sweOwnVIF1;
static int          sweOwnGIF;

#ifndef SYNC
#if 0
static int          sweHandlerVIF0Hid = -1;
#endif
static int          sweHandlerVIF1Hid = -1;
static int          sweHandlerGIFHid = -1;
#endif /* !SYNC */

static int          sweVSYNCHandlerHid = -1;

#ifdef TIMER
static int          sweOwnTIM1;
static int          sweTim1HandlerHid = -1;
#endif /* TIMER */

#ifdef WATCHDOG
static volatile int sweWatchDog;
#endif /* WATCHDOG */
static volatile int sweDispatching;
static void        *sweFlipSt;
static int          sweFlipId;

/* Only for use in the interupt handler, or at startup */
static swe_pkt     *sweVU0pkt;
static swe_pkt     *sweVU1pkt;
static swe_pkt     *sweGIFpkt;

swe_pkt            *sweChainBase;
swe_pkt            *sweCurrentBlockBase;
swe_pkt            *sweCurrentBase;
swe_pkt            *sweChainEnd;
swe_pkt            *sweGarbageStart;

int                 sweNumDispatched;
int                 sweNumHandler;

volatile int        sweFlipPending = 0;

/* States: 0 off, 2/3 on started, 7 on waiting to end */
volatile int sweAutoFlip = 0; /* static */

volatile int        sweNumFlipsInQueue = 0;

_rwSkyTwoCircuit tcaaDisp;

int                 sweLocalPacketState;
u_long128          *sweRealLocalPacketBase;
u_long128          *sweLocalPacketBase;
u_long128          *sweLocalPacketHigh;
u_long128          *sweLocalPacket;
#ifdef LOCAL_REG_SUPPORT
/* Only here to keep the linker happy in non optimisied builds */
u_long128          *__localLocalPacketPointer;
#endif

#ifdef LESSEOPS
unsigned int        sweLocalPacketGifQWC;
#endif /* LESSEOPS */
int                 sweLocalPacketSize;

/* Deferred packet adding */
u_long128          *swePacketToAddFirst;
int                 swePacketToAddFirstChannel;

#ifdef TIMER
static volatile unsigned long sweHighCount;
#endif /* TIMER */

circularAllocator  *circAllocator;
static RwFreeList  *state_chainBlockFreeList;

/* Cache these pointers - they are obtained from a function call...! */
static sceDmaChan  *dmaChanFromSPR;
static sceDmaChan  *dmaChanGIF;
static sceDmaChan  *dmaChanVIF0;
static sceDmaChan  *dmaChanVIF1;

long                sweFrameRenderCount = 0;
long                sweFrameRenderCount2 = 0;

/* Vars for PURef list */
static unsigned int **swePURefList = (unsigned int **)NULL;
static int          swePURefMaxSize = 0;
static int          swePURefSize = 0;

#define SWEPUREFIS 128

/* Use half offset? */
int                 sweUseHalfOffset = FALSE;

/* is the current drawing half offset? */
volatile long       sweCurrentHalfOffset = 0;

#ifdef DEBUGWITHMARK
unsigned int        sweDebugMark = 0x8000;
#endif /* DEBUGWITHMARK */

#ifdef PG

/* These are a set of functions to take advantage of gcc's profiling support */
/* We have loads of memory, 
 * do we create 2, 4Mb arrays which we cache align and 0 */
/* One of these will be used to count function executions, 
 * and the other to note */
/* interupt driven sampling */

/* WARNING If your code size > 4MB this code tramples !!!! */

#ifndef PGA

static RwUInt32     sweProfileCount[1024 *
                                    1024] __attribute__ ((aligned(64)));
static RwUInt32     sweProfileHits[1024 *
                                   1024] __attribute__ ((aligned(64)));

#else /* !PGA */

unsigned char      *swePHbuf = NULL;
size_t              swePHbufsize = 0;
size_t              swePHoffset = 0;
unsigned int        swePHscale = 0;

#endif /* !PGA */

#define PG_VURUNNING    1
#define PG_DMACH1       2
#define PG_DMACH2       4
#define PG_GW           8
#define PG_VGW          16
long                sweProfORL = 0;
long                sweProfORH = 0;
static long         sweUnitProfTotal = 0;
static long         sweUnitProf[PG_VURUNNING + PG_DMACH1 + PG_DMACH2 +
                                PG_GW + PG_VGW + 1];
#endif /* PG */

#ifdef RWMETRICS
static RwSkyMetrics state_skyMetrics;
#endif /* RWMETRICS */

RwInt32 swePreAllocSize = 0;
RwInt32 swePreAllocCount = 0;
RwBool swePreAllocLimit = FALSE;
RwBool sweNoFreeLists = FALSE;
swe_pkt *sweHighWaterMark;

/* save restore gp */

/* CodeWarrior won't compile this inline asm yet */
#if (defined(__MWERKS__))

#include "baevent.h"
#define SKY_INITIALIZE_SAVED_GP()  EventInitSavedGp()
#define SKY_INTR_GET_GP(_A)        EventIntrGetGp(&(_A))

#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": Workarounds for __MWERKS__ == " _SKY_EXPAND(__MWERKS__))

#endif /* (defined(__MWERKS__)) */

#if  (!defined(SKY_INITIALIZE_SAVED_GP))
#define SKY_INITIALIZE_SAVED_GP() \
    asm volatile (".set noat                    \n\
                .set noreorder                  \n\
                lui $at, %hi(_RwSavedGP)        \n\
                addiu $at, $at, %lo(_RwSavedGP) \n\
                sw $gp, 0($at)                  \n\
                .set reorder                    \n\
                .set at                         \n\
                .globl _RwSavedGP               \n\
                .data                           \n\
                .align  3                       \n\
                _RwSavedGP:                     \n\
                .word 0xdeadbeaf                \n\
                .text" )
#endif /* (!defined(SKY_INITIALIZE_SAVED_GP)) */

#if (!defined(SKY_INTR_GET_GP))
#define SKY_INTR_GET_GP(_A)  \
    asm volatile ("or %0, $gp, $0               \n\
                .set noat                       \n\
                .set noreorder                  \n\
                lui $at, %%hi(_RwSavedGP)       \n\
                addiu $at,$at, %%lo(_RwSavedGP) \n\
                lw $gp, 0($at)                  \n\
                .set reorder                    \n\
                .set at " : "=r" ( _A ) )
#endif /* (!defined(SKY_INTR_GET_GP)) */

#if (!defined(_MW_ISUSED))
#define _MW_ISUSED(_ARG_LIST)  /* No op */
#endif /* (!defined(_MW_ISUSED)) */

#define INTR_RESTORE_GP(A)      \
    asm volatile ("or $gp, %0, $0" : : "r" ( A ) )

#ifdef VISTIME

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                         7 segment digits
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

#define RWALIGN16 __attribute__ ((aligned(16)))

static unsigned long digitZero[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 36),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) |

         ((2048 + 0) << 4)),};

static unsigned long digitOne[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 12),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitTwo[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 36),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitThree[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 36),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitFour[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 30),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitFive[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 36),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitSix[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 42),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitSeven[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 18),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitEight[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 48),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitNine[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 42),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        /* Cross bar 4 tris */
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) | (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 11) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) |

         ((2048 + 8) << 4)),};

static unsigned long digitElle[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 18),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 11) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 8) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 7) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 2) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 5) << 20) | ((2048 + 3) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 6) << 20) |

         ((2048 + 0) << 4)),};

static unsigned long digitPoint[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 6),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 7) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) |
         ((2048 + 10) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 10) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 10) << 20) | ((2048 + 7) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 10) << 4)),
        ((0l << 32) | (0x80l << 24) | (0xffl << 16) | (0xffl << 8) |
         (0xffl)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |

         ((2048 + 7) << 4)),};

static unsigned long digitBack[] RWALIGN16 =
{
    /* Gif tag */
    ((2l << 60) | (1l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 6),
        ((0x5l << 4) | (0x1l)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 0) << 20) | ((2048 + 0) << 4)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |
         ((2048 + 12) << 4)),
        ((0l << 32) | (0x80l << 24) | (0x00l << 16) | (0x00l << 8) |
         (0x00l)),
        ((0xffffffffl << 32) | ((2048 + 12) << 20) |

         ((2048 + 0) << 4)),};

static unsigned long pos0[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 0 - 12) << 4)), (0x18),};

static unsigned long pos1[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 12 - 12) << 4)), (0x18),};

static unsigned long pos2[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 24 - 12) << 4)), (0x18),};

static unsigned long pos3[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 36 - 12) << 4)), (0x18),};

static unsigned long pos4[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 48 - 12) << 4)), (0x18),};

static unsigned long pos5[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 60 - 12) << 4)), (0x18),};

static unsigned long pos6[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 72 - 12) << 4)), (0x18),};

static unsigned long pos7[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 84 - 12) << 4)), (0x18),};

static unsigned long pos8[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 96 - 12) << 4)), (0x18),};

static unsigned long pos9[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 108 - 12) << 4)), (0x18),};

static unsigned long posA[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 120 - 12) << 4)), (0x18),};

static unsigned long posB[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 132 - 12) << 4)), (0x18),};

static unsigned long posC[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 144 - 12) << 4)), (0x18),};

static unsigned long posD[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 156 - 12) << 4)), (0x18),};

static unsigned long posE[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 - 168 - 12) << 4)), (0x18),};

static unsigned long pos0h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 0 - 12) << 4)), (0x18),};

static unsigned long pos1h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 12 - 12) << 4)), (0x18),};

static unsigned long pos2h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 24 - 12) << 4)), (0x18),};

static unsigned long pos3h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 36 - 12) << 4)), (0x18),};

static unsigned long pos4h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 48 - 12) << 4)), (0x18),};

static unsigned long pos5h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 60 - 12) << 4)), (0x18),};

static unsigned long pos6h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 72 - 12) << 4)), (0x18),};

static unsigned long pos7h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 84 - 12) << 4)), (0x18),};

static unsigned long pos8h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 96 - 12) << 4)), (0x18),};

static unsigned long pos9h[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 35) | ((2048 - 108 - 12) << 4)), (0x18),};

static unsigned long posAh[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 36) | ((2048 - 120 - 12) << 4)), (0x18),};

static unsigned long posBh[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 36) | ((2048 - 132 - 12) << 4)), (0x18),};

static unsigned long posCh[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 36) | ((2048 - 144 - 12) << 4)), (0x18),};

static unsigned long posDh[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 36) | ((2048 - 156 - 12) << 4)), (0x18),};

static unsigned long posEh[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((4097l << 36) | ((2048 - 168 - 12) << 4)), (0x18),};

/* Off screen */
static unsigned long posl[] RWALIGN16 =
{
    /* Gif tag */
    ((1l << 60) | (0l << 58) | (0x3l << 47) | (1l << 46) | (1l << 15) | 1),
        ((0xel)), ((2048l << 36) | ((2048 + 12) << 4)), (0x18),};

#endif /* VISTIME */

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                 Replacements for some libdma functions

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/***********************************************************************
 sweDmaSend

 On Entry : dma channel
            tag addr
            extra bits to OR in
 On Exit  :

 Sends a Source chain to channel. Can wait forever. OR's in extra bits to
 allow transfer tag and TIE, etc
 */
void
sweDmaSend(sceDmaChan * d, void *tag, unsigned int extra)
{
    unsigned int        chcr;
    RWFUNCTION(RWSTRING("sweDmaSend"));

    /* This will almost never execute */
    do
    {
    }
    while ((*(volatile u_int *) &((d)->chcr)) & 0x0100);

    d->tadr = (sceDmaTag *) tag;
    /* Seems unnecessary, but the libs do it */
    d->qwc = 0;
    chcr = *(unsigned int *) &d->chcr;
    /* Set STR, TIE, MOD=chain, DIR bits + extra */
    chcr |= extra | 0x105;
#ifdef NOTIE
    chcr &= ~0x80;
#endif /* NOTIE */
    *(unsigned int *) &d->chcr = chcr;

    RWRETURNVOID();
}

static              RwBool
_sweAppendPktToDispatchList(void *addr, int ch)
{
    swe_pkt            *ptr;
    swe_pkt            *blockPtr;
    RWFUNCTION(RWSTRING("_sweAppendPktToDispatchList"));
    PFENTRY(PF_sweAppendPktToDispatchList);

#if 0
    /* Really I should probably save the old interupt state, but I don't */
    DI();

    if ((sweCurrentBlockBase != sweChainEnd)
        && (sweCurrentBase != sweChainEnd)
        && (sweCurrentBase != sweChainEnd - 1))
    {
        /* We attempt to coalesce blocks */

        /* I asume that chain is never set on a non suitable pkt type */

        /* If both the last pkt and the new one are chains ... */
        if (
            ((ch & SWE_PKT_DMA_MODE_MASK) ==
             SWE_PKT_DMA_MODE_CHAIN)
            &&
            (((sweChainEnd - 1)->type & SWE_PKT_DMA_MODE_MASK)
             == SWE_PKT_DMA_MODE_CHAIN)
            /* and of the same tag transfer type */
            && ((ch & 0x400) == ((sweChainEnd - 1)->type & 0x400))
            /* and the same local type */
            && ((ch & SWE_PKT_LOCAL)
                == ((sweChainEnd - 1)->type & SWE_PKT_LOCAL)))
            /* Should check SWE_PKT_SWAP also here */
        {
            if (_sweAppendToChain((sweChainEnd - 1)->addr, addr))
            {
                (sweChainEnd - 1)->type |= SWE_PKT_NONCONTIG;
                EI();

                PFEXIT(PF_sweAppendPktToDispatchList);
                RWRETURN(TRUE);
            }
        }
    }

    EI();
#endif

    if ((!sweNoFreeLists)
        && (sweChainEnd == sweCurrentBlockBase + (SWE_CHAIN_BLOCK - 1)))
    {
        TRACEPRINTF(
                    ("%s(%d):%s - run out of space. Adding new block\n",
                     __FILE__, __LINE__, __FUNCTION__));

        /* We've run out of space, so we alloc a new block and add a GOTO */
        PFCALL(PF_sweAppendPktToDispatchList);
        ptr = (swe_pkt *) RwFreeListAlloc(state_chainBlockFreeList);
        PFRET(PF_sweAppendPktToDispatchList);
        if (ptr == NULL)
        {
            TRACEPRINTF(("%s(%d):%s - circularMalloc failed\n",
                         __FILE__, __LINE__, __FUNCTION__));

            TRACEPRINTF(("%s(%d):%s - Leave\n",
                         __FILE__, __LINE__, __FUNCTION__));

            PFEXIT(PF_sweAppendPktToDispatchList);
            RWRETURN(FALSE);
        }
        sweChainEnd->type = SWE_PKT_GOTO;
        sweChainEnd->addr = ptr;
        blockPtr = ptr;
    }
    else if ((sweNoFreeLists) && (sweChainEnd == sweHighWaterMark))
    {
        /* We need to allow space */
        while (sweGarbageStart == sweCurrentBlockBase)
        {
            _sweFlush();
            _sweGarbageCollectChain();
        }
        sweChainEnd->type = SWE_PKT_GOTO;
        sweChainEnd->addr = sweCurrentBlockBase;
        ptr = sweCurrentBlockBase;
        blockPtr = sweCurrentBlockBase;
    }
    else
    {
        ptr = sweChainEnd;
        blockPtr = sweCurrentBlockBase;
    }

    if (sweNoFreeLists)
    {
        /* If we are just about to run into the tail of the list we stall */
        while (ptr + 1 == sweGarbageStart)
        {
            _sweFlush();
            _sweGarbageCollectChain();
        }
    }

    /* Set up pkt */

    TRACEPRINTF(("%s(%d):%s - set up pkt\n",
                 __FILE__, __LINE__, __FUNCTION__));

    ptr->type = ch;
    ptr->addr = addr;

    sweCurrentBlockBase = blockPtr;

    /* We update this last so that an interupt handler invoked before */
    /* this point doesn't get confused */

    TRACEPRINTF(("%s(%d):%s - finalising sweChainEnd\n",
                 __FILE__, __LINE__, __FUNCTION__));

    sweChainEnd = ptr + 1;

    TRACEPRINTF(("%s(%d):%s - Leave\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFEXIT(PF_sweAppendPktToDispatchList);
    RWRETURN(TRUE);
}


/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                         Memory functions

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/***********************************************************************
 sweCloseLocalPkt

 On Entry :
 On Exit  :

 If a local pkt is being build by rendering functions, close it.
 */
/**
 * \ingroup sky2unsupported
 * \ref sweCloseLocalPkt closes a local packet. Dependent on type it
 * also updates a dma tag at the beginning of the packet.
 *
 * \see sweOpenLocalPkt
 */
void
sweCloseLocalPkt(void)
{
    RWFUNCTION(RWSTRING("sweCloseLocalPkt"));
    PFENTRY(PFsweCloseLocalPkt);

    TRACEPRINTF(("%s(%d):%s - Enter\n",
                 __FILE__, __LINE__, __FUNCTION__));

    if (sweLocalPacketState != SWE_LPS_NONE)
    {
        TRACEPRINTF(("%s(%d):%s - a packet was open\n",
                     __FILE__, __LINE__, __FUNCTION__));

#ifndef USEDIRECT
        if ( /* sweLocalPacketBase */ SCRATCHPAD != sweLocalPacket)
#else /* !USEDIRECT */
        if ((u_long128 *)
            ((RwUInt8 *) sweRealLocalPacketBase + DIRECTOFFSET) !=
            sweLocalPacket)
#endif /* !USEDIRECT */
        {
            RwUInt32            numQuads = ( sweLocalPacket -
                                             sweLocalPacketBase );


#ifndef USEDIRECT
#define TMP_ARG1  (int) /* sweLocalPacketBase */ SCRATCHPAD
#else /* !USEDIRECT */
#define TMP_ARG1 (int) ((char *) sweRealLocalPacketBase + DIRECTOFFSET)
#endif /* !USEDIRECT */
            TRACEPRINTF(("%s(%d):%s - and non zero length at %x->%x\n",
                         __FILE__, __LINE__, __FUNCTION__,
                         TMP_ARG1,
                         (int) sweLocalPacket));
#undef TMP_ARG1

            /* We have a buffer of 32 bytes at the end of the pkt so we */
            /* don't need to check for space on closure */

            if (!(sweLocalPacketState & SWE_LPS_NOFIXUP))
            {

#ifdef LESSEOPS
                if (!sweLocalPacketGifQWC)
                {
                    /* gif end tag */
                    *(long *) sweLocalPacket = 0x0000000000008000;
                    *((long *) sweLocalPacket + 1) = 0x0000000000000000;
                    sweLocalPacket++;
                    numQuads++;
                }
#endif /* LESSEOPS */
                TRACEPRINTF(("%s(%d):%s - finalising tag %d\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             (numQuads - 1)));

                /* finalise dma tag at front of buffer */
                *(long *) sweLocalPacketBase =
                    (numQuads - 1) | (0x7l << 28) | (0x1l << 31);
#if defined(VIF1RENDER)
                if ((numQuads - 1) > 0)
                {
                    *((long *) sweLocalPacketBase + 1) = ((0x50l << 24)
                                                          |
                                                          (long)
                                                          (numQuads -
                                                           1)) << 32;
                }
                else
                {
                    *((long *) sweLocalPacketBase + 1) = 0;
                }
#endif /* defined(VIF1RENDER) */
            }

            /* Correct numQuads */
#ifndef USEDIRECT
            numQuads =
                sweLocalPacket - /* sweLocalPacketBase */ SCRATCHPAD;
#else /* !USEDIRECT */
            numQuads = sweLocalPacket
                - (u_long128 *) ((RwUInt8 *) sweRealLocalPacketBase +
                                 DIRECTOFFSET);
#endif /* !USEDIRECT */

            /* Flush any packet that is pending */
            if (swePacketToAddFirst)
            {
                TRACEPRINTF(
                            ("%s(%d):%s - calling _sweAppendPktToDispatchList\n",
                             __FILE__, __LINE__, __FUNCTION__));
                PFCALL(PFsweCloseLocalPkt);
                _sweAppendPktToDispatchList(swePacketToAddFirst,
                                            swePacketToAddFirstChannel);
                PFRET(PFsweCloseLocalPkt);
                swePacketToAddFirst = (u_long128 *)NULL;
                TRACEPRINTF(("%s(%d):%s - returned from _sweAppendPktToDispatchList\n",
                             __FILE__, __LINE__, __FUNCTION__));
            }

            /* Flush D$ so that the processor doesn't overwrite with cache */
            /* FlushCache(0); */

#ifndef USEDIRECT
            TRACEPRINTF(("%s(%d):%s - Start DMA\n",
                         __FILE__, __LINE__, __FUNCTION__));
            /* DMA from SPR to real memory */
            dmaChanFromSPR->sadr = (u_int *) SCRATCHPAD;
#if 1
            *(volatile u_int*)&dmaChanFromSPR->madr
                                             = (u_int)sweRealLocalPacketBase;
            *(volatile u_int*)&dmaChanFromSPR->qwc = (u_int)numQuads;
            *((volatile u_int*)(&(dmaChanFromSPR->chcr))) |= D_CHCR_STR_M;
#else
            PFCALL(PFsweCloseLocalPkt);
            sceDmaRecvN(dmaChanFromSPR, sweRealLocalPacketBase,
                        numQuads);
            PFRET(PFsweCloseLocalPkt);
#endif

#ifdef SYNCSPR
            /* Need to make sure that it's done with */
            sweInlineDmaSync(dmaChanFromSPR);
#endif
            TRACEPRINTF(("%s(%d):%s - Started DMA\n",
                         __FILE__, __LINE__, __FUNCTION__));
#else /* !USEDIRECT */
/* *INDENT-OFF* */
                asm volatile ("sync.l");
/* *INDENT-ON* */
#endif /* !USEDIRECT */

            swePacketToAddFirst = sweRealLocalPacketBase;

            if (!(sweLocalPacketState & SWE_LPS_NOFIXUP))
            {
#if (!defined(VIF1RENDER))
                swePacketToAddFirstChannel =
                    SWE_PKT_GIF | SWE_PKT_CIRCALLOC |
                    SWE_PKT_DMA_MODE_CHAIN | SWE_PKT_LOCAL;
#else /* (!defined(VIF1RENDER)) */
                swePacketToAddFirstChannel =
                    SWE_PKT_VU1 | SWE_PKT_CIRCALLOC |
                    SWE_PKT_DMA_MODE_CHAIN_TTE | SWE_PKT_LOCAL;
#endif /* (!defined(VIF1RENDER)) */
            }
            else
            {
                /* We carefully arranged that SWE_PKT_LOCAL and SWE_LPS_NOFIXUP
                 * have the same value */
                swePacketToAddFirstChannel = sweLocalPacketState
                    | SWE_PKT_CIRCALLOC;
            }

            TRACEPRINTF(("%s(%d):%s - iState to None\n",
                         __FILE__, __LINE__, __FUNCTION__));

            sweLocalPacketState = SWE_LPS_NONE;
        }
        else
        {
            TRACEPRINTF(("%s(%d):%s - but was zero length at %x\n",
                         __FILE__, __LINE__, __FUNCTION__,
                         (int) sweRealLocalPacketBase));

            if (sweLocalPacketSize)
            {
                /* This is local, allocated by the circular allocator */
                PFCALL(PFsweCloseLocalPkt);
                circularFree(circAllocator, sweRealLocalPacketBase);
                PFRET(PFsweCloseLocalPkt);
            }
        }
        sweLocalPacketSize = 0;
        sweLocalPacketBase = (u_long128 *)NULL;
        sweRealLocalPacketBase = (u_long128 *)NULL;
        sweLocalPacketHigh = (u_long128 *)NULL;
        sweLocalPacket = (u_long128 *)NULL;
        sweLocalPacketState = SWE_LPS_NONE;

    }

#if 0
    /* Can't do this yet as we have refs to pending pks */
    /* We have to flush the PUref list */
    if (swePURefSize)
    {
        TRACEPRINTF(("%s(%d):%s - adding %d procrastinated refs\n",
                     __FILE__, __LINE__, __FUNCTION__, swePURefSize));
        while (swePURefSize--)
        {
            int                 cnt;

            cnt = *(swePURefList[swePURefSize] + 1);

            *(swePURefList[swePURefSize] + 1) = 0;
            while (cnt > 0)
            {
                _sweAppendPktToDispatchList(swePURefList[swePURefSize],
                                            SWE_PKT_RASUREF
                                            |
                                            ((cnt
                                              >
                                              SWE_PKT_IMM_MAX ?
                                              SWE_PKT_IMM_MAX : cnt) <<
                                             SWE_PKT_IMM_SHIFT));
                cnt -= SWE_PKT_IMM_MAX;
            }
        }
        swePURefSize = 0;
    }
#endif

    TRACEPRINTF(("%s(%d):%s - Leave\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFEXIT(PFsweCloseLocalPkt);

    RWRETURNVOID();
}

/* Temporary hack */
void
sweFlushPURef(void)
{
    RWFUNCTION(RWSTRING("sweFlushPURef"));
    PFENTRY(PFsweFlushPURef);
    /* We have to flush the PUref list */
#ifdef SWEASYNC
    if (sweDontFlushRefs)
    {
        PFEXIT(PFsweFlushPURef);
        RWRETURNVOID();
    }
#endif /* SWEASYNC */
    if (swePURefSize)
    {
        TRACEPRINTF(("%s(%d):%s - adding %d procrastinated refs\n",
                     __FILE__, __LINE__, __FUNCTION__, swePURefSize));
        while (swePURefSize--)
        {
            int                 cnt;

            cnt = *(swePURefList[swePURefSize] + 1);

            *(swePURefList[swePURefSize] + 1) = 0;
            while (cnt > 0)
            {
                PFCALL(PFsweFlushPURef);
                _sweAppendPktToDispatchList(swePURefList[swePURefSize],
                                            SWE_PKT_RASUREF
                                            |
                                            ((cnt
                                              >
                                              SWE_PKT_IMM_MAX ?
                                              SWE_PKT_IMM_MAX : cnt) <<
                                             SWE_PKT_IMM_SHIFT));
                PFRET(PFsweFlushPURef);
                cnt -= SWE_PKT_IMM_MAX;
            }
        }
        swePURefSize = 0;
    }
    PFEXIT(PFsweFlushPURef);

    RWRETURNVOID();
}

/***********************************************************************
 sweOpenLocalPkt

 On Entry : type (SWE_LPS_CONT, SWE_LPS_PRIM)
            size (hint. 0 gets default. 128bit units)
 On Exit  : success, failure

 Open a new local pkt. Will close the existing one if of a different type
 */
/**
 * \ingroup sky2unsupported
 * \ref sweOpenLocalPkt opens a local packet. If necessary it will
 * first close one of a different type.
 * also updates a dma tag at the beginning of the packet.
 *
 * \param type  type of packet
 * \param size  size of packet. 0 gets a default size, while a negative number
 * is abs(size) or more. Units are u_long128.
 *
 * \return Returns TRUE on success.
 *
 * \see sweCloseLocalPkt
 */
RwBool
sweOpenLocalPkt(int type, int size)
{
    u_long128          *ptr;
    RWFUNCTION(RWSTRING("sweOpenLocalPkt"));
    PFENTRY(PFsweOpenLocalPkt);

    TRACEPRINTF(("%s(%d):%s - Enter\n",
                 __FILE__, __LINE__, __FUNCTION__));

    /* we should probably check the type field */

    if ((sweLocalPacketState != type)
        && (sweLocalPacketState != SWE_LPS_NONE))
    {
        TRACEPRINTF(
                    ("%s(%d):%s - a packet was open and must be closed\n",
                     __FILE__, __LINE__, __FUNCTION__));

        PFCALL(PFsweOpenLocalPkt);
        sweCloseLocalPkt();
        PFRET(PFsweOpenLocalPkt);

        TRACEPRINTF(("%s(%d):%s - returned from close\n",
                     __FILE__, __LINE__, __FUNCTION__));
    }

    if (sweLocalPacketState != SWE_LPS_NONE)
    {
        TRACEPRINTF(("%s(%d):%s - a packet is still open\n",
                     __FILE__, __LINE__, __FUNCTION__));

        if (size < 0)
            size = -size;
        if (!size)
            size = SWE_LPS_INITIAL_SIZE;

        /* if we have a size hint we realloc here */
        if ((size) && (sweLocalPacket + size + 2 > sweLocalPacketHigh))
        {
#ifndef USEDIRECT
            RwUInt32            numQuads = sweLocalPacket

                - /* sweLocalPacketBase */ SCRATCHPAD;
#else /* !USEDIRECT */
            RwUInt32            numQuads = sweLocalPacket
                - (u_long128 *) ((RwUInt8 *) sweRealLocalPacketBase +

                                 DIRECTOFFSET);
#endif /* !USEDIRECT */
            TRACEPRINTF(
                        ("%s(%d):%s - try to circularRealloc adding %d\n",
                         __FILE__, __LINE__, __FUNCTION__, size));

            /* We can't permit a size of > SWE_LPS_MAX_PACKET_SIZE*16 */
            /* (MaxQWC + dmatag) Local packet data is -1 due to extra GIF
             * tag */

            TRACEPRINTF(("%s(%d):%s - makes size %d\n",
                         __FILE__, __LINE__, __FUNCTION__,
                         (numQuads + size + 2) * 16));

            if ((numQuads + size) <= SWE_LPS_MAX_PACKET_SIZE)
            {
                /* Failure here isn't catastrophic */
#ifdef USEDIRECT
                /* *INDENT-OFF* */
                asm volatile ("sync.l");
                /* *INDENT-ON* */
#endif /* USEDIRECT */
                PFCALL(PFsweOpenLocalPkt);
                circularReallocMacro(ptr, circAllocator,
                                    sweRealLocalPacketBase,
                                    (numQuads + size + 2) * 16);
                PFRET(PFsweOpenLocalPkt);
                if (ptr)
                {
                    TRACEPRINTF(("%s(%d):%s - circularRealloc %d\n",
                                 __FILE__, __LINE__, __FUNCTION__,
                                 (numQuads + size + 2) * 16));

                    sweLocalPacketSize = (numQuads + size + 2) * 16;
#ifndef USEDIRECT
                    sweLocalPacketHigh =
                        (u_long128 *) ((char *) SCRATCHPAD +
                                       sweLocalPacketSize - 32);
#else /* !USEDIRECT */
                    sweLocalPacketHigh =
                        (u_long128 *) ((char *) ptr + DIRECTOFFSET +
                                       sweLocalPacketSize - 32);
#endif /* !USEDIRECT */
#ifndef USEDIRECT
                    /*sweLocalPacketBase = SCRATCHPAD; - still in SPR */
                    /*sweLocalPacket = SCRATCHPAD + numQuads; - still in SPR */
#else /* !USEDIRECT */
                    sweLocalPacketBase =
                        (u_long128 *) (ptr +
                                       (sweLocalPacketBase -
                                        sweRealLocalPacketBase));
                    sweLocalPacket =
                        (u_long128 *) ((RwUInt8 *) ptr + DIRECTOFFSET) +
                        numQuads;
#endif /* !USEDIRECT */
                    if (sweLocalPacketState & SWE_LPS_NOFIXUP)
                    {
                        /* we need to overwrite the intr in the last qwc */
                        RWASSERT(sweLocalPacket != sweLocalPacketBase);
                        if (*(int *)(sweLocalPacket-1) == (int)0xf0000000)
                        {
                            TRACEPRINTF(("%s(%d):%s - backing of %p (%x)\n",
                                         __FILE__, __LINE__, __FUNCTION__,
                                         sweLocalPacket,
                                         ((int)ptr+(int)sweLocalPacket-(int)sweLocalPacketBase)));
                            sweLocalPacket--;
                        }
                    }
                    sweRealLocalPacketBase = ptr;
                }
                else
                {
                    TRACEPRINTF(
                                ("%s(%d):%s - Circular realloc failed so close\n",
                                 __FILE__, __LINE__, __FUNCTION__));
                    PFCALL(PFsweOpenLocalPkt);
                    sweCloseLocalPkt();
                    PFRET(PFsweOpenLocalPkt);

                    TRACEPRINTF(
                                ("%s(%d):%s - Leave via recursive call...\n",
                                 __FILE__, __LINE__, __FUNCTION__));

#ifndef PROFILE
                    RWRETURN(sweOpenLocalPkt(type, size));
#else /* !PROFILE */
                    {
                        RwBool              yesno;

                        PFCALL(PFsweOpenLocalPkt);
                        yesno = sweOpenLocalPkt(type, size);
                        PFRET(PFsweOpenLocalPkt);
                        PFEXIT(PFsweOpenLocalPkt);
                        RWRETURN(yesno);
                    }
#endif /* !PROFILE */
                }
            }
            else
            {
                TRACEPRINTF(
                            ("%s(%d):%s - New size > SWE_LPS_MAX_PACKET_SIZE so close\n",
                             __FILE__, __LINE__, __FUNCTION__));

                PFCALL(PFsweOpenLocalPkt);
                sweCloseLocalPkt();
                PFRET(PFsweOpenLocalPkt);

                TRACEPRINTF(
                            ("%s(%d):%s - Leave via recursive call...\n",
                             __FILE__, __LINE__, __FUNCTION__));

#ifndef PROFILE
                RWRETURN(sweOpenLocalPkt(type, size));
#else /* !PROFILE */
                {
                    RwBool              yesno;

                    PFCALL(PFsweOpenLocalPkt);
                    yesno = sweOpenLocalPkt(type, size);
                    PFRET(PFsweOpenLocalPkt);
                    PFEXIT(PFsweOpenLocalPkt);
                    RWRETURN(yesno);
                }
#endif /* !PROFILE */
            }
        }
        else
        {
            if (sweLocalPacketState & SWE_LPS_NOFIXUP)
            {
                /* we need to overwrite the intr in the last qwc */
                RWASSERT(sweLocalPacket != sweLocalPacketBase);
                if (*(int *)(sweLocalPacket-1) == (int)0xf0000000)
                {
                    TRACEPRINTF(("%s(%d):%s - backing of %p (%x)\n",
                                 __FILE__, __LINE__, __FUNCTION__,
                                 sweLocalPacket,
                                 ((int)ptr+(int)sweLocalPacket-(int)sweLocalPacketBase)));
                    sweLocalPacket--;
                }
            }
        }

        TRACEPRINTF(("%s(%d):%s - Leave\n",
                     __FILE__, __LINE__, __FUNCTION__));

        PFEXIT(PFsweOpenLocalPkt);
        RWRETURN(TRUE);
    }
    else
    {
        if ((size <= 0) && (-size < SWE_LPS_INITIAL_SIZE))
        {
            size = SWE_LPS_INITIAL_SIZE;
        }
        else
        {
            size = size < 0 ? -size : size;
        }
        if (size > SWE_LPS_MAX_PACKET_SIZE)
            size = SWE_LPS_MAX_PACKET_SIZE;

        TRACEPRINTF(("%s(%d):%s - circularMallocing %d\n",
                     __FILE__, __LINE__, __FUNCTION__,
                     (size + 2) * 16));

        PFCALL(PFsweOpenLocalPkt);
        ptr = (u_long128 *)
            circularMalloc(circAllocator, (size + 2) * 16,
                           calDMA_ALLOC);
        PFRET(PFsweOpenLocalPkt);
        if (!ptr)
        {
#ifndef NDEBUG
            printf("sweOpenLocalPkt() circularMalloc failed\n");
#endif /* !NDEBUG */

            PFEXIT(PFsweOpenLocalPkt);
            RWRETURN(FALSE);
        }
        TRACEPRINTF(("%s(%d):%s - pkt really at %p\n",
                     __FILE__, __LINE__, __FUNCTION__, ptr));

        /* If we are in the middle of adding a packet, must make sure we are
         * done with the SPR.
         */
        if (swePacketToAddFirst)
        {
            /* Need to make sure that it's done with */
#ifndef USEDIRECT
#ifndef SYNCSPR
            TRACEPRINTF(("%s(%d):%s - Syncing SPR\n",
                         __FILE__, __LINE__, __FUNCTION__));
            /* Need to make sure that it's done with */
            sweInlineDmaSync(dmaChanFromSPR);
            TRACEPRINTF(("%s(%d):%s - Done Syncing SPR\n",
                         __FILE__, __LINE__, __FUNCTION__));
#endif
#else /* !USEDIRECT */
            /* *INDENT-OFF* */
            asm volatile ("sync.l");
            /* *INDENT-ON* */
#endif /* !USEDIRECT */

            PFCALL(PFsweOpenLocalPkt);
            _sweAppendPktToDispatchList(swePacketToAddFirst,
                                        swePacketToAddFirstChannel);
            PFRET(PFsweOpenLocalPkt);
            swePacketToAddFirst = (u_long128 *)NULL;
        }
        PFCALL(PFsweOpenLocalPkt);
        sweFlushPURef();
        PFRET(PFsweOpenLocalPkt);

        sweLocalPacketSize = (size + 2) * 16;
        sweRealLocalPacketBase = ptr;
#ifndef USEDIRECT
        sweLocalPacketBase = SCRATCHPAD;
        sweLocalPacket = SCRATCHPAD;
        sweLocalPacketHigh =
            (u_long128 *) ((char *) SCRATCHPAD + sweLocalPacketSize -
                           32);
#else /* !USEDIRECT */
        sweLocalPacketBase =
            (u_long128 *) ((RwUInt8 *) ptr + DIRECTOFFSET);
        sweLocalPacket = sweLocalPacketBase;
        sweLocalPacketHigh =
            (u_long128 *) ((char *) sweLocalPacketBase +
                           sweLocalPacketSize - 32);
#endif /* !USEDIRECT */
        sweLocalPacketState = type;

        if (!(sweLocalPacketState & SWE_LPS_NOFIXUP))
        {
            /* Basic tag */
            *(long *) sweLocalPacketBase = (0x7l << 28) | (0x1l << 31);
            *((long *) sweLocalPacketBase + 1) = 0;
            sweLocalPacket++;
        }
#ifdef LESSEOPS
        else
        {
            sweLocalPacketGifQWC = 0;
        }
#endif /* LESSEOPS */

        TRACEPRINTF(("%s(%d):%s - Leave\n",
                     __FILE__, __LINE__, __FUNCTION__));

        PFEXIT(PFsweOpenLocalPkt);
        RWRETURN(TRUE);
    }
}

/***********************************************************************
 sweFinaliseOpenLocalPkt

 On Entry : type (SWE_LPS_CONT, SWE_LPS_PRIM)
            size (hint. 0 gets default. 128bit units)
 On Exit  : success, failure

 */

 /**
 * \ingroup sky2unsupported
 * \ref sweFinaliseOpenLocalPkt attempts to extend a packet using the
 * following logic:
 *
 * If type isn't the same as the underlying type of the current pkt, or the
 * new type doesn't have SWE_LPS_NOFIXUP set, this is the same as
 * sweCloseLocalPkt();sweOpenLocalPkt(type, size)
 *
 * If the types are the same and both types have SWE_LPS_NOFIXUP set, this
 * is the same as sweOpenLocalPkt(type, size)
 *
 * If the types are the same, but the current type doesn't have SWE_LPS_NOFIXUP
 * set, where as the new one does, the current pkt has the dma/vif tag at its
 * start finalised, it is resized if required, and SWE_LPS_NOFIXUP is ORd
 * into the current type.
 *
 * If the types are the same, but the old type had SWE_LPS_NOFIXUP set where
 * as the new one does not, the current pkt has its final qwc overwritten, as it
 * is assumed to be an interupt/end and sweLocalPacketBase/sweLocalPacket are
 * updated. ~SWE_LPS_NOFIXUP is AND'd into the current type. The pkt is
 * resized if required. If no space is avialable it is closed and a new one
 * opened.
 *
 * If the function fails, the current pkt is closed, and no valid local pkt
 * is available for use.
 *
 * \param type  type of packet
 * \param size  size of packet. 0 gets a default size, while a negative number
 * is abs(size) or more. Units are u_long128.
 *
 * \return Returns TRUE on success.
 *
 * \see sweOpenLocalPkt
 * \see sweCloseLocalPkt
 */
RwBool
sweFinaliseOpenLocalPkt(int type, int size)
{
    RWFUNCTION(RWSTRING("sweFinaliseOpenLocalPkt"));
    PFENTRY(PF_sweFinaliseOpenLocalPkt);

    TRACEPRINTF(("%s(%d):%s - %x, %d\n",
                 __FILE__, __LINE__, __FUNCTION__, type, size));
    TRACEPRINTF(("%s(%d):%s - sweLocalPacket %p, sweLocalPacketBase %p\n",
                 __FILE__, __LINE__, __FUNCTION__, sweLocalPacket,
                 sweLocalPacketBase));

    if ((sweLocalPacketState) &&
        (!(sweLocalPacketState & SWE_LPS_NOFIXUP)) &&
        (type & SWE_LPS_NOFIXUP))
    {
        if (TYPE_CHECK == (unsigned int) type)
        {
            RwUInt32            numQuads =
                sweLocalPacket - sweLocalPacketBase;

            /* This is considered the most often called path */

#ifdef LESSEOPS
            if (!sweLocalPacketGifQWC)
            {
                /* gif end tag */
                *(long *) sweLocalPacket = 0x0000000000008000;
                *((long *) sweLocalPacket + 1) = 0x0000000000000000;
                sweLocalPacket++;
                numQuads++;
            }
#endif /* LESSEOPS */

            TRACEPRINTF(("%s(%d):%s - numQuads %d sweLocalPacketBase %p\n",
                         __FILE__, __LINE__, __FUNCTION__, numQuads,
                         sweLocalPacketBase));
            /* finalise dma tag at front of buffer */
            /* Initially we have to write an end with interupt */
            *(long *) sweLocalPacketBase = (numQuads - 1) | (0x7l << 28)
                | (1l << 31);

#if defined(VIF1RENDER)
            if ((numQuads - 1) > 0)
            {
                *((long *) sweLocalPacketBase + 1) =
                    ((0x50l << 24) | (long) (numQuads - 1)) << 32;
            }
            else
            {
                *((long *) sweLocalPacketBase + 1) = 0;
            }
#endif /* defined(VIF1RENDER) */

            /* We now update the type of the open pkt */
            sweLocalPacketState = type;

            if (size < 0)
                size = -size;
            if (!size)
                size = SWE_LPS_INITIAL_SIZE;

            /* if we have a size hint we realloc here */
            if ((size) &&
                (sweLocalPacket + size + 2 > sweLocalPacketHigh))
            {
                RwBool              ret;

                TRACEPRINTF(("%s(%d):%s - Calling sweOpenLocalPkt %x, %d\n",
                             __FILE__, __LINE__, __FUNCTION__, type,
                             size));
                PFCALL(PF_sweFinaliseOpenLocalPkt);
                ret = sweOpenLocalPkt(type, size);
                PFRET(PF_sweFinaliseOpenLocalPkt);

                /* We now check to see if the pkt changed due to the Open */
                /* If it didn't, we can safely change the end(i) to cnt */
                /* I'd prefer not to know about SCRATCHPAD, but I can see */
                /* no other way to check */
#ifndef USEDIRECT
                if ((ret) && (SCRATCHPAD != sweLocalPacket))
#else /* !USEDIRECT */
                if ((ret)  &&
                    ((u_long128*) ((RwUInt8 *) sweRealLocalPacketBase +
                                   DIRECTOFFSET) != sweLocalPacket))
#endif /* !USEDIRECT */
                {
#if 0
                    /* We now overwrite the end with interupt, to be a count */
                    *(long *) sweLocalPacketBase =
                        (*(long *) sweLocalPacketBase & 0x7fff)
                        | (numQuads - 1) | (0x1l << 28);
#else
                    *(long *) sweLocalPacketBase =
                        (numQuads - 1) | (0x1l << 28);
#endif
                }

                TRACEPRINTF(("%s(%d):%s - sweLocalPacket %p, sweLocalPacketBase %p\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             sweLocalPacket, sweLocalPacketBase));
                PFEXIT(PF_sweFinaliseOpenLocalPkt);
                RWRETURN(ret);
            }
            else
            {
                /* We now overwrite the end with interupt, to be a count */
#if 0
                *(long *) sweLocalPacketBase =
                    (*(long *) sweLocalPacketBase & 0x7fff) |
                    (numQuads - 1) |
                    (0x1l << 28);
#else
                *(long *) sweLocalPacketBase =
                    (numQuads - 1) | (0x1l << 28);
#endif

                TRACEPRINTF(("%s(%d):%s - sweLocalPacket %p, sweLocalPacketBase %p\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             sweLocalPacket, sweLocalPacketBase));
                PFEXIT(PF_sweFinaliseOpenLocalPkt);
                RWRETURN(TRUE);
            }
        }
        else
        {
            PFCALL(PF_sweFinaliseOpenLocalPkt);
            sweCloseLocalPkt();
            PFRET(PF_sweFinaliseOpenLocalPkt);
            PFEXIT(PF_sweFinaliseOpenLocalPkt);
            RWRETURN(sweOpenLocalPkt(type, size));
        }
    }
    else if ((sweLocalPacketState)
             && (sweLocalPacketState & SWE_LPS_NOFIXUP)
             && (!(type & SWE_LPS_NOFIXUP)))
    {
        /* If you get here you must have appended a DMAend0 with interupt */
        if (PACKET_CHECK == (unsigned int) sweLocalPacketState)
        {
            if (size < 0)
                size = -size;
            if (!size)
                size = SWE_LPS_INITIAL_SIZE;

            /* if we have a size hint we realloc here */
            if ((size)
                && (sweLocalPacket + size + 2 > sweLocalPacketHigh))
            {
                /* This case is more messy */
                RwBool              ret;

                /* We don't use the real new type as this might damage the */
                /* old pkt. We open the old type, then set eh new type and */
                /* perform the required adjustments */
                TRACEPRINTF(("%s(%d):%s - Calling sweOpenLocalPkt %x, %d\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             sweLocalPacketState, size));
                PFCALL(PF_sweFinaliseOpenLocalPkt);
                ret = sweOpenLocalPkt(sweLocalPacketState, size);
                PFRET(PF_sweFinaliseOpenLocalPkt);

                /* We now check to see if the pkt changed due to the Open */
                /* I'd prefer not to know about SCRATCHPAD, but I can see */
                /* no other way to check */
                if (ret)
                {
#ifndef USEDIRECT
                    if (SCRATCHPAD != sweLocalPacket)
#else /* !USEDIRECT */
                    if ((u_long128 *)
                        ((RwUInt8 *) sweRealLocalPacketBase +
                         DIRECTOFFSET) != sweLocalPacket)
#endif /* !USEDIRECT */
                    {
                        /* This means that we didn't open a new pkt */
                        TRACEPRINTF(("%s(%d):%s - using old pkt\n",
                                     __FILE__, __LINE__, __FUNCTION__));
                        sweLocalPacketBase = sweLocalPacket++;
                    }
                    else
                    {
                        TRACEPRINTF(("%s(%d):%s - using new pkt\n",
                                     __FILE__, __LINE__, __FUNCTION__));
                        sweLocalPacket = sweLocalPacketBase + 1;
                    }
                    sweLocalPacketState = type;
                }
                TRACEPRINTF(("%s(%d):%s - sweLocalPacket %p, sweLocalPacketBase %p\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             sweLocalPacket, sweLocalPacketBase));

                PFEXIT(PF_sweFinaliseOpenLocalPkt);
                RWRETURN(ret);
            }
            else
            {
                /* We now update the type of the open pkt */
                sweLocalPacketState = type;

                /* Set the new Beginning */
                sweLocalPacketBase = sweLocalPacket - 1;

                TRACEPRINTF(("%s(%d):%s - sweLocalPacket %p, sweLocalPacketBase %p\n",
                             __FILE__, __LINE__, __FUNCTION__,
                             sweLocalPacket, sweLocalPacketBase));
                PFEXIT(PF_sweFinaliseOpenLocalPkt);
                RWRETURN(TRUE);
            }
        }
        else
        {
            PFCALL(PF_sweFinaliseOpenLocalPkt);
            sweCloseLocalPkt();
            PFRET(PF_sweFinaliseOpenLocalPkt);
            PFEXIT(PF_sweFinaliseOpenLocalPkt);
            RWRETURN(sweOpenLocalPkt(type, size));
        }
    }
    else if (!(sweLocalPacketState)
             || ((sweLocalPacketState & SWE_LPS_NOFIXUP)
                 && (type & SWE_LPS_NOFIXUP)))
    {
        /* rare path, so do the simple thing */
        PFEXIT(PF_sweFinaliseOpenLocalPkt);
        RWRETURN(sweOpenLocalPkt(type, size));
    }
    else
    {
        /* rare path, so do the simple thing */
        PFCALL(PF_sweFinaliseOpenLocalPkt);
        sweCloseLocalPkt();
        PFRET(PF_sweFinaliseOpenLocalPkt);
        PFEXIT(PF_sweFinaliseOpenLocalPkt);
        RWRETURN(sweOpenLocalPkt(type, size));
    }
}

/***********************************************************************
 _sweGarbageCollectChain

 On Entry :
 On Exit  :

 Run down the chain releasing processed locally allocated pkts and dumping
 processed blocks.
 */
void
_sweGarbageCollectChain(void)
{
    swe_pkt            *ptr;
    RWFUNCTION(RWSTRING("_sweGarbageCollectChain"));
    PFENTRY(PF_sweGarbageCollectChain);

    TRACEPRINTF(("%s(%d):%s - Enter\n",__FILE__, __LINE__, __FUNCTION__));

    DI();
    /* release up any processed packets we own and discard blocks */
    ptr = sweGarbageStart;
    while ((ptr != sweChainEnd) && (ptr->type & SWE_PKT_PROCESSED))
    {
        if ((ptr->type & SWE_PKT_TYPE_MASK) == SWE_PKT_GOTO)
        {
            if (sweChainBase != sweCurrentBlockBase)
            {
                void               *tmp;

                tmp = ptr->addr;
                PFCALL(PF_sweGarbageCollectChain);
                RwFreeListFree(state_chainBlockFreeList, sweChainBase);
                PFRET(PF_sweGarbageCollectChain);
                sweChainBase = ptr = (swe_pkt *)tmp;
            }
            else
            {
                 ptr = (swe_pkt *)(ptr->addr);
            }
        }
        else
        {
            if ((ptr->type & SWE_PKT_LOCAL) && (ptr->addr))
            {
                if (!(ptr->type & SWE_PKT_NONCONTIG))
                {
                    /* Simple block release */
                    if (ptr->type & SWE_PKT_CIRCALLOC)
                    {
                        PFCALL(PF_sweGarbageCollectChain);
                        circularFree(circAllocator, ptr->addr);
                        PFRET(PF_sweGarbageCollectChain);
                    }
                    else
                    {
                        PFCALL(PF_sweGarbageCollectChain);
                        RwFree(ptr->addr);
                        PFRET(PF_sweGarbageCollectChain);
                    }
                    ptr->addr = (u_long128 *)NULL;
                }
                else
                {
                    unsigned long      *freeptr;
                    unsigned long      *curptr;

                    /* We have to parse the chain */

                    /* We don't release call'd blocks, as these might be */
                    /* referenced more than once. Include a NULL pkt */
                    /* of LOCAl type to release them */
                    freeptr = (unsigned long *) ptr->addr;
                    curptr = (unsigned long *) freeptr;
                    ptr->addr = NULL;
                    while (((((*curptr) >> 28) & 0xf) != 8)
                           && ((((*curptr) >> 28) & 0xf) != 0xf))
                    {
                        if ((((*curptr) >> 28) & 0x7) == 2)
                        {
                            /* next jumps to a new block, so release current */
                            curptr =
                                (unsigned long *) (unsigned
                                                   int) (*curptr >> 32);
                            if (ptr->type & SWE_PKT_CIRCALLOC)
                            {
                                PFCALL(PF_sweGarbageCollectChain);
                                circularFree(circAllocator, freeptr);
                                PFRET(PF_sweGarbageCollectChain);
                            }
                            else
                            {
                                PFCALL(PF_sweGarbageCollectChain);
                                RwFree(freeptr);
                                PFRET(PF_sweGarbageCollectChain);
                            }
                            freeptr = curptr;
                        }
                        else
                        {
                            if (((((*curptr) >> 28) & 0xf) == 1)
                                || ((((*curptr) >> 28) & 0xf) == 5))
                            {
                                /* cnt, call need skip qwc */
                                curptr =
                                    curptr + (*curptr & 0xffff) * 2;
                            }
                            curptr += 2;
                        }
                    }
                    if (ptr->type & SWE_PKT_CIRCALLOC)
                    {
                        PFCALL(PF_sweGarbageCollectChain);
                        circularFree(circAllocator, freeptr);
                        PFRET(PF_sweGarbageCollectChain);
                    }
                    else
                    {
                        PFCALL(PF_sweGarbageCollectChain);
                        RwFree(freeptr);
                        PFRET(PF_sweGarbageCollectChain);
                    }
                }
            }
            ptr++;
        }
    }
    sweGarbageStart = ptr;
    /* If the whole of the last block is processed, reset pointers */

    /* This is tricky as it needs to be interupt safe, but if all blocks */
    /* including the last are processed, there can never be an end of DMA */
    /* interupt */
    if (sweCurrentBase == sweChainEnd)
    {
        sweCurrentBlockBase = sweChainBase;
        sweCurrentBase = sweChainBase;
        sweChainEnd = sweChainBase;
        sweGarbageStart = sweChainBase;
    }

    /* This is not how I'd like to do it. The logic in dmaalloc needs to
       be fixed */
    FlushCache(0);

    EI();

    TRACEPRINTF(("%s(%d):%s - After traversal:\n",
                 __FILE__, __LINE__, __FUNCTION__));
    TRACEPRINTF(("%s(%d):%s - sweChainBase %x\n",
                 __FILE__, __LINE__, __FUNCTION__, (int) sweChainBase));
    TRACEPRINTF(("%s(%d):%s - sweCurrentBlockBase %x\n",
                 __FILE__, __LINE__, __FUNCTION__,
                 (int) sweCurrentBlockBase));
    TRACEPRINTF(("%s(%d):%s - sweCurrentBase %x\n",
                 __FILE__, __LINE__, __FUNCTION__,
                 (int) sweCurrentBase));
    TRACEPRINTF(("%s(%d):%s - sweChainEnd %x\n",
                 __FILE__, __LINE__, __FUNCTION__, (int) sweChainEnd));

    TRACEPRINTF(("%s(%d):%s - Leave\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFEXIT(PF_sweGarbageCollectChain);
    RWRETURNVOID();
}

#ifdef PROCRAS
#ifdef DUMPDETAIL

/***********************************************************************
 detailDumpDMAPkt

 On Entry : indent string, address to dump from
 On Exit  :

 Print out a detailed DMA Pkt packet
 */
static              RwBool
detailDumpDMAPkt(char *indent, u_long128 * addr)
{
    static const char   dmaCmds[8][6] = { "refe", "cnt", "next", "ref",
        "refs", "call", "ret", "end"
    };
    RwUInt64            d;
    RwUInt32            a, b, c,j;
    RwUInt32            ze = 0;
    volatile RwUInt32  *vol = &ze;
    RWFUNCTION(RWSTRING("detailDumpDMAPkt"));

    do
    {
        /* Extract the fields of the DMA Tag */
        d = *(RwUInt64 *) addr;
        a = (RwUInt32) (d >> 32);
        c = (RwUInt32) (d & 0xffff);
        b = (RwUInt32) ((d >> 28) & 7);

        /* Print out the DMA Tag fields */
        printf("%s%p: %.8x_%.8x_%.16lx %s %d\n",
               indent, addr,
               *((unsigned int *) addr + 3),
               *((unsigned int *) addr + 2), d, dmaCmds[b], c);

        /* Deal with QWC quadwords after the DMA Tag (all commands) */
        while (c--)
        {
            addr++;
            printf("%s%p: %.8x_%.8x_%.8x_%.8x\n",
                   indent, addr,
                   *((unsigned int *) addr + 3),
                   *((unsigned int *) addr + 2),
                   *((unsigned int *) addr + 1),
                   *((unsigned int *) addr + 0));
             /* We put a pause in here as dsnetm has a buffer
              * overrun problem */
             for (j = 0; j < 100000; j++)
             {
                 if (*vol)
                 {
                     printf("Odd?\n");
                 }
             }
        }

        /* Now deal with the behaviour of the command itself */
        if (b == 2)
        {
            addr = (u_long128 *) a;
        }
        else if (b == 5)
        {
#ifdef DUMPDETAILFOLLOWCALLS
            /* Follow the call */
            char                newIndent[80];

            strcpy(newIndent, indent);
            strcat(newIndent, "    ");
            if (!detailDumpDMAPkt(newIndent, (u_long128 *) a))
            {
                RWRETURN( (0) );
            }
#endif /* DUMPDETAILFOLLOWCALLS */
            addr++;
        }
        else
        {
            addr++;
        }
    }
    while ((b != 0) && (b != 7) && (b != 6));

    /* Return 0 if the DMA was just stopped, 1 if a return was found */
    RWRETURN( (b == 6) );
}
#endif /* DUMPDETAIL */

/***********************************************************************
 sweDumpChain

 On Entry :
 On Exit  :

 Print out the chain. This function will need to be updated each  time
 a new pkt type is added.
 */
static void
sweDumpChain(void)
{
    swe_pkt            *ptr;
    RWFUNCTION(RWSTRING("sweDumpChain"));
    PFENTRY(PFsweDumpChain);

    ptr = sweChainBase;
    printf("\nChain Base: %p\n", (unsigned) ptr);
    printf("sweCurrentBlockBase: %p\n", (unsigned) sweCurrentBlockBase);
    printf("sweCurrentBase: %p\n", (unsigned) sweCurrentBase);
    printf("sweChainEnd: %p\n", (unsigned) sweChainEnd);
    while ((ptr != sweChainEnd))
    {
        if (ptr->type & SWE_PKT_LOCAL)
            printf("L");
        else
            printf(" ");
        if (ptr->type & SWE_PKT_PROCESSED)
            printf("L");
        else
            printf(" ");
        if (ptr->type & SWE_PKT_NONCONTIG)
            printf("N");
        else
            printf(" ");
        printf(" ");
        if (ptr->type & SWE_PKT_SWAP)
            printf("S");
        else
            printf(" ");
        printf(" ");
        switch (ptr->type & SWE_PKT_TYPE_MASK)
        {
            case SWE_PKT_VU0:
                {
                    if (ptr->type & 0x400)
                    {
                        printf("Vu0 with tag addr %.8x (%.16lx)\n",
                               (unsigned) ptr->addr,
                               (ptr->addr ? *(unsigned long *) ptr->
                                addr : 0));
                    }
                    else
                    {
                        printf("Vu0          addr %.8x (%.16lx)\n",
                               (unsigned) ptr->addr,
                               (ptr->addr ? *(unsigned long *) ptr->
                                addr : 0));
                    }
                    ptr++;
                    break;
                }
            case SWE_PKT_VU1:
                {
                    if (ptr->type & 0x400)
                    {
                        printf("Vu1 with tag addr %.8x (%.16lx)\n",
                               (unsigned) ptr->addr,
                               (ptr->addr ? *(unsigned long *) ptr->
                                addr : 0));
                    }
                    else
                    {
                        printf("Vu1          addr %.8x (%.16lx)\n",
                               (unsigned) ptr->addr,
                               (ptr->addr ? *(unsigned long *) ptr->
                                addr : 0));
                    }
#ifdef DUMPDETAIL
                    detailDumpDMAPkt("", (u_long128 *) ptr->addr);
#endif /* DUMPDETAIL */
                    ptr++;
                    break;
                }
            case SWE_PKT_GIF:
                {
                    printf("Gif          addr %.8x (%.16lx)\n",
                           (unsigned) ptr->addr,
                           (ptr->addr ? *(unsigned long *) ptr->
                            addr : 0));
                    ptr++;
                    break;
                }
            case SWE_PKT_FLIP0:
                {
                    printf("Flip0   dbuf addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
            case SWE_PKT_FLIP1:
                {
                    printf("Flip1   dbuf addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
            case SWE_PKT_RASUREF:
                {
                    printf("Rasuref %d   addr %.8x (%.8x)\n",
                           (ptr->type & SWE_PKT_IMM_MASK) ? (ptr->type &
                                                             SWE_PKT_IMM_MASK)
                           >> SWE_PKT_IMM_SHIFT : 1,
                           (unsigned) ptr->addr,
                           (ptr->addr ? *(unsigned *) ptr->addr : 0));
                    ptr++;
                    break;
                }
            case SWE_PKT_NULL:
                {
                    printf("Null         addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
            case SWE_PKT_GOTO:
                {
                    printf("Goto         addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr = ptr->addr;
                    break;
                }
#ifdef GSB
            case SWE_PKT_WAIT_DRAWNEXT:
                {
                    printf("WaitDrawNext addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
            case SWE_PKT_INC_TIME:
                {
                    printf("Inc Time     addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
#endif /* GSB */
            case SWE_PKT_CALL:
                {
                    printf("Callback     addr %.8x\n",
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
            default:
                {
                    printf("Unknown %.4x addr %.8x\n",
                           (ptr->type & SWE_PKT_TYPE_MASK),
                           (unsigned) ptr->addr);
                    ptr++;
                    break;
                }
        }
    }

    PFEXIT(PFsweDumpChain);
    RWRETURNVOID();
}
#endif /* PROCRAS */

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                         Interupt Handlers

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/* Handlers are guaranteed to execute with interupts disabled, so don't
   need to be reentrant or have to take precautions about accessing vars */

/***********************************************************************
 sweHandler

 On Entry : channel number
 On Exit  : -1 to prevent futher chaining

 Note that we go quiescent on flips as the app will probably need to
 _sweWaitFlip()
 Warning: This code assumes a single dispatch thread. In a multichannel
 dispatch model, abit of reworking will be required.
 */

static int
sweHandler(int ch)
{
    unsigned int oldgp;
#if (0)
    RWFUNCTION(RWSTRING("sweHandler"));
#endif /* (0) */

    SKY_INTR_GET_GP(oldgp);

    PFENTRY(PFsweHandler);
    sweNumHandler++;

    /* early out */
    if (sweCurrentBase == sweChainEnd)
    {
        PFEXIT(PFsweHandler);
        INTR_RESTORE_GP(oldgp);
        EXITHANDLER();
        return( (0) );
    }

    /* We really should check that it is us! */
    if ((sweDispatching) &&
        (((sweCurrentBase->type & 0xf) == (unsigned int) ch)
#ifdef SWEASYNC
#ifdef NONASYNCTEST2
         || ((sweCurrentBase->type & SWE_PKT_TYPE_MASK) == SWE_PKT_AGIF)
#endif /* !NONASYNCTEST2 */
         || ((sweAsyncInProgress)
             && ((((sweCurrentBase+1)->type & 0xf) == (unsigned int) ch)))
#endif /* SWEASYNC */
        ))
    {
        /* Now some more time consuming checks 
         * Basically a full set provided here, though we only use 0-3 
         * at present. Yes I should check for Bus error etc, but that 
         * won't happen in a production environemnt :-) 
         */
        switch (ch)
        {
#if 0
            case DMAC_VIF0:
                {
                    u_int   d0_chcr = *D0_CHCR;

                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d0_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int result;
                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 1
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (result));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_CHAIN)
                    {
                        if (((d0_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d0_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d0_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 1
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
#endif
            case DMAC_VIF1:
                {
                    u_int   d1_chcr = *D1_CHCR;
#ifdef SWEASYNC
#ifdef NONASYNCTEST2
                    if (sweAsyncInProgress)
                    {
                        /* if its us, just clear down and mark as processed */
                        /* Should do full checks here, but for now */
                        int __tmp;
#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */

                        /* Clear interupt */
                        asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 2
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                        (sweCurrentBase+1)->type |= SWE_PKT_PROCESSED;
                        sweAsyncInProgress = FALSE;
#ifdef COLOURDMA
                        asm volatile ("sync.l");
                        dmacolour &= ~0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef NONASYNCTEST
                        if ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_VU1)
                        {
                                    PFCALL(PFsweHandler);
                                    sweDmaSend(dmaChanVIF1,
                                               sweCurrentBase->addr,
                                               ((sweCurrentBase->type & 0x700)
                                                == 0x500) ? 0xc0 : 0x80);
                                    PFRET(PFsweHandler);
                                    sweNumDispatched++;
#ifdef COLOURDMA
                                    asm volatile ("sync.l");
                                    dmacolour |= 0xff0000l;
                                    asm volatile ("sync.l");
                                    DPUT_GS_BGCOLOR(dmacolour);
                                    asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef DMATIME
                                    sweDmaTimer = _sweReadTimer();
#endif /* DMATIME */
                        }
                        else
                        {
                            scePrintf("AGIF logic error \n");
                        }
#endif /* NONASYNCTEST */
                        PFEXIT(PFsweHandler);
                        INTR_RESTORE_GP(oldgp);

                        EXITHANDLER();
                        return( (0) );
                    }
#endif /* NONASYNCTEST2 */
#endif /* SWEASYNC */

                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d1_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            USEINTVAR(__tmp);

#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */

                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 2
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
#ifdef COLOURDMA
                            asm volatile ("sync.l");
                            dmacolour &= ~0xff0000l;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef DMATIME
                            sweDmaRunTime += _sweReadTimer() - sweDmaTimer;
#endif /* DMATIME */
#ifdef SWEASYNC
                            if (sweAsyncInProgress)
                            {
                                sweAsyncInProgress = FALSE;

                                /* Just inc the pointer and exit */
                                sweCurrentBase->type |= SWE_PKT_PROCESSED;
                                sweCurrentBase++;
                                
                                PFEXIT(PFsweHandler);
                                INTR_RESTORE_GP(oldgp);

                                EXITHANDLER();
                                return( (0) );
                            }
#endif /* SWEASYNC */
                            break;
                        }
                    }
                    else if (((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                              == SWE_PKT_DMA_MODE_CHAIN)
#ifdef SWEASYNC
#ifdef NONASYNCTEST2
                             || ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                                 == SWE_PKT_AGIF)
#endif /* NONASYNCTEST2 */
#endif /* SWEASYNC */
                            )
                    {
                        if (((d1_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d1_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d1_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                            USEINTVAR(__tmp);

#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */

                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 2
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
#ifdef COLOURDMA
                            asm volatile ("sync.l");
                            dmacolour &= ~0xff0000l;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef DMATIME
                            sweDmaRunTime += _sweReadTimer() - sweDmaTimer;
#endif /* DMATIME */
#ifdef SWEASYNC
                            if (sweAsyncInProgress)
                            {
                                sweAsyncInProgress = FALSE;

                                /* Just inc the pointer and exit */
                                sweCurrentBase->type |= SWE_PKT_PROCESSED;
                                sweCurrentBase++;
                                
                                PFEXIT(PFsweHandler);
                                INTR_RESTORE_GP(oldgp);

                                EXITHANDLER();
                                return( (0) );
                            }
#endif /* SWEASYNC */
                            break;
                        }
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
            case DMAC_GIF:
                {
                    u_int   d2_chcr = *D2_CHCR;

#ifdef SWEASYNC
                    if (sweAsyncInProgress)
                    {
                        /* if its us, just clear down and mark as processed */
                        /* Should do full checks here, but for now */
                        int __tmp;
                        USEINTVAR(__tmp);

#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */

                        DPUT_GIF_MODE(0);

                        /* Clear interupt */
                        asm volatile (" .set noreorder
                                    .set noat
                                    lui %0, 0x1001
                                    addiu $at, $0, 4
                                    sw $at, -0x1ff0(%0)
                                    sync.l
                                    .set reorder
                                    .set at
                                  " : "=r" (__tmp));
                        (sweCurrentBase+1)->type |= SWE_PKT_PROCESSED;
                        sweAsyncInProgress = FALSE;
#ifdef COLOURDMA
                        asm volatile ("sync.l");
                        dmacolour &= ~0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef NONASYNCTEST
                        if ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_VU1)
                        {
                                    PFCALL(PFsweHandler);
                                    sweDmaSend(dmaChanVIF1,
                                               sweCurrentBase->addr,
                                               ((sweCurrentBase->type & 0x700)
                                                == 0x500) ? 0xc0 : 0x80);
                                    PFRET(PFsweHandler);
                                    sweNumDispatched++;
#ifdef COLOURDMA
                                    asm("sync.l");
                                    dmacolour |= 0xff0000l;
                                    asm("sync.l");
                                    DPUT_GS_BGCOLOR(dmacolour);
                                    asm("sync.l");
#endif  /* COLOURDMA */
#ifdef DMATIME
                                    sweDmaTimer = _sweReadTimer();
#endif /* DMATIME */
                        }
                        else
                        {
                            scePrintf("AGIF logic error \n");
                        }
#endif /* NONASYNCTEST */
                        {
                            RwUInt32 reg;

                            do
                            {
                                reg = DGET_GIF_STAT();
                            }
                            while (((reg & 0xc00) == 0xc00) || (reg & 0x60)
                                   || (reg & 0x1f000000));
                        }
                        PFEXIT(PFsweHandler);
                        INTR_RESTORE_GP(oldgp);

                        EXITHANDLER();
                        return( (0) );
                    }
#endif /* SWEASYNC */
                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d2_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            USEINTVAR(__tmp);

#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */
                            if (sweCurrentBase->type & SWE_PKT_ASYNC)
                            {
                                DPUT_GIF_MODE(0);
                            }

                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 4
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
#ifdef COLOURDMA
                            asm volatile ("sync.l");
                            dmacolour &= ~0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                            {
                                RwUInt32 reg;

                                do
                                {
                                    reg = DGET_GIF_STAT();
                                }
                                while (((reg & 0xc00) == 0xc00) || (reg & 0x60)
                                       || (reg & 0x1f000000));
                            }
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_CHAIN)
                    {
                        if (((d2_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d2_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d2_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                            USEINTVAR(__tmp);

#if (defined(__MWERKS__) && defined(RWVERBOSE))
#pragma unused (__tmp)
#endif /* (defined(__MWERKS__) && defined(RWVERBOSE)) */
                            if (sweCurrentBase->type & SWE_PKT_ASYNC)
                            {
                                DPUT_GIF_MODE(0);
                            }

                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 4
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
#ifdef COLOURDMA
                            asm volatile ("sync.l");
                            dmacolour &= ~0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                            {
                                RwUInt32 reg;

                                do
                                {
                                    reg = DGET_GIF_STAT();
                                }
                                while (((reg & 0xc00) == 0xc00) || (reg & 0x60)
                                       || (reg & 0x1f000000));
                            }
                            break;
                        }
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
#if 0
            case DMAC_FROM_IPU:
                {
                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((*D3_CHCR & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 8
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
            case DMAC_TO_IPU:
                {
                    u_int   d4_chcr = *D4_CHCR;

                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d4_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x10
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_CHAIN)
                    {
                        if (((d4_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d4_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d4_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x10
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
#if 0
                /* These are currently missing in the headers */
            case DMAC_SIF0:
                {
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
            case DMAC_SIF1:
                {
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
            case DMAC_SIF2:
                {
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
#endif
            case DMAC_FROM_SPR:
                {
                    u_int   d8_chcr = *D8_CHCR;

                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d8_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x100
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_CHAIN)
                    {
                        if (((d8_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d8_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d8_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x100
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_INTERL)
                    {
                        int __tmp;
                                /* Clear interupt */
                        asm volatile (" .set noreorder
                                    .set noat
                                    lui %0, 0x1001
                                    addiu $at, $0, 0x100
                                    sw $at, -0x1ff0(%0)
                                    sync.l
                                    .set reorder
                                    .set at
                                  " : "=r" (__tmp));
                        break;
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
            case DMAC_TO_SPR:
                {
                    u_int   d9_chcr = *D9_CHCR;

                    if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                        == SWE_PKT_DMA_MODE_NORM)
                    {
                        if ((d9_chcr & D_CHCR_MOD_M)
                            == (SWE_PKT_DMA_MODE_NORM >> SWE_DMA_MODE_SHIFT))
                        {
                            int __tmp;
                            /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x200
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_CHAIN)
                    {
                        if (((d9_chcr & D_CHCR_MOD_M)
                             == (SWE_PKT_DMA_MODE_CHAIN >> SWE_DMA_MODE_SHIFT))
                            && (((d9_chcr & 0xf0000000) == (0x80000000)) ||
                                ((d9_chcr & 0xf0000000) == (0xf0000000))
                                )
                            )
                        {
                            int __tmp;
                                /* Clear interupt */
                            asm volatile (" .set noreorder
                                        .set noat
                                        lui %0, 0x1001
                                        addiu $at, $0, 0x200
                                        sw $at, -0x1ff0(%0)
                                        sync.l
                                        .set reorder
                                        .set at
                                      " : "=r" (__tmp));
                            break;
                        }
                    }
                    else if ((sweCurrentBase->type & SWE_PKT_DMA_MODE_MASK)
                             == SWE_PKT_DMA_MODE_INTERL)
                    {
                        int __tmp;
                                /* Clear interupt */
                        asm volatile (" .set noreorder
                                    .set noat
                                    lui %0, 0x1001
                                    addiu $at, $0, 0x200
                                    sw $at, -0x1ff0(%0)
                                    sync.l
                                    .set reorder
                                    .set at
                                  " : "=r" (__tmp));
                        break;
                    }
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
#endif
            default:
                {
                    /* Don't have a clue mate. Should never get here */
                    PFEXIT(PFsweHandler);
                    INTR_RESTORE_GP(oldgp);

                    EXITHANDLER();
                    return( (0) );
                }
        }

        /* mark current as processed */
        sweCurrentBase->type |= SWE_PKT_PROCESSED;
        sweCurrentBase++;
        sweDispatching = FALSE;
    }
    else
    {
        /* If there are no flips pending we try to kick the chain */
        /* PFEXIT(PFsweHandler); */
        /* INTR_RESTORE_GP(oldgp); */
        /* EXITHANDLER(); */
        /* return( (0) ); */
    }

    /* Docs are unclear if I need to clear the interupt somehow, or if kernel
     * does so */
    /* dispatch next item */
    while ((!sweDispatching) && (sweCurrentBase != sweChainEnd)
           && (!sweFlipPending) && (!sweAutoFlip))
    {
        if (sweCurrentBase->type & SWE_PKT_PROCESSED)
        {
            /* Skip over processed, eg AGIF pkts */
            sweCurrentBase++;
            continue;
        }
        switch (sweCurrentBase->type & SWE_PKT_TYPE_MASK)
        {
            /* If you add a case here, remember to update _sweFlush() too */
#if 0
            case SWE_PKT_VU0:
                {
                    sweDispatching = TRUE;
                    PFCALL(PFsweHandler);
                    sweDmaSend(dmaChanVIF0, sweCurrentBase->addr,
                               ((sweCurrentBase->type & 0x700) ==
                                0x500) ? 0xc0 : 0x80);
                    PFRET(PFsweHandler);
                    sweNumDispatched++;
                    break;
                }
#endif
            case SWE_PKT_VU1:
#ifdef SWEASYNC
#ifdef NONASYNCTEST2 
            case SWE_PKT_AGIF:
#endif /* NONASYNCTEST2 */
#endif /* SWEASYNC */
                {
                    sweDispatching = TRUE;
#ifdef SWEASYNC
#ifdef NONASYNCTEST
#ifdef NONASYNCTEST2
                    if ((sweCurrentBase+1 != sweChainEnd)
                        && (((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_AGIF)
                        && ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                            != SWE_PKT_AGIF))
                    {
                        /* We lie and dispatch on VU1 TTE */
                        sweAsyncInProgress = TRUE;
                        /* Set GIF for interrupted transfer */
                        sweDmaSend(dmaChanVIF1, (sweCurrentBase+1)->addr, 0xc0);
                        sweNumDispatched++;
                        sweNumAsyncDispatched++;
#ifdef COLOURDMA
                        asm volatile ("sync.l");
                        dmacolour |= 0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
#endif  /* COLOURDMA */
                        break;
                    }
#else /* NONASYNCTEST2 */
                    if ((sweCurrentBase+1 != sweChainEnd)
                        && (((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_AGIF))
                    {
                        sweAsyncInProgress = TRUE;
                        /* Set GIF for interrupted transfer */
                        DPUT_GIF_MODE(GIF_MODE_IMT_M);
                        sweDmaSend(dmaChanGIF, (sweCurrentBase+1)->addr, 0x80);
                        sweNumDispatched++;
                        sweNumAsyncDispatched++;
#ifdef COLOURDMA
                        asm volatile ("sync.l");
                        dmacolour |= 0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
#endif  /* COLOURDMA */
                        break;
                    }
#endif /* NONASYNCTEST2 */
#endif /* NONASYNCTEST */
#endif /* SWEASYNC */
                    PFCALL(PFsweHandler);
                    sweDmaSend(dmaChanVIF1, sweCurrentBase->addr,
                               ((sweCurrentBase->type & 0x700) ==
                                0x500) ? 0xc0 : 0x80);
                    PFRET(PFsweHandler);
                    sweNumDispatched++;
#ifdef COLOURDMA
                    asm volatile ("sync.l");
                    dmacolour |= 0xff0000l;
                    asm volatile ("sync.l");
                    DPUT_GS_BGCOLOR(dmacolour);
                    asm volatile ("sync.l");
#endif  /* COLOURDMA */
#ifdef DMATIME
                    sweDmaTimer = _sweReadTimer();
#endif /* DMATIME */
#ifdef SWEASYNC
                    /* Can we kick an async transfer */
                    if ((sweCurrentBase+1 != sweChainEnd)
                        && (((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_AGIF))
                    {
                        sweAsyncInProgress = TRUE;
                        /* Set GIF for interrupted transfer */
                        DPUT_GIF_MODE(GIF_MODE_IMT_M);
                        sweDmaSend(dmaChanGIF, (sweCurrentBase+1)->addr, 0x80);
                        sweNumDispatched++;
                        sweNumAsyncDispatched++;
#ifdef COLOURDMA
                        asm volatile ("sync.l");
                        dmacolour |= 0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
#endif  /* COLOURDMA */
                    }
#endif /* SWEASYNC */
                    break;
                }
            case SWE_PKT_GIF:
#if defined(SWEASYNC) && !defined(NONASYNCTEST2)
            case SWE_PKT_AGIF:
#endif /* defined(SWEASYNC) && !defined(NONASYNCTEST2) */
                {
                    sweDispatching = TRUE;
#ifndef LESSEOPS
                    while (sceGsSyncPath(1, 0))
                    {
                        ;
                    }
#endif /* LESSEOPS */
                    PFCALL(PFsweHandler);
                    sweDmaSend(dmaChanGIF, sweCurrentBase->addr, 0x80);
                    PFRET(PFsweHandler);
                    sweNumDispatched++;
#ifdef COLOURDMA
                    asm volatile ("sync.l");
                    dmacolour |= 0xffl;
                    asm volatile ("sync.l");
                    DPUT_GS_BGCOLOR(dmacolour);
                    asm volatile ("sync.l");
#endif  /* COLOURDMA */
                    break;
                }
            case SWE_PKT_FLIP0:
                {
                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweFlipSt =
                        (void *) (((int) sweCurrentBase->addr) & ~1);
                    sweFlipId = 0;
#ifdef GSB
                    if (skyDMAGCVTValue % skyNumSeqFrms != skyRenderSlot)
                    {
                        /* We will need to protect against other dma here */

                        /* hitting this bit of code probably indicates an */
                        /* error in the system's design */

                        /* We need to flip and continue immediately */
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                        sweCurrentBase++;
                        /* A fake VSync has occured */
                        skyDMAGCVTValue++;
                        break;
                    }
#endif /* GSB */
#if defined(TEAR) || defined(RUNTIMETEAR)
#ifdef RUNTIMETEAR
                    if (sweTear)
                    {
#endif /* RUNTIMETEAR */
#ifdef GSB
#ifdef VISTIME
                        /* Display unit number */
                        {
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, posB,
                                                      sizeof(posB) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, posC,
                                                      sizeof(posC) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, posD,
                                                      sizeof(posD) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, posE,
                                                      sizeof(posE) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                            sweInlineDmaSendN(dmaChanGIF, digitBack,
                                              sizeof(digitBack) >> 4);
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                                      sizeof(digitZero) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                                      sizeof(digitOne) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                                      sizeof(digitTwo) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                                      sizeof(digitThree) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                        }
#endif /* VISTIME */
#endif /* GSB */
                        PFCALL(PFsweHandler);
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                        PFRET(PFsweHandler);
                        sweFlipPending = 0;
#ifdef GSB
                        /* If we are using real VSYNC based swaps we can: */
                        /* A real/fake VSync has occured */
                        skyDMAGCVTValue++;
                        /* Inform merge unit */
                        if (!skyGsmSysReadyRequired)
                        {
                            gsbDrawDone(GSB_DRAWDONE_SET);
                            skyNeedDrawNext = TRUE;
                        }
#endif /* GSB */
#ifdef RUNTIMETEAR
                    }
                    else
                    {
#endif /* RUNTIMETEAR */
#endif /* defined(TEAR) || defined(RUNTIMETEAR) */
#if !defined(TEAR) || defined(RUNTIMETEAR)
                        sweFlipPending = 1;
                        if (!sweAutoFlip)
                        {
                            sweAutoFlip = ((int) (sweCurrentBase->addr) & 1)
                                + (((int) (sweCurrentBase->addr) & 1) << 1);

                        }
#ifdef RUNTIMETEAR
                    }
#endif /* RUNTIMETEAR */
#endif /* !defined(TEAR) || defined(RUNTIMETEAR) */
                    sweCurrentBase++;
                    sweNumFlipsInQueue--;
#ifdef RWMETRICS
                    state_skyMetrics.flipPktTime = _sweReadTimer();
#endif /* RWMETRICS */
                    break;
                }
            case SWE_PKT_FLIP1:
                {
                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweFlipSt =
                        (void *) (((int) sweCurrentBase->addr) & ~1);
                    sweFlipId = 1;
#ifdef GSB
                    if (skyDMAGCVTValue % skyNumSeqFrms != skyRenderSlot)
                    {
                        /* We will need to protect against other dma here */

                        /* hitting this bit of code probably indicates an */
                        /* error in the system's design */

                        /* We need to flip and continue immediately */
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                        sweCurrentBase++;
                        /* A fake VSync has occured */
                        skyDMAGCVTValue++;
                        break;
                    }
#endif /* GSB */
#if defined(TEAR)||defined(RUNTIMETEAR)
#ifdef RUNTIMETEAR
                    if (sweTear)
                    {
#endif /* RUNTIMETEAR */
#ifdef GSB
#ifdef VISTIME
                        /* Display unit number */
                        {
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, posB,
                                                      sizeof(posB) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, posC,
                                                      sizeof(posC) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, posD,
                                                      sizeof(posD) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, posE,
                                                      sizeof(posE) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                            sweInlineDmaSendN(dmaChanGIF, digitBack,
                                              sizeof(digitBack) >> 4);
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                                      sizeof(digitZero) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                                      sizeof(digitOne) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                                      sizeof(digitTwo) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                                      sizeof(digitThree) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                        }
#endif /* VISTIME */
#endif /* GSB */
                        PFCALL(PFsweHandler);
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                        PFRET(PFsweHandler);
                        sweFlipPending = 0;
#ifdef GSB
                        /* If we are using real VSYNC based swaps we can: */
                        /* A real/fake VSync has occured */
                        skyDMAGCVTValue++;
                        /* Inform merge unit */
                        if (!skyGsmSysReadyRequired)
                        {
                            gsbDrawDone(GSB_DRAWDONE_SET);
                            skyNeedDrawNext = TRUE;
                        }
#endif /* GSB */
#ifdef RUNTIMETEAR
                    }
                    else
                    {
#endif /* RUNTIMETEAR */
#endif /* defined(TEAR)||defined(RUNTIMETEAR) */
#if !defined(TEAR)||defined(RUNTIMETEAR)
                        sweFlipPending = 1;
                        if (!sweAutoFlip)
                        {
                            sweAutoFlip = (((int) sweCurrentBase->addr) & 1)
                                + (((int) (sweCurrentBase->addr) & 1) << 1);
                        }
#ifdef RUNTIMETEAR
                    }
#endif /* RUNTIMETEAR */
#endif /* !defined(TEAR)||defined(RUNTIMETEAR) */
                    sweCurrentBase++;
                    sweNumFlipsInQueue--;
#ifdef RWMETRICS
                    state_skyMetrics.flipPktTime = _sweReadTimer();
#endif /* RWMETRICS */
                    break;
                }
            case SWE_PKT_GOTO:
                {
                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweCurrentBase = (swe_pkt *)sweCurrentBase->addr;
                    break;
                }
            case SWE_PKT_RASUREF:
                {
                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    if (sweCurrentBase->type & SWE_PKT_IMM_MASK)
                    {
                        *(unsigned int *) (sweCurrentBase->addr)
                            -= (sweCurrentBase->type & SWE_PKT_IMM_MASK)
                                >> SWE_PKT_IMM_SHIFT;
                    }
                    else
                    {
                        *(unsigned int *) (sweCurrentBase->addr) -= 1;
                    }
                    sweCurrentBase++;
                    break;
                }
            case SWE_PKT_NULL:
                {
                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweCurrentBase++;
                    break;
                }
#ifdef GSB
            case SWE_PKT_WAIT_DRAWNEXT:
                {
#if 0
                    /* Ideally I'd like to do : */
                    if (skyNeedDrawNext)
                    {
                        gsbDrawNext(GSB_DRAWNEXT_WAIT);
                        gsbDrawDone(GSB_DRAWDONE_CLEAR);
                        skyNeedDrawNext = FALSE;
                    }

                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweCurrentBase++;
                    /* But I'm in an interput routine so I can't block */
#else
                    if (skyNeedDrawNext)
                    {
                        /* Note bug in gsbDrawNext() prevents us using the */
                        /* non-blocking version at present */
#if 0
                        if (gsbDrawNext(GSB_DRAWNETX_NOWAIT)==GSB_DRAWNETX_SET)
                        {
                            /* Continue directly */
                            gsbDrawDone(GSB_DRAWDONE_CLEAR);
                            sweDispatching = FALSE;
                            sweCurrentBase->type |= SWE_PKT_PROCESSED;
                            sweCurrentBase++;
                        }
                        else
#endif
                        {
                            /* Drop out of interrupt driven dispatch and ... */
                            sweDispatching = TRUE;
                        }
#endif
                    }
                    else
                    {
                        /* We don't need to do anything */
                        sweDispatching = FALSE;
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        break;
                    }
                    break;
                }
            case SWE_PKT_INC_TIME:
                {
                    skyDMAGCVTValue++;

                    sweDispatching = FALSE;
                    sweCurrentBase->type |= SWE_PKT_PROCESSED;
                    sweCurrentBase++;
                    break;
                }
#endif /* GSB */
            case SWE_PKT_CALL:
                {
                    /* If the callback needs to prevent continued execution
                       it must return FALSE, else it returns TRUE */
                    sweDispatching = !((sweDmaCallback)sweCurrentBase->addr)
                                                                       (TRUE);
                    if (!sweDispatching)
                    {
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                    }
                    break;
                }
            default:          /* ?? */
                break;
        }
    }
#ifdef GSB
    /* ... fix up if it was a draw next */
    if (sweCurrentBase != sweChainEnd)
    {
        if ((sweCurrentBase->type & SWE_PKT_TYPE_MASK) == 
            SWE_PKT_WAIT_DRAWNEXT)
        {
            sweDispatching = FALSE;
        }
    }
#endif /* GSB */
    PFEXIT(PFsweHandler);
    INTR_RESTORE_GP(oldgp);
    EXITHANDLER();
    return( (0) );
}

static void
sweFSAASwapCircuit(int sweFlipId)
{
    /* send the data to the GS... we want to do this *now* and hence
     * we use the Sony calls and not the swe equivalents.
     */

#if (defined(RWDMACHAN))
    sceDmaChan *d = sceDmaGetChan(2);
#endif /* (defined(RWDMACHAN)) */
    RWFUNCTION(RWSTRING("sweFSAASwapCircuit"));

    if (sweFlipId & 1)
    {
#if (defined(RWDMACHAN))
        /* scePrintf("2c Swap %x\n", (int)tcaaDisp.dmaDisp1); */
        sceDmaSend(d, tcaaDisp.dmaDisp2);
#endif /* (defined(RWDMACHAN)) */
        DPUT_GS_DISPLAY1( *(u_long *)&tcaaDisp.display11); /*DISPLAY1 */
        DPUT_GS_DISPFB1(*(u_long *)&tcaaDisp.dispfb11);  /*DISPFB1 */
    }
    else
    {
#if (defined(RWDMACHAN))
        /* scePrintf("2c Swap %x\n", (int)tcaaDisp.dmaDisp2); */
        sceDmaSend(d, tcaaDisp.dmaDisp1);
#endif /* (defined(RWDMACHAN)) */
        DPUT_GS_DISPLAY1( *(u_long *)&tcaaDisp.display10); /*DISPLAY1 */
        DPUT_GS_DISPFB1(*(u_long *)&tcaaDisp.dispfb10);  /*DISPFB1 */
    }

    RWRETURNVOID();
}

/***********************************************************************
 sweFSAADoBlit

 On Entry :
 On Exit  :

 Blit the back buffer to the front buffer.
 For the first 4 frames all we do is compute dma packets.
 */
static void
sweFSAA0DoBlit(void)
{
    RWALIGN(static u_long128 dmaData1[20], 64);
    RWALIGN(static u_long128 dmaData2[20], 64);
    RWALIGN(static u_long128 dmaData3[20], 64);
    RWALIGN(static u_long128 dmaData4[20], 64);
    u_long128 *dmaData = (u_long128 *)NULL;
    unsigned long tmp, tmp1;
    u_long128 ltmp;
    RwUInt32 count = 0;
    RwUInt32 offset, filter;
    RWFUNCTION(RWSTRING("sweFSAA0DoBlit"));

    if (skyFSAA0FrameCount < 4)
    {
        if (skyFSAA0FrameCount == 0)
        {
            dmaData = dmaData1;
        }
        else if (skyFSAA0FrameCount == 1)
        {
            dmaData = dmaData2;
        }
        else if (skyFSAA0FrameCount == 2)
        {
            dmaData = dmaData3;
        }
        else if (skyFSAA0FrameCount == 3)
        {
            dmaData = dmaData4;
        }

        offset = (skyFSAA0FrameCount & 1) ? 1 : 0;
        filter = (skyFSAA0FrameCount >= 2) ? 1 : 0;

        /* DMA header */
        tmp = (7l << 28) | (17); /* END DMAtag, 17 quadword after the dmatag */
        tmp1 = 0l;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* GIF path3 A+D mode */
        tmp = /* NLOOP */ 16l
            | /* EOP */ (1l << 15)
            | /* PRE */ (0l << 46)
            | /* FLG */ (0l << 58)
            | /* NREG */ (1l << 60);
        tmp1 = /* A+D */ (0xel << (64 - 64));
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* write front frame register */
        tmp = (sweDb.draw11.frame1.PSM << 24) |
              ((skyFSAA0VisibleWidth >> 6) << 16) | (0l << 0);
        tmp1 = GS_FRAME_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* write front offset register - no offsets to make coords easy */
        tmp = 0l;
        tmp1 = GS_XYOFFSET_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* write front scissor register - we want the whole screen*/
        tmp = 0l | (0x7fffl<<16) | (0l<<32) | (0x7fffl<<48);
        tmp1 = GS_SCISSOR_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* write front test register - no Z no alpha */
        tmp = (1l << 17) | (0l << 16) ; /* ztest off, all pixels pass */
        tmp1 = GS_TEST_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* zbuffer not updated */
        tmp = (1l << 32) | (sweDb.draw11.zbuf1.PSM << 24) |
              sweDb.draw11.zbuf1.ZBP;
        tmp1 = GS_ZBUF_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* because it's only a pretense that the texture map is 640x448
         * (and we've told the gs that it's 1024x1024) we need to turn on
         * region clamp to get the right result at the edges.
         */
        tmp = ((skyFSAA0RenderHeight-1l) << 34) | (0l << 24) |
			  ((skyFSAA0RenderWidth -1l) << 14) | (0l << 4) | (2l << 2) | 2l;
        tmp1 = GS_CLAMP_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* let's use a texture map... */
        tmp = (1l << 35) | (10l << 30) | (10l << 26) |
              (sweDb.draw11.frame1.PSM << 20) |
			  ((skyFSAA0RenderWidth >> 6) << 14) |
              ((sweDb.draw11.frame1.FBP << 11) >> 6);
        tmp1 = GS_TEX0_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* bilinear filtering */
        tmp = (filter << 6) | (filter << 5) | (0l << 2) | (1 << 0);
        tmp1 = GS_TEX1_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* now we want to draw a sprite */
        tmp = (1l << 8) | (1l << 4) | 6;
        tmp1 = GS_PRIM;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* First vertex, top left */
        tmp = ((0l+offset) << 20) | (0l << 4); /* texture */
        tmp1 = GS_UV;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* top left (0,0) */
        tmp = 0l;
        tmp1 = GS_XYZ2;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* bottom right  */
        tmp = ((skyFSAA0RenderHeight+offset) << 20) |
              (skyFSAA0RenderWidth << 4); /* texture */
        tmp1 = GS_UV;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        tmp = ((skyFSAA0RenderHeight>>1) << 20) |
              (skyFSAA0VisibleWidth << 4);
        tmp1 = GS_XYZ2;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        tmp = skyXyoffset_1;
        tmp1 = GS_XYOFFSET_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        /* finally put back the frame and zbuf registers */
        /* the front and back are the same, so we pick either one */
        tmp = *(long*)&sweDb.draw01.frame1;
        tmp1 = GS_FRAME_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        tmp = *(long*)&sweDb.draw01.zbuf1;
        tmp1 = GS_ZBUF_1;
        MAKE128(ltmp, tmp1, tmp);
        dmaData[count++] = ltmp;

        SyncDCache(dmaData, SCESYNCDCACHEROUNDUP(dmaData+count));

        skyFSAA0FrameCount++;
    }
    else
    {
        /* send the data to the GS... we want to do this *now* and hence
         * we use the Sony calls and not the swe equivalents.
         */
        sceDmaChan *d = sceDmaGetChan(2);

        offset = (DGET_GS_CSR() >> 13) & 0x1;

        sceDmaSend(d, offset ? dmaData4 : dmaData3);

        /*
         * If we were to turn off FSAA0 we you use the following call
         *
         *      sceDmaSend(d, offset ? dmaData2 : dmaData1);
         */
    }

    RWRETURNVOID();
}

/***********************************************************************
 sweVSNYCHandler

 On Entry : cause
 On Exit  : 0 to give the rest of the chain a look in

 If a flip is pending, do a flip and reset. This will have to be rev'd if
 we wish to support interlaced modes
 */
static int
sweVSYNCHandler(int ca)
{
    unsigned int oldgp;
#if (0)
    RWFUNCTION(RWSTRING("sweVSYNCHandler"));
#endif /* (0) */

    SKY_INTR_GET_GP(oldgp);

    PFENTRY(PFsweVSYNCHandler);
    /* If we are in an interlaced mode we need to do something like:
     * if ((DGET_GS_CSR() >> 13) & 0x1)
     * {
     * oddfield so just return 0
     * }
     * or if we could guarantee 60Hz performance here, we could do the
     * add half offset on even trick, but this might impact our transform
     * too.
     */

#ifdef RWMETRICS
    state_skyMetrics.lastFrameVSyncCount++;
    state_skyMetrics.frameVSyncsOverPeriod[state_skyMetrics.curFrame
                                     >> rwSKYMETRICSFRAMESPERSAMPLE]++;
#endif /* RWMETRICS */

#ifdef VISTIME
    sweFrameRenderCount2++;
#endif /* VISTIME */

    if ((ca == INTC_VBON) && (sweFlipPending || sweAutoFlip))
    {
#ifdef WATCHDOG
        sweWatchDog = 0;
#endif /* WATCHDOG */
#ifdef VISTIME
#ifdef DRIVETIME
        int                 i;

        /* Time in 1/10 ms for 100MHz busclk */
#ifndef TIMERHIREZ
        sweFrameRenderCount = (long)((float)sweFrameRenderCount/(921.6f));
#else /* !TIMERHIREZ */
        sweFrameRenderCount = (long)((float)sweFrameRenderCount/(14745.6f));
#endif /* !TIMERHIREZ */
        for (i = 0; i < 10; i++)
        {
            sweInlineDmaSync(dmaChanGIF);

            switch (i + (sweCurrentHalfOffset << 6))
            {
                case 0:
                    sweInlineDmaSendN(dmaChanGIF, pos9,
                                      sizeof(pos9) >> 4);
                    break;
                case 1:
                    sweInlineDmaSendN(dmaChanGIF, pos8,
                                      sizeof(pos8) >> 4);
                    break;
                case 2:
                    sweInlineDmaSendN(dmaChanGIF, pos7,
                                      sizeof(pos7) >> 4);
                    break;
                case 3:
                    sweInlineDmaSendN(dmaChanGIF, pos6,
                                      sizeof(pos6) >> 4);
                    break;
                case 4:
                    sweInlineDmaSendN(dmaChanGIF, pos5,
                                      sizeof(pos5) >> 4);
                    break;
                case 5:
                    sweInlineDmaSendN(dmaChanGIF, pos4,
                                      sizeof(pos4) >> 4);
                    break;
                case 6:
                    sweInlineDmaSendN(dmaChanGIF, pos3,
                                      sizeof(pos3) >> 4);
                    break;
                case 7:
                    sweInlineDmaSendN(dmaChanGIF, pos2,
                                      sizeof(pos2) >> 4);
                    break;
                case 8:
                    sweInlineDmaSendN(dmaChanGIF, pos1,
                                      sizeof(pos1) >> 4);
                    break;
                case 9:
                    sweInlineDmaSendN(dmaChanGIF, pos0,
                                      sizeof(pos0) >> 4);
                    break;
                case 64:
                    sweInlineDmaSendN(dmaChanGIF, pos9h,
                                      sizeof(pos9h) >> 4);
                    break;
                case 65:
                    sweInlineDmaSendN(dmaChanGIF, pos8h,
                                      sizeof(pos8h) >> 4);
                    break;
                case 66:
                    sweInlineDmaSendN(dmaChanGIF, pos7h,
                                      sizeof(pos7h) >> 4);
                    break;
                case 67:
                    sweInlineDmaSendN(dmaChanGIF, pos6h,
                                      sizeof(pos6h) >> 4);
                    break;
                case 68:
                    sweInlineDmaSendN(dmaChanGIF, pos5h,
                                      sizeof(pos5h) >> 4);
                    break;
                case 69:
                    sweInlineDmaSendN(dmaChanGIF, pos4h,
                                      sizeof(pos4h) >> 4);
                    break;
                case 70:
                    sweInlineDmaSendN(dmaChanGIF, pos3h,
                                      sizeof(pos3h) >> 4);
                    break;
                case 71:
                    sweInlineDmaSendN(dmaChanGIF, pos2h,
                                      sizeof(pos2h) >> 4);
                    break;
                case 72:
                    sweInlineDmaSendN(dmaChanGIF, pos1h,
                                      sizeof(pos1h) >> 4);
                    break;
                case 73:
                    sweInlineDmaSendN(dmaChanGIF, pos0h,
                                      sizeof(pos0h) >> 4);
                    break;
                default:
                    sweInlineDmaSendN(dmaChanGIF, posl,
                                      sizeof(posl) >> 4);
                    break;
            }
            sweInlineDmaSync(dmaChanGIF);
            sweInlineDmaSendN(dmaChanGIF, digitBack,
                              sizeof(digitBack) >> 4);
            sweInlineDmaSync(dmaChanGIF);
            if ((sweFrameRenderCount) || (i < 3))
            {
                switch (i == 1 ? 11 : sweFrameRenderCount % 10)
                {
                    case 0:
                        sweInlineDmaSendN(dmaChanGIF, digitZero,
                                          sizeof(digitZero) >> 4);
                        break;
                    case 1:
                        sweInlineDmaSendN(dmaChanGIF, digitOne,
                                          sizeof(digitOne) >> 4);
                        break;
                    case 2:
                        sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                          sizeof(digitTwo) >> 4);
                        break;
                    case 3:
                        sweInlineDmaSendN(dmaChanGIF, digitThree,
                                          sizeof(digitThree) >> 4);
                        break;
                    case 4:
                        sweInlineDmaSendN(dmaChanGIF, digitFour,
                                          sizeof(digitFour) >> 4);
                        break;
                    case 5:
                        sweInlineDmaSendN(dmaChanGIF, digitFive,
                                          sizeof(digitFive) >> 4);
                        break;
                    case 6:
                        sweInlineDmaSendN(dmaChanGIF, digitSix,
                                          sizeof(digitSix) >> 4);
                        break;
                    case 7:
                        sweInlineDmaSendN(dmaChanGIF, digitSeven,
                                          sizeof(digitSeven) >> 4);
                        break;
                    case 8:
                        sweInlineDmaSendN(dmaChanGIF, digitEight,
                                          sizeof(digitEight) >> 4);
                        break;
                    case 9:
                        sweInlineDmaSendN(dmaChanGIF, digitNine,
                                          sizeof(digitNine) >> 4);
                        break;
                    case 11:
                        sweInlineDmaSendN(dmaChanGIF, digitPoint,
                                          sizeof(digitPoint) >> 4);
                        break;
                    default:
                        sweInlineDmaSendN(dmaChanGIF, digitElle,
                                          sizeof(digitElle) >> 4);
                        break;
                }
            }
            sweInlineDmaSync(dmaChanGIF);
            if (i != 1)
            {
                sweFrameRenderCount /= 10;
            }
        }
#endif /* DRIVETIME */
        {
            sweInlineDmaSync(dmaChanGIF);
            if (sweCurrentHalfOffset)
            {
                sweInlineDmaSendN(dmaChanGIF, pos0h,
                                  sizeof(pos0h) >> 4);
            }
            else
            {
                sweInlineDmaSendN(dmaChanGIF, pos0, sizeof(pos0) >> 4);
            }
            sweInlineDmaSync(dmaChanGIF);
            sweInlineDmaSendN(dmaChanGIF, digitBack,
                              sizeof(digitBack) >> 4);
            sweInlineDmaSync(dmaChanGIF);
            switch (sweFrameRenderCount2)
            {
                case 0:
                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                      sizeof(digitZero) >> 4);
                    break;
                case 1:
                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                      sizeof(digitOne) >> 4);
                    break;
                case 2:
                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                      sizeof(digitTwo) >> 4);
                    break;
                case 3:
                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                      sizeof(digitThree) >> 4);
                    break;
                case 4:
                    sweInlineDmaSendN(dmaChanGIF, digitFour,
                                      sizeof(digitFour) >> 4);
                    break;
                case 5:
                    sweInlineDmaSendN(dmaChanGIF, digitFive,
                                      sizeof(digitFive) >> 4);
                    break;
                case 6:
                    sweInlineDmaSendN(dmaChanGIF, digitSix,
                                      sizeof(digitSix) >> 4);
                    break;
                case 7:
                    sweInlineDmaSendN(dmaChanGIF, digitSeven,
                                      sizeof(digitSeven) >> 4);
                    break;
                case 8:
                    sweInlineDmaSendN(dmaChanGIF, digitEight,
                                      sizeof(digitEight) >> 4);
                    break;
                case 9:
                    sweInlineDmaSendN(dmaChanGIF, digitNine,
                                      sizeof(digitNine) >> 4);
                    break;
                default:
                    sweInlineDmaSendN(dmaChanGIF, digitElle,
                                      sizeof(digitElle) >> 4);
                    break;
            }
            sweInlineDmaSync(dmaChanGIF);
        }
#ifdef GSB
        /* Display unit number */
        {
            sweInlineDmaSync(dmaChanGIF);
            switch (skyRenderSlot)
            {
                case 0:
                    sweInlineDmaSendN(dmaChanGIF, posB, sizeof(posB) >> 4);
                    break;
                case 1:
                    sweInlineDmaSendN(dmaChanGIF, posC, sizeof(posC) >> 4);
                    break;
                case 2:
                    sweInlineDmaSendN(dmaChanGIF, posD, sizeof(posD) >> 4);
                    break;
                case 3:
                    sweInlineDmaSendN(dmaChanGIF, posE, sizeof(posE) >> 4);
                    break;
            }
            sweInlineDmaSync(dmaChanGIF);
            sweInlineDmaSendN(dmaChanGIF, digitBack,
                              sizeof(digitBack) >> 4);
            sweInlineDmaSync(dmaChanGIF);
            switch (skyRenderSlot)
            {
                case 0:
                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                      sizeof(digitZero) >> 4);
                    break;
                case 1:
                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                      sizeof(digitOne) >> 4);
                    break;
                case 2:
                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                      sizeof(digitTwo) >> 4);
                    break;
                case 3:
                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                      sizeof(digitThree) >> 4);
                    break;
            }
            sweInlineDmaSync(dmaChanGIF);
        }
#endif /* GSB */
#endif /* VISTIME */

#ifdef RWMETRICS
        state_skyMetrics.flipPktToFlipTime = _sweReadTimer() - state_skyMetrics.flipPktTime;
#endif /* RWMETRICS */

        /* This is a bit messy, but no one should see the effects outside */
        /* as VISTIME isn't a public options */
        if ((sweUseHalfOffset) && (!sweAutoFlip))
        {
            /* The current frame is about to end */
            /* This seems to be the only way to check which field is displayed */
            if ((DGET_GS_CSR() >> 13) & 0x1)
            {
                sweCurrentHalfOffset = 0;
                /* Currently Displayed Odd, so write for odd */
                if (sweFlipId)
                {
                    PFCALL(PFsweVSYNCHandler);
#if defined(GSB) && defined(GSPLUS)
                    sceGsPlusSetHalfOffset(&((sceGsPlusDBuffDc *)
                                             sweFlipSt)->draw11, 2048, 2048, 0);
                    sceGsPlusSetHalfOffset2(&((sceGsPlusDBuffDc *)
                                              sweFlipSt)->draw12,2048, 2048, 0);
#else /* defined(GSB) && defined(GSPLUS) */
                    sceGsSetHalfOffset(&((sceGsDBuffDc *)sweFlipSt)->draw11,
                                       2048, 2048, 0);
                    sceGsSetHalfOffset2(&((sceGsDBuffDc *)sweFlipSt)->draw12,
                                        2048, 2048, 0);
#endif /* defined(GSB) && defined(GSPLUS) */
                    PFRET(PFsweVSYNCHandler);
                }
                else
                {
                    PFCALL(PFsweVSYNCHandler);
#if defined(GSB) && defined(GSPLUS)
                    sceGsPlusSetHalfOffset(&((sceGsPlusDBuffDc *)
                                             sweFlipSt)->draw01, 2048, 2048, 0);
                    sceGsPlusSetHalfOffset2(&((sceGsPlusDBuffDc *)
                                              sweFlipSt)->draw02, 2048, 2048,0);
#else /* defined(GSB) && defined(GSPLUS) */
                    sceGsSetHalfOffset(&((sceGsDBuffDc *)sweFlipSt)->draw01,
                                       2048, 2048, 0);
                    sceGsSetHalfOffset2(&((sceGsDBuffDc *)sweFlipSt)->draw02,
                                        2048, 2048, 0);
#endif /* defined(GSB) && defined(GSPLUS) */
                    PFRET(PFsweVSYNCHandler);
                }
            }
            else
            {
                sweCurrentHalfOffset = 1;
                /* Currently Displayed Even, so write for even */
                if (sweFlipId)
                {
                    PFCALL(PFsweVSYNCHandler);
#if defined(GSB) && defined(GSPLUS)
                    sceGsPlusSetHalfOffset(&((sceGsPlusDBuffDc *)
                                             sweFlipSt)->draw11, 2048, 2048, 1);
                    sceGsPlusSetHalfOffset2(&((sceGsPlusDBuffDc *)
                                              sweFlipSt)->draw12, 2048, 2048,1);
#else /* defined(GSB) && defined(GSPLUS) */
                    sceGsSetHalfOffset(&((sceGsDBuffDc *)sweFlipSt)->draw11,
                                       2048, 2048, 1);
                    sceGsSetHalfOffset2(&((sceGsDBuffDc *)sweFlipSt)->draw12,
                                        2048, 2048, 1);
#endif /* defined(GSB) && defined(GSPLUS) */
                    PFRET(PFsweVSYNCHandler);
                }
                else
                {
                    PFCALL(PFsweVSYNCHandler);
#if defined(GSB) && defined(GSPLUS)
                    sceGsPlusSetHalfOffset(&((sceGsPlusDBuffDc *)
                                             sweFlipSt)->draw01, 2048, 2048, 1);
                    sceGsPlusSetHalfOffset2(&((sceGsPlusDBuffDc *)
                                              sweFlipSt)->draw02, 2048, 2048,1);
#else /* defined(GSB) && defined(GSPLUS) */
                    sceGsSetHalfOffset(&((sceGsDBuffDc *)sweFlipSt)->draw01,
                                       2048, 2048, 1);
                    sceGsSetHalfOffset2(&((sceGsDBuffDc *)sweFlipSt)->draw02,
                                        2048, 2048, 1);
#endif /* defined(GSB) && defined(GSPLUS) */
                    PFRET(PFsweVSYNCHandler);
                }
            }
            /* Force the update to complete */
/* *INDENT-OFF* */
            __asm volatile ("sync.l");
/* *INDENT-ON* */
        }

        PFCALL(PFsweVSYNCHandler);
#if defined(GSB) && defined(GSPLUS)
        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */

        /* if we render to a large off-screen buffer and sample down,
         * then we never want to flip.  Instead we do a blit.
         */
        if (skyVideoMode->flags & rwVIDEOMODEFSAA0)
        {
            sweFSAA0DoBlit();
        }

        /* we have set up front and back to be the same in the FSAA0
         * mode, so we can flip with no effect, except to reprogram
         * the draw and display registers.
         */

        /* if FSAA1
         * Sony kindly fail to provide support the 1st read circuit,
         * so we send our own DMA packet
         */
        if (skyVideoMode->flags & rwVIDEOMODEFSAA1)
        {
            ((sceGsDBuffDc *)sweFlipSt)->disp[0].pmode.EN1=1;
            ((sceGsDBuffDc *)sweFlipSt)->disp[0].pmode.EN1=1;

            /*
             * If we were to turn off FSAA1 we would
             * use the following code.
             *
             *      ((sceGsDBuffDc *)sweFlipSt)->disp[0].pmode.EN1=0;
             *      ((sceGsDBuffDc *)sweFlipSt)->disp[0].pmode.EN1=0;
             */

	        sweFSAASwapCircuit(sweFlipId);
        }
        
        /* endif FSAA1 */

        /*
         * libgraph.h:int sceGsSwapDBuffDc(sceGsDBuffDc *db, int id);
         */

        sceGsSwapDBuffDc( (sceGsDBuffDc *) sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
        PFRET(PFsweVSYNCHandler);
#ifdef GSB
        /* If we are using real VSYNC based swaps we can: */
        /* A real/fake VSync has occured */
        skyDMAGCVTValue++;
        /* Inform merge unit */
        if (!skyGsmSysReadyRequired)
        {
            gsbDrawDone(GSB_DRAWDONE_SET);
            skyNeedDrawNext = TRUE;
        }
        /* but in practise it is more efficient not to do it this way */
#endif /* GSB */

        /* Swap required frame in case in auto flip mode */
        sweFlipId ^= 1;
        sweFlipPending = 0;
#ifdef RWMETRICS
        state_skyMetrics.vSyncsSinceLastFlip = state_skyMetrics.lastFrameVSyncCount;
        state_skyMetrics.lastFrameVSyncCount = 0;
#endif /* RWMETRICS */

#ifdef VISTIME
        sweFrameRenderCount = 0;
        sweFrameRenderCount2 = 0;
#endif /* VISTIME */

        /* Auto flip must flip an even number of frames, so we count in bit 0 */
        /* Really this should all be rolled into the FlipPending var */
        if (sweAutoFlip)
        {
            sweAutoFlip ^= 1;
            if (sweAutoFlip == 6)
            {
                /* We've autoflipped an even number of frames so turn off */
                sweAutoFlip = 0;
            }
            else
            {
                sweFlipPending = 1;
            }
        }

        /* Update the front and back buffer fake rasters */
        _rpSkyFrameBufferRastersUpdate();

        /* We attempt to kick off another dma pkt if there is one */
        if ((sweCurrentBase != sweChainEnd) && !(sweAutoFlip))
        {
            /* This works because of the dispatching and flip pending vars */
            sweHandler(0);
        }

    }
#ifdef WATCHDOG
    else
    {
        sweWatchDog++;
    }
#endif /* WATCHDOG */
    PFEXIT(PFsweVSYNCHandler);
    INTR_RESTORE_GP(oldgp);
#ifdef EIEXIT
    ExitHandler();
#endif /* EIEXIT */

    return( (0) );
}

#ifdef TIMER

/***********************************************************************
 sweTim1Handler

 On Entry : cause
 On Exit  : 0 to give the rest of the chain a look in

 Inc the timer high bits
 */
static int
sweTim1Handler(int ca)
{
    unsigned int oldgp;
#if (0)
    RWFUNCTION(RWSTRING("sweTim1Handler"));
#endif /* (0) */

    SKY_INTR_GET_GP(oldgp);

    PFENTRY(PFsweTim1Handler);
    if ((ca == INTC_TIM1) && (*T1_MODE & 0x800))
    {
        *T1_MODE |= 0x800;
#ifndef PROFILE
        sweHighCount += 0x10000;
        /* ensure the store retires */
/* *INDENT-OFF* */
        __asm volatile ( "sync.l");
/* *INDENT-ON* */
#else /* !PROFILE */
        {
            unsigned long       savevi;
            unsigned long       tmp;
            unsigned long       savevf;
            unsigned long       tmp1;
/* *INDENT-OFF* */
            __asm volatile ("
            cfc2        %0, $vi1
            addiu       %1, $0, 0xff
            ctc2        %1, $vi1
            qmfc2       %2, $vf1
            vlqi.xy     $vf1, ($vi1++)
            qmfc2       %1, $vf1
            li          %3, 0x10000
            daddu       %1, %1, %3
            qmtc2       %1, $vf1
            vsqd.xy     $vf1, (--$vi1)
            qmtc2       %2, $vf1
            ctc2        %0, $vi1"
            : "=r" (savevi),
              "=r" (tmp),
              "=r" (savevf),
              "=r" (tmp1));
/* *INDENT-ON* */
        }
#endif /* !PROFILE */

#ifdef RWMETRICS
        {
            /* We get unit profiles here */
            RwUInt32            vpustat = 0;
            RwUInt32            ch1stat;
            RwUInt32            ch2stat;
            RwUInt32            vifstat;
            RwUInt32            gifstat;
            RwUInt32            sample = (state_skyMetrics.curFrame >>
                                          rwSKYMETRICSFRAMESPERSAMPLE);
/* *INDENT-OFF* */
            asm volatile (" cfc2 %0, $29 " : "=r" (vpustat));
/* *INDENT-ON* */
            ch1stat = DGET_D1_CHCR();
            ch2stat = DGET_D2_CHCR();
            vifstat = DGET_VIF1_STAT();
            gifstat = DGET_GIF_STAT();
            state_skyMetrics.frameProfTotal[sample]++;
            if (vpustat & 0x100)
            {
                state_skyMetrics.frameVu1Running[sample]++;
            }
            if (ch1stat & D_CHCR_STR_M)
            {
                state_skyMetrics.frameDma1Running[sample]++;
            }
            if (ch2stat & D_CHCR_STR_M)
            {
                state_skyMetrics.frameDma2Running[sample]++;
            }
            /* Internal1 is the time over which dma1 is stalled and no PATH1
               or 3 transfer is taking place. This is effectively the time
               available for async texture transfers to take place */
            /* GIF_STAT_APATH_M define is broken */
            if ((vifstat & VIF1_STAT_VEW_M) && !(gifstat & (0x03<<10)))
            {
                state_skyMetrics.frameinternal1[sample]++;
            }
        }
#endif /* RWMETRICS */

#ifdef PG
        /* We coerce the exception address to be between 1 & 6 MB and inc uc */
        {
            int                 lastUnits;

            {
                /* We get unit profiles here */
                unsigned int        vpustat;
                unsigned int        vifstat;
                unsigned int        ch1stat;
                unsigned int        ch2stat;

/* *INDENT-OFF* */
                asm volatile (" cfc2 %0, $29 " : "=r" (vpustat));
/* *INDENT-ON* */

                vifstat = DGET_VIF1_STAT();
                ch1stat = DGET_D1_CHCR();
                ch2stat = DGET_D2_CHCR();
                sweUnitProfTotal++;
                sweUnitProf[
                            (lastUnits =
                             (((vpustat & 0x100) ? PG_VURUNNING : 0)
                              +
                              ((ch1stat & D_CHCR_STR_M) ? PG_DMACH1
                               : 0) +
                              ((ch2stat & D_CHCR_STR_M) ? PG_DMACH2
                               : 0) +
                              ((vpustat & 0x1000) ? PG_GW : 0) +
                              ((vifstat & VIF1_STAT_VGW_M) ? PG_VGW
                               : 0)))]++;

            }
            /* Use the if below to select types of samples */
            /* if (lastUnits == 0) */
            {
#ifndef PGA
                RwUInt32            epc;
                RwUInt32            hits;

                /* epc = iGetCop0(14); */
/* *INDENT-OFF* */
                /* asm volatile ( "mfc0 %0, $14" : "=r" (epc)); */
/* *INDENT-ON* */
                epc = *(RwUInt32 *) (0x20100000 - 4);
                if (epc >= (1024 * 1024 * 5))
                {
                    epc = (5 * 1024 * 1024 - 4);
                    sweProfORH++;
                }
                if (epc < (1 * 1024 * 1024))
                {
                    epc = (1 * 1024 * 1024);
                    sweProfORL++;
                }
                epc = (epc + (0x20000000 - 0x100000)) >> 2;

                hits = sweProfileHits[epc];
                hits++;
                sweProfileHits[epc] = hits;
#else /* !PGA */
                /* Simulate the kernel profil functionality, but with saturate */
                if (swePHbuf)
                {
                    RwUInt32            epc;
                    RwUInt32            hits;

                    epc = *(RwUInt32 *) (0x20100000 - 4);
                    if (epc < swePHoffset)
                    {
                        epc = swePHoffset;
                        sweProfORL++;
                    }
                    epc = (epc - swePHoffset);
                    if ((((long) epc * (long) swePHscale) >> 16) >=
                        swePHbufsize)
                    {
                        sweProfORH++;
                    }
                    else
                    {
                        hits =
                            *(unsigned short *) (swePHbuf +
                                                 (((long)
                                                   epc *
                                                   (long)
                                                   swePHscale) >> 16));
                        hits++;
                        if (hits < 0x10000)
                            *(unsigned short *) (swePHbuf +
                                                 (((long)
                                                   epc *
                                                   (long)
                                                   swePHscale) >>
                                                  16)) = hits;
                    }
                }
#endif /* !PGA */
            }
        }
#endif /* PG */
    }
    PFEXIT(PFsweTim1Handler);
    INTR_RESTORE_GP(oldgp);
#ifdef EIEXIT
    ExitHandler();
#endif /* EIEXIT */
    return( (0) );
}
#endif /* TIMER */

#ifdef RWMETRICS

void
_sweMetricsReset(void)
{
    RWFUNCTION(RWSTRING("_sweMetricsReset"));

    DI();
    /* We want a decent sample period, so use sliding window over several frames */
    state_skyMetrics.curFrame++;
    state_skyMetrics.curFrame %=
        (rwSKYMETRICSSAMPLES << rwSKYMETRICSFRAMESPERSAMPLE);

    if (
        (state_skyMetrics.curFrame & ((1 << rwSKYMETRICSFRAMESPERSAMPLE) - 1))
        == 0)
    {
        RwUInt32            sample = (state_skyMetrics.curFrame >>
                                      rwSKYMETRICSFRAMESPERSAMPLE);
        int i;

        state_skyMetrics.profTotal = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
            state_skyMetrics.profTotal += state_skyMetrics.frameProfTotal[sample];
        state_skyMetrics.frameProfTotal[sample] = 0;

        state_skyMetrics.vu1Running = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
            state_skyMetrics.vu1Running += state_skyMetrics.frameVu1Running[sample];
        state_skyMetrics.frameVu1Running[sample] = 0;

        state_skyMetrics.dma1Running = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
            state_skyMetrics.dma1Running += state_skyMetrics.frameDma1Running[sample];
        state_skyMetrics.frameDma1Running[sample] = 0;

        state_skyMetrics.dma2Running = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
            state_skyMetrics.dma2Running += state_skyMetrics.frameDma2Running[sample];
        state_skyMetrics.frameDma2Running[sample] = 0;

        state_skyMetrics.internal1 = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
            state_skyMetrics.internal1 += state_skyMetrics.frameinternal1[sample];
        state_skyMetrics.frameinternal1[sample] = 0;

        state_skyMetrics.totalVSyncsOverPeriod = 0;
        for (i=0; i<rwSKYMETRICSSAMPLES; i++)
        {
            state_skyMetrics.totalVSyncsOverPeriod
                               += state_skyMetrics.frameVSyncsOverPeriod[sample];
        }
        state_skyMetrics.frameVSyncsOverPeriod[sample] = 0;
    }
    EI();

    RWRETURNVOID();
}

RwSkyMetrics       *
_sweMetricsGet(void)
{
    RwUInt32            i;
    RWFUNCTION(RWSTRING("_sweMetricsGet"));

    state_skyMetrics.profTotal = 0;
    state_skyMetrics.vu1Running = 0;
    state_skyMetrics.dma1Running = 0;
    state_skyMetrics.dma2Running = 0;
    state_skyMetrics.internal1 = 0;
    state_skyMetrics.vSyncsSinceLastFlip = 0;
    state_skyMetrics.lastFrameVSyncCount = 0;
    state_skyMetrics.totalVSyncsOverPeriod = 0;

    for (i = 0; i < rwSKYMETRICSSAMPLES; i++)
    {
        state_skyMetrics.frameProfTotal[i] = 0;
        state_skyMetrics.frameVu1Running[i] = 0;
        state_skyMetrics.frameDma1Running[i] = 0;
        state_skyMetrics.frameDma2Running[i] = 0;
        state_skyMetrics.frameinternal1[i] = 0;
        state_skyMetrics.frameVSyncsOverPeriod[i] = 0;
    }

    RWRETURN(&state_skyMetrics);
}

#endif /* RWMETRICS */

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                                 API

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/***********************************************************************
 _sweHook()

 On Entry:
 On Exit : success/failure

 Hook all required interrupts and attach interrupt handlers. Set up
 timer if required.
 */
RwBool
_sweHook()
{
    RWFUNCTION(RWSTRING("_sweHook"));

    /* Hook the DMA interupt */
#ifndef SYNC
#if 0
    if ((sweHandlerVIF0Hid =
         AddDmacHandler(DMAC_VIF0, sweHandler, 0)) == -1)
    {
        PFCALL(PF_sweOpen);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#endif

    if ((sweHandlerVIF1Hid =
         AddDmacHandler(DMAC_VIF1, sweHandler, 0)) == -1)
    {
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
    if ((sweHandlerGIFHid = AddDmacHandler(DMAC_GIF, sweHandler, 0))
        == -1)
    {
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#if 0
    if ((sweOwnVIF0 = EnableDmac(DMAC_VIF0)) == -1)
    {
        PFCALL(PF_sweOpen);
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#endif
    if ((sweOwnVIF1 = EnableDmac(DMAC_VIF1)) == -1)
    {
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
    if ((sweOwnGIF = EnableDmac(DMAC_GIF)) == -1)
    {
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#endif /* !SYNC */

#ifndef TEAR
    if ((sweVSYNCHandlerHid =
         AddIntcHandler(INTC_VBON, sweVSYNCHandler, 0)) == -1)
    {
#ifndef SYNC
        if (sweOwnGIF)
        {
            sweOwnGIF = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_GIF);
            PFRET(PF_sweOpen);
        }
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
#endif /* !SYNC */
        PFCALL(PF_sweOpen);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }

    if ((sweOwnVBON = EnableIntc(INTC_VBON)) == -1)
    {
        sweOwnVBON = 0;
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_VBON, sweVSYNCHandlerHid);
        sweVSYNCHandlerHid = -1;
        PFRET(PF_sweOpen);
#ifndef SYNC
        if (sweOwnGIF)
        {
            sweOwnGIF = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_GIF);
            PFRET(PF_sweOpen);
        }
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
#endif /* !SYNC */
        PFCALL(PF_sweOpen);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#endif /* !TEAR */

#ifdef TIMER
    if (
        (sweTim1HandlerHid =
         AddIntcHandler(INTC_TIM1, sweTim1Handler, 0)) == -1)
    {
#ifndef TEAR
        if (sweOwnVBON)
        {
            PFCALL(PF_sweOpen);
            DisableIntc(INTC_VBON);
            PFRET(PF_sweOpen);
        }
        sweOwnVBON = 0;
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_VBON, sweVSYNCHandlerHid);
        sweVSYNCHandlerHid = -1;
        PFRET(PF_sweOpen);
#endif /* !TEAR */
#ifndef SYNC
        if (sweOwnGIF)
        {
            sweOwnGIF = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_GIF);
            PFRET(PF_sweOpen);
        }
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
#endif /* !SYNC */
        PFCALL(PF_sweOpen);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
    /* Set up time1 */
#ifndef PROFILE
    sweHighCount = 0;
#else /* !PROFILE */
    {
        unsigned long       savevi;
        unsigned long       savevf; /* lie */
/* *INDENT-OFF* */
        __asm volatile ("
        cfc2        %0, $vi1
        ctc2        %2, $vi1
        qmfc2       %1, $vf1
        vsub.xy     $vf1, $vf1, $vf1
        vsqi.xy     $vf1, ($vi1++)
        qmtc2       %1, $vf1
        ctc2        %0, $vi1"
                        : "=r&" (savevi),
                        "=r" (savevf)
                        : "r" (255));
/* *INDENT-ON* */
    }
#endif /* !PROFILE */
    *T1_COUNT = 0;
    *T1_COMP = 0x8000;
    *T1_HOLD = 0;
#ifndef TIMERHIREZ
    *T1_MODE = 0xc81;
    *T1_MODE = 0x281;
#else /* TIMERHIREZ */
    *T1_MODE = 0xc80;
    *T1_MODE = 0x280;
#endif /* TIMERHIREZ */

    if ((sweOwnTIM1 = EnableIntc(INTC_TIM1)) == -1)
    {
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_TIM1, sweTim1HandlerHid);
        sweTim1HandlerHid = -1;
        PFRET(PF_sweOpen);
#ifndef TEAR
        if (sweOwnVBON)
        {
            PFCALL(PF_sweOpen);
            DisableIntc(INTC_VBON);
            PFRET(PF_sweOpen);
        }
        sweOwnVBON = 0;
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_VBON, sweVSYNCHandlerHid);
        sweVSYNCHandlerHid = -1;
        PFRET(PF_sweOpen);
#endif /* !TEAR */
#ifndef SYNC
        if (sweOwnGIF)
        {
            sweOwnGIF = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_GIF);
            PFRET(PF_sweOpen);
        }
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
#endif /* !SYNC */
        PFCALL(PF_sweOpen);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
#endif /* TIMER */

    {
        sceDmaEnv           env;

        /* whisper to me about emotional state */
        sceDmaGetEnv(&env);
        TRACEPRINTF(("%s(%d):%s - DMA rcycle was %d\n",
                     __FILE__, __LINE__, __FUNCTION__,
                     ((int) env.rcycle) - 1));
        env.rcycle = 2;
        TRACEPRINTF(("%s(%d):%s - DMA rcycle was %d\n",
                     __FILE__, __LINE__, __FUNCTION__,
                     ((int) env.rcycle) - 1));
        sceDmaPutEnv(&env);
    }

    RWRETURN(TRUE);
}
/***********************************************************************
 _sweOpen

 On Entry : none
 On Exit  : success/failure
 */
RwBool
_sweOpen(void)
{
    RWFUNCTION(RWSTRING("_sweOpen"));
    PFENTRY(PF_sweOpen);

    SKY_INITIALIZE_SAVED_GP();

    /* Start with memory allocation */
    PFCALL(PF_sweOpen);
    circAllocator = circularAllocOpen(sweCircAllocBlockSize);
    PFRET(PF_sweOpen);
    if (!circAllocator)
    {
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }

#ifdef SWEASYNC
    sweAsyncInProgress = FALSE;
#endif /* SWEASYNC */

    /* We replace FreeLists only if a limit has been set. If not, we continue
       to call the FreeList functions, even if they are a malloc wrapper */
    sweNoFreeLists = FALSE;
    if ((RWSRCGLOBAL(memoryAlloc) != _rwFreeListAllocReal)
        && (swePreAllocLimit))
    {
        sweNoFreeLists = TRUE;
    }

    if (!sweNoFreeLists)
    {
        PFCALL(PF_sweOpen);
        state_chainBlockFreeList =
            RwFreeListCreate(SWE_CHAIN_BLOCK * sizeof(swe_pkt), 10, 0);
        PFRET(PF_sweOpen);
        if (!state_chainBlockFreeList)
        {
            PFCALL(PF_sweOpen);
            circularAllocClose(circAllocator);
            PFRET(PF_sweOpen);
            PFEXIT(PF_sweOpen);
            RWRETURN(FALSE);
        }
    
        if (!(sweChainBase =
              (swe_pkt *) RwFreeListAlloc(state_chainBlockFreeList)))
        {
            PFCALL(PF_sweOpen);
            RwFreeListDestroy(state_chainBlockFreeList);
            circularAllocClose(circAllocator);
            PFRET(PF_sweOpen);
            PFEXIT(PF_sweOpen);
            RWRETURN(FALSE);
        }
    }
    else
    {
        /* This is being used as a memory system up indicator */
        state_chainBlockFreeList = (RwFreeList*)-1;
        sweChainBase = (swe_pkt *)RwMalloc(SWE_CHAIN_BLOCK * sizeof(swe_pkt)
                                           * swePreAllocCount);
        if (!sweChainBase)
        {
            PFCALL(PF_sweOpen);
            circularAllocClose(circAllocator);
            PFRET(PF_sweOpen);
            PFEXIT(PF_sweOpen);
            RWRETURN(FALSE);
        }
        sweHighWaterMark = (swe_pkt *)((RwInt8*)sweChainBase
                                       + SWE_CHAIN_BLOCK * sizeof(swe_pkt)
                                         * swePreAllocCount
                                       - sizeof(swe_pkt));
    }
    sweCurrentBlockBase = sweChainBase;
    sweCurrentBase = sweChainBase;
    sweChainEnd = sweChainBase;
    sweGarbageStart = sweChainBase;

    /* Grab pointers to all the DMA channel registers we need */
    PFCALL(PF_sweOpen);
    dmaChanFromSPR = sceDmaGetChan(SCE_DMA_fromSPR);
    dmaChanGIF = sceDmaGetChan(SCE_DMA_GIF);
    dmaChanVIF0 = sceDmaGetChan(SCE_DMA_VIF0);
    dmaChanVIF1 = sceDmaGetChan(SCE_DMA_VIF1);
    PFRET(PF_sweOpen);

    if (!_sweHook())
    {
        if (!sweNoFreeLists)
        {
            RwFreeListFree(state_chainBlockFreeList, sweChainBase);
            RwFreeListDestroy(state_chainBlockFreeList);
        }
        else
        {
            RwFree(sweCurrentBlockBase);
        }
        state_chainBlockFreeList = (RwFreeList *) NULL;
        circularAllocClose(circAllocator);
        RWRETURN(FALSE);
    }

    sweVU0pkt = (swe_pkt *)NULL;
    sweVU1pkt = (swe_pkt *)NULL;
    sweGIFpkt = (swe_pkt *)NULL;
    sweLocalPacketState = SWE_LPS_NONE;
    sweLocalPacketSize = 0;
    sweRealLocalPacketBase = (u_long128 *)NULL;
    sweLocalPacketBase = (u_long128 *)NULL;
    sweLocalPacketHigh = (u_long128 *)NULL;
    sweLocalPacket = (u_long128 *)NULL;
    swePacketToAddFirst = (u_long128 *)NULL;
    swePacketToAddFirstChannel = 0;
    sweNumDispatched = 0;
#ifdef SWEASYNC
    sweNumAsyncDispatched = 0;
#endif /* SWEASYNC */
    sweNumHandler = 0;
#ifdef LESSEOPS
    sweLocalPacketGifQWC = 0;
#endif /* LESSEOPS */
    /* set up PURef list */

    swePURefList = ( (unsigned int **)
                     RwMalloc(sizeof(unsigned int *) * SWEPUREFIS) );
    if (!swePURefList)
    {
        /* malloc failed */

#ifdef TIMER
        if (sweOwnTIM1)
        {
            PFCALL(PF_sweOpen);
            DisableIntc(INTC_TIM1);
            PFRET(PF_sweOpen);
        }
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_TIM1, sweTim1HandlerHid);
        sweTim1HandlerHid = -1;
        PFRET(PF_sweOpen);
#endif /* TIMER */
#ifndef TEAR
        if (sweOwnVBON)
        {
            PFCALL(PF_sweOpen);
            DisableIntc(INTC_VBON);
            PFRET(PF_sweOpen);
        }
        sweOwnVBON = 0;
        PFCALL(PF_sweOpen);
        RemoveIntcHandler(INTC_VBON, sweVSYNCHandlerHid);
        sweVSYNCHandlerHid = -1;
        PFRET(PF_sweOpen);
#endif /* !TEAR */
#ifndef SYNC
        if (sweOwnGIF)
        {
            sweOwnGIF = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_GIF);
            PFRET(PF_sweOpen);
        }
        if (sweOwnVIF1)
        {
            sweOwnVIF1 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF1);
            PFRET(PF_sweOpen);
        }
#if 0
        if (sweOwnVIF0)
        {
            sweOwnVIF0 = 0;
            PFCALL(PF_sweOpen);
            DisableDmac(DMAC_VIF0);
            PFRET(PF_sweOpen);
        }
#endif
        PFCALL(PF_sweOpen);
#if 0
        RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
        sweHandlerVIF0Hid = -1;
#endif
        RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
        sweHandlerVIF1Hid = -1;
        RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
        sweHandlerGIFHid = -1;
        PFRET(PF_sweOpen);
#endif /* !SYNC */
        PFCALL(PF_sweOpen);
        if (!sweNoFreeLists)
        {
            RwFreeListFree(state_chainBlockFreeList, sweChainBase);
            RwFreeListDestroy(state_chainBlockFreeList);
        }
        else
        {
            RwFree(sweCurrentBlockBase);
        }
        state_chainBlockFreeList = (RwFreeList *) NULL;
        circularAllocClose(circAllocator);
        PFRET(PF_sweOpen);
        PFEXIT(PF_sweOpen);
        RWRETURN(FALSE);
    }
    swePURefMaxSize = SWEPUREFIS;
    swePURefSize = 0;
    DPUT_VIF0_ERR(DGET_VIF0_ERR() | VIF0_ERR_ME0_M);
    DPUT_VIF1_ERR(DGET_VIF1_ERR() | VIF1_ERR_ME0_M);

    /* Prealloc if required */
    if (swePreAllocSize)
    {
        if (!circularAllocPreAlloc(circAllocator, swePreAllocSize))
        {
            printf("circularAllocPreAlloc failed. Pressing on\n");
        }
    }
    if ((!sweNoFreeLists) && (swePreAllocCount))
    {
        int i;
        char **ptr = (char **)NULL, **ptr1;

        for (i = 0; i<swePreAllocCount; i++)
        {
            if ((ptr1 = (char**)RwFreeListAlloc(state_chainBlockFreeList)))
            {
                *ptr1 = (char*)ptr;
                ptr = ptr1;
            }
            else
            {
                printf("Dma chain pre alloc failed\n");
                break;
            }
        }
        /* Now free them */
        while (ptr != NULL)
        {
            ptr1 = (char**)(*ptr);
            RwFreeListFree(state_chainBlockFreeList, ptr);
            ptr = ptr1;
        }
    }
    if (swePreAllocLimit)
    {
        if (!circularLimitAlloc(circAllocator, swePreAllocLimit))
        {
            printf("circularLimitAlloc failed. Pressing on\n");
        }
    }

    PFEXIT(PF_sweOpen);
    RWRETURN(TRUE);
}

/***********************************************************************
 _sweUnhook

 On Entry :
 On Exit  :

 Unhook interrupt handlers and vectors.
 */
void
_sweUnhook()
{
    RWFUNCTION(RWSTRING("_sweUnhook"));
#ifndef SYNC
    /* Wait for the chain to be exhausted */
    while (((*(swe_pkt * volatile *) &sweCurrentBase) != sweChainEnd)
           || (sweFlipPending))
    {
        if (!sweDispatching && !sweFlipPending && !sweAutoFlip)
        {
            PFCALL(PF_sweClose);
            _sweFlush();
            PFRET(PF_sweClose);
        }
        else
        {
            START_CRITICAL_SECTION;
            if (sweAutoFlip)
            {
                /* Request end of autoflip */
                sweAutoFlip |= 4;
            }
            END_CRITICAL_SECTION;
        }
    }
#endif /* !SYNC */
    /* Make sure the last set of allocations are freed */
    _sweGarbageCollectChain();

#ifdef TIMER
    if (sweOwnTIM1)
    {
        PFCALL(PF_sweClose);
        DisableIntc(INTC_TIM1);
        PFRET(PF_sweClose);
    }
    PFCALL(PF_sweClose);
    RemoveIntcHandler(INTC_TIM1, sweTim1HandlerHid);
    sweTim1HandlerHid = -1;
    PFRET(PF_sweClose);
#endif /* TIMER */
#ifndef TEAR
    if (sweOwnVBON)
    {
        PFCALL(PF_sweClose);
        DisableIntc(INTC_VBON);
        PFRET(PF_sweClose);
    }
    PFCALL(PF_sweClose);
    RemoveIntcHandler(INTC_VBON, sweVSYNCHandlerHid);
    sweVSYNCHandlerHid = -1;
    PFRET(PF_sweClose);
#endif /* !TEAR */
#ifndef SYNC
    if (sweOwnGIF)
    {
        sweOwnGIF = 0;
        PFCALL(PF_sweClose);
        DisableDmac(DMAC_GIF);
        PFRET(PF_sweClose);
    }
    if (sweOwnVIF1)
    {
        sweOwnVIF1 = 0;
        PFCALL(PF_sweClose);
        DisableDmac(DMAC_VIF1);
        PFRET(PF_sweClose);
    }
#if 0
    if (sweOwnVIF0)
    {
        sweOwnVIF0 = 0;
        PFCALL(PF_sweClose);
        DisableDmac(DMAC_VIF0);
        PFRET(PF_sweClose);
    }
#endif
    PFCALL(PF_sweClose);
    RemoveDmacHandler(DMAC_GIF, sweHandlerGIFHid);
    sweHandlerGIFHid = -1;
    RemoveDmacHandler(DMAC_VIF1, sweHandlerVIF1Hid);
    sweHandlerVIF1Hid = -1;
#if 0
    RemoveDmacHandler(DMAC_VIF0, sweHandlerVIF0Hid);
    sweHandlerVIF0Hid = -1;
#endif
#endif /* !SYNC */
    RWRETURNVOID();
}

/***********************************************************************
 _sweClose

 On Entry : none
 On Exit  : none
 */
void
_sweClose(void)
{
    RWFUNCTION(RWSTRING("_sweClose"));
    PFENTRY(PF_sweClose);

#ifdef PROCRAS
    PFCALL(PF_sweClose);
    /* We have to close the local pkt here so that DumpChain get all pkts */
    sweCloseLocalPkt();
    sweDumpChain();
    _sweFlushHid();
    PFRET(PF_sweClose);
#endif /* PROCRAS */

    _sweUnhook();

    if (swePURefList)
    {
        RwFree(swePURefList);
    }
    swePURefList = (unsigned int **)NULL;
    swePURefMaxSize = 0;
    swePURefSize = 0;

    /* Check how big this got. */
    /* This is a bit ugly as I need to know about the internals of RwFreeList */
    if (!sweNoFreeLists)
    {
        if (swePreAllocCount
            && (RWSRCGLOBAL(memoryAlloc) == _rwFreeListAllocReal))
        {
            int i=0;
            RwFreeBlock        *fbpCur;
        
            /* We should have a real free list */
            fbpCur = state_chainBlockFreeList->firstBlock;
            while (fbpCur)
            {
                RwFreeBlock        *nextBlock;
        
                nextBlock = fbpCur->nextBlock;
                i++;
                fbpCur = nextBlock;
            }
            printf("state_chainBlockFreeList had %d elements\n",
                   i*state_chainBlockFreeList->entriesPerBlock);
        }
        RwFreeListFree(state_chainBlockFreeList, sweChainBase);
        RwFreeListDestroy(state_chainBlockFreeList);
    }
    else
    {
        /* There is only one block */
        RwFree(sweCurrentBlockBase);
    }
    state_chainBlockFreeList = (RwFreeList *) NULL;
    circularAllocClose(circAllocator);
    PFEXIT(PF_sweClose);
    RWRETURNVOID();
}

RwBool
_swePreAlloc(int memory, int chain, RwBool limit)
{
    RWFUNCTION(RWSTRING("_swePreAlloc"));

    if (state_chainBlockFreeList)
    {
        printf("Too Late. Dma system started\n");
        RWRETURN(FALSE);
    }
    swePreAllocSize = memory;
    swePreAllocCount = chain;
    swePreAllocLimit = limit;
    if ((limit) && (memory <= 1))
    {
        printf("Warning: nonsensical limited memory value chosen. Limit removed\n");
        swePreAllocLimit = FALSE;
    }
    RWRETURN(TRUE);
}

/***********************************************************************
 _sweFlush

 On Entry : none
 On Exit  : none

 Inform system that DMA activity should start
 */
void
#ifndef PROCRAS
_sweFlush(void)
#else                           /* PROCRAS */
_sweFlushHid(void)
#endif                          /* PROCRAS */
{
    RWFUNCTION(RWSTRING("_sweFlushHid"));

#ifndef PROCRAS
    PFENTRY(PF_sweFlush);
#else /* PROCRAS */
    PFENTRY(PF_sweFlushHid);
#endif /* PROCRAS */

    if (sweFlipPending || sweAutoFlip)
    {
#ifndef PROCRAS
        PFEXIT(PF_sweFlush);
#else /* PROCRAS */
        PFEXIT(PF_sweFlushHid);
#endif /* PROCRAS */
        RWRETURNVOID();
    }

    TRACEPRINTF(("%s(%d):%s - Enter\n",
                 __FILE__, __LINE__, __FUNCTION__));

#ifndef PROCRAS
    PFCALL(PF_sweFlush);
#else /* PROCRAS */
    PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
    sweCloseLocalPkt();
#ifndef PROCRAS
    PFRET(PF_sweFlush);
#else /* PROCRAS */
    PFRET(PF_sweFlushHid);
#endif /* PROCRAS */

#ifndef SYNCSPR
    /* Flush any packet that is pending */
    if (swePacketToAddFirst)
    {
        TRACEPRINTF(("%s(%d):%s - Done Syncing SPR\n",
                     __FILE__, __LINE__, __FUNCTION__));
        /* Need to make sure that it's done with */
#ifndef PROCRAS
        PFCALL(PF_sweFlush);
#else /* PROCRAS */
        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
#ifndef USEDIRECT
        sweInlineDmaSync(dmaChanFromSPR);
#else /* !USEDIRECT */
/* *INDENT-OFF* */
        asm volatile ("sync.l");
/* *INDENT-ON* */
#endif /* !USEDIRECT */
        _sweAppendPktToDispatchList(swePacketToAddFirst,
                                    swePacketToAddFirstChannel);
#ifndef PROCRAS
        PFRET(PF_sweFlush);
#else /* PROCRAS */
        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
        swePacketToAddFirst = (u_long128 *)NULL;
        TRACEPRINTF(("%s(%d):%s - Done Syncing SPR\n",
                     __FILE__, __LINE__, __FUNCTION__));
    }
#endif
    sweFlushPURef();

#ifndef SYNC
#if 0
    if (EnableDmac(DMAC_VIF0))
        printf("PNSD: Enabled DMAC_VIF0\n");
    if (EnableDmac(DMAC_VIF1))
        printf("PNSD: Enabled DMAC_VIF1\n");
    if (EnableDmac(DMAC_GIF))
        printf("PNSD: Enabled DMAC_GIF\n");
#else
#ifndef PROCRAS
    PFCALL(PF_sweFlush);
#else /* PROCRAS */
    PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */

#if 0
    if ((!(DGET_D_STAT() & D_STAT_CIM0_M))
        /* || (!(DGET_D0_CHCR() & D_CHCR_TIE_M)) */ )
    {
        /* scePrintf("Had to reenable VIF0\n"); */
        EnableDmac(DMAC_VIF0);
    }
#endif
    if ((!(DGET_D_STAT() & D_STAT_CIM1_M))
        /* || (!(DGET_D1_CHCR() & D_CHCR_TIE_M)) */ )
    {
        /* scePrintf("Had to reenable VIF1\n"); */
        EnableDmac(DMAC_VIF1);
    }
    if ((!(DGET_D_STAT() & D_STAT_CIM2_M))
        /* || (!(DGET_D2_CHCR() & D_CHCR_TIE_M)) */ )
    {
        /* scePrintf("Had to reenable GIF\n"); */
        EnableDmac(DMAC_GIF);
    }

#ifndef PROCRAS
    PFRET(PF_sweFlush);
#else /* PROCRAS */
    PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
#endif
#endif /* ! SYNC */

#if 0
    if (sweCurrentBase == sweChainEnd)
    {
        scePrintf("_sweFlush called on an empty chain!\n");
    }
#endif

#ifdef PROCRAS
#ifndef SYNC
    sweNumDispatched = 0;
    sweNumHandler = 0;
    printf("Entering Procratinated Non Synchronous Dispatch\n");
#if 0
    if (EnableDmac(DMAC_VIF0))
        printf("PNSD: Enabled DMAC_VIF0\n");
#endif
    if (EnableDmac(DMAC_VIF1))
        printf("PNSD: Enabled DMAC_VIF1\n");
    if (EnableDmac(DMAC_GIF))
        printf("PNSD: Enabled DMAC_GIF\n");
    printf("PNSD: sweNumDispatched = %d, sweNumHandler= %d\n",
           sweNumDispatched, sweNumHandler);
    /* This is a bit more complicated as we need to loop until all are sent */
    while (sweCurrentBase != sweChainEnd)
    {
        int                 i;

        printf("PNSD: currentBase = %p\n", (unsigned) sweCurrentBase);
#endif /* !SYNC */
#endif /* PROCRAS */

        /* If there are any packets remaing, and we are quiescent submit them */
#ifndef SYNC
        while ((!sweDispatching) && (!sweFlipPending)
               && (sweCurrentBase != sweChainEnd))
#else /* SYNC */
        while ((sweCurrentBase != sweChainEnd))
#endif /* SYNC */
        {
            TRACEPRINTF(("%s(%d):%s - Processing %x\n",
                         __FILE__, __LINE__, __FUNCTION__,
                         (sweCurrentBase->type & SWE_PKT_TYPE_MASK)));

#ifdef PROCRAS
#ifndef SYNC
            printf("PNSD: Processing %p from _sweFlushHid()\n",
                   (sweCurrentBase->type & SWE_PKT_TYPE_MASK));
#endif /* !SYNC */
#endif /* PROCRAS */

#ifdef PROCRAS
#ifdef SYNC
            printf("PSD: currentBase = %p (%p)\n",
                   (unsigned) sweCurrentBase,
                   (sweCurrentBase->type & SWE_PKT_TYPE_MASK));
#endif /* SYNC */
#endif /* PROCRAS */
            if (sweCurrentBase->type & SWE_PKT_PROCESSED)
            {
               /* Skip over processed, eg AGIF pkts */
                sweCurrentBase++;
                continue;
            }

            switch (sweCurrentBase->type & SWE_PKT_TYPE_MASK)
            {
                    /* If you add a case here, remember to update the Handler too */
#if 0
                case SWE_PKT_VU0:
                    {
                        sweInlineDmaSync(dmaChanVIF0);
                        sweDispatching = TRUE;
#ifndef PROCRAS
                        PFCALL(PF_sweFlush);
#else /* PROCRAS */
                        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweDmaSend(dmaChanVIF0,
                                   sweCurrentBase->addr,
                                   ((sweCurrentBase->type & 0x700)
                                    == 0x500) ? 0xc0 : 0x80);
#ifndef PROCRAS
                        PFRET(PF_sweFlush);
#else /* PROCRAS */
                        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweNumDispatched++;
#ifdef SYNC
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        sweDispatching = FALSE;
#endif /* SYNC */
                        break;
                    }
#endif
                case SWE_PKT_VU1:
#ifdef SWEASYNC
#ifdef NONASYNCTEST2 
                case SWE_PKT_AGIF:
#endif /* NONASYNCTEST2 */
#endif /* SWEASYNC */
                    {
                        sweInlineDmaSync(dmaChanVIF1);
                        /* These macros are our version, and should also
                           stop reordering. From later Sony libs, these become
                           function calls  */
                        DI();
                        sweDispatching = TRUE;
#ifdef SWEASYNC
#ifdef NONASYNCTEST
#ifdef NONASYNCTEST2
                        if ((sweCurrentBase+1 != sweChainEnd)
                            && (((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                                == SWE_PKT_AGIF)
                            && ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                                != SWE_PKT_AGIF))
                        {
                            /* We lie and dispatch on VU1 TTE */
                            sweAsyncInProgress = TRUE;
                            sweDmaSend(dmaChanVIF1, (sweCurrentBase+1)->addr,
                                       0xc0);
                            sweNumDispatched++;
                            sweNumAsyncDispatched++;
#ifdef COLOURDMA
                            DI();
                            asm volatile ("sync.l");
                            dmacolour |= 0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                            EI();
#ifdef SYNC
                            sweInlineDmaSync(dmaChanVIF1);
                            (sweCurrentBase+1)->type |= SWE_PKT_PROCESSED;
                            sweAsyncInProgress = FALSE;
#endif /* SYNC */
                            break;
                        }
#else /* NONASYNCTEST2 */
                        if ((sweCurrentBase+1 != sweChainEnd)
                            && ((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                                == SWE_PKT_AGIF))
                        {
                            sweAsyncInProgress = TRUE;
                            /* Set GIF for interrupted transfer */
                            DPUT_GIF_MODE(GIF_MODE_IMT_M);
                            sweDmaSend(dmaChanGIF, (sweCurrentBase+1)->addr, 0x80);
                            sweNumDispatched++;
                            sweNumAsyncDispatched++;
#ifdef COLOURDMA
                            DI();
                            asm volatile ("sync.l");
                            dmacolour |= 0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                            EI();
#ifdef SYNC
                            sweInlineDmaSync(dmaChanGIF);
                            (sweCurrentBase+1)->type |= SWE_PKT_PROCESSED;
                            sweAsyncInProgress = FALSE;
#endif /* SYNC */
                            break;
                        }
#endif /* NONASYNCTEST2 */
#endif /* NONASYNCTEST */
#endif /* SWEASYNC */
#ifndef PROCRAS
                        PFCALL(PF_sweFlush);
#else /* PROCRAS */
                        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
#ifdef DMATIME
                        sweDmaTimer = _sweReadTimer();
#endif /* DMATIME */
#ifdef SWEASYNC
#ifdef NONASYNCTEST2
                        if ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                            == SWE_PKT_AGIF)
                        {
                            sweDmaSend(dmaChanVIF1, sweCurrentBase->addr, 0xc0);
#ifdef COLOURDMA
                            DI();
                            asm volatile ("sync.l");
                            dmacolour |= 0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                        }
                        else
#endif /* NONASYNCTEST2 */
#endif /* SWEASYNC */
                        {
                            sweDmaSend(dmaChanVIF1,
                                       sweCurrentBase->addr,
                                       ((sweCurrentBase->type & 0x700)
                                        == 0x500) ? 0xc0 : 0x80);
#ifdef COLOURDMA
                            DI();
                            asm volatile ("sync.l");
                            dmacolour |= 0xff0000l;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                        }
#ifndef PROCRAS
                        PFRET(PF_sweFlush);
#else /* PROCRAS */
                        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweNumDispatched++;
#if defined(SWEASYNC) && !defined(SYNC)
                        /* Can we kick an async transfer */
                        if ((sweCurrentBase+1 != sweChainEnd)
                            && (((sweCurrentBase+1)->type & SWE_PKT_TYPE_MASK)
                                == SWE_PKT_AGIF)
#ifdef NONASYNCTEST2
                            && ((sweCurrentBase->type & SWE_PKT_TYPE_MASK)
                                != SWE_PKT_AGIF)
#endif /* NONASYNCTEST2 */
                           )
                        {
                            sweAsyncInProgress = TRUE;
                            /* Set GIF for interrupted transfer */
                            DPUT_GIF_MODE(GIF_MODE_IMT_M);
                            sweDmaSend(dmaChanGIF, (sweCurrentBase+1)->addr,
                                       0x80);
                            sweNumDispatched++;
                            sweNumAsyncDispatched++;
#ifdef COLOURDMA
                            DI();
                            asm volatile ("sync.l");
                            dmacolour |= 0xffl;
                            asm volatile ("sync.l");
                            DPUT_GS_BGCOLOR(dmacolour);
                            asm volatile ("sync.l");
#endif  /* COLOURDMA */
                        }
#endif /* defined(SWEASYNC) && !defined(SYNC) */
                        EI();
#ifdef SYNC
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        sweDispatching = FALSE;
#endif /* SYNC */
                        break;
                    }
                case SWE_PKT_GIF:
#if defined(SWEASYNC) && !defined(NONASYNCTEST2)
                case SWE_PKT_AGIF:
#endif /* defined(SWEASYNC) && !defined(NONASYNCTEST2) */
                    {
#ifndef LESSEOPS
#ifdef SYNC
                        sweInlineDmaSync(dmaChanGIF);
#endif /* SYNC */
                        while (sceGsSyncPath(1, 0))
                        {
                            ;
                        }
#else /* LESSEOPS */
                        sweInlineDmaSync(dmaChanGIF);
#endif /* LESSEOPS */
                        DI();
                        sweDispatching = TRUE;
                        EI();
#ifndef PROCRAS
                        PFCALL(PF_sweFlush);
#else /* PROCRAS */
                        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweDmaSend(dmaChanGIF,
                                   sweCurrentBase->addr, 0x80);
#ifdef COLOURDMA
                        DI();
                        asm volatile ("sync.l");
                        dmacolour |= 0xffl;
                        asm volatile ("sync.l");
                        DPUT_GS_BGCOLOR(dmacolour);
                        asm volatile ("sync.l");
                        EI();
#endif  /* COLOURDMA */
#ifndef PROCRAS
                        PFRET(PF_sweFlush);
#else /* PROCRAS */
                        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweNumDispatched++;
#ifdef SYNC
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        sweDispatching = FALSE;
#endif /* SYNC */
                        break;
                    }
                case SWE_PKT_FLIP0:
                    {
                        DI();
                        sweDispatching = FALSE;
                        EI();
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweFlipSt =
                            (void
                             *) ((int) (sweCurrentBase->addr) & ~1);
                        sweFlipId = 0;
#ifdef GSB
                        if (skyDMAGCVTValue % skyNumSeqFrms != skyRenderSlot)
                        {
                            /* We will need to protect against other dma here */
                            sweInlineDmaSync(dmaChanVIF1);

                            /* hitting this bit of code probably indicates an */
                            /* error in the system's design */

                            /* We need to flip and continue immediately */
#if defined(GSB) && defined(GSPLUS)
                            sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                            sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                            sweCurrentBase++;
                            /* A fake VSync has occured */
                            skyDMAGCVTValue++;
                            break;
                        }
#endif /* GSB */
#if defined(TEAR)||defined(RUNTIMETEAR)
#ifdef RUNTIMETEAR
                        if (sweTear)
                        {
#endif /* RUNTIMETEAR */
#ifdef GSB
#ifdef VISTIME
                        /* Display unit number */
                        {
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, posB,
                                                      sizeof(posB) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, posC,
                                                      sizeof(posC) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, posD,
                                                      sizeof(posD) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, posE,
                                                      sizeof(posE) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                            sweInlineDmaSendN(dmaChanGIF, digitBack,
                                              sizeof(digitBack) >> 4);
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                                      sizeof(digitZero) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                                      sizeof(digitOne) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                                      sizeof(digitTwo) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                                      sizeof(digitThree) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                        }
#endif /* VISTIME */
#endif /* GSB */
#ifndef PROCRAS
                        PFCALL(PF_sweFlush);
#else /* PROCRAS */
                        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweInlineDmaSync(dmaChanVIF1);
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
#ifndef PROCRAS
                        PFRET(PF_sweFlush);
#else /* PROCRAS */
                        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweFlipPending = 0;
                        sweNumFlipsInQueue--;
#ifdef GSB
                        /* If we are using real VSYNC based swaps we can: */
                        /* A real/fake VSync has occured */
                        skyDMAGCVTValue++;
                        /* Inform merge unit */
                        if (!skyGsmSysReadyRequired)
                        {
                            gsbDrawDone(GSB_DRAWDONE_SET);
                            skyNeedDrawNext = TRUE;
                        }
#endif /* GSB */
                        sweCurrentBase++;
#ifdef RUNTIMETEAR
                        }
                        else
                        {
#endif /* RUNTIMETEAR */
#endif /* defined(TEAR)||defined(RUNTIMETEAR) */
#if !defined(TEAR)||defined(RUNTIMETEAR)
                        START_CRITICAL_SECTION;
                        sweFlipPending = 1;
                        sweNumFlipsInQueue--;
                        if (!sweAutoFlip)
                        {
                            sweAutoFlip =
                                ((int) (sweCurrentBase->addr) &
                                 1) +
                                (((int)
                                  (sweCurrentBase->addr) & 1) << 1);
                        }
                        sweCurrentBase++;
                        END_CRITICAL_SECTION;
#ifdef RUNTIMETEAR
                        }
#endif /* RUNTIMETEAR */
#endif /* !defined(TEAR)||defined(RUNTIMETEAR) */
#ifdef RWMETRICS
                        state_skyMetrics.flipPktTime = _sweReadTimer();
#endif /* RWMETRICS */
#ifdef SYNC
                        while (sweFlipPending)
                        {
                            ;
                        }
#endif /* SYNC */
                        break;
                    }
                case SWE_PKT_FLIP1:
                    {
                        DI();
                        sweDispatching = FALSE;
                        EI();
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweFlipSt =
                            (void
                             *) (((int) sweCurrentBase->addr) & ~1);
                        sweFlipId = 1;
#ifdef GSB
                        if (skyDMAGCVTValue % skyNumSeqFrms != skyRenderSlot)
                        {
                            /* We will need to protect against other dma here */
                            sweInlineDmaSync(dmaChanVIF1);

                            /* hitting this bit of code probably indicates an */
                            /* error in the system's design */

                            /* We need to flip and continue immediately */
#if defined(GSB) && defined(GSPLUS)
                            sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                            sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
                            sweCurrentBase++;
                            /* A fake VSync has occured */
                            skyDMAGCVTValue++;
                            break;
                        }
#endif /* GSB */
#if defined(TEAR)||defined(RUNTIMETEAR)
#ifdef RUNTIMETEAR
                        if (sweTear)
                        {
#endif /* RUNTIMETEAR */
#ifdef GSB
#ifdef VISTIME
                        /* Display unit number */
                        {
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, posB,
                                                      sizeof(posB) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, posC,
                                                      sizeof(posC) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, posD,
                                                      sizeof(posD) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, posE,
                                                      sizeof(posE) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                            sweInlineDmaSendN(dmaChanGIF, digitBack,
                                              sizeof(digitBack) >> 4);
                            sweInlineDmaSync(dmaChanGIF);
                            switch (skyRenderSlot)
                            {
                                case 0:
                                    sweInlineDmaSendN(dmaChanGIF, digitZero,
                                                      sizeof(digitZero) >> 4);
                                    break;
                                case 1:
                                    sweInlineDmaSendN(dmaChanGIF, digitOne,
                                                      sizeof(digitOne) >> 4);
                                    break;
                                case 2:
                                    sweInlineDmaSendN(dmaChanGIF, digitTwo,
                                                      sizeof(digitTwo) >> 4);
                                    break;
                                case 3:
                                    sweInlineDmaSendN(dmaChanGIF, digitThree,
                                                      sizeof(digitThree) >> 4);
                                    break;
                            }
                            sweInlineDmaSync(dmaChanGIF);
                        }
#endif /* VISTIME */
#endif /* GSB */
#ifndef PROCRAS
                        PFCALL(PF_sweFlush);
#else /* PROCRAS */
                        PFCALL(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweInlineDmaSync(dmaChanVIF1);
#if defined(GSB) && defined(GSPLUS)
                        sceGsPlusSwapDBuffDc(sweFlipSt, sweFlipId);
#else /* defined(GSB) && defined(GSPLUS) */
                        sceGsSwapDBuffDc(sweFlipSt, sweFlipId);
#endif /* defined(GSB) && defined(GSPLUS) */
#ifndef PROCRAS
                        PFRET(PF_sweFlush);
#else /* PROCRAS */
                        PFRET(PF_sweFlushHid);
#endif /* PROCRAS */
                        sweFlipPending = 0;
                        sweNumFlipsInQueue--;
#ifdef GSB
                        /* If we are using real VSYNC based swaps we can: */
                        /* A real/fake VSync has occured */
                        skyDMAGCVTValue++;
                        /* Inform merge unit */
                        if (!skyGsmSysReadyRequired)
                        {
                            gsbDrawDone(GSB_DRAWDONE_SET);
                            skyNeedDrawNext = TRUE;
                        }
#endif /* GSB */
                        sweCurrentBase++;
#ifdef RUNTIMETEAR
                        }
                        else
                        {
#endif /* RUNTIMETEAR */
#endif /* defined(TEAR)||defined(RUNTIMETEAR) */
#if !defined(TEAR)||defined(RUNTIMETEAR)
                        START_CRITICAL_SECTION;
                        sweFlipPending = 1;
                        sweNumFlipsInQueue--;
                        if (!sweAutoFlip)
                        {
                            sweAutoFlip =
                                ((int) (sweCurrentBase->addr) &
                                 1) +
                                (((int)
                                  (sweCurrentBase->addr) & 1) << 1);
                        }
                        sweCurrentBase++;
                        END_CRITICAL_SECTION;
#ifdef RUNTIMETEAR
                        }
#endif /* RUNTIMETEAR */
#endif /* !defined(TEAR)||defined(RUNTIMETEAR) */
#ifdef RWMETRICS
                        state_skyMetrics.flipPktTime = _sweReadTimer();
#endif /* RWMETRICS */
#ifdef SYNC
                        while (sweFlipPending)
                        {
                            ;
                        }
#endif /* SYNC */
                        break;
                    }
                case SWE_PKT_GOTO:
                    {
			DI();
                        sweDispatching = FALSE;
			EI();
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase = (swe_pkt *)sweCurrentBase->addr;
                        break;
                    }
                case SWE_PKT_RASUREF:
                    {
			DI();
                        sweDispatching = FALSE;
			EI();
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        if (sweCurrentBase->type & SWE_PKT_IMM_MASK)
                        {
                            *(unsigned int *) (sweCurrentBase->addr)
                                -=
                                (sweCurrentBase->type &
                                 SWE_PKT_IMM_MASK) >> SWE_PKT_IMM_SHIFT;
                        }
                        else
                        {
                            *(unsigned int *) (sweCurrentBase->addr)
                                -= 1;
                        }
                        sweCurrentBase++;
                        break;
                    }
                case SWE_PKT_NULL:
                    {
			DI();
                        sweDispatching = FALSE;
			EI();
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        break;
                    }
#ifdef GSB
                case SWE_PKT_WAIT_DRAWNEXT:
                    {

                        if ((skyGsmSysReadyRequired)
                            && (skyDMAGCVTValue % skyNumSeqFrms == skyRenderSlot))
                        {
                            if (!(--skyGsmSysReadyRequired))
                            {
#if 0
                         printf("%s(%d):%s - gsbDrawDone(GSB_DRAWDONE_CLEAR)\n",
                                __FILE__, __LINE__, __FUNCTION__);
#endif
                                gsbDrawDone(GSB_DRAWDONE_CLEAR);

#if 0
                         printf("%s(%d):%s - gsbSetSysReady(GSB_READY_SET)\n",
                                __FILE__, __LINE__, __FUNCTION__);
#endif
                                gsbSetSysReady(GSB_READY_SET);
                                skyGsmSysReadyRequired = FALSE;
                            }
                        }
                        if (skyNeedDrawNext)
                        {
                            if (!skyGsmSysReadyRequired)
                            {
                                gsbDrawNext(GSB_DRAWNEXT_WAIT);
                                gsbDrawDone(GSB_DRAWDONE_CLEAR);
                                skyNeedDrawNext = FALSE;
                            }
                        }
                        sweDispatching = FALSE;
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        break;
                    }
                case SWE_PKT_INC_TIME:
                    {
                        skyDMAGCVTValue++;

                        sweDispatching = FALSE;
                        sweCurrentBase->type |= SWE_PKT_PROCESSED;
                        sweCurrentBase++;
                        break;
                    }
#endif /* GSB */
                case SWE_PKT_CALL:
                    {
                        /* If the callback needs to prevent continued execution
                           it must return FALSE, else it returns TRUE */
                        sweDispatching =
                               !((sweDmaCallback)sweCurrentBase->addr)(FALSE);
                        if (!sweDispatching)
                        {
                            sweCurrentBase->type |= SWE_PKT_PROCESSED;
                            sweCurrentBase++;
                        }
                        break;
                    }
                default:      /* ?? */
                    break;
            }
        }

#ifdef PROCRAS
#ifndef SYNC
        /* Wait for current chain to complete and or any display flip */
        i = 0;
        while ((sweDispatching) || (sweFlipPending))
        {
            if (i > 100000000)
            {
                printf
                    ("PNSD: Waiting... (sweDispatching = %d, sweFlipPending = %d)\n",
                     sweDispatching, sweFlipPending);
                printf
                    ("PNSD: Waiting... (sweNumDispatched = %d, sweNumHandler= %d)\n",
                     sweNumDispatched, sweNumHandler);
                i = 0;
#if 0
                if (EnableDmac(DMAC_VIF0))
                    printf("PNSD: Enabled DMAC_VIF0\n");
                if (EnableDmac(DMAC_VIF1))
                    printf("PNSD: Enabled DMAC_VIF1\n");
                if (EnableDmac(DMAC_GIF))
                    printf("PNSD: Enabled DMAC_GIF\n");
                sweHandler(sweCurrentBase->type & 0xf);
#endif
            }
            i++;
        }
        printf
            ("PNSD: sweNumDispatched = %d, sweNumHandler= %d\n",
             sweNumDispatched, sweNumHandler);
    }
#endif /* !SYNC */
#endif /* PROCRAS */

    TRACEPRINTF(("%s(%d):%s - Leave)\n",
                 __FILE__, __LINE__, __FUNCTION__));

#ifdef PROCRAS
#ifndef SYNC
    printf("PNSD: Done\n");
#else /* !SYNC */
    printf("PSD: Done\n");
#endif /* !SYNC */
#endif /* PROCRAS */

#ifndef PROCRAS
    PFEXIT(PF_sweFlush);
#else /* PROCRAS */
    PFEXIT(PF_sweFlushHid);
#endif /* PROCRAS */

    RWRETURNVOID();
}

#ifdef PROCRAS
void
_sweFlush(void)
{
    RWFUNCTION(RWSTRING("_sweFlush"));
    PFENTRY(PF_sweFlush);
    /* Do nothing here */
    PFEXIT(PF_sweFlush);

    RWRETURNVOID();
}
#endif /* PROCRAS */

RwBool
sweCallbackRestart(void)
{
    RWFUNCTION(RWSTRING("sweCallbackRestart"));
    if ((sweCurrentBase->type & SWE_PKT_TYPE_MASK) == SWE_PKT_CALL)
    {
        sweDispatching = FALSE;
        sweCurrentBase->type |= SWE_PKT_PROCESSED;
        sweCurrentBase++;

        _sweFlush();

        RWRETURN(TRUE);
    }
    else
    {
        RWRETURN(FALSE);
    }
}

#ifdef MORECPU
/***********************************************************************
 _sweWaitQueue

 Wait on flips in queue. It is deliberately +1
 */
void
_sweWaitQueue()
{
    RWFUNCTION(RWSTRING("_sweWaitQueue"));
#ifndef PROCRAS
    /* Wait for a reasonable number of flips in the buffer */
#ifdef COLOURDMA
    if (sweNumFlipsInQueue > sweMaxFlips+1)
    {
        DI();
        asm volatile ("sync.l");
        dmacolour |= 0x5000l;
        asm volatile ("sync.l");
        DPUT_GS_BGCOLOR(dmacolour);
        asm volatile ("sync.l");
        EI();
    }
#endif  /* COLOURDMA */
    while (sweNumFlipsInQueue > sweMaxFlips+1)
    {
        if (!sweDispatching && !sweFlipPending && !sweAutoFlip)
        {
            _sweFlush();
        }
        else
        {
            /* We assume that if autoflip is on and MAXFLIPS are exceeded */
            /* the prgrammer is an idiot, so turn off auto flip */
            START_CRITICAL_SECTION;
            if (sweAutoFlip)
            {
                /* Request end of autoflip */
                sweAutoFlip |= 4;
            }
            END_CRITICAL_SECTION;
#ifdef WATCHDOG
            /* Watch dog code. If we claim to be dispatching, but neither
               vif or gif dma is active, unset dispatching. */
            if ((sweDispatching) && (sweWatchDog > 4))
            {
                u_int d1_chcr = *D1_CHCR;
                u_int d2_chcr = *D2_CHCR;
                if (!(d1_chcr & D_CHCR_STR_M) && !(d2_chcr & D_CHCR_STR_M))
                {
                    printf("WatchDog in ReqFlip: sweDispatching still"
                           " true after 4 vsyncs, but no dma.\n");
                }
            }
#endif /* WATCHDOG */
        }
    }
#ifdef COLOURDMA
    DI();
    asm volatile ("sync.l");
    dmacolour &= ~0xff00l;
    asm volatile ("sync.l");
    DPUT_GS_BGCOLOR(dmacolour);
    asm volatile ("sync.l");
    EI();
#endif  /* COLOURDMA */
#endif /* !PROCRAS */
    RWRETURNVOID();
}
#endif /* !MORECPU */
/***********************************************************************
 _sweReqFlip

 On Entry : addr   sceGsDBufDc
            id     buffer id
 On Exit  : none

 Add a buffer flip to the chain. This isn't really a dma function, but it
 is easier to have it here.
 */
void
_sweReqFlip(void *addr, int id, unsigned int flags)
{
    RWFUNCTION(RWSTRING("_sweReqFlip"));
    PFENTRY(PF_sweReqFlip);

    TRACEPRINTF(("%s(%d):%s - Enter\n",
                 __FILE__, __LINE__, __FUNCTION__));

    /* Not convinced by the TEAR predication here */
#ifndef MORECPU
#ifndef PROCRAS
    /* Wait for a reasonable number of flips in the buffer */
    while (sweNumFlipsInQueue > sweMaxFlips)
    {
        if (!sweDispatching && !sweFlipPending && !sweAutoFlip)
        {
            PFCALL(PF_sweReqFlip);
            _sweFlush();
            PFRET(PF_sweReqFlip);
        }
        else
        {
            /* We assume that if autoflip is on and MAXFLIPS are exceeded */
            /* the prgrammer is an idiot, so turn off auto flip */
            START_CRITICAL_SECTION;
            if (sweAutoFlip)
            {
                /* Request end of autoflip */
                sweAutoFlip |= 4;
            }
            END_CRITICAL_SECTION;
#ifdef WATCHDOG
            /* Watch dog code. If we claim to be dispatching, but neither
               vif or gif dma is active, unset dispatching. */
            if ((sweDispatching) && (sweWatchDog > 4))
            {
                u_int d1_chcr = *D1_CHCR;
                u_int d2_chcr = *D2_CHCR;
                if (!(d1_chcr & D_CHCR_STR_M) && !(d2_chcr & D_CHCR_STR_M))
                {
                    printf("WatchDog in ReqFlip: sweDispatching still"
                           " true after 4 vsyncs, but no dma.\n");
                }
            }
#endif /* WATCHDOG */
        }
    }
#endif /* !PROCRAS */
#endif /* !MORECPU */

    /* If autoflip is on, request end */
    /* Logic: If autoflip is being used, the app expects to drop down to */
    /* zero queued frames, so there are no queued requests which might turn */
    /* it on again. If there are, we are going to drop to 20/16.7Hz for the */
    /* queued frames until they clear */
    START_CRITICAL_SECTION;
    if (sweAutoFlip)
    {
        /* Request end of autoflip */
        sweAutoFlip |= 4;
    }
    END_CRITICAL_SECTION;

#ifdef GSB
    skyGCVTValue++;
#endif /* GSB */

    /* If we are quiescent, do a flip, else add one to the chain */
    if (id & 0x1)
    {
        PFCALL(PF_sweReqFlip);
        _sweAddPkt((void *) ((int) addr | (flags & 1)), SWE_PKT_FLIP1);
        PFRET(PF_sweReqFlip);
    }
    else
    {
        PFCALL(PF_sweReqFlip);
        _sweAddPkt((void *) ((int) addr | (flags & 1)), SWE_PKT_FLIP0);
        PFRET(PF_sweReqFlip);
    }
    START_CRITICAL_SECTION;
    sweNumFlipsInQueue++;
    END_CRITICAL_SECTION;
    PFCALL(PF_sweReqFlip);
    _sweFlush();
    PFRET(PF_sweReqFlip);

    TRACEPRINTF(("%s(%d):%s - Leave\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFEXIT(PF_sweReqFlip);
    RWRETURNVOID();
}

/***********************************************************************
 _sweWaitFlip

 On Entry : none
 On Exit  : none

 Wait for a flip to occur and a sync
 Warning: AutoFlip changes the meaning of this funtion somewhat
 */
void
_sweWaitFlip(void)
{
    RWFUNCTION(RWSTRING("_sweWaitFlip"));
    PFENTRY(PF_sweWaitFlip);

    /* if a requested flip is outstanding, wait for it */
    while (sweFlipPending)
    {
        ;
    }

    PFEXIT(PF_sweWaitFlip);

    RWRETURNVOID();
}

/***********************************************************************
 _sweAddPkt

 On Entry : addr   address of DMA tag
          : ch     ch number
 On Exit  : success/failure

 Add a user supplied pkt to the dma chain
 */

/* This functions is not interupt safe if the interupt routines can add to
   the chain. We will have to fix it eventually */
/**
 * \ingroup sky2unsupported
 * \ref _sweAddPkt provides a means to add an arbitrary (pseudo)
 * packet to the interrupt dispatch list.
 *
 * \param addr  pointer to data
 * \param ch  (pseudo) channel specifier
 *
 * \return TRUE on success
 */
RwBool
_sweAddPkt(void *addr, int ch)
{
    RWFUNCTION(RWSTRING("_sweAddPkt"));
    PFENTRY(PF_sweAddPkt);

    TRACEPRINTF(("%s(%d):%s - Enter\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFCALL(PF_sweAddPkt);
    sweCloseLocalPkt();
    PFRET(PF_sweAddPkt);

    /* This'll get any pending packets */
    if (swePacketToAddFirst)
    {
#ifndef USEDIRECT
#ifndef SYNCSPR
        TRACEPRINTF(("%s(%d):%s - Syncing SPR\n",
                     __FILE__, __LINE__, __FUNCTION__));
        /* Need to make sure that it's done with */
        sweInlineDmaSync(dmaChanFromSPR);
        TRACEPRINTF(("%s(%d):%s - Done Syncing SPR\n",
                     __FILE__, __LINE__, __FUNCTION__));
#endif
#else /* !USEDIRECT */
/* *INDENT-OFF* */
        asm volatile ("sync.l");
/* *INDENT-ON* */
#endif /* !USEDIRECT */
        PFCALL(PF_sweAddPkt);
        _sweAppendPktToDispatchList(swePacketToAddFirst,
                                    swePacketToAddFirstChannel);
        PFRET(PF_sweAddPkt);
        swePacketToAddFirst = (u_long128 *)NULL;
    }
    sweFlushPURef();

    TRACEPRINTF(
                ("%s(%d):%s - Leave through call to _swAppendPktToDispatchList()\n",
                 __FILE__, __LINE__, __FUNCTION__));

    PFEXIT(PF_sweAddPkt);
    RWRETURN(_sweAppendPktToDispatchList(addr, ch));
}

/***********************************************************************
 _sweAppendToChain

 On Entry : addr   address of DMA tag
          : link   address of new chunk of chain
 On Exit  : success/failure

 Append a new chunk to a chain pointed to by addr. I make the usual
 assumptions about end of chain. Its hard to do much checking in this
 function. I rather assume that the new chunk is correctly terminated
 and that the pky type in non contig.
 */

/* This functions is not interupt safe. An interupt might cause the chain
   being appended to, to be passed to th dma. */
RwBool
_sweAppendToChain(void *addr, void *link)
{
    unsigned long      *curptr = (unsigned long *) addr;
    RWFUNCTION(RWSTRING("_sweAppendToChain"));
    PFENTRY(PF_sweAppendToChain);

    if (!(addr && link))
    {
        PFEXIT(PF_sweAppendToChain);
        RWRETURN(FALSE);
    }
    /* We have to parse the chain */
    /* We assume that call's always return */
    while (((((*curptr) >> 28) & 0xf) != 8)
           && ((((*curptr) >> 28) & 0xf) != 0xf))
    {
        if ((((*curptr) >> 28) & 0x7) == 2)
        {
            /* next jumps to a new block */
            curptr = (unsigned long *) (unsigned int) (*curptr >> 32);
        }
        else
        {
            if (((((*curptr) >> 28) & 0xf) == 1)
                || ((((*curptr) >> 28) & 0xf) == 5))
            {
                /* cnt, call need skip qwc */
                curptr = curptr + (*curptr & 0xffff) * 2;
            }
            curptr += 2;
        }
    }
    /* curptr now points to the last tag in the chain. We update it */
    /* We are a bit stuffed it the the last tag is a refe */
    if ((((*curptr) >> 28) & 0xf) == 8)
    {
        PFEXIT(PF_sweAppendToChain);
        RWRETURN(FALSE);
    }
    else
    {
        /* Currrent tag is end(i) */
        *curptr = ((*curptr) & (~0xf0000000l)) | (2l << 28)
            | (((unsigned long) (unsigned int) link) << 32);
        PFCALL(PF_sweAppendToChain);
        SyncDCache(curptr, SCESYNCDCACHEROUNDUP(curptr + 1));
        PFRET(PF_sweAppendToChain);
    }

    PFEXIT(PF_sweAppendToChain);
    RWRETURN(TRUE);
}

/***********************************************************************
 _sweAddCont

 On Entry : arg   item for pkt
 On Exit  :

 Add to local pkt of cont type.
 */
void
_sweAddCont(u_long128 arg)
{
    RWFUNCTION(RWSTRING("_sweAddCont"));
    PFENTRY(PF_sweAddCont);

    if (sweLocalPacketState != SWE_LPS_CONT)
    {
        PFCALL(PF_sweAddCont);
        sweOpenLocalPkt(SWE_LPS_CONT, 0);
        PFRET(PF_sweAddCont);
    }
    if (sweLocalPacket < sweLocalPacketHigh)
    {
        *sweLocalPacket++ = arg;
        PFEXIT(PF_sweAddCont);
        RWRETURNVOID();
    }
    else
    {
        u_long128          *ptr /*  = (u_long128 *)NULL */;
        int                 size;

#ifndef USEDIRECT
        RwUInt32            numQuads = sweLocalPacket -
            /* sweLocalPacketBase */ SCRATCHPAD;
#else /* !USEDIRECT */
        RwUInt32            numQuads = sweLocalPacket
            -

            (u_long128 *) ((RwUInt8 *) sweRealLocalPacketBase +
                           DIRECTOFFSET);
#endif /* !USEDIRECT */

        /* we've run out of space so we realloc for now */
        /* We use a double until you hit SWE_LPS_MAX_BLOCK, at which point */
        /* we add the constant instead. We are size limited to */
        /* SWE_LPS_MAX_PACKET_SIZE at which point we close the pkt and open a */
        /* new one of constant size */
        if (numQuads < SWE_LPS_MAX_BLOCK)
            size = numQuads;
        else
            size = SWE_LPS_MAX_BLOCK;

        if ((numQuads + size) <= SWE_LPS_MAX_PACKET_SIZE)
        {
            /* Failure here isn't catastrophic... */
#ifdef USEDIRECT
/* *INDENT-OFF* */
            asm volatile ("sync.l");
/* *INDENT-ON* */
#endif /* USEDIRECT */
            PFCALL(PF_sweAddCont);
            circularReallocMacro(ptr, circAllocator,
                                sweRealLocalPacketBase,
                                (numQuads + size + 2) * 16);
            PFRET(PF_sweAddCont);
            if (ptr)
            {
                sweLocalPacketSize = (numQuads + size + 2) * 16;
#ifndef USEDIRECT
                sweLocalPacketHigh =
                    (u_long128 *) ((char *) SCRATCHPAD +
                                   sweLocalPacketSize - 32);
#else /* !USEDIRECT */
                sweLocalPacketHigh =
                    (u_long128 *) ((char *) ptr + DIRECTOFFSET +
                                   sweLocalPacketSize - 32);
#endif /* !USEDIRECT */
#ifndef USEDIRECT
                /* sweLocalPacket = SCRATCHPAD + numQuads; - still in SPR */
                /* sweLocalPacketBase = SCRATCHPAD; still in SPR */
#else /* !USEDIRECT */
                sweLocalPacketBase =
                    (u_long128 *) (ptr +
                                   (sweLocalPacketBase -
                                    sweRealLocalPacketBase));
                sweLocalPacket =
                    (u_long128 *) ((RwUInt8 *) ptr +
                                   DIRECTOFFSET) + numQuads;
#endif /* !USEDIRECT */
                sweRealLocalPacketBase = ptr;
            }
            else
            {
                PFCALL(PF_sweAddCont);
                sweCloseLocalPkt();
                PFRET(PF_sweAddCont);
                if (!sweOpenLocalPkt(SWE_LPS_CONT, size))
                {
                    /* ... but basically is here */
                    /* Help, help! */
#ifndef NDEBUG
                    printf
                        ("_sweAddCont() opening a new packet failed\n");
#endif /* !NDEBUG */
                    /* A recovery strategy might be to flush the current
                     * queue, and then try again */
                }
            }
        }
        else
        {
            PFCALL(PF_sweAddCont);
            sweCloseLocalPkt();
            PFRET(PF_sweAddCont);
            if (!sweOpenLocalPkt(SWE_LPS_CONT, size))
            {
                /* Help, help! */
#ifndef NDEBUG
                printf("_sweAddCont() opening a new packet failed\n");
#endif /* !NDEBUG */
                /* A recovery strategy might be to flush the current
                 * queue, and then try again */
            }
        }
        *sweLocalPacket++ = arg;
    }
    PFEXIT(PF_sweAddCont);

    RWRETURNVOID();
}

/***********************************************************************
 _sweAddPrim

 On Entry : arg   item for pkt
 On Exit  :

 Add to local pkt of prim type.
 */
void
_sweAddPrim(u_long128 arg)
{
    RWFUNCTION(RWSTRING("_sweAddPrim"));
    PFENTRY(PF_sweAddPrim);
    if (sweLocalPacketState != SWE_LPS_PRIM)
    {
        PFCALL(PF_sweAddPrim);
        sweOpenLocalPkt(SWE_LPS_PRIM, 0);
        PFRET(PF_sweAddPrim);
    }
    if (sweLocalPacket < sweLocalPacketHigh)
    {
        *sweLocalPacket++ = arg;
        PFEXIT(PF_sweAddPrim);
        RWRETURNVOID();
    }
    else
    {
        u_long128          *ptr;
        int                 size;

#ifndef USEDIRECT
        RwUInt32            numQuads = sweLocalPacket -
            /*  sweLocalPacketBase */ SCRATCHPAD;
#else /* !USEDIRECT */
        RwUInt32            numQuads = sweLocalPacket
            -

            (u_long128 *) ((RwUInt8 *) sweRealLocalPacketBase +
                           DIRECTOFFSET);
#endif /* !USEDIRECT */

        /* we've run out of space so we realloc for now */
        /* We use a double until you hit SWE_LPS_MAX_BLOCK, at which point */
        /* we add the constant instead. We are size limited to */
        /* SWE_LPS_MAX_PACKET_SIZE at which point we close the pkt and open a */
        /* new one of constant size */
        if (numQuads < SWE_LPS_MAX_BLOCK)
            size = numQuads;
        else
            size = SWE_LPS_MAX_BLOCK;

        if ((numQuads + size) <= SWE_LPS_MAX_PACKET_SIZE)
        {
            /* Failure here isn't catastrophic... */
#ifdef USEDIRECT
/* *INDENT-OFF* */
            asm volatile ("sync.l");
/* *INDENT-ON* */
#endif /* USEDIRECT */
            PFCALL(PF_sweAddPrim);
            circularReallocMacro(ptr, circAllocator,
                                sweRealLocalPacketBase,
                                (numQuads + size + 2) * 16);
            PFRET(PF_sweAddPrim);
            if (ptr)
            {
                sweLocalPacketSize = (numQuads + size + 2) * 16;
#ifndef USEDIRECT
                sweLocalPacketHigh =
                    (u_long128 *) ((char *) SCRATCHPAD +
                                   sweLocalPacketSize - 32);
#else /* !USEDIRECT */
                sweLocalPacketHigh =
                    (u_long128 *) ((char *) ptr + DIRECTOFFSET +
                                   sweLocalPacketSize - 32);
#endif /* !USEDIRECT */
#ifndef USEDIRECT
                /* sweLocalPacket = ptr + numQuads; - still in SPR */
                /* sweLocalPacketBase = SCRATCHPAD; - still in SPR */
#else /* !USEDIRECT */
                sweLocalPacketBase =
                    (u_long128 *) (ptr +
                                   (sweLocalPacketBase -
                                    sweRealLocalPacketBase));
                sweLocalPacket =
                    (u_long128 *) ((RwUInt8 *) ptr +
                                   DIRECTOFFSET) + numQuads;
#endif /* !USEDIRECT */
                sweRealLocalPacketBase = ptr;
            }
            else
            {
                PFCALL(PF_sweAddPrim);
                sweCloseLocalPkt();
                PFRET(PF_sweAddPrim);
                if (!sweOpenLocalPkt(SWE_LPS_PRIM, size))
                {
                    /* ... but basically is here */
                    /* Help, help! */
#ifndef NDEBUG
                    printf
                        ("_sweAddCont() opening a new packet failed\n");
#endif /* !NDEBUG */
                    /* A recovery strategy might be to flush the current
                     * queue, and then try again */
                }
            }
        }
        else
        {
            PFCALL(PF_sweAddPrim);
            sweCloseLocalPkt();
            PFRET(PF_sweAddPrim);
            if (!sweOpenLocalPkt(SWE_LPS_PRIM, size))
            {
                /* Help, help! */
#ifndef NDEBUG
                printf("_sweAddCont() opening a new packet failed\n");
#endif /* !NDEBUG */
                /* A recovery strategy might be to flush the current
                 * queue, and then try again */
            }
        }
        *sweLocalPacket++ = arg;
    }
    PFEXIT(PF_sweAddPrim);

    RWRETURNVOID();
}

/***********************************************************************
 _sweProcrastinatedAddURef

 On Entry : ptr to uref count
 On Exit  :

 */
void
_sweProcrastinatedAddURef(unsigned int *ptr)
{
    RWFUNCTION(RWSTRING("_sweProcrastinatedAddURef"));
    PFENTRY(PF_sweProcrastinatedAddURef);
    if (swePURefSize == swePURefMaxSize)
    {
        /* We've run out of space so realloc. This won't happen very often */
        unsigned int      **tmp;

        PFCALL(PF_sweProcrastinatedAddURef);
        if (!(tmp = (unsigned int **)
              RwRealloc(swePURefList,
                        sizeof(unsigned int *) * (swePURefMaxSize << 1))))
        {
            PFRET(PF_sweProcrastinatedAddURef);
            PFEXIT(PF_sweProcrastinatedAddURef);
            RWRETURNVOID();
        }
        PFRET(PF_sweProcrastinatedAddURef);

        swePURefList = tmp;
        swePURefMaxSize <<= 1;
    }
    swePURefList[swePURefSize++] = ptr;
    PFEXIT(PF_sweProcrastinatedAddURef);
    RWRETURNVOID();
}

#ifdef TIMER

/***********************************************************************
 _sweReadTimer

 On Entry :
 On Exit  : 64bit time

 */
unsigned long
_sweReadTimer(void)
{
    unsigned long       high0, low0, high1, low1;

    RWFUNCTION(RWSTRING("_sweReadTimer"));

    PFENTRY(PF_sweReadTimer);

#ifndef PROFILE
    DI();
    high0 = sweHighCount;
    low0 = *T1_COUNT;

    high1 = ((*T1_MODE) & 0x800) ? high0 + 1 : high0;
    low1 = *T1_COUNT;
    EI();
#else /* !PROFILE */
    {
        unsigned long       savevi;
        unsigned long       tmp2;
        unsigned long       savevf; /* lie */
/* *INDENT-OFF* */
        __asm volatile ("
        cfc2    %0, $vi1
        addiu   %1, $0, 0xff
        ctc2    %1, $vi1
        qmfc2   %6, $vf1
        li      %1, 0x10000800
        vlqi.xy $vf1, ($vi1++)
        qmfc2   %2, $vf1
        lhu     %4, 0(%1)
        vlqd.xy $vf1, (--$vi1)
        qmfc2   %3, $vf1
        lhu     %5, 0(%1)
        qmtc2   %6, $vf1
        ctc2    %0, $vi1 "
                        : "=r&" (savevi),
                        "=r&" (tmp2),
                        "=r&" (high0),
                        "=r&" (high1),
                        "=r&" (low0),
                        "=r&" (low1),
                        "=r&" (savevf));
    }
/* *INDENT-ON* */
#endif /* !PROFILE */

        if (high0 == high1)
        {
            PFEXIT(PF_sweReadTimer);
            RWRETURN( (high0 | (low0 & 0xffff)) );
        }
        else
        {
            PFEXIT(PF_sweReadTimer);
            RWRETURN( (high1 | (low1 & 0xffff)) );
        }
        PFEXIT(PF_sweReadTimer);
    }
#else /* TIMER */
unsigned long
_sweReadTimer(void)
{
    RWFUNCTION(RWSTRING("_sweReadTimer"));
    RWRETURN( (0) );
}
#endif /* TIMER */

#ifdef PG

/* We assume that no code executes below 2Mb */

void
_sweProfileReset(void)
{
    int                 i;
    RWFUNCTION(RWSTRING("_sweProfileReset"));

#ifndef PGA
    /* Zero arrays */

    for (i = 0; i < 1024 * 1024; i++)
    {
        sweProfileCount[i] = 0;
    }
    for (i = 0; i < 1024 * 1024; i++)
    {
        sweProfileHits[i] = 0;
    }
#else /* !PGA */
    monstartup((char *) 0x00100000, (char *) 0x00500000);
#endif /* !PGA */
    {
        /* zero out unit profile array */
        int                 i;

        for (i = 0;
             i <
             PG_VURUNNING + PG_DMACH1 +
             PG_DMACH2 + PG_GW + PG_VGW + 1; i++)
        {
            sweUnitProf[i] = 0;
        }
        sweUnitProfTotal = 0;

        sweProfORL = 0;
        sweProfORH = 0;
    }
    /* We use uncached access - think we are allowed to use FlushCache here :-) */
    FlushCache(0);

    RWRETURNVOID();

}

void
_sweMcountHolder(void)
{
    RWFUNCTION(RWSTRING("_sweMcountHolder"));
#ifndef PGA
    /* This isn't a real function. It is just somewhere to stick _mcount */
/* *INDENT-OFF* */
    asm volatile ("
        .globl _mcount
        .globl _mcountend
        _mcount:
        .set noreorder
        .set noat
                sw $2, 0($sp)
                sw $3, 4($sp)

                lui $2, %hi((sweProfileCount+0x20000000)-0x100000)
                addiu $2, $2, %lo((sweProfileCount+0x20000000)-0x100000)

                addu $2, $2, $31

                lw $3, 0($2)

                addiu $3, $3, 1

                sw $3, 0($2)

                addiu $2, $1, 0
                addiu $1, $31, 0
                addiu $31, $2, 0

                lw $3, 4($sp)
                lw $2, 0($sp)

                j $1
                daddu $sp, $sp, 8
        _mcountend:
        .set    reorder
        .set    at ");
/* *INDENT-ON* */
#endif /* !PGA */
    /* The following isn't used, but is the patch I need to put in over the trap */
#if 0
    /* 0909 version */
/* *INDENT-OFF* */
    asm volatile ("
        .globl _trap_patch
        _trap_patch:
        .set noreorder
        .set noat
                b 1f    #nop    # used for safety during the update then set back to nop
                nop
                b 1f    #lui    $k0,0x8000
                nop     #sq     $sp,0x10c0($k0)
                sq      $31,0x10d0($26)
                sq      $1,0x10e0($26)
        0:      mfc0    $1,$13
                mfc0    $26,$12
                and     $1,$1,$26
                srl     $1,$1,8
                andi    $1,$1,0x00ff
                plzcw   $26,$1
                andi    $26,$26,0x00ff
                addiu   $1,$0,0x1e
                subu    $1,$1,$26
                sll     $1,$1,2
                lui     $26,0x8001
                addu    $26,$26,$1
                lw      $26,-0xec0($26)
                jr      $26
                nop

        1:      lui     $26,0x8000
                sq      $29,0x10c0($26)
                sq      $31,0x10d0($26)
                sq      $1,0x10e0($26)

                mfc0    $1,$14
                lui     $26,%hi(0x20100000)
                b       0b
                sw      $1, -4($26)

        .set    reorder
        .set    at ");
/* *INDENT-ON* */
#endif
#if 0
    /* 1020 version */
/* *INDENT-OFF* */
    asm volatile ("
        .globl _trap_patch
        _trap_patch:
        .set noreorder
        .set noat
                b 1f    #nop    # used for safety during the update then set back to nop
                nop
                b 1f    #lui    $k0,0x8000
                nop     #sq     $sp,0x1100($k0)
                sq      $31,0x1110($26)
                sq      $1,0x1120($26)
        0:      mfc0    $1,$13
                mfc0    $26,$12
                and     $1,$1,$26
                srl     $1,$1,8
                andi    $1,$1,0x00ff
                plzcw   $26,$1
                andi    $26,$26,0x00ff
                addiu   $1,$0,0x1e
                subu    $1,$1,$26
                sll     $1,$1,2
                lui     $26,0x8001
                addu    $26,$26,$1
                lw      $26,-0xb80($26)
                jr      $26
                nop

        1:      lui     $26,0x8000
                sq      $29,0x1100($26)
                sq      $31,0x1110($26)
                sq      $1,0x1120($26)

                mfc0    $1,$14
                lui     $26,%hi(0x20100000)
                b       0b
                sw      $1, -4($26)

        .set    reorder
        .set    at ");
/* *INDENT-ON* */
#endif
#if 0
    /* 2.1.4 version */
/* *INDENT-OFF* */
    asm volatile ("
        .globl _trap_patch
        _trap_patch:
        .set noreorder
        .set noat
                b 1f    #nop    # used for safety during the update then set back to nop
                nop
                b 1f    #lui    $k0,0x8000
                nop     #sq     $sp,0x10c0($k0)
                sq      $31,0x10d0($26)
                sq      $1,0x10e0($26)
        0:      mfc0    $1,$13
                mfc0    $26,$12
                and     $1,$1,$26
                srl     $1,$1,8
                andi    $1,$1,0x00ff
                plzcw   $26,$1
                andi    $26,$26,0x00ff
                addiu   $1,$0,0x1e
                subu    $1,$1,$26
                sll     $1,$1,2
                lui     $26,0x8001
                addu    $26,$26,$1
                lw      $26,0x2380($26)
                jr      $26
                nop

        1:      lui     $26,0x8000
                sq      $29,0x10c0($26)
                sq      $31,0x10d0($26)
                sq      $1,0x10e0($26)

                mfc0    $1,$14
                lui     $26,%hi(0x20100000)
                b       0b
                sw      $1, -4($26)

        .set    reorder
        .set    at ");
/* *INDENT-ON* */
#endif
#if 1
    /* 2.3.0 version */
/* *INDENT-OFF* */
    asm volatile ("
        .globl _trap_patch
        _trap_patch:
        .set noreorder
        .set noat
                b 1f    #nop    # used for safety during the update then set back to nop
                nop
                b 1f    #lui    $k0,0x8000
                nop     #sq     $sp,0x1140($k0)
                sq      $31,0x1150($26)
                sq      $1,0x1160($26)
        0:      mfc0    $1,$13
                mfc0    $26,$12
                and     $1,$1,$26
                srl     $1,$1,8
                andi    $1,$1,0x00ff
                plzcw   $26,$1
                andi    $26,$26,0x00ff
                addiu   $1,$0,0x1e
                subu    $1,$1,$26
                sll     $1,$1,2
                lui     $26,0x8001
                addu    $26,$26,$1
                lw      $26,0x4180($26)
                jr      $26
                nop

        1:      lui     $26,0x8000
                sq      $29,0x1140($26)
                sq      $31,0x1150($26)
                sq      $1,0x1160($26)

                mfc0    $1,$14
                lui     $26,%hi(0x20100000)
                b       0b
                sw      $1, -4($26)

        .set    reorder
        .set    at ");
/* *INDENT-ON* */
#endif
    RWRETURNVOID();

}

void
_sweProfileDump(void)
{
    int                 i, j;
    RwUInt32           *uc;
    RwUInt32            hitTotal = 0;
    RwUInt32            ze = 0;
    volatile RwUInt32  *vol = &ze;
    RWFUNCTION(RWSTRING("_sweProfileDump"));

#ifndef PGA
#if 0
    /* We can't be bothered with human readable stuff now */

    /* dump profile info to stdout */
    printf("Count data\n\n");
    uc = sweProfileCount + (0x20000000 >> 2);
    for (i = 0; i < 1024 * 1024; i++)
    {
        if (uc[i] > 0)
        {
            printf("%.16x: %d\n", i * 4 + 0x100000, uc[i]);
            /* We put a pause in here as dsnetm has a buffer overrun problem */
            for (j = 0; j < 100000; j++)
            {
                if (*vol)
                {
                    printf("Odd?\n");
                }
            }
        }
    }

    printf("\n\nHit data\n\n");
    uc = sweProfileHits + (0x20000000 >> 2);
    for (i = 0; i < 1024 * 1024; i++)
    {
        if (uc[i] > 0)
        {
            hitTotal += uc[i];
            printf("%.16x: %d\n", i * 4 + 0x100000, uc[i]);
            /* We put a pause in here as dsnetm has a buffer overrun problem */
            for (j = 0; j < 100000; j++)
            {
                if (*vol)
                {
                    printf("Odd?\n");
                }
            }
        }
    }
    printf("\nTotal Hits %d\n", hitTotal);
#endif
#endif /* !PGA */

    /* Now attempt to dump in gmon.out format */
    {
#ifndef PGA
        int                 fd;

        if (
            (fd =
             sceOpen("host:gmon.out",
                     SCE_WRONLY | SCE_CREAT | SCE_TRUNC)) != -1)
        {
            struct gmon_hdr     hdr;
            char                buf[5] = GMON_MAGIC;
            unsigned char       tag = GMON_TAG_BB_COUNT;
            unsigned int        nblocks = 0;

            printf("Dumping host:gmon.out\n");

            printf("Above address range: %ld\n", sweProfORH);
            printf("Below address range: %ld\n", sweProfORL);

            hdr.cookie[0] = buf[0];
            hdr.cookie[1] = buf[1];
            hdr.cookie[2] = buf[2];
            hdr.cookie[3] = buf[3];
            hdr.version[0] = GMON_VERSION;
            hdr.version[1] = 0;
            hdr.version[2] = 0;
            hdr.version[3] = 0;

            sceWrite(fd, &hdr, sizeof(hdr));

            /* Write a histogram. We clamp values as we only have 16 bits */
            tag = GMON_TAG_TIME_HIST;
            sceWrite(fd, &tag, 1);
            /* Write header */
            {
                struct gmon_hist_hdr hh;

                *(RwUInt32 *) & hh.low_pc = 0x00100000;
                *(RwUInt32 *) & hh.high_pc = 0x00500000;
                *(RwUInt32 *) & hh.hist_size = 0x00100000;
                *(RwUInt32 *) & hh.prof_rate = 2250; /* assumes 147.456MHz */
                hh.dimen[0] = 's';
                hh.dimen[1] = 'e';
                hh.dimen[2] = 'c';
                hh.dimen[3] = 'o';
                hh.dimen[4] = 'n';
                hh.dimen[5] = 'd';
                hh.dimen[6] = 's';
                hh.dimen[7] = '\0';
                hh.dimen_abbrev = 's';

                sceWrite(fd, &hh, sizeof(hh));
            }
            /* Now write the data */
            uc = sweProfileHits + (0x20000000 >> 2);
            {
                RwUInt16            fbuf[1024];

                for (j = 0; j < 1024; j++)
                {
                    for (i = 0; i < 1024; i++)
                    {
                        /* skip _mcount */
                        if (
                            (((i + (j * 1024)) * 4 + 0x100000) <
                             (RwUInt32)_mcount)
                            ||
                            (((i + (j * 1024)) * 4 + 0x100000)
                             >= (RwUInt32)_mcountend))
                        {
                            if (uc[i + (j * 1024)] > 0xffff)
                            {
                                printf("Hits at %p saturated\n",
                                       (i + (j * 1024)) * 4 + 0x100000);
                                fbuf[i] = 0xffff;
                            }
                            else
                            {
                                fbuf[i] = (RwUInt16) uc[i + (j * 1024)];
                            }
                        }
                        else
                        {
                            int                 k;

                            printf
                                ("Location %8x in _mcount. %d hits ignored\n",
                                 ((i + (j * 1024)) * 4 +
                                  0x100000), uc[i + (j * 1024)]);
                            /* We put a pause in here as dsnetm has a buffer
                             * overrun problem */
                            for (k = 0; k < 100000; k++)
                            {
                                if (*vol)
                                {
                                    printf("Odd?\n");
                                }
                            }
                        }
                    }
                    sceWrite(fd, fbuf, sizeof(fbuf));
                }
            }

            /* Write fake arcs to get function counts */
            tag = GMON_TAG_CG_ARC;
            uc = sweProfileCount + (0x20000000 >> 2);
            for (i = 0; i < 1024 * 1024; i++)
            {
                if (uc[i] > 0)
                {
                    struct gmon_cg_arc_record grec;

                    sceWrite(fd, &tag, 1);

                    *(RwUInt32 *) & grec.from_pc = 0x00100000;
                    *(RwUInt32 *) & grec.self_pc = i * 4 + 0x100000;
                    *(RwUInt32 *) & grec.count = uc[i];
                    sceWrite(fd, &grec, sizeof(grec));
                }
            }

#if 0
            /* Write basic block counts (we assume a function is a bb) */
            tag = GMON_TAG_BB_COUNT;
            sceWrite(fd, &tag, 1);
            /* How may will we write? */
            nblocks = 0;
            uc = sweProfileCount + (0x20000000 >> 2);
            for (i = 0; i < 1024 * 1024; i++)
            {
                if (uc[i] > 0)
                {
                    nblocks++;
                }
            }
            sceWrite(fd, &nblocks, sizeof(nblocks));
            printf("Writing 0x%p basic block hit counts\n", nblocks);
            /* write data */
            uc = sweProfileCount + (0x20000000 >> 2);
            for (i = 0; i < 1024 * 1024; i++)
            {
                if (uc[i] > 0)
                {
                    unsigned int        addr, data;

                    addr = i * 4 + 0x100000;
                    data = uc[i];
                    sceWrite(fd, &addr, sizeof(addr));
                    sceWrite(fd, &data, sizeof(data));
#if 0
                    /* We put a pause in here as dsnetm has a buffer
                     * overrun problem */
                    for (j = 0; j < 100000; j++)
                    {
                        if (*vol)
                        {
                            printf("Odd?\n");
                        }
                    }
#endif
                }
            }
#endif

            sceClose(fd);
        }
#if 0
        {
            /* We dump in human readable form */
            uc = sweProfileHits + (0x20000000 >> 2);
            {
                for (i = 0; i < 1024 * 1024; i++)
                {
                    if (uc[i])
                    {
                        printf("%08x: %d\n", i * 4 + 0x100000, uc[i]);
                        /* We put a pause in here as dsnetm has a buffer
                         * overrun problem */
                        for (j = 0; j < 100000; j++)
                        {
                            if (*vol)
                            {
                                printf("Odd?\n");
                            }
                        }
                    }
                    else
                    {
                        if (i > 0)
                        {
                            if (uc[i] != uc[i - 1])
                            {
                                printf("...\n");
                                /* We put a pause in here as dsnetm has a buffer
                                 * overrun problem */
                                for (j = 0; j < 100000; j++)
                                {
                                    if (*vol)
                                    {
                                        printf("Odd?\n");
                                    }
                                }
                            }
                        }
                        if (i + 1 < 1024 * 1024)
                        {
                            if (uc[i] != uc[i + 1])
                            {
                                printf("   ...\n");
                                /* We put a pause in here as dsnetm has a buffer
                                 * overrun problem */
                                for (j = 0; j < 100000; j++)
                                {
                                    if (*vol)
                                    {
                                        printf("Odd?\n");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
#endif
#else /* !PGA */
        /* Use the gmon.c style dumper */
        _mcleanup();
#endif /* !PGA */
        {
            unsigned long       vurun;
            unsigned long       dma1;
            unsigned long       dma2;
            unsigned long       vugw;
            unsigned long       vifgw;

            printf("Total Unit hits %ld\n", sweUnitProfTotal);

            /* We now need to figure out how much on each unit before */
            /* we print out the mesh */

            vurun = 0;
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                if (i & PG_VURUNNING)
                    vurun += sweUnitProf[i];
            }

            dma1 = 0;
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                if (i & PG_DMACH1)
                    dma1 += sweUnitProf[i];
            }

            dma2 = 0;
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                if (i & PG_DMACH2)
                    dma2 += sweUnitProf[i];
            }

            vugw = 0;
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                if (i & PG_GW)
                    vugw += sweUnitProf[i];
            }

            vifgw = 0;
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                if (i & PG_VGW)
                    vifgw += sweUnitProf[i];
            }

            printf("VU1 utilisation %f%%\n",
                   100.0f * (float) vurun / (float) sweUnitProfTotal);
            printf("DMA1 utilisation %f%%\n",
                   100.0f * (float) dma1 / (float) sweUnitProfTotal);
            printf("DMA2 utilisation %f%%\n",
                   100.0f * (float) dma2 / (float) sweUnitProfTotal);
            printf("VU stall due to XGKICK %f%%\n",
                   100.0f * (float) vugw / (float) sweUnitProfTotal);
            printf("VIF stall due to GIF %f%%\n",
                   100.0f * (float) vifgw / (float) sweUnitProfTotal);
            printf("Raw figures for simultaneous unit use:\n");
            for (i = 0;
                 i <
                 PG_VURUNNING + PG_DMACH1 + PG_DMACH2 + PG_GW +
                 PG_VGW + 1; i++)
            {
                printf("%02x: %20ld\n", i, sweUnitProf[i]);
            }
            printf("VU running    %02x\n", PG_VURUNNING);
            printf("DMA ch1       %02x\n", PG_DMACH1);
            printf("DMA ch2       %02x\n", PG_DMACH2);
            printf("VU XG stall   %02x\n", PG_GW);
            printf("VIF GIF stall %02x\n", PG_VGW);
        }
    }
    RWRETURNVOID();

}

#endif /* PG */

/************************************************************************
 * Sweet Emotion                                                        *
 *                                                                      *
 * Hadashi de odorou  Volume agete                                      *
 * poppuko-n houbari  asa made tawamureruno                             *
 * Nemuranai machi wa  mabayui daiyamondo                               *
 * akubi nan ka suru  namaikina kimi dakedo                             *
 *    sono shigusa imanimo hoo-hoo-hoo  tameshiteru? Hey hey hey        *
 *      Sweet Emotion                                                   *
 *                                                                      *
 * ...                                                                  *
 ************************************************************************/

