static void sys16_sprite_decode(int num_banks, int bank_size) {
        UBytePtr base = memory_region(REGION_GFX2);
        UBytePtr temp = new UBytePtr(bank_size);
        int i;

        if (temp == null) {
            return;
        }

        for (i = num_banks; i > 0; i--) {
            UBytePtr finish = new UBytePtr(base, 2 * bank_size * i);
            UBytePtr dest = new UBytePtr(finish, - 2 * bank_size);

            UBytePtr p1 = new UBytePtr(temp);
            UBytePtr p2 = new UBytePtr(temp, bank_size / 2);

            /*unsigned*/ char data;

            memcpy(temp, new UBytePtr(base, bank_size * (i - 1)), bank_size);
            /*
	note: both pen#0 and pen#15 are transparent.
	we replace references to pen#15 with pen#0, to simplify the sprite rendering
             */
            do {
                data = (char) (p2.readinc() & 0xFF);
                if ((data & 0x0f) == 0x0f) {
                    if ((data & 0xf0) != 0xf0 && (data & 0xf0) != 0) {
                        dest.writeinc((data >> 4) & 0xFF);
                    } else {
                        dest.writeinc(0xff);
                    }
                    dest.writeinc(0xff);
                } else if ((data & 0xf0) == 0xf0) {
                    dest.writeinc(0x00);
                    if ((data & 0x0f) == 0x0f) {
                        data &= 0xf0;
                    }
                    dest.writeinc(data & 0xf);
                } else {
                    dest.writeinc((data >> 4) & 0xFF);
                    dest.writeinc(data & 0xF);
                }

                data = (char) (p1.readinc() & 0xFF);
                if ((data & 0x0f) == 0x0f) {
                    if ((data & 0xf0) != 0xf0 && (data & 0xf0) != 0) {
                        dest.writeinc((data >> 4) & 0xFF);
                    } else {
                        dest.writeinc(0xff);
                    }
                    dest.writeinc(0xff);
                } else if ((data & 0xf0) == 0xf0) {
                    dest.writeinc(0x00);
                    if ((data & 0x0f) == 0x0f) {
                        data &= 0xf0;
                    }
                    dest.writeinc(data & 0xf);
                } else {
                    dest.writeinc((data >> 4) & 0xFF);
                    dest.writeinc(data & 0xF);
                }
            } while (dest.offset < finish.offset);
        }
        temp = null;
    }

    /*TODO*///	
/*TODO*///	static void sys16_sprite_decode2( int num_banks, int bank_size, int side_markers ){
/*TODO*///		unsigned char *base = memory_region(REGION_GFX2);
/*TODO*///		unsigned char *temp = malloc( bank_size );
/*TODO*///		int i;
/*TODO*///	
/*TODO*///		if( !temp ) return;
/*TODO*///	
/*TODO*///		for( i = num_banks; i >0; i-- ){
/*TODO*///			unsigned char *finish	= base + 2*bank_size*i;
/*TODO*///			unsigned char *dest = finish - 2*bank_size;
/*TODO*///	
/*TODO*///			unsigned char *p1 = temp;
/*TODO*///			unsigned char *p2 = temp+bank_size/4;
/*TODO*///			unsigned char *p3 = temp+bank_size/2;
/*TODO*///			unsigned char *p4 = temp+bank_size/4*3;
/*TODO*///	
/*TODO*///			unsigned char data;
/*TODO*///	
/*TODO*///			memcpy (temp, base+bank_size*(i-1), bank_size);
/*TODO*///	
/*TODO*///	/*
/*TODO*///		note: both pen#0 and pen#15 are transparent.
/*TODO*///		we replace references to pen#15 with pen#0, to simplify the sprite rendering
/*TODO*///	*/
/*TODO*///			do {
/*TODO*///				data = *p4++;
/*TODO*///				if( side_markers )
/*TODO*///				{
/*TODO*///					if( (data&0x0f) == 0x0f )
/*TODO*///					{
/*TODO*///						if((data&0xf0) !=0xf0 && (data&0xf0) !=0)
/*TODO*///							*dest++ = data >> 4;
/*TODO*///						else
/*TODO*///							*dest++ = 0xff;
/*TODO*///						*dest++ = 0xff;
/*TODO*///					}
/*TODO*///					else if( (data&0xf0) == 0xf0 )
/*TODO*///					{
/*TODO*///						*dest++ = 0x00;
/*TODO*///						if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///						*dest++ = data &0xf;
/*TODO*///					}
/*TODO*///					else
/*TODO*///					{
/*TODO*///						*dest++ = data >> 4;
/*TODO*///						*dest++ = data & 0xF;
/*TODO*///					}
/*TODO*///				}
/*TODO*///				else
/*TODO*///				{
/*TODO*///					if( (data&0xf0) == 0xf0 ) data &= 0x0f;
/*TODO*///					if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///					*dest++ = data >> 4;
/*TODO*///					*dest++ = data & 0xF;
/*TODO*///				}
/*TODO*///	
/*TODO*///				data = *p3++;
/*TODO*///				if( side_markers )
/*TODO*///				{
/*TODO*///					if( (data&0x0f) == 0x0f )
/*TODO*///					{
/*TODO*///						if((data&0xf0) !=0xf0 && (data&0xf0) !=0)
/*TODO*///							*dest++ = data >> 4;
/*TODO*///						else
/*TODO*///							*dest++ = 0xff;
/*TODO*///						*dest++ = 0xff;
/*TODO*///					}
/*TODO*///					else if( (data&0xf0) == 0xf0 )
/*TODO*///					{
/*TODO*///						*dest++ = 0x00;
/*TODO*///						if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///						*dest++ = data &0xf;
/*TODO*///					}
/*TODO*///					else
/*TODO*///					{
/*TODO*///						*dest++ = data >> 4;
/*TODO*///						*dest++ = data & 0xF;
/*TODO*///					}
/*TODO*///				}
/*TODO*///				else
/*TODO*///				{
/*TODO*///					if( (data&0xf0) == 0xf0 ) data &= 0x0f;
/*TODO*///					if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///					*dest++ = data >> 4;
/*TODO*///					*dest++ = data & 0xF;
/*TODO*///				}
/*TODO*///	
/*TODO*///	
/*TODO*///				data = *p2++;
/*TODO*///				if( side_markers )
/*TODO*///				{
/*TODO*///					if( (data&0x0f) == 0x0f )
/*TODO*///					{
/*TODO*///						if((data&0xf0) !=0xf0 && (data&0xf0) !=0)
/*TODO*///							*dest++ = data >> 4;
/*TODO*///						else
/*TODO*///							*dest++ = 0xff;
/*TODO*///						*dest++ = 0xff;
/*TODO*///					}
/*TODO*///					else if( (data&0xf0) == 0xf0 )
/*TODO*///					{
/*TODO*///						*dest++ = 0x00;
/*TODO*///						if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///						*dest++ = data &0xf;
/*TODO*///					}
/*TODO*///					else
/*TODO*///					{
/*TODO*///						*dest++ = data >> 4;
/*TODO*///						*dest++ = data & 0xF;
/*TODO*///					}
/*TODO*///				}
/*TODO*///				else
/*TODO*///				{
/*TODO*///					if( (data&0xf0) == 0xf0 ) data &= 0x0f;
/*TODO*///					if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///					*dest++ = data >> 4;
/*TODO*///					*dest++ = data & 0xF;
/*TODO*///				}
/*TODO*///	
/*TODO*///				data = *p1++;
/*TODO*///				if( side_markers )
/*TODO*///				{
/*TODO*///					if( (data&0x0f) == 0x0f )
/*TODO*///					{
/*TODO*///						if((data&0xf0) !=0xf0 && (data&0xf0) !=0)
/*TODO*///							*dest++ = data >> 4;
/*TODO*///						else
/*TODO*///							*dest++ = 0xff;
/*TODO*///						*dest++ = 0xff;
/*TODO*///					}
/*TODO*///					else if( (data&0xf0) == 0xf0 )
/*TODO*///					{
/*TODO*///						*dest++ = 0x00;
/*TODO*///						if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///						*dest++ = data &0xf;
/*TODO*///					}
/*TODO*///					else
/*TODO*///					{
/*TODO*///						*dest++ = data >> 4;
/*TODO*///						*dest++ = data & 0xF;
/*TODO*///					}
/*TODO*///				}
/*TODO*///				else
/*TODO*///				{
/*TODO*///					if( (data&0xf0) == 0xf0 ) data &= 0x0f;
/*TODO*///					if( (data&0x0f) == 0x0f ) data &= 0xf0;
/*TODO*///					*dest++ = data >> 4;
/*TODO*///					*dest++ = data & 0xF;
/*TODO*///				}
/*TODO*///	
/*TODO*///			} while( dest<finish );
/*TODO*///		}
/*TODO*///		free( temp );
/*TODO*///	}
/*TODO*///	
/*TODO*///	int gr_bitmap_width;
/*TODO*///	
/*TODO*///	static void generate_gr_screen(int w,int bitmap_width,int skip,int start_color,int end_color,int source_size)
/*TODO*///	{
/*TODO*///		UINT8 *buf;
/*TODO*///		UINT8 *gr = memory_region(REGION_GFX3);
/*TODO*///		UINT8 *grr = NULL;
/*TODO*///	    int i,j,k;
/*TODO*///	    int center_offset=0;
/*TODO*///	
/*TODO*///	
/*TODO*///		buf=malloc(source_size);
/*TODO*///		if(buf==NULL) return;
/*TODO*///	
/*TODO*///		gr_bitmap_width = bitmap_width;
/*TODO*///	
/*TODO*///		memcpy(buf,gr,source_size);
/*TODO*///		memset(gr,0,256*bitmap_width);
/*TODO*///	
/*TODO*///		if (w!=gr_bitmap_width)
/*TODO*///		{
/*TODO*///			if (skip>0) // needs mirrored RHS
/*TODO*///				grr=gr;
/*TODO*///			else
/*TODO*///			{
/*TODO*///				center_offset=(gr_bitmap_width-w);
/*TODO*///				gr+=center_offset/2;
/*TODO*///			}
/*TODO*///		}
/*TODO*///	
/*TODO*///	    // build gr_bitmap
/*TODO*///		for (i=0; i<256; i++)
/*TODO*///		{
/*TODO*///			UINT8 last_bit;
/*TODO*///			UINT8 color_data[4];
/*TODO*///	
/*TODO*///			color_data[0]=start_color; color_data[1]=start_color+1;
/*TODO*///			color_data[2]=start_color+2; color_data[3]=start_color+3;
/*TODO*///			last_bit=((buf[0]&0x80)==0)|(((buf[0x4000]&0x80)==0)<<1);
/*TODO*///			for (j=0; j<w/8; j++)
/*TODO*///			{
/*TODO*///				for (k=0; k<8; k++)
/*TODO*///				{
/*TODO*///					UINT8 bit=((buf[0]&0x80)==0)|(((buf[0x4000]&0x80)==0)<<1);
/*TODO*///					if (bit!=last_bit && bit==0 && i>1)
/*TODO*///					{ // color flipped to 0,advance color[0]
/*TODO*///						if (color_data[0]+end_color <= end_color)
/*TODO*///						{
/*TODO*///							color_data[0]+=end_color;
/*TODO*///						}
/*TODO*///						else
/*TODO*///						{
/*TODO*///							color_data[0]-=end_color;
/*TODO*///						}
/*TODO*///					}
/*TODO*///					*gr = color_data[bit];
/*TODO*///					last_bit=bit;
/*TODO*///					buf[0] <<= 1; buf[0x4000] <<= 1; gr++;
/*TODO*///				}
/*TODO*///				buf++;
/*TODO*///			}
/*TODO*///	
/*TODO*///			if (grr!=NULL)
/*TODO*///			{ // need mirrored RHS
/*TODO*///				UINT8 *_gr=gr-1;
/*TODO*///				_gr -= skip;
/*TODO*///				for (j=0; j<w-skip; j++)
/*TODO*///				{
/*TODO*///					*gr++ = *_gr--;
/*TODO*///				}
/*TODO*///				for (j=0; j<skip; j++) *gr++ = 0;
/*TODO*///			}
/*TODO*///			else if (center_offset!=0)
/*TODO*///			{
/*TODO*///				gr+=center_offset;
/*TODO*///			}
/*TODO*///		}
/*TODO*///	
/*TODO*///		i=1;
/*TODO*///		while ( (1<<i) < gr_bitmap_width ) i++;
/*TODO*///		gr_bitmap_width=i; // power of 2
/*TODO*///	
/*TODO*///	}