diff options
author | Ivor Hewitt <ivor@ivor.org> | 2005-04-12 04:28:18 +0000 |
---|---|---|
committer | Ivor Hewitt <ivor@ivor.org> | 2005-04-12 04:28:18 +0000 |
commit | a811be570533a4349bab5a584b622cdce5fe5aa9 (patch) | |
tree | 8ec9f537b11c2d287e81cac3033ebd9b737bb14b |
Initial import
43 files changed, 23020 insertions, 0 deletions
diff --git a/libxvmc/Imakefile b/libxvmc/Imakefile new file mode 100644 index 000000000000..6b740d20fd10 --- /dev/null +++ b/libxvmc/Imakefile @@ -0,0 +1,50 @@ +#define DoNormalLib NormalLibXvMC +#define DoSharedLib SharedLibXvMC +#define DoDebugLib DebugLibXvMC +#define DoProfileLib ProfileLibXvMC +#define LibName viaXvMC +#define SoRev SOXVMCREV +#define LibHeaders NO + +#define OUTOFTREE + +#include <Threads.tmpl> + +#ifdef OUTOFTREE +VIADRIVERSRC=../unichrome +#else +VIADRIVERSRC=$(XF86DRIVERSRC)/via +#endif + +#ifdef SharedXvMCReqs +REQUIREDLIBS = SharedXvMCReqs -lXv +#endif + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + + DEFINES = $(ALLOC_DEFINES) -DTRUE=1 -DFALSE=0 + INCLUDES = -I$(XINCLUDESRC) -I$(INCLUDESRC) -I$(XLIBSRC) -I$(EXTINCSRC) \ + -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(DRMSRCDIR)/shared \ + -I$(XF86OSSRC)/linux/drm/kernel -I$(VIADRIVERSRC) + SRCS = viaXvMC.c viaLowLevel.c + OBJS = viaXvMC.o viaLowLevel.o xf86drm.o xf86drmHash.o \ + xf86drmRandom.o xf86drmSL.o + LINTLIBS = $(LINTXLIB) + + +#include <Library.tmpl> + + +#if defined(LinuxArchitecture) +OS_SUBDIR = linux + +LinkSourceFile(xf86drm.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmHash.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) +#endif + +DependTarget() + diff --git a/libxvmc/viaLowLevel.c b/libxvmc/viaLowLevel.c new file mode 100644 index 000000000000..1cbeb1868524 --- /dev/null +++ b/libxvmc/viaLowLevel.c @@ -0,0 +1,1198 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. All rights reserved. + * Copyright (c) 2003 Andreas Robinson. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +/* + * Low-level functions that deal directly with the hardware. In the future, + * these functions might be implemented in a kernel module. Also, some of them + * would benefit from DMA. + * + * Authors: Andreas Robinson 2003. Thomas Hellström 2004. Ivor Hewitt 2005. + */ + +#define VIDEO_DMA +/*#define HQV_USE_IRQ */ + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include <time.h> +#include <sys/time.h> +#include <stdio.h> + +#define PCI_CHIP_VT3204 0x3108 /* K8M800 */ +#define PCI_CHIP_VT3259 0x3118 /* PM800/PM880/CN400 */ +#define PCI_CHIP_CLE3122 0x3122 /* CLE266 */ +#define PCI_CHIP_VT3205 0x7205 /* KM400 */ + +/* + * For Other architectures than i386 these might have to be modified for + * bigendian etc. + */ + +#define MPEGIN(xl,reg) \ + *((volatile CARD32 *)(((CARD8 *)(xl)->mmioAddress) + 0xc00 + (reg))) + +#define VIDIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x200 + (reg))) + +#define REGIN(ctx,reg) \ + *((volatile CARD32 *)(((CARD8 *)(ctx)->mmioAddress) + 0x0000 + (reg))) + +#define HQV_CONTROL 0x1D0 +#define HQV_SRC_OFFSET 0x1CC +#define HQV_SRC_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_MINIFY_DEBLOCK 0x1E8 + +#define REG_HQV1_INDEX 0x00001000 + +#define HQV_SW_FLIP 0x00000010 +#define HQV_FLIP_STATUS 0x00000001 +#define HQV_SUBPIC_FLIP 0x00008000 +#define HQV_FLIP_ODD 0x00000020 +#define HQV_DEINTERLACE 0x00010000 +#define HQV_FIELD_2_FRAME 0x00020000 +#define HQV_FRAME_2_FIELD 0x00040000 +#define HQV_FIELD_UV 0x00100000 +#define HQV_DEBLOCK_HOR 0x00008000 +#define HQV_DEBLOCK_VER 0x80000000 +#define HQV_YUV420 0xC0000000 +#define HQV_YUV422 0x80000000 +#define HQV_ENABLE 0x08000000 +#define HQV_GEN_IRQ 0x00000080 + +#define V_COMPOSE_MODE 0x98 +#define V1_COMMAND_FIRE 0x80000000 +#define V3_COMMAND_FIRE 0x40000000 + +/* SUBPICTURE Registers */ +#define SUBP_CONTROL_STRIDE 0x1C0 +#define SUBP_STARTADDR 0x1C4 +#define RAM_TABLE_CONTROL 0x1C8 +#define RAM_TABLE_READ 0x1CC + +/* SUBP_CONTROL_STRIDE 0x3c0 */ +#define SUBP_HQV_ENABLE 0x00010000 +#define SUBP_IA44 0x00020000 +#define SUBP_AI44 0x00000000 +#define SUBP_STRIDE_MASK 0x00001fff +#define SUBP_CONTROL_MASK 0x00070000 + +/* RAM_TABLE_CONTROL 0x3c8 */ +#define RAM_TABLE_RGB_ENABLE 0x00000007 + + +#define VIA_REG_STATUS 0x400 +#define VIA_REG_GEMODE 0x004 +#define VIA_REG_SRCBASE 0x030 +#define VIA_REG_DSTBASE 0x034 +#define VIA_REG_PITCH 0x038 +#define VIA_REG_SRCCOLORKEY 0x01C +#define VIA_REG_KEYCONTROL 0x02C +#define VIA_REG_SRCPOS 0x008 +#define VIA_REG_DSTPOS 0x00C +#define VIA_REG_GECMD 0x000 +#define VIA_REG_DIMENSION 0x010 /* width and height */ +#define VIA_REG_FGCOLOR 0x018 + + +#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */ +#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */ +#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */ +#define VIA_GEM_8bpp 0x00000000 +#define VIA_GEM_16bpp 0x00000100 +#define VIA_GEM_32bpp 0x00000300 +#define VIA_GEC_BLT 0x00000001 +#define VIA_PITCH_ENABLE 0x80000000 +#define VIA_GEC_INCX 0x00000000 +#define VIA_GEC_DECY 0x00004000 +#define VIA_GEC_INCY 0x00000000 +#define VIA_GEC_DECX 0x00008000 +#define VIA_GEC_FIXCOLOR_PAT 0x00002000 + + +#define VIA_BLIT_CLEAR 0x00 +#define VIA_BLIT_COPY 0xCC +#define VIA_BLIT_FILL 0xF0 +#define VIA_BLIT_SET 0xFF + +#define VIA_SYNCWAITTIMEOUT 50000 /* Might be a bit conservative */ +#define VIA_DMAWAITTIMEOUT 150000 +#define VIA_VIDWAITTIMEOUT 50000 +#define VIA_XVMC_DECODERTIMEOUT 50000 /*(microseconds)*/ + +#define VIA_AGP_HEADER5 0xFE040000 +#define VIA_AGP_HEADER6 0xFE050000 + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(xl, flags) \ + (xl)->curWaitFlags |= (flags) +#define BEGIN_RING_AGP(xl,size) \ + do { \ + if ((xl)->agp_pos > (LL_AGP_CMDBUF_SIZE-(size))) { \ + agpFlush(xl); \ + } \ + } while(0) +#define OUT_RING_AGP(xl, val) do{ \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val); \ + } while(0); + +#define OUT_RING_QW_AGP(xl, val1, val2) \ + do { \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val1); \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val2); \ + } while (0) + + +#define BEGIN_HEADER5_AGP(xl, index) \ + do { \ + BEGIN_RING_AGP(xl, 8); \ + (xl)->agp_mode = VIA_AGP_HEADER5; \ + (xl)->agp_index = (index); \ + (xl)->agp_header_start = (xl)->agp_pos; \ + (xl)->agp_pos += 4; \ + } while (0) + +#define BEGIN_HEADER6_AGP(xl) \ + do { \ + BEGIN_RING_AGP(xl, 8); \ + (xl)->agp_mode = VIA_AGP_HEADER6; \ + (xl)->agp_header_start = (xl)->agp_pos; \ + (xl)->agp_pos += 4; \ + } while (0) + +#define BEGIN_HEADER5_DATA(xl, size, index) \ + do { \ + if ((xl)->agp_pos > (LL_AGP_CMDBUF_SIZE-((size) + 16))) { \ + agpFlush(xl); \ + BEGIN_HEADER5_AGP((xl), (index)); \ + } else if ((xl)->agp_mode && (((xl)->agp_mode != VIA_AGP_HEADER5) || \ + (xl)->agp_index != index)) { \ + finish_header_agp(xl); \ + BEGIN_HEADER5_AGP((xl), (index)); \ + } \ + else if ((xl->agp_mode != VIA_AGP_HEADER5)) { \ + BEGIN_HEADER5_AGP((xl), (index)); \ + } \ + }while(0) + +#define BEGIN_HEADER6_DATA(xl, size) \ + do{ \ + if ((xl)->agp_pos > (LL_AGP_CMDBUF_SIZE-(((size) << 1) + 16))) { \ + agpFlush(xl); \ + BEGIN_HEADER6_AGP((xl)); \ + } else if ((xl)->agp_mode && ((xl)->agp_mode != VIA_AGP_HEADER6)) { \ + finish_header_agp(xl); \ + BEGIN_HEADER6_AGP(xl); \ + } \ + else if ((xl->agp_mode != VIA_AGP_HEADER6)) { \ + BEGIN_HEADER6_AGP((xl)); \ + } \ + }while(0) + + +static void +finish_header_agp(XvMCLowLevel *xl) +{ + int + numDWords,i; + CARD32 + *hb; + + if (!xl->agp_mode) return; + numDWords = xl->agp_pos - xl->agp_header_start - 4; + hb = xl->agp_buffer + xl->agp_header_start; + switch (xl->agp_mode) { + case VIA_AGP_HEADER5: + hb[0] = VIA_AGP_HEADER5 | xl->agp_index; + hb[1] = numDWords ; + hb[2] = 0x00F50000; /* SW debug flag. (?) */ + break; + default: + hb[0] = VIA_AGP_HEADER6; + hb[1] = numDWords >> 1 ; + hb[2] = 0x00F60000; /* SW debug flag. (?) */ + break; + } + hb[3] = 0; + if (numDWords & 3) { + for (i=0; i<(4 - (numDWords & 3)); ++i) + OUT_RING_AGP(xl, 0x00000000); + } + xl->agp_mode = 0; +} + +void +hwlLock(XvMCLowLevel *xl, int videoLock) +{ + LL_HW_LOCK(xl); +} + +void +hwlUnlock(XvMCLowLevel *xl, int videoLock) +{ + LL_HW_UNLOCK(xl); +} + +static unsigned +timeDiff(struct timeval *now,struct timeval *then) { + return (now->tv_usec >= then->tv_usec) ? + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); +} + +void +setAGPSyncLowLevel(XvMCLowLevel *xl, int val, CARD32 timeStamp) +{ + xl->agpSync = val; + xl->agpSyncTimeStamp = timeStamp; +} + +CARD32 +viaDMATimeStampLowLevel(XvMCLowLevel *xl) +{ + if (xl->use_agp) { + viaBlit(xl, 32, xl->tsOffset, 1, xl->tsOffset, 1, 1, 1, 0, 0, + VIABLIT_FILL, xl->curTimeStamp); + return xl->curTimeStamp++; + } + return 0; +} + +static void +viaDMAWaitTimeStamp(XvMCLowLevel *xl, CARD32 timeStamp, int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + if (xl->use_agp && (xl->lastReadTimeStamp - timeStamp > (1 << 23))) { + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then,&here); + + while(((xl->lastReadTimeStamp = *xl->tsP) - timeStamp) > (1 << 23)) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_DMAWAITTIMEOUT) { + if(((xl->lastReadTimeStamp = *xl->tsP) - timeStamp) > (1 << 23)) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) nanosleep(&sleep, &rem); + } + } +} + +static int +viaDMAInitTimeStamp(XvMCLowLevel *xl) +{ + int ret = 0; + + if (xl->use_agp) { + xl->tsMem.context = *(xl->drmcontext); + xl->tsMem.size = 64; + xl->tsMem.type = VIDEO; + if (drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, &xl->tsMem, sizeof(xl->tsMem)) < 0) + return ret; + if (xl->tsMem.size != 64) + return -1; + xl->tsOffset = (xl->tsMem.offset + 31) & ~31; + xl->tsP = (CARD32 *)xl->fbAddress + (xl->tsOffset >> 2); + xl->curTimeStamp = 1; + *xl->tsP = 0; + } + return 0; +} + +static int +viaDMACleanupTimeStamp(XvMCLowLevel *xl) +{ + + if (!(xl->tsMem.size) || !xl->use_agp) return 0; + return drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, &xl->tsMem, sizeof(xl->tsMem)); +} + + +static CARD32 +viaMpegGetStatus(XvMCLowLevel *xl) +{ + return MPEGIN(xl,0x54); +} + +static int +viaMpegIsBusy(XvMCLowLevel *xl, CARD32 mask, CARD32 idle) +{ + CARD32 tmp = viaMpegGetStatus(xl); + + /* + * Error detected. + * FIXME: Are errors really shown when error concealment is on? + */ + + if (tmp & 0x70) return 0; + + return (tmp & mask) != idle; +} + + +static void +syncDMA(XvMCLowLevel *xl, unsigned int doSleep) +{ + + /* + * Ideally, we'd like to have an interrupt wait here, but, according to second hand + * information, the hardware does not support this, although earlier S3 chips do that. + * It is therefore not implemented into the DRM, and we'll do a user space wait here. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then,&here); + while( !(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_DMAWAITTIMEOUT) { + if( !(REGIN(xl, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) nanosleep(&sleep, &rem); + } + while( REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY ) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_DMAWAITTIMEOUT) { + if( REGIN(xl, VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY ) { + xl->errors |= LL_DMA_TIMEDOUT; + break; + } + } + if (doSleep) nanosleep(&sleep, &rem); + } +} + +#ifdef HQV_USE_IRQ +static void +syncVideo(XvMCLowLevel *xl, unsigned int doSleep) +{ + int proReg=0; + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + + /* + * Wait for HQV completion using completion interrupt. Nothing strange here. + * Note that the interrupt handler clears the HQV_FLIP_STATUS bit, so we + * can't wait on that one. + */ + + if ((VIDIN(xl, HQV_CONTROL|proReg) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP))) { + drm_via_irqwait_t irqw; + irqw.request.irq = 1; + irqw.request.type = VIA_IRQ_ABSOLUTE; + if (drmCommandWriteRead(xl->fd, DRM_VIA_WAIT_IRQ, &irqw, sizeof(irqw)) < 0) + xl->errors |= LL_VIDEO_TIMEDOUT; + } +} +#else +static void +syncVideo(XvMCLowLevel *xl, unsigned int doSleep) +{ + /* + * Wait for HQV completion. Nothing strange here. We assume that the HQV + * Handles syncing to the V1 / V3 engines by itself. It should be safe to + * always wait for SUBPIC_FLIP completion although subpictures are not always + * used. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + + int proReg=0; + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then,&here); + while((VIDIN(xl, HQV_CONTROL|proReg) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP )) ) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_SYNCWAITTIMEOUT) { + if((VIDIN(xl, HQV_CONTROL|proReg) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP )) ) { + xl->errors |= LL_VIDEO_TIMEDOUT; + break; + } + } + if (doSleep) nanosleep(&sleep, &rem); + } +} +#endif + +static void +syncAccel(XvMCLowLevel *xl, unsigned int mode, unsigned int doSleep) +{ + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 mask = ((mode & LL_MODE_2D) ? VIA_2D_ENG_BUSY : 0) | + ((mode & LL_MODE_3D) ? VIA_3D_ENG_BUSY : 0); + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then,&here); + while( REGIN(xl, VIA_REG_STATUS) & mask) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_SYNCWAITTIMEOUT) { + if( REGIN(xl, VIA_REG_STATUS) & mask) { + xl->errors |= LL_ACCEL_TIMEDOUT; + break; + } + } + if (doSleep) nanosleep(&sleep, &rem); + } +} + + +static void +syncMpeg(XvMCLowLevel *xl, unsigned int mode, unsigned int doSleep) +{ + /* + * Ideally, we'd like to have an interrupt wait here, but from information from VIA + * at least the MPEG completion interrupt is broken on the CLE266, which was + * discovered during validation of the chip. + */ + + struct timeval now, then; + struct timezone here; + struct timespec sleep, rem; + CARD32 busyMask = 0; + CARD32 idleVal = 0; + CARD32 ret; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then,&here); + if (mode & LL_MODE_DECODER_SLICE) { + busyMask = VIA_SLICEBUSYMASK; + idleVal = VIA_SLICEIDLEVAL; + } + if (mode & LL_MODE_DECODER_IDLE) { + busyMask |= VIA_BUSYMASK; + idleVal = VIA_IDLEVAL; + } + while(viaMpegIsBusy(xl, busyMask, idleVal)) { + gettimeofday(&now,&here); + if (timeDiff(&now,&then) > VIA_XVMC_DECODERTIMEOUT) { + if (viaMpegIsBusy(xl, busyMask, idleVal)) { + xl->errors |= LL_DECODER_TIMEDOUT; + } + break; + } + if (doSleep) nanosleep(&sleep, &rem); + } + + ret = viaMpegGetStatus(xl); + if (ret & 0x70) { + xl->errors |= ((ret & 0x70) >> 3); + } + return; +} + +static void +pciFlush(XvMCLowLevel *xl) +{ + int ret; + drm_via_cmdbuffer_t b; + unsigned mode=xl->curWaitFlags; + + finish_header_agp(xl); + b.buf = (char *)xl->pci_buffer; + b.size = xl->pci_pos * sizeof(CARD32); + if (xl->performLocking) hwlLock(xl,0); + if ((mode != LL_MODE_VIDEO) && (mode != 0)) { + syncDMA(xl, 0); + } + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) { + syncAccel(xl, mode, 0); + } + if (mode & LL_MODE_VIDEO) { + syncVideo(xl, 1); + } + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) { + syncMpeg(xl, mode, 0); + } + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) hwlUnlock(xl,0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + xl->pci_pos = 0; + xl->curWaitFlags = 0; +} + +static void +agpFlush(XvMCLowLevel *xl) +{ + drm_via_cmdbuffer_t b; + int ret; + int i; + + finish_header_agp(xl); + if (xl->use_agp) { + b.buf = (char *)xl->agp_buffer; + b.size = xl->agp_pos * sizeof(CARD32); + if (xl->agpSync) { + syncXvMCLowLevel(xl, LL_MODE_DECODER_IDLE, 1, xl->agpSyncTimeStamp); + xl->agpSync = 0; + } + if (xl->performLocking) hwlLock(xl,0); + do { + ret = drmCommandWrite(xl->fd, DRM_VIA_CMDBUFFER, &b, sizeof(b)); + } while (-EAGAIN == ret); + if (xl->performLocking) hwlUnlock(xl,0); + + if (ret) { + xl->errors |= LL_AGP_COMMAND_ERR; + for(i=0; i<xl->agp_pos; i+=2) { + printf("0x%lx, 0x%lx\n", xl->agp_buffer[i], xl->agp_buffer[i+1]); + } + exit(-1); + } else { + xl->agp_pos = 0; + } + xl->curWaitFlags &= LL_MODE_VIDEO; + } else { + unsigned mode=xl->curWaitFlags; + + b.buf = (char *)xl->agp_buffer; + b.size = xl->agp_pos * sizeof(CARD32); + if (xl->performLocking) hwlLock(xl,0); + if ((mode != LL_MODE_VIDEO) && (mode != 0)) + syncDMA(xl, 0); + if ((mode & LL_MODE_2D) || (mode & LL_MODE_3D)) + syncAccel(xl, mode, 0); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, 1); + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, 0); + ret = drmCommandWrite(xl->fd, DRM_VIA_PCICMD, &b, sizeof(b)); + if (xl->performLocking) hwlUnlock(xl,0); + if (ret) { + xl->errors |= LL_PCI_COMMAND_ERR; + } + xl->agp_pos = 0; + xl->curWaitFlags = 0; + } +} + +unsigned +flushXvMCLowLevel(XvMCLowLevel *xl) +{ + unsigned + errors; + + if(xl->pci_pos) pciFlush(xl); + if(xl->agp_pos) agpFlush(xl); + errors = xl->errors; + if (errors) printf("Error 0x%x\n", errors); + xl->errors = 0; + return errors; +} + +void +flushPCIXvMCLowLevel(XvMCLowLevel *xl) +{ + if(xl->pci_pos) pciFlush(xl); + if ((!xl->use_agp && xl->agp_pos)) agpFlush(xl); +} + + +__inline static void pciCommand(XvMCLowLevel *xl, unsigned offset, unsigned value, unsigned flags) +{ + if (xl->pci_pos > (LL_PCI_CMDBUF_SIZE-2)) pciFlush(xl); + if (flags) xl->curWaitFlags |= flags; + xl->pci_buffer[xl->pci_pos++] = /*(offset >> 2) | 0xF0000000;*/ offset; + xl->pci_buffer[xl->pci_pos++] = value; +} + +void +viaMpegSetSurfaceStride(XvMCLowLevel * xl, ViaXvMCContext *ctx) +{ + CARD32 y_stride = ctx->yStride; + CARD32 uv_stride = y_stride >> 1; + + BEGIN_HEADER6_DATA(xl, 1); + OUT_RING_QW_AGP(xl, 0xc50, (y_stride >> 3) | ((uv_stride >> 3) << 16)); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + + +void +viaVideoSetSWFLipLocked(XvMCLowLevel *xl, + unsigned yOffs, + unsigned uOffs, + unsigned vOffs) { + int proReg=0; + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + +#ifdef VIDEO_DMA + BEGIN_HEADER6_DATA(xl, 3); + if (xl->chipId == PCI_CHIP_VT3259) + { + OUT_RING_QW_AGP(xl, (proReg|HQV_SRC_OFFSET) + 0x200 , 0); + } + + OUT_RING_QW_AGP(xl, (proReg|HQV_SRC_STARTADDR_Y) + 0x200, yOffs); + + if (xl->chipId == PCI_CHIP_VT3259) + { + OUT_RING_QW_AGP(xl, (proReg|HQV_SRC_STARTADDR_U) + 0x200, vOffs); + } + else + { + OUT_RING_QW_AGP(xl, HQV_SRC_STARTADDR_U + 0x200, uOffs); + OUT_RING_QW_AGP(xl, HQV_SRC_STARTADDR_V + 0x200 , vOffs); + } + WAITFLAGS(xl, LL_MODE_VIDEO); +#else + pciCommand(xl, VIA_AGP_HEADER6, 3, LL_MODE_VIDEO); + pciCommand(xl, 0x00F60000, 0, 0); + if (xl->chipId == PCI_CHIP_VT3259) + pciCommand(xl, proReg|HQV_SRC_OFFSET + 0x200 , 0, 0); + pciCommand(xl, proReg|HQV_SRC_STARTADDR_Y + 0x200, yOffs, 0); + if (xl->chipId == PCI_CHIP_VT3259) + { + pciCommand(xl, proReg|HQV_SRC_STARTADDR_U + 0x200, vOffs, 0); + } + { + pciCommand(xl, HQV_SRC_STARTADDR_U + 0x200, uOffs, 0); + pciCommand(xl, HQV_SRC_STARTADDR_V + 0x200 , vOffs, 0); + } + else +#endif +} + +void +viaVideoSWFlipLocked(XvMCLowLevel *xl, unsigned flags, + int progressiveSequence) +{ + int proReg=0; + CARD32 andWd,orWd; + andWd = 0; + orWd = HQV_ENABLE; + + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + + if ((flags & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + andWd = 0xFFFFFFFFU; + orWd = HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | + HQV_FRAME_2_FIELD | + HQV_YUV420 | + HQV_SW_FLIP | + HQV_FLIP_STATUS | + HQV_SUBPIC_FLIP; + } else if ((flags & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + andWd = ~HQV_FLIP_ODD; + orWd = HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | + HQV_FRAME_2_FIELD | + HQV_YUV420 | + HQV_FLIP_ODD | + HQV_SW_FLIP | + HQV_FLIP_STATUS | + HQV_SUBPIC_FLIP; + } else if ((flags & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + andWd = ~(HQV_DEINTERLACE | + HQV_FRAME_2_FIELD | + HQV_FIELD_2_FRAME | + HQV_FIELD_UV); + orWd = HQV_YUV420 | + HQV_SW_FLIP | + HQV_FLIP_STATUS | + HQV_SUBPIC_FLIP; + } + if (progressiveSequence) { + andWd &= ~HQV_FIELD_UV; + orWd &= ~HQV_FIELD_UV; + } + +#ifdef VIDEO_DMA + syncVideo(xl,1); + BEGIN_HEADER6_DATA(xl, 1); + OUT_RING_QW_AGP(xl, (proReg|HQV_CONTROL) + 0x200 , HQV_ENABLE | HQV_GEN_IRQ | orWd); + WAITFLAGS(xl, LL_MODE_VIDEO); + agpFlush(xl); +#else + pciCommand(xl, VIA_AGP_HEADER6, 1, LL_MODE_VIDEO); + pciCommand(xl, 0x00F60000, 0, 0); + pciCommand(xl, (proReg|HQV_CONTROL) + 0x200 , HQV_ENABLE | HQV_GEN_IRQ | orWd , 0); + pciCommand(xl, 0, 0, 0); +#endif +} + + +void +viaMpegSetFB(XvMCLowLevel *xl,unsigned i, + unsigned yOffs, + unsigned uOffs, + unsigned vOffs) { + + if (xl->chipId == PCI_CHIP_VT3259) + { + i *= (4*2); + BEGIN_HEADER6_DATA(xl, 2); + OUT_RING_QW_AGP(xl, 0xc28 + i, yOffs >> 3); + OUT_RING_QW_AGP(xl, 0xc2c + i, vOffs >> 3); + } + else + { + i *= (4*3); + BEGIN_HEADER6_DATA(xl, 3); + OUT_RING_QW_AGP(xl, 0xc20 + i, yOffs >> 3); + OUT_RING_QW_AGP(xl, 0xc24 + i, uOffs >> 3); + OUT_RING_QW_AGP(xl, 0xc28 + i, vOffs >> 3); + } + + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + +void +viaMpegBeginPicture(XvMCLowLevel *xl,ViaXvMCContext *ctx, + unsigned width, + unsigned height, + const XvMCMpegControl *control) { + + unsigned j, mb_width, mb_height; + mb_width = (width + 15) >> 4; + + mb_height = + ((control->mpeg_coding == XVMC_MPEG_2) && + (control->flags & XVMC_PROGRESSIVE_SEQUENCE)) ? + 2*((height+31) >> 5) : (((height+15) >> 4)); + + BEGIN_HEADER6_DATA(xl, 72); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, 0xc00, + ((control->picture_structure & XVMC_FRAME_PICTURE) << 2) | + ((control->picture_coding_type & 3) << 4) | + ((control->flags & XVMC_ALTERNATE_SCAN) ? (1 << 6) : 0)); + + if (!(ctx->intraLoaded)) { + OUT_RING_QW_AGP(xl, 0xc5c, 0); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, 0xc60, + ctx->intra_quantiser_matrix[j] | + (ctx->intra_quantiser_matrix[j+1] << 8) | + (ctx->intra_quantiser_matrix[j+2] << 16) | + (ctx->intra_quantiser_matrix[j+3] << 24)); + } + ctx->intraLoaded = 1; + } + + if (!(ctx->nonIntraLoaded)) { + OUT_RING_QW_AGP(xl, 0xc5c, 1); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, 0xc60, + ctx->non_intra_quantiser_matrix[j] | + (ctx->non_intra_quantiser_matrix[j+1] << 8) | + (ctx->non_intra_quantiser_matrix[j+2] << 16) | + (ctx->non_intra_quantiser_matrix[j+3] << 24)); + } + ctx->nonIntraLoaded = 1; + } + + if (!(ctx->chromaIntraLoaded)) { + OUT_RING_QW_AGP(xl, 0xc5c, 2); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, 0xc60, + ctx->chroma_intra_quantiser_matrix[j] | + (ctx->chroma_intra_quantiser_matrix[j+1] << 8) | + (ctx->chroma_intra_quantiser_matrix[j+2] << 16) | + (ctx->chroma_intra_quantiser_matrix[j+3] << 24)); + } + ctx->chromaIntraLoaded = 1; + } + + if (!(ctx->chromaNonIntraLoaded)) { + OUT_RING_QW_AGP(xl, 0xc5c, 3); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, 0xc60, + ctx->chroma_non_intra_quantiser_matrix[j] | + (ctx->chroma_non_intra_quantiser_matrix[j+1] << 8) | + (ctx->chroma_non_intra_quantiser_matrix[j+2] << 16) | + (ctx->chroma_non_intra_quantiser_matrix[j+3] << 24)); + } + ctx->chromaNonIntraLoaded = 1; + } + + OUT_RING_QW_AGP(xl, 0xc90, + ((mb_width * mb_height) & 0x3fff) | + ((control->flags & XVMC_PRED_DCT_FRAME) ? ( 1 << 14) : 0) | + ((control->flags & XVMC_TOP_FIELD_FIRST) ? (1 << 15) : 0 ) | + ((control->mpeg_coding == XVMC_MPEG_2) ? (1 << 16) : 0) | + ((mb_width & 0xff) << 18)); + + OUT_RING_QW_AGP(xl, 0xc94, + ((control->flags & XVMC_CONCEALMENT_MOTION_VECTORS) ? 1 : 0) | + ((control->flags & XVMC_Q_SCALE_TYPE) ? 2 : 0) | + ((control->intra_dc_precision & 3) << 2) | + (((1 + 0x100000 / mb_width) & 0xfffff) << 4) | + ((control->flags & XVMC_INTRA_VLC_FORMAT) ? (1 << 24) : 0)); + + OUT_RING_QW_AGP(xl, 0xc98, + (((control->FHMV_range) & 0xf) << 0) | + (((control->FVMV_range) & 0xf) << 4) | + (((control->BHMV_range) & 0xf) << 8) | + (((control->BVMV_range) & 0xf) << 12) | + ((control->flags & XVMC_SECOND_FIELD) ? (1 << 20) : 0) | + (0x0a6 << 16)); + +} + + + +void +viaMpegReset(XvMCLowLevel *xl) +{ + int i,j; + + BEGIN_HEADER6_DATA(xl, 50); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, 0xcf0 ,0); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(xl, 0xcc0 ,0); + OUT_RING_QW_AGP(xl, 0xc0c, 0x43|0x20 ); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl, j, 0); + } + + OUT_RING_QW_AGP(xl, 0xc0c, 0x1c3); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl,j,0); + + for (i = 0; i < 19; i++) + OUT_RING_QW_AGP(xl, 0xc08 ,0); + + OUT_RING_QW_AGP(xl, 0xc98, 0x400000); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(xl, 0xcc0 ,0); + OUT_RING_QW_AGP(xl, 0xc0c, 0x1c3|0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl,j,0); + } + OUT_RING_QW_AGP(xl, 0xcf0 ,0); + +} + +void +viaMpegWriteSlice(XvMCLowLevel *xl, CARD8* slice, int nBytes, CARD32 sCode) +{ + int i, n, r; + CARD32* buf; + int count; + + if (xl->errors & (LL_DECODER_TIMEDOUT | + LL_IDCT_FIFO_ERROR | + LL_SLICE_FIFO_ERROR | + LL_SLICE_FAULT)) return; + + n = nBytes >> 2; + if (sCode) nBytes += 4; + r = nBytes & 3; + buf = (CARD32*) slice; + + if (r) nBytes += 4 - r; + + nBytes += 8; + + BEGIN_HEADER6_DATA(xl, 2); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + OUT_RING_QW_AGP(xl, 0xc9c, nBytes); + + if (sCode) OUT_RING_QW_AGP(xl, 0xca0, sCode); + + i = 0; + count = 0; + + do { + count += (LL_AGP_CMDBUF_SIZE -20); + count = (count > n) ? n : count; + BEGIN_HEADER5_DATA(xl, (count - i), 0xca0); + + for (; i < count; i++) { + OUT_RING_AGP(xl, *buf++); + } + finish_header_agp(xl); + } while (i < n); + + BEGIN_HEADER5_DATA(xl, 3, 0xca0); + + if (r) { + OUT_RING_AGP(xl, *buf & ((1 << (r << 3)) - 1)); + } + OUT_RING_AGP(xl,0); + OUT_RING_AGP(xl,0); + finish_header_agp(xl); +} + +void +viaVideoSubPictureOffLocked(XvMCLowLevel *xl) { + + CARD32 stride; + int proReg=0; + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + + stride = VIDIN(xl,proReg|SUBP_CONTROL_STRIDE); +#ifdef VIDEO_DMA + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + BEGIN_HEADER6_DATA(xl,1); + OUT_RING_QW_AGP(xl, proReg|SUBP_CONTROL_STRIDE | 0x200, stride & ~SUBP_HQV_ENABLE); +#else + pciCommand(xl, VIA_AGP_HEADER6, 1, LL_MODE_VIDEO); + pciCommand(xl, 0x00F60000, 0, 0); + pciCommand(xl, proReg|SUBP_CONTROL_STRIDE | 0x200, stride & ~SUBP_HQV_ENABLE, 0); + pciCommand(xl, 0, 0, 0); +#endif + +} + +void +viaVideoSubPictureLocked(XvMCLowLevel *xl,ViaXvMCSubPicture *pViaSubPic) { + + unsigned i; + CARD32 cWord; + + int proReg=0; + if (xl->chipId == PCI_CHIP_VT3259) proReg = REG_HQV1_INDEX; + +#ifdef VIDEO_DMA + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + BEGIN_HEADER6_DATA(xl, VIA_SUBPIC_PALETTE_SIZE + 2); +#else + pciCommand(xl, VIA_AGP_HEADER6, VIA_SUBPIC_PALETTE_SIZE + 2, LL_MODE_VIDEO); + pciCommand(xl, 0x00F60000, 0, 0); +#endif + for (i=0; i<VIA_SUBPIC_PALETTE_SIZE; ++i) { +#ifdef VIDEO_DMA + OUT_RING_QW_AGP(xl, proReg|RAM_TABLE_CONTROL | 0x200, pViaSubPic->palette[i]); +#else + pciCommand(xl, proReg|RAM_TABLE_CONTROL | 0x200, pViaSubPic->palette[i], 0); +#endif + } + + cWord = (pViaSubPic->stride & SUBP_STRIDE_MASK) | SUBP_HQV_ENABLE; + cWord |= (pViaSubPic->ia44) ? SUBP_IA44 : SUBP_AI44; +#ifdef VIDEO_DMA + OUT_RING_QW_AGP(xl, proReg|SUBP_STARTADDR | 0x200, pViaSubPic->offset); + OUT_RING_QW_AGP(xl, proReg|SUBP_CONTROL_STRIDE | 0x200, cWord); +#else + pciCommand(xl, proReg|SUBP_STARTADDR | 0x200, pViaSubPic->offset, 0); + pciCommand(xl, proReg|SUBP_CONTROL_STRIDE | 0x200, cWord, 0); +#endif +} + +void +viaBlit(XvMCLowLevel *xl,unsigned bpp,unsigned srcBase, + unsigned srcPitch,unsigned dstBase,unsigned dstPitch, + unsigned w,unsigned h,int xdir,int ydir, unsigned blitMode, + unsigned color) +{ + + CARD32 dwGEMode = 0, srcY=0, srcX, dstY=0, dstX; + CARD32 cmd; + + + if (!w || !h) + return; + + finish_header_agp(xl); + + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + srcX = srcBase & 31; + dstX = dstBase & 31; + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + srcX >>= 2; + dstX >>= 2; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + srcX >>= 4; + dstX >>= 4; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + BEGIN_RING_AGP(xl, 20); + WAITFLAGS(xl, LL_MODE_2D); + + + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_GEMODE), dwGEMode); + cmd = 0; + + if (xdir < 0) { + cmd |= VIA_GEC_DECX; + srcX += (w - 1); + dstX += (w - 1); + } + if (ydir < 0) { + cmd |= VIA_GEC_DECY; + srcY += (h - 1); + dstY += (h - 1); + } + + switch(blitMode) { + case VIABLIT_TRANSCOPY: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCCOLORKEY), color); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_KEYCONTROL), 0x4000); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + break; + case VIABLIT_FILL: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_FGCOLOR), color); + cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); + break; + default: + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_KEYCONTROL), 0x0); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + } + + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCBASE), (srcBase & ~31) >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DSTBASE), (dstBase & ~31) >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_SRCPOS), ((srcY << 16) | srcX)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DSTPOS), ((dstY << 16) | dstX)); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_DIMENSION), (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(xl, H1_ADDR(VIA_REG_GECMD), cmd); +} + +unsigned +syncXvMCLowLevel(XvMCLowLevel *xl, unsigned int mode, unsigned int doSleep, + CARD32 timeStamp) +{ + unsigned + errors; + + if (mode == 0) { + errors = xl->errors; + xl->errors = 0; + return errors; + } + + if ((mode & (LL_MODE_VIDEO | LL_MODE_3D)) || !xl->use_agp) { + if (xl->performLocking) + hwlLock(xl,0); + if ((mode != LL_MODE_VIDEO)) + syncDMA(xl, doSleep); + if (mode & LL_MODE_3D) + syncAccel(xl, mode, doSleep); + if (mode & LL_MODE_VIDEO) + syncVideo(xl, doSleep); + if (xl->performLocking) + hwlUnlock(xl,0); + } else { + viaDMAWaitTimeStamp(xl, timeStamp, doSleep); + } + + if (mode & (LL_MODE_DECODER_SLICE | LL_MODE_DECODER_IDLE)) + syncMpeg(xl, mode, doSleep); + + errors = xl->errors; + xl->errors = 0; + + return errors; +} + +int +initXvMCLowLevel(XvMCLowLevel *xl, int fd, drm_context_t *ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, int useAgp, unsigned chipId ) +{ + xl->agp_pos = 0; + xl->pci_pos = 0; + xl->use_agp = useAgp; + xl->fd = fd; + xl->drmcontext = ctx; + xl->hwLock = hwLock; + xl->mmioAddress = mmioAddress; + xl->fbAddress = fbAddress; + xl->curWaitFlags = 0; + xl->performLocking = 1; + xl->errors = 0; + xl->agpSync = 0; + xl->agp_mode = 0; + xl->chipId = chipId; + return viaDMAInitTimeStamp(xl); + +} + +void +setLowLevelLocking(XvMCLowLevel *xl, int performLocking) +{ + xl->performLocking = performLocking; +} + +void +closeXvMCLowLevel(XvMCLowLevel *xl) +{ + viaDMACleanupTimeStamp(xl); +} + diff --git a/libxvmc/viaLowLevel.h b/libxvmc/viaLowLevel.h new file mode 100644 index 000000000000..515bd1440a45 --- /dev/null +++ b/libxvmc/viaLowLevel.h @@ -0,0 +1,131 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 The Unichrome Project. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +/* + * Authors: Thomas Hellström 2004 - 2005. + */ + + +#ifndef VIA_LOWLEVEL_H +#define VIA_LOWLEVEL_H + + +/* + * The below define is cache size sensitive. Increasing the AGP buffer size + * will enable the library to do deeper pipelining, but will degrade the + * performance in the drm dma command verifier. + */ + +#define LL_AGP_CMDBUF_SIZE (4096*3) +#define LL_PCI_CMDBUF_SIZE (4096) + +#define LL_MODE_DECODER_SLICE 0x01 +#define LL_MODE_DECODER_IDLE 0x02 +#define LL_MODE_VIDEO 0x04 +#define LL_MODE_2D 0x08 +#define LL_MODE_3D 0x10 + +/* + * Errors + */ + +#define LL_DECODER_TIMEDOUT 0x00000001 +#define LL_IDCT_FIFO_ERROR 0x00000002 +#define LL_SLICE_FIFO_ERROR 0x00000004 +#define LL_SLICE_FAULT 0x00000008 +#define LL_DMA_TIMEDOUT 0x00000010 +#define LL_VIDEO_TIMEDOUT 0x00000020 +#define LL_ACCEL_TIMEDOUT 0x00000040 +#define LL_PCI_COMMAND_ERR 0x00000080 +#define LL_AGP_COMMAND_ERR 0x00000100 + +#define VIA_SLICEBUSYMASK 0x00000200 +#define VIA_BUSYMASK 0x00000207 +#define VIA_SLICEIDLEVAL 0x00000200 +#define VIA_IDLEVAL 0x00000204 + +#include "via_drm.h" + +typedef struct{ + CARD32 agp_buffer[LL_AGP_CMDBUF_SIZE]; + CARD32 pci_buffer[LL_PCI_CMDBUF_SIZE]; + unsigned agp_pos; + unsigned pci_pos; + unsigned flip_pos; + int use_agp; + int agp_mode; + int agp_header_start; + int agp_index; + int fd; + drm_context_t *drmcontext; + drmLockPtr hwLock; + drmAddress mmioAddress; + drmAddress fbAddress; + unsigned curWaitFlags; + int performLocking; + unsigned errors; + drm_via_mem_t tsMem; + CARD32 tsOffset; + volatile CARD32 *tsP; + CARD32 curTimeStamp; + CARD32 lastReadTimeStamp; + int agpSync; + CARD32 agpSyncTimeStamp; + unsigned chipId; +}XvMCLowLevel; + + +extern int initXvMCLowLevel(XvMCLowLevel *xl, int fd, drm_context_t *ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress,int useAgp, unsigned chipId ); + +extern void setLowLevelLocking(XvMCLowLevel *xl, int perFormLocking); +extern void closeXvMCLowLevel(XvMCLowLevel *xl); +extern void flushPCIXvMCLowLevel(XvMCLowLevel *xl); +extern CARD32 viaDMATimeStampLowLevel(XvMCLowLevel *xl); +extern void setAGPSyncLowLevel(XvMCLowLevel *xl, int val, CARD32 timeStamp); + + +/* + * These two functions also return and clear the current error status. + */ + +extern unsigned flushXvMCLowLevel(XvMCLowLevel *xl); +extern unsigned syncXvMCLowLevel(XvMCLowLevel *xl, unsigned int mode, + unsigned int doSleep, CARD32 timeStamp); + +extern void hwlUnlock(XvMCLowLevel *xl, int videoLock); +extern void hwlLock(XvMCLowLevel *xl, int videoLock); + + +#define LL_HW_LOCK(xl) \ + do { \ + DRM_LOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext,0); } while(0); +#define LL_HW_UNLOCK(xl) \ + do {DRM_UNLOCK((xl)->fd,(xl)->hwLock,*(xl)->drmcontext); \ + } while(0); + + +#endif diff --git a/libxvmc/viaXvMC.c b/libxvmc/viaXvMC.c new file mode 100644 index 000000000000..d2dc530c637f --- /dev/null +++ b/libxvmc/viaXvMC.c @@ -0,0 +1,1837 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +/* + *Author: Thomas Hellström, 2004. + *TODO: Picture copying support. + *Change: 0.9.3, Bugfix by Pascal Brisset. + *Change: 0.10.1, Support for interlaced streams Thanks to Pascal Brisset. + */ + +#undef WAITPAUSE + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <time.h> +#include <fourcc.h> +#include <Xv.h> +#include <xf86drm.h> +#include <pthread.h> +#include "vldXvMC.h" + + +#define SAREAPTR(ctx) ((ViaXvMCSAreaPriv *) \ + (((CARD8 *)(ctx)->sAreaAddress) + \ + (ctx)->sAreaPrivOffset)) + + + +static int error_base; +static int event_base; + + +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') + +static unsigned yOffs (ViaXvMCSurface *srf) +{ + return srf->offsets[0]; +} + +static unsigned vOffs (ViaXvMCSurface *srf) +{ + return srf->offsets[0] + srf->yStride * srf->height; +} + +static unsigned uOffs (ViaXvMCSurface *srf) +{ + return srf->offsets[0] + ( srf->yStride * srf->height) + + (srf->yStride >> 1) * (srf->height >> 1); +} + + +static void defaultQMatrices(ViaXvMCContext *ctx) +{ + int i; + + static const char intra[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 + }; + + for( i=0; i<64; ++i) { + ctx->intra_quantiser_matrix[i] = intra[i]; + ctx->non_intra_quantiser_matrix[i] = 16; + } + ctx->intraLoaded = 0; + ctx->nonIntraLoaded = 0; +} + + +static void releaseDecoder(ViaXvMCContext *ctx,int clearCtx) +{ + volatile ViaXvMCSAreaPriv *sAPriv; + + sAPriv = SAREAPTR(ctx); + UNICHROME_UNLOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, ctx->drmcontext); +} + + +static int grabDecoder( ViaXvMCContext *ctx, int *hadLastLock) +{ + volatile ViaXvMCSAreaPriv *sAPriv = SAREAPTR(ctx); + int retFtx, lc; + + /* + * Try to grab the decoder. If it is not available we will sleep until + * it becomes available or for a maximum of 20 ms. + * Then try to grab it again, unless a timeout occured. If the decoder is + * available, the lock should be reasonably fast. + */ + + if (ctx->haveDecoder) { + flushXvMCLowLevel(&ctx->xl); /* Ignore errors here. */ + /* + fprintf(stderr,"ViaXvMC: ERROR: Trying to re-lock decoder.\n"); */ + *hadLastLock = 1; + return 0; + } + UNICHROME_LOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, ctx->drmcontext, lc, + retFtx); + *hadLastLock = (ctx->drmcontext == lc); + + return retFtx; +} + +static void setupAttribDesc(Display *display, XvPortID port, + const ViaXvMCAttrHolder *attrib, + XvAttribute attribDesc[]) +{ + XvAttribute *XvAttribs,*curAD; + int num; + unsigned i,j; + + XLockDisplay(display); + XvAttribs = XvQueryPortAttributes(display, port, &num); + for(i=0; i<attrib->numAttr; ++i) { + curAD = attribDesc + i; + curAD->flags = 0; + curAD->min_value = 0; + curAD->max_value = 0; + curAD->name = NULL; + for(j=0; j<num; ++j) { + if (attrib->attributes[i].attribute == + XInternAtom(display,XvAttribs[j].name,TRUE)) { + *curAD = XvAttribs[j]; + curAD->name = strdup(XvAttribs[j].name); + break; + } + } + } + if (XvAttribs) XFree(XvAttribs); + XUnlockDisplay(display); + +} + +static void releaseAttribDesc(int numAttr, XvAttribute attribDesc[]) +{ + int i; + + for (i=0; i<numAttr; ++i) { + if (attribDesc[i].name) + free(attribDesc[i].name); + } +} + +static Status releaseContextResources(Display *display, XvMCContext *context, + int freePrivate, Status errType) +{ + ViaXvMCContext *pViaXvMC = (ViaXvMCContext *) context->privData; + + switch(pViaXvMC->resources) { + case context_lowLevel: + closeXvMCLowLevel(&pViaXvMC->xl); + case context_mutex: + pthread_mutex_destroy(&pViaXvMC->ctxMutex); + case context_sAreaMap: + drmUnmap(pViaXvMC->sAreaAddress,pViaXvMC->sAreaSize); + case context_fbMap: + drmUnmap(pViaXvMC->fbAddress,pViaXvMC->fbSize); + case context_mmioMap: + drmUnmap(pViaXvMC->mmioAddress,pViaXvMC->mmioSize); + case context_context: + XLockDisplay(display); + _xvmc_destroy_context(display, context); + XUnlockDisplay(display); + case context_fd: + if (pViaXvMC->fd >= 0) + drmClose(pViaXvMC->fd); + pViaXvMC->fd = -1; + if (!freePrivate) break; + default: + free(pViaXvMC); + } + return errType; +} + + +Status XvMCCreateContext(Display *display, XvPortID port, + int surface_type_id, int width, int height, int flags, + XvMCContext *context) +{ + ViaXvMCContext *pViaXvMC; + int priv_count; + uint *priv_data; + uint magic; + unsigned i; + Status ret; + int major, minor; + ViaXvMCCreateContextRec *tmpComm; + drmVersionPtr drmVer; + char curBusID[20]; + + /* + * Verify Obvious things first + */ + + if(context == NULL) { + return XvMCBadContext; + } + + if(!(flags & XVMC_DIRECT)) { + fprintf(stderr,"Indirect Rendering not supported! Using Direct.\n"); + } + + /* + *FIXME: Check $DISPLAY for legal values here + */ + + context->surface_type_id = surface_type_id; + context->width = (unsigned short)((width + 15) & ~15); + context->height = (unsigned short)((height + 15) & ~15); + context->flags = flags; + context->port = port; + + /* + * Width, Height, and flags are checked against surface_type_id + * and port for validity inside the X server, no need to check + * here. + */ + + /* Allocate private Context data */ + context->privData = (void *)malloc(sizeof(ViaXvMCContext)); + if(!context->privData) { + fprintf(stderr,"Unable to allocate resources for XvMC context.\n"); + return BadAlloc; + } + + pViaXvMC = (ViaXvMCContext *)context->privData; + pViaXvMC->resources = context_none; + + /* Verify the XvMC extension exists */ + + XLockDisplay(display); + if(! XvMCQueryExtension(display, &event_base, + &error_base)) { + fprintf(stderr,"XvMC Extension is not available!\n"); + free(pViaXvMC); + XUnlockDisplay(display); + return BadAlloc; + } + + /* Verify XvMC version */ + ret = XvMCQueryVersion(display, &major, &minor); + if(ret) { + fprintf(stderr,"XvMCQuery Version Failed, unable to determine " + "protocol version\n"); + } + XUnlockDisplay(display); + + /* FIXME: Check Major and Minor here */ + + /* Check for drm */ + + if(! drmAvailable()) { + fprintf(stderr,"Direct Rendering is not avilable on this system!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + /* + * We don't know the BUSID. Have the X server tell it to us by faking + * a working drm connection. + */ + + strncpy(curBusID,"NOBUSID",20); + pViaXvMC->fd = -1; + + do { + if (strcmp(curBusID,"NOBUSID")) { + if((pViaXvMC->fd = drmOpen("via",curBusID)) < 0) { + fprintf(stderr,"DRM Device for via could not be opened.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_fd; + + if (NULL == (drmVer = drmGetVersion(pViaXvMC->fd))) { + fprintf(stderr, + "viaXvMC: Could not get drm version."); + return releaseContextResources(display, context, 1, BadAlloc); + } + if (((drmVer->version_major != 2 ) || (drmVer->version_minor < 0))) { + fprintf(stderr, + "viaXvMC: Kernel drm is not compatible with XvMC.\n"); + fprintf(stderr, + "viaXvMC: Kernel drm version: %d.%d.%d " + "and I need at least version 2.0.0.\n" + "Please update.\n", + drmVer->version_major,drmVer->version_minor, + drmVer->version_patchlevel); + drmFreeVersion(drmVer); + return releaseContextResources(display, context, 1, BadAlloc); + } + drmFreeVersion(drmVer); + drmGetMagic(pViaXvMC->fd,&magic); + } else { + magic = 0; + } + context->flags = (unsigned long)magic; + + /* + * Pass control to the X server to create a drmContext for us, and + * validate the width / height and flags. + */ + + XLockDisplay(display); + if((ret = _xvmc_create_context(display, context, &priv_count, + &priv_data))) { + XUnlockDisplay(display); + fprintf(stderr,"Unable to create XvMC Context.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + if(priv_count != (sizeof(ViaXvMCCreateContextRec) >> 2)) { + fprintf(stderr,"_xvmc_create_context() returned incorrect " + "data size!\n"); + fprintf(stderr,"\tExpected %d, got %d\n", + (sizeof(ViaXvMCCreateContextRec) >> 2), + priv_count); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_context; + + tmpComm = ( ViaXvMCCreateContextRec *) priv_data; + + if ((tmpComm->major != VIAXVMC_MAJOR) || + (tmpComm->minor != VIAXVMC_MINOR)) { + fprintf(stderr,"Version mismatch between the XFree86 via driver\n" + "and the XvMC library. Cannot continue!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + if (strncmp(curBusID, tmpComm->busIdString, 20)) { + releaseContextResources(display, context, 0, Success); + pViaXvMC->resources = context_none; + strncpy(curBusID, tmpComm->busIdString, 20); + XFree(priv_data); + continue; + } + + if (!tmpComm->authenticated) { + XFree(priv_data); + return releaseContextResources(display, context, 1, BadAlloc); + } + + } while (pViaXvMC->fd < 0); + + pViaXvMC->ctxNo = tmpComm->ctxNo; + pViaXvMC->drmcontext = tmpComm->drmcontext; + pViaXvMC->fbOffset = tmpComm->fbOffset; + pViaXvMC->fbSize = tmpComm->fbSize; + pViaXvMC->mmioOffset = tmpComm->mmioOffset; + pViaXvMC->mmioSize = tmpComm->mmioSize; + pViaXvMC->sAreaOffset = tmpComm->sAreaOffset; + pViaXvMC->sAreaSize = tmpComm->sAreaSize; + pViaXvMC->sAreaPrivOffset = tmpComm->sAreaPrivOffset; + pViaXvMC->decoderOn = 0; + pViaXvMC->xvMCPort = tmpComm->xvmc_port; + pViaXvMC->useAGP = tmpComm->useAGP; + pViaXvMC->chipId = tmpComm->chipId; + for (i=0; i<VIA_MAX_RENDSURF; ++i) { + pViaXvMC->rendSurf[i] = 0; + } + strncpy(pViaXvMC->busIdString,tmpComm->busIdString,20); + pViaXvMC->busIdString[20] = '\0'; + pViaXvMC->attrib = tmpComm->initAttrs; + pViaXvMC->lastSrfDisplaying = ~0; + setupAttribDesc(display, port, &pViaXvMC->attrib, pViaXvMC->attribDesc); + +fprintf("XvMCCreateContext: Chipid %08x, %08x\n", pViaXvMC->chipId, tmpComm->chipId); + + /* + * Must free the private data we were passed from X + */ + + XFree(priv_data); + + /* + * Map the register memory + */ + + if(drmMap(pViaXvMC->fd,pViaXvMC->mmioOffset, + pViaXvMC->mmioSize,&(pViaXvMC->mmioAddress)) < 0) { + fprintf(stderr,"Unable to map the display chip mmio registers.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_mmioMap; + + /* + * Map Framebuffer memory + */ + + if(drmMap(pViaXvMC->fd,pViaXvMC->fbOffset, + pViaXvMC->fbSize,&(pViaXvMC->fbAddress)) < 0) { + fprintf(stderr,"Unable to map XvMC Framebuffer.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_fbMap; + + + /* + * Map XvMC Sarea and get the address of the HW lock. + */ + + if(drmMap(pViaXvMC->fd,pViaXvMC->sAreaOffset, + pViaXvMC->sAreaSize,&(pViaXvMC->sAreaAddress)) < 0) { + fprintf(stderr,"Unable to map DRI SAREA.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_sAreaMap; + + + pViaXvMC->hwLock = (drmLockPtr) pViaXvMC->sAreaAddress; + defaultQMatrices(pViaXvMC); + pViaXvMC->chromaIntraLoaded = 1; + pViaXvMC->chromaNonIntraLoaded = 1; + pViaXvMC->yStride = (width + 31) & ~31; + pViaXvMC->haveDecoder = 0; + pViaXvMC->attribChanged = 1; + pViaXvMC->haveXv = 0; + pViaXvMC->port = context->port; + pthread_mutex_init(&pViaXvMC->ctxMutex,NULL); + pViaXvMC->resources = context_mutex; + pViaXvMC->timeStamp = 0; + + if (initXvMCLowLevel(&pViaXvMC->xl, pViaXvMC->fd, &pViaXvMC->drmcontext, + pViaXvMC->hwLock, pViaXvMC->mmioAddress, + pViaXvMC->fbAddress, pViaXvMC->useAGP, pViaXvMC->chipId )) { + fprintf(stderr,"ViaXvMC: Could not allocate timestamp blit area\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_lowLevel; + setAGPSyncLowLevel(&pViaXvMC->xl, 1, 0); + hwlLock(&pViaXvMC->xl,1); + setLowLevelLocking(&pViaXvMC->xl,0); + viaVideoSubPictureOffLocked(&pViaXvMC->xl); + flushXvMCLowLevel(&pViaXvMC->xl); /* Ignore errors here. */ + setLowLevelLocking(&pViaXvMC->xl,1); + hwlUnlock(&pViaXvMC->xl,1); + return Success; +} + + +Status XvMCDestroyContext(Display *display, XvMCContext *context) +{ + ViaXvMCContext *pViaXvMC; + + + if(context == NULL) { + return (error_base + XvMCBadContext); + } + if(NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + + /* + * Release decoder if we have it. In case of crash or termination + * before XvMCDestroyContext, the X server will take care of this. + */ + + releaseAttribDesc(pViaXvMC->attrib.numAttr,pViaXvMC->attribDesc); + releaseDecoder(pViaXvMC,1); + return releaseContextResources(display, context, 1, Success); +} + +Status XvMCCreateSurface( Display *display, XvMCContext *context, + XvMCSurface *surface) +{ + ViaXvMCContext *pViaXvMC; + ViaXvMCSurface *pViaSurface; + int priv_count; + unsigned *priv_data; + unsigned i; + Status ret; + + if((surface == NULL) || (context == NULL) || (display == NULL)){ + return BadValue; + } + + pViaXvMC = (ViaXvMCContext *)context->privData; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + if(pViaXvMC == NULL) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return (error_base + XvMCBadContext); + } + + pViaSurface = surface->privData = (ViaXvMCSurface *)malloc(sizeof(ViaXvMCSurface)); + if(!surface->privData) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAlloc; + } + XLockDisplay(display); + if((ret = _xvmc_create_surface(display, context, surface, + &priv_count, &priv_data))) { + XUnlockDisplay(display); + free(pViaSurface); + fprintf(stderr,"Unable to create XvMC Surface.\n"); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return ret; + } + XUnlockDisplay(display); + + pViaSurface->srfNo = priv_data[0]; + + /* + * Store framebuffer offsets to the buffers allocated for this surface. + * For some chipset revisions, surfaces may be double-buffered. + */ + + pViaSurface->numBuffers = priv_data[1]; + for (i=0; i < pViaSurface->numBuffers; ++i) { + pViaSurface->offsets[i] = priv_data[i+2]; + } + pViaSurface->curBuf = 0; + + + /* Free data returned from xvmc_create_surface */ + + XFree(priv_data); + + pViaSurface->width = context->width; + pViaSurface->height = context->height; + pViaSurface->yStride = pViaXvMC->yStride; + pViaSurface->privContext = pViaXvMC; + pViaSurface->privSubPic = NULL; + pViaSurface->needsSync = 0; + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + +Status XvMCDestroySurface(Display *display, XvMCSurface *surface) +{ + ViaXvMCSurface *pViaSurface; + + if((display == NULL) || (surface == NULL)) { + return BadValue; + } + if(surface->privData == NULL) { + return (error_base + XvMCBadSurface); + } + + pViaSurface = (ViaXvMCSurface *)surface->privData; + + XLockDisplay(display); + _xvmc_destroy_surface(display,surface); + XUnlockDisplay(display); + + free(pViaSurface); + surface->privData = NULL; + return Success; +} + +Status XvMCPutSlice2(Display *display,XvMCContext *context, char *slice, + int nBytes, int sliceCode) +{ + ViaXvMCContext *pViaXvMC; + CARD32 sCode = 0x00010000 | (sliceCode & 0xFF) << 24; + + if((display == NULL) || (context == NULL)) { + return BadValue; + } + if(NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (!pViaXvMC->haveDecoder) { + fprintf(stderr,"XvMCPutSlice: This context does not own decoder!\n"); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAlloc; + } + + viaMpegWriteSlice(&pViaXvMC->xl, (CARD8 *)slice, nBytes, sCode); + + flushPCIXvMCLowLevel(&pViaXvMC->xl); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + +Status XvMCPutSlice(Display *display,XvMCContext *context, char *slice, + int nBytes) +{ + ViaXvMCContext *pViaXvMC; + + if((display == NULL) || (context == NULL)) { + return BadValue; + } + if(NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + if (!pViaXvMC->haveDecoder) { + fprintf(stderr,"XvMCPutSlice: This context does not own decoder!\n"); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAlloc; + } + + viaMpegWriteSlice(&pViaXvMC->xl, (CARD8 *)slice, nBytes, 0); + flushPCIXvMCLowLevel(&pViaXvMC->xl); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + +static Status updateXVOverlay(Display *display,ViaXvMCContext *pViaXvMC, + ViaXvMCSurface *pViaSurface, Drawable draw, + short srcx, short srcy, unsigned short srcw, + unsigned short srch,short destx,short desty, + unsigned short destw,unsigned short desth) +{ + ViaXvMCCommandBuffer buf; + ViaXvMCSubPicture *pViaSubPic; + Status ret; + + if (!pViaXvMC->haveXv) { + pViaXvMC->xvImage = + XvCreateImage(display,pViaXvMC->port,FOURCC_XVMC, + (char *)&buf,pViaSurface->width, + pViaSurface->height); + pViaXvMC->gc = XCreateGC(display,draw,0,0); + pViaXvMC->haveXv = 1; + } + pViaXvMC->draw = draw; + pViaXvMC->xvImage->data = (char *)&buf; + + buf.command = (pViaXvMC->attribChanged) ? + VIA_XVMC_COMMAND_FDISPLAY : VIA_XVMC_COMMAND_DISPLAY; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; + pViaSubPic = pViaSurface->privSubPic; + buf.subPicNo = ((NULL == pViaSubPic) ? 0 : pViaSubPic->srfNo ) + | VIA_XVMC_VALID; + buf.attrib = pViaXvMC->attrib; + + XLockDisplay(display); + + if ((ret = XvPutImage(display,pViaXvMC->port,draw,pViaXvMC->gc, + pViaXvMC->xvImage,srcx,srcy,srcw,srch, + destx,desty,destw,desth))) { + XUnlockDisplay(display); + return ret; + } + XSync(display, 0); + XUnlockDisplay(display); + pViaXvMC->attribChanged = 0; + return Success; +} + +Status XvMCPutSurface(Display *display,XvMCSurface *surface,Drawable draw, + short srcx, short srcy, unsigned short srcw, + unsigned short srch,short destx,short desty, + unsigned short destw,unsigned short desth, int flags) +{ + /* + * This function contains some hairy locking logic. What we really want to + * do is to flip the picture ASAP, to get a low latency and smooth playback. + * However, if somebody else used the overlay since we used it last or if it is + * our first time, we'll have to call X to update the overlay first. Otherwise + * we'll do the overlay update once we've flipped. Since we release the hardware + * lock when we call X, X needs to verify using the SAREA that nobody else flipped + * in a picture between the lock release and the X server control. Similarly + * when the overlay update returns, we have to make sure that we still own the + * overlay. + */ + + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + volatile ViaXvMCSAreaPriv *sAPriv; + Status ret; + unsigned dispSurface, lastSurface; + int overlayUpdated; + + if((display == NULL) || (surface == NULL)) { + return BadValue; + } + if(NULL == (pViaSurface = surface->privData )) { + return (error_base + XvMCBadSurface); + } + if (NULL == (pViaXvMC = pViaSurface->privContext)) { + return (error_base + XvMCBadContext); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + pViaSubPic = pViaSurface->privSubPic; + sAPriv = SAREAPTR( pViaXvMC ); + hwlLock(&pViaXvMC->xl,1); + + /* + * Put a surface ID in the SAREA to "authenticate" to the + * X server. + */ + + dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; + lastSurface = pViaXvMC->lastSrfDisplaying; + sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] = + pViaXvMC->lastSrfDisplaying = pViaSurface->srfNo | VIA_XVMC_VALID; + overlayUpdated = 0; + + viaVideoSetSWFLipLocked(&pViaXvMC->xl, yOffs(pViaSurface), uOffs(pViaSurface), + vOffs(pViaSurface)); + + if (lastSurface != dispSurface) { + hwlUnlock(&pViaXvMC->xl,1); + + /* + * We weren't the last to display. Update the overlay before flipping. + */ + + flushPCIXvMCLowLevel(&pViaXvMC->xl); + ret = updateXVOverlay(display,pViaXvMC,pViaSurface,draw,srcx,srcy,srcw, + srch,destx,desty,destw,desth); + if (ret) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return ret; + } + + hwlLock(&pViaXvMC->xl,1); + overlayUpdated = 1; + if (pViaXvMC->lastSrfDisplaying != sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]) { + + /* + * Race. Somebody beat us to the port. + */ + + hwlUnlock(&pViaXvMC->xl,1); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAccess; + } + } + setLowLevelLocking(&pViaXvMC->xl,0); + + /* + * Subpictures + */ + + if (NULL != pViaSubPic) { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] + != (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = + pViaSubPic->srfNo | VIA_XVMC_VALID; + viaVideoSubPictureLocked(&pViaXvMC->xl, pViaSubPic); + } + } else { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] & VIA_XVMC_VALID) { + viaVideoSubPictureOffLocked(&pViaXvMC->xl); + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; + } + } + + /* + * Flip + */ + + viaVideoSWFlipLocked(&pViaXvMC->xl, flags, pViaSurface->progressiveSequence); + flushPCIXvMCLowLevel(&pViaXvMC->xl); + setLowLevelLocking(&pViaXvMC->xl,1); + hwlUnlock(&pViaXvMC->xl,1); + + if (overlayUpdated) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + + /* + * Update overlay + */ + + ret = updateXVOverlay(display,pViaXvMC,pViaSurface,draw,srcx,srcy,srcw, + srch,destx,desty,destw,desth); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return ret; + +} + +void debugControl(const XvMCMpegControl *control) { + printf("BVMV_range: %u\n",control->BVMV_range); + printf("BHMV_range: %u\n",control->BHMV_range); + printf("FVMV_range: %u\n",control->FVMV_range); + printf("FHMV_range: %u\n",control->FHMV_range); + printf("picture_structure: %u\n", control->picture_structure); + printf("intra_dc_precision: %u\n", control->intra_dc_precision); + printf("picture_coding_type: %u\n", control->picture_coding_type); + printf("mpeg_coding: %u\n", control->mpeg_coding); + printf("flags: 0x%x\n", control->flags); +} + + + + +Status XvMCBeginSurface(Display *display, + XvMCContext *context, + XvMCSurface *target_surface, + XvMCSurface *past_surface, + XvMCSurface *future_surface, + const XvMCMpegControl *control) +{ + ViaXvMCSurface *targS,*futS,*pastS; + ViaXvMCContext *pViaXvMC; + int hadDecoderLast; + CARD32 timeStamp; + + if((display == NULL) || (context == NULL) || (target_surface == NULL)) { + return BadValue; + } + + pViaXvMC = context->privData; + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (grabDecoder(pViaXvMC, &hadDecoderLast)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAlloc; + } + pViaXvMC->haveDecoder = 1; + + /* + * We need to wait for decoder idle at next flush, since hardware doesn't queue + * beginsurface requests until the decoder is idle. This is + * done by waiting on the last previous timestamp, or if there was another context + * having the decoder before us, by emitting a new one. + */ + + if (pViaXvMC->useAGP) { + if (!hadDecoderLast || pViaXvMC->timeStamp == 0) { + timeStamp = viaDMATimeStampLowLevel(&pViaXvMC->xl); + if (flushXvMCLowLevel(&pViaXvMC->xl)) { + releaseDecoder(pViaXvMC, 0); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadAlloc; + } + pViaXvMC->timeStamp = timeStamp; + } else { + timeStamp = pViaXvMC->timeStamp; + } + setAGPSyncLowLevel(&pViaXvMC->xl, 1, timeStamp); + } + + if (!hadDecoderLast || !pViaXvMC->decoderOn) { + pViaXvMC->intraLoaded = 0; + pViaXvMC->nonIntraLoaded = 0; + } + + viaMpegReset(&pViaXvMC->xl); + + targS = (ViaXvMCSurface *)target_surface->privData; + futS = NULL; + pastS = NULL; + + + pViaXvMC->rendSurf[0] = targS->srfNo | VIA_XVMC_VALID; + if (future_surface) { + futS = (ViaXvMCSurface *)future_surface->privData; + futS->needsSync = 0; + } + if (past_surface) { + pastS = (ViaXvMCSurface *)past_surface->privData; + pastS->needsSync = 0; + } + + + targS->progressiveSequence = (control->flags & XVMC_PROGRESSIVE_SEQUENCE); + targS->privSubPic = NULL; + + viaMpegSetSurfaceStride(&pViaXvMC->xl,pViaXvMC); + + viaMpegSetFB(&pViaXvMC->xl,0,yOffs(targS),uOffs(targS),vOffs(targS)); + if (past_surface) { + viaMpegSetFB(&pViaXvMC->xl,1,yOffs(pastS),uOffs(pastS),vOffs(pastS)); + } else { + viaMpegSetFB(&pViaXvMC->xl,1,0,0,0); + } + + if (future_surface) { + viaMpegSetFB(&pViaXvMC->xl,2,yOffs(futS),uOffs(futS),vOffs(futS)); + } else { + viaMpegSetFB(&pViaXvMC->xl,2,0,0,0); + } + + viaMpegBeginPicture(&pViaXvMC->xl,pViaXvMC,context->width,context->height,control); + flushPCIXvMCLowLevel(&pViaXvMC->xl); + targS->needsSync = 1; + targS->syncMode = LL_MODE_DECODER_IDLE; + pViaXvMC->decoderOn = 1; + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + +Status XvMCSyncSurface(Display *display,XvMCSurface *surface) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + unsigned i; + + if((display == NULL) || (surface == NULL)) { + return BadValue; + } + if(surface->privData == NULL) { + return (error_base + XvMCBadSurface); + } + + pViaSurface = (ViaXvMCSurface *)surface->privData; + pViaXvMC = pViaSurface->privContext; + + if(pViaXvMC == NULL) { + return (error_base + XvMCBadSurface); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + if (pViaSurface->needsSync) { + CARD32 timeStamp = pViaSurface->timeStamp; + int syncMode = pViaSurface->syncMode; + + if (pViaXvMC->useAGP) { + + syncMode = (pViaSurface->syncMode == LL_MODE_2D || + pViaSurface->timeStamp < pViaXvMC->timeStamp) ? + LL_MODE_2D : LL_MODE_DECODER_IDLE; + if (pViaSurface->syncMode != LL_MODE_2D) + timeStamp = pViaXvMC->timeStamp; + + } else if (syncMode != LL_MODE_2D && + pViaXvMC->rendSurf[0] != (pViaSurface->srfNo | VIA_XVMC_VALID)) { + + pViaSurface->needsSync = 0; + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + + if (syncXvMCLowLevel(&pViaXvMC->xl, syncMode, 1, + pViaSurface->timeStamp)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadValue; + } + pViaSurface->needsSync = 0; + } + + if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { + pViaSurface->needsSync = 0; + for (i=0; i<VIA_MAX_RENDSURF; ++i) { + pViaXvMC->rendSurf[i] = 0; + } + } + + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + +Status XvMCLoadQMatrix(Display *display, XvMCContext *context, + const XvMCQMatrix *qmx) +{ + ViaXvMCContext + *pViaXvMC; + + if((display == NULL) || (context == NULL)) { + return BadValue; + } + if(NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (qmx->load_intra_quantiser_matrix) { + memcpy(pViaXvMC->intra_quantiser_matrix, + qmx->intra_quantiser_matrix, + sizeof(qmx->intra_quantiser_matrix)); + pViaXvMC->intraLoaded = 0; + } + + if (qmx->load_non_intra_quantiser_matrix) { + memcpy(pViaXvMC->non_intra_quantiser_matrix, + qmx->non_intra_quantiser_matrix, + sizeof(qmx->non_intra_quantiser_matrix)); + pViaXvMC->nonIntraLoaded = 0; + } + + if (qmx->load_chroma_intra_quantiser_matrix) { + memcpy(pViaXvMC->chroma_intra_quantiser_matrix, + qmx->chroma_intra_quantiser_matrix, + sizeof(qmx->chroma_intra_quantiser_matrix)); + pViaXvMC->chromaIntraLoaded = 0; + } + + if (qmx->load_chroma_non_intra_quantiser_matrix) { + memcpy(pViaXvMC->chroma_non_intra_quantiser_matrix, + qmx->chroma_non_intra_quantiser_matrix, + sizeof(qmx->chroma_non_intra_quantiser_matrix)); + pViaXvMC->chromaNonIntraLoaded = 0; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + + return Success; +} + +/* + * Below, we provide functions unusable for this implementation, but for + * standard completeness. + */ + + +Status XvMCRenderSurface +( + Display *display, + XvMCContext *context, + unsigned int picture_structure, + XvMCSurface *target_surface, + XvMCSurface *past_surface, + XvMCSurface *future_surface, + unsigned int flags, + unsigned int num_macroblocks, + unsigned int first_macroblock, + XvMCMacroBlockArray *macroblock_array, + XvMCBlockArray *blocks + ) +{ + return (error_base + XvMCBadContext); +} + +Status XvMCCreateBlocks +( + Display *display, + XvMCContext *context, + unsigned int num_blocks, + XvMCBlockArray * block + ) +{ + return (error_base + XvMCBadContext); +} + +Status XvMCDestroyBlocks (Display *display, XvMCBlockArray * block) +{ + return Success; +} + +Status XvMCCreateMacroBlocks +( + Display *display, + XvMCContext *context, + unsigned int num_blocks, + XvMCMacroBlockArray * blocks + ) +{ + return (error_base + XvMCBadContext); +} + +Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray * block) +{ + return (error_base + XvMCBadContext); +} + +Status XvMCCreateSubpicture( Display *display, + XvMCContext *context, + XvMCSubpicture *subpicture, + unsigned short width, + unsigned short height, + int xvimage_id) +{ + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + int priv_count; + unsigned *priv_data; + Status ret; + + if((subpicture == NULL) || (context == NULL) || (display == NULL)){ + return BadValue; + } + + pViaXvMC = (ViaXvMCContext *)context->privData; + if(pViaXvMC == NULL) { + return (error_base + XvMCBadContext); + } + + subpicture->privData = (ViaXvMCSubPicture *) + malloc(sizeof(ViaXvMCSubPicture)); + if(!subpicture->privData) { + return BadAlloc; + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + subpicture->width = context->width; + subpicture->height = context->height; + subpicture->xvimage_id = xvimage_id; + pViaSubPic = (ViaXvMCSubPicture *)subpicture->privData; + + XLockDisplay(display); + if((ret = _xvmc_create_subpicture(display, context, subpicture, + &priv_count, &priv_data))) { + XUnlockDisplay(display); + free(pViaSubPic); + fprintf(stderr,"Unable to create XvMC Subpicture.\n"); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return ret; + } + XUnlockDisplay(display); + + + subpicture->num_palette_entries = VIA_SUBPIC_PALETTE_SIZE; + subpicture->entry_bytes = 3; + strncpy(subpicture->component_order,"YUV",4); + pViaSubPic->srfNo = priv_data[0]; + pViaSubPic->offset = priv_data[1]; + pViaSubPic->stride = (subpicture->width + 31) & ~31; + pViaSubPic->privContext = pViaXvMC; + pViaSubPic->ia44 = (xvimage_id == FOURCC_IA44); + pViaSubPic->needsSync = 0; + + /* Free data returned from _xvmc_create_subpicture */ + + XFree(priv_data); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + +Status +XvMCSetSubpicturePalette (Display *display, XvMCSubpicture *subpicture, + unsigned char *palette) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + unsigned i; + CARD32 tmp; + + if((subpicture == NULL) || (display == NULL)){ + return BadValue; + } + if(subpicture->privData == NULL) { + return (error_base + XvMCBadSubpicture); + } + pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; + for (i=0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + tmp = *palette++ << 8; + tmp |= *palette++ << 16; + tmp |= *palette++ << 24; + tmp |= ((i & 0x0f) << 4) | 0x07; + pViaSubPic->palette[i] = tmp; + } + + pViaXvMC = pViaSubPic->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + sAPriv = SAREAPTR( pViaXvMC ); + hwlLock(&pViaXvMC->xl,1); + setLowLevelLocking(&pViaXvMC->xl,0); + + /* + * If the subpicture is displaying, Immeadiately update it with the + * new palette. + */ + + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + viaVideoSubPictureLocked(&pViaXvMC->xl,pViaSubPic); + } + flushPCIXvMCLowLevel(&pViaXvMC->xl); + setLowLevelLocking(&pViaXvMC->xl,1); + hwlUnlock(&pViaXvMC->xl,1); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + +static int findOverlap(unsigned width,unsigned height, + short *dstX, short *dstY, + short *srcX, short *srcY, + unsigned short *areaW, unsigned short *areaH) +{ + int + w,h; + unsigned + mWidth,mHeight; + + w = *areaW; + h = *areaH; + + if ((*dstX >= width) || (*dstY >= height)) + return 1; + if (*dstX < 0) { + w += *dstX; + *srcX -= *dstX; + *dstX = 0; + } + if (*dstY < 0) { + h += *dstY; + *srcY -= *dstY; + *dstY = 0; + } + if ((w <= 0) || ((h <= 0))) + return 1; + mWidth = width - *dstX; + mHeight = height - *dstY; + *areaW = (w <= mWidth) ? w : mWidth; + *areaH = (h <= mHeight) ? h : mHeight; + return 0; +} + + + +Status XvMCClearSubpicture ( + Display *display, + XvMCSubpicture *subpicture, + short x, + short y, + unsigned short width, + unsigned short height, + unsigned int color + ) +{ + + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + short dummyX,dummyY; + unsigned long bOffs; + + if((subpicture == NULL) || (display == NULL)) { + return BadValue; + } + if(subpicture->privData == NULL) { + return (error_base + XvMCBadSubpicture); + } + pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; + pViaXvMC = pViaSubPic->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + /* Clip clearing area so that it fits inside subpicture. */ + + if (findOverlap(subpicture->width, subpicture->height, &x, &y, + &dummyX, &dummyY, &width, &height)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + + bOffs = pViaSubPic->offset + y*pViaSubPic->stride + x; + viaBlit(&pViaXvMC->xl, 8, 0, pViaSubPic->stride, bOffs, pViaSubPic->stride, + width, height, 1, 1, VIABLIT_FILL, color); + pViaSubPic->needsSync = 1; + pViaSubPic->timeStamp = viaDMATimeStampLowLevel(&pViaXvMC->xl); + if (flushXvMCLowLevel(&pViaXvMC->xl)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadValue; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + +Status +XvMCCompositeSubpicture ( + Display *display, + XvMCSubpicture *subpicture, + XvImage *image, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short dstx, + short dsty + ) +{ + + unsigned i; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + CARD8 *dAddr, *sAddr; + + if((subpicture == NULL) || (display == NULL) || (image == NULL)){ + return BadValue; + } + if(NULL == (pViaSubPic = (ViaXvMCSubPicture *)subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaXvMC = pViaSubPic->privContext; + + + if (image->id != subpicture->xvimage_id) + return BadMatch; + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + + /* + * Clip copy area so that it fits inside subpicture and image. + */ + + if (findOverlap(subpicture->width, subpicture->height, + &dstx, &dsty, &srcx, &srcy, &width, &height)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + if (findOverlap(image->width, image->height, + &srcx, &srcy, &dstx, &dsty, &width, &height)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(&pViaXvMC->xl, LL_MODE_2D, 0, pViaSubPic->timeStamp)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadValue; + } + pViaSubPic->needsSync = 0; + } + + for(i=0; i<height; ++i) { + dAddr = (((CARD8 *)pViaXvMC->fbAddress) + + (pViaSubPic->offset + (dsty+i)*pViaSubPic->stride + dstx)); + sAddr = (((CARD8 *)image->data) + + (image->offsets[0] + (srcy+i)*image->pitches[0] + srcx)); + memcpy(dAddr,sAddr,width); + } + + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + + +Status +XvMCBlendSubpicture ( + Display *display, + XvMCSurface *target_surface, + XvMCSubpicture *subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, + short surfy, + unsigned short surfw, + unsigned short surfh + ) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCSubPicture *pViaSubPic; + + if((display == NULL) || target_surface == NULL){ + return BadValue; + } + + if (subx || suby || surfx || surfy || + (subw != surfw) || (subh != surfh)) { + fprintf(stderr,"ViaXvMC: Only completely overlapping subpicture " + "supported.\n"); + return BadValue; + } + + if(NULL == (pViaSurface = target_surface->privData)) { + return (error_base + XvMCBadSurface); + } + + if (subpicture) { + + if(NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaSurface->privSubPic = pViaSubPic; + } else { + pViaSurface->privSubPic = NULL; + } + return Success; +} + +Status +XvMCBlendSubpicture2 ( + Display *display, + XvMCSurface *source_surface, + XvMCSurface *target_surface, + XvMCSubpicture *subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, + short surfy, + unsigned short surfw, + unsigned short surfh + ) +{ + ViaXvMCSurface *pViaSurface,*pViaSSurface; + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + + unsigned width,height; + + if((display == NULL) || target_surface == NULL || source_surface == NULL){ + return BadValue; + } + + if (subx || suby || surfx || surfy || + (subw != surfw) || (subh != surfh)) { + fprintf(stderr,"ViaXvMC: Only completely overlapping subpicture " + "supported.\n"); + return BadMatch; + } + + if(NULL == (pViaSurface = target_surface->privData)) { + return (error_base + XvMCBadSurface); + } + + if(NULL == (pViaSSurface = source_surface->privData)) { + return (error_base + XvMCBadSurface); + } + pViaXvMC = pViaSurface->privContext; + width = pViaSSurface->width; + height = pViaSSurface->height; + if (width != pViaSurface->width || height != pViaSSurface->height) { + return BadMatch; + } + + if (XvMCSyncSurface(display,source_surface)) { + return BadValue; + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + viaBlit(&pViaXvMC->xl, 8, yOffs(pViaSSurface), pViaSSurface->yStride, + yOffs(pViaSurface), pViaSurface->yStride, + width, height, 1, 1, VIABLIT_COPY, 0); + flushPCIXvMCLowLevel(&pViaXvMC->xl); + viaBlit(&pViaXvMC->xl, 8, uOffs(pViaSSurface), pViaSSurface->yStride >> 1, + uOffs(pViaSurface), pViaSurface->yStride >> 1, + width >> 1, height >> 1, 1, 1, VIABLIT_COPY, 0); + flushPCIXvMCLowLevel(&pViaXvMC->xl); + viaBlit(&pViaXvMC->xl, 8, vOffs(pViaSSurface), pViaSSurface->yStride >> 1, + vOffs(pViaSurface), pViaSurface->yStride >> 1, + width >> 1, height >> 1, 1, 1, VIABLIT_COPY, 0); + pViaSurface->needsSync = 1; + pViaSurface->syncMode = LL_MODE_2D; + pViaSurface->timeStamp = viaDMATimeStampLowLevel(&pViaXvMC->xl); + if (flushXvMCLowLevel(&pViaXvMC->xl)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadValue; + } + if (subpicture) { + + if(NULL == (pViaSubPic = subpicture->privData)) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return (error_base + XvMCBadSubpicture); + } + + pViaSurface->privSubPic = pViaSubPic; + } else { + pViaSurface->privSubPic = NULL; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + +Status +XvMCSyncSubpicture (Display *display, XvMCSubpicture *subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + Status retVal=0; + + if((display == NULL) || subpicture == NULL){ + return BadValue; + } + if(NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + pViaXvMC = pViaSubPic->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(&pViaXvMC->xl, LL_MODE_2D, + 0, pViaSubPic->timeStamp)) { + retVal = BadValue; + } + pViaSubPic->needsSync = 0; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return retVal; +} + +Status +XvMCFlushSubpicture (Display *display, XvMCSubpicture *subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + + if((display == NULL) || subpicture == NULL){ + return BadValue; + } + if(NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + + return Success; +} + +Status +XvMCDestroySubpicture (Display *display, XvMCSubpicture *subpicture) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + + if((display == NULL) || subpicture == NULL){ + return BadValue; + } + if(NULL == (pViaSubPic = subpicture->privData)) { + return (error_base + XvMCBadSubpicture); + } + pViaXvMC = pViaSubPic->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + + sAPriv = SAREAPTR(pViaXvMC); + hwlLock(&pViaXvMC->xl,1); + setLowLevelLocking(&pViaXvMC->xl,0); + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + ( pViaSubPic->srfNo | VIA_XVMC_VALID )) { + viaVideoSubPictureOffLocked(&pViaXvMC->xl); + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = 0; + } + flushPCIXvMCLowLevel(&pViaXvMC->xl); + setLowLevelLocking(&pViaXvMC->xl,1); + hwlUnlock(&pViaXvMC->xl,1); + + XLockDisplay(display); + _xvmc_destroy_subpicture(display,subpicture); + XUnlockDisplay(display); + + free(pViaSubPic); + subpicture->privData = NULL; + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + + return Success; +} + +Status +XvMCGetSubpictureStatus (Display *display, XvMCSubpicture *subpic, int *stat) +{ + ViaXvMCSubPicture *pViaSubPic; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + + + if((display == NULL) || subpic == NULL){ + return BadValue; + } + if(NULL == (pViaSubPic = subpic->privData)) { + return (error_base + XvMCBadSubpicture); + } + if (stat) { + *stat = 0; + pViaXvMC = pViaSubPic->privContext; + sAPriv = SAREAPTR( pViaXvMC ); + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) + *stat |= XVMC_DISPLAYING; + } + return Success; +} + +Status +XvMCFlushSurface (Display *display, XvMCSurface *surface) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + Status ret; + + if((display == NULL) || surface == NULL){ + return BadValue; + } + if(NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + + pViaXvMC = pViaSurface->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (pViaSurface->needsSync) + pViaSurface->timeStamp = pViaXvMC->timeStamp = + viaDMATimeStampLowLevel(&pViaXvMC->xl); + ret = (flushXvMCLowLevel(&pViaXvMC->xl)) ? BadValue : Success; + if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { + hwlLock(&pViaXvMC->xl,0); + pViaXvMC->haveDecoder = 0; + releaseDecoder(pViaXvMC, 0); + hwlUnlock(&pViaXvMC->xl,0); + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + sched_yield(); + return ret; +} + +Status +XvMCGetSurfaceStatus (Display *display, XvMCSurface *surface, int *stat) +{ + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + volatile ViaXvMCSAreaPriv *sAPriv; + unsigned i; + int ret = 0; + + if((display == NULL) || surface == NULL){ + return BadValue; + } + if(NULL == (pViaSurface = surface->privData)) { + return (error_base + XvMCBadSurface); + } + if (stat) { + *stat = 0; + pViaXvMC = pViaSurface->privContext; + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + sAPriv = SAREAPTR( pViaXvMC ); + if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] + == (pViaSurface->srfNo | VIA_XVMC_VALID)) + *stat |= XVMC_DISPLAYING; + for (i=0; i<VIA_MAX_RENDSURF; ++i) { + if(pViaXvMC->rendSurf[i] == + (pViaSurface->srfNo | VIA_XVMC_VALID)) { + *stat |= XVMC_RENDERING; + break; + } + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + } + return ret; +} + +XvAttribute * +XvMCQueryAttributes ( + Display *display, + XvMCContext *context, + int *number + ) +{ + ViaXvMCContext *pViaXvMC; + XvAttribute *ret; + unsigned long siz; + + *number = 0; + if ((display == NULL) || (context == NULL)) { + return NULL; + } + + if (NULL == (pViaXvMC = context->privData)) { + return NULL; + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (NULL != (ret = (XvAttribute *) + malloc(siz = VIA_NUM_XVMC_ATTRIBUTES*sizeof(XvAttribute)))) { + memcpy(ret,pViaXvMC->attribDesc,siz); + *number = VIA_NUM_XVMC_ATTRIBUTES; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + + return ret; +} + +Status +XvMCSetAttribute ( + Display *display, + XvMCContext *context, + Atom attribute, + int value + ) +{ + int found; + unsigned i; + ViaXvMCContext *pViaXvMC; + ViaXvMCCommandBuffer buf; + + if ((display == NULL) || (context == NULL)) { + return (error_base + XvMCBadContext); + } + + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + + found = 0; + for (i=0; i < pViaXvMC->attrib.numAttr; ++i) { + if (attribute == pViaXvMC->attrib.attributes[i].attribute) { + if ((!(pViaXvMC->attribDesc[i].flags & XvSettable)) || + value < pViaXvMC->attribDesc[i].min_value || + value > pViaXvMC->attribDesc[i].max_value) + return BadValue; + pViaXvMC->attrib.attributes[i].value = value; + found = 1; + pViaXvMC->attribChanged = 1; + break; + } + } + if (!found) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return BadMatch; + } + if (pViaXvMC->haveXv) { + buf.command = VIA_XVMC_COMMAND_ATTRIBUTES; + pViaXvMC->xvImage->data = (char *)&buf; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.attrib = pViaXvMC->attrib; + XLockDisplay(display); + pViaXvMC->attribChanged = + XvPutImage(display,pViaXvMC->port,pViaXvMC->draw, + pViaXvMC->gc, + pViaXvMC->xvImage,0,0,1,1,0,0,1,1); + XUnlockDisplay(display); + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} + + +Status +XvMCGetAttribute ( + Display *display, + XvMCContext *context, + Atom attribute, + int *value + ) +{ + int found; + unsigned i; + ViaXvMCContext *pViaXvMC; + + if ((display == NULL) || (context == NULL)) { + return (error_base + XvMCBadContext); + } + + if (NULL == (pViaXvMC = context->privData)) { + return (error_base + XvMCBadContext); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + found = 0; + for (i=0; i < pViaXvMC->attrib.numAttr; ++i) { + if (attribute == pViaXvMC->attrib.attributes[i].attribute) { + if (pViaXvMC->attribDesc[i].flags & XvGettable) { + *value = pViaXvMC->attrib.attributes[i].value; + found = 1; + break; + } + } + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + + if (!found) + return BadMatch; + return Success; +} + + +Status XvMCHideSurface(Display *display,XvMCSurface *surface) +{ + + ViaXvMCSurface *pViaSurface; + ViaXvMCContext *pViaXvMC; + ViaXvMCSubPicture *pViaSubPic; + volatile ViaXvMCSAreaPriv *sAPriv; + ViaXvMCCommandBuffer buf; + Status ret; + + if ((display == NULL) || (surface == NULL)) { + return BadValue; + } + if (NULL == (pViaSurface = surface->privData )) { + return (error_base + XvMCBadSurface); + } + if (NULL == (pViaXvMC = pViaSurface->privContext)) { + return (error_base + XvMCBadContext); + } + + pthread_mutex_lock( &pViaXvMC->ctxMutex ); + if (!pViaXvMC->haveXv) { + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + + sAPriv = SAREAPTR( pViaXvMC ); + hwlLock(&pViaXvMC->xl,1); + + if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] != + (pViaSurface->srfNo | VIA_XVMC_VALID)) { + hwlUnlock(&pViaXvMC->xl,1); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; + } + setLowLevelLocking(&pViaXvMC->xl,0); + if (NULL != (pViaSubPic = pViaSurface->privSubPic)) { + if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == + (pViaSubPic->srfNo | VIA_XVMC_VALID)) { + sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; + viaVideoSubPictureOffLocked(&pViaXvMC->xl); + } + } + flushPCIXvMCLowLevel(&pViaXvMC->xl); + setLowLevelLocking(&pViaXvMC->xl,1); + hwlUnlock(&pViaXvMC->xl,1); + + buf.command = VIA_XVMC_COMMAND_UNDISPLAY; + buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; + buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; + pViaXvMC->xvImage->data = (char *)&buf; + if ((ret = XvPutImage(display,pViaXvMC->port,pViaXvMC->draw, + pViaXvMC->gc, + pViaXvMC->xvImage,0,0,1,1,0,0,1,1))) { + fprintf(stderr,"XvMCPutSurface: Hiding overlay failed.\n"); + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return ret; + } + pthread_mutex_unlock( &pViaXvMC->ctxMutex ); + return Success; +} diff --git a/libxvmc/viaXvMCPriv.h b/libxvmc/viaXvMCPriv.h new file mode 100644 index 000000000000..94b2404f7d5c --- /dev/null +++ b/libxvmc/viaXvMCPriv.h @@ -0,0 +1,205 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004 Thomas Hellström. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIAXVMCPRIV_H +#define _VIAXVMCPRIV_H 1 + +#include <X11/Xlibint.h> +#include <XvMC.h> +#include <XvMClib.h> +#include <stdlib.h> +#include "vldXvMC.h" +#include "via_xvmc.h" +#include "viaLowLevel.h" + + + +extern Status _xvmc_create_context(Display *dpy, XvMCContext *context, + int *priv_count, uint **priv_data); +extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context); +extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context, + XvMCSurface *surface, int *priv_count, + uint **priv_data); +extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface); +extern Status _xvmc_create_subpicture(Display *dpy, XvMCContext *context, + XvMCSubpicture *subpicture, + int *priv_count, uint **priv_data); +extern Status _xvmc_destroy_subpicture(Display *dpy, + XvMCSubpicture *subpicture); + +#define VIA_SUBPIC_PALETTE_SIZE 16 /*Number of colors in subpicture palette*/ +#define VIA_CBUFFERSIZE 4096 /*Hardware command buffer size*/ +#define VIA_MAX_BUFS 2 /*Number of YUV buffers per surface*/ +#define VIA_MAX_RENDSURF 3 /*Maximum numbers of surfaces per context + that can answer RENDERING to a rendering + query*/ + +typedef enum{ + context_lowLevel, + context_mutex, + context_sAreaMap, + context_fbMap, + context_mmioMap, + context_context, + context_fd, + context_none +} ContextRes; + +typedef struct{ + unsigned ctxNo; /* XvMC private context reference number */ + pthread_mutex_t ctxMutex; /* Mutex for multi-threading. Not used */ + drm_context_t drmcontext; /* The drm context */ + drm_handle_t fbOffset; /* Handle to drm frame-buffer area */ + drm_handle_t mmioOffset; /* Handle to drm mmio area */ + drm_handle_t sAreaOffset; /* Handle to drm shared memory area */ + unsigned fbSize; /* Size of drm frame-buffer area */ + unsigned mmioSize; /* Size of drm mmio area */ + unsigned sAreaSize; /* Size of drm shared memory area */ + unsigned sAreaPrivOffset; /* Offset in sarea to private part */ + drmAddress fbAddress; /* Virtual address of frame buffer area */ + drmAddress mmioAddress; /* Virtual address of mmio area */ + drmAddress sAreaAddress; /* Virtual address of shared memory area */ + char busIdString[21]; /* Busid of video card */ + unsigned yStride; /* Y stride of surfaces in this context */ + int fd; /* FD for connection to drm module */ + unsigned char intra_quantiser_matrix[64]; + unsigned char non_intra_quantiser_matrix[64]; + unsigned char chroma_intra_quantiser_matrix[64]; + unsigned char chroma_non_intra_quantiser_matrix[64]; + unsigned rendSurf[VIA_MAX_RENDSURF]; /* Which surfaces answer rendering to + a rendering query */ + int decoderOn; /* Decoder switched on ? */ + int intraLoaded; /* Intra quantiser matrix loaded in + decoder? */ + int nonIntraLoaded; /* Non-Intra quantiser matrix loaded + in decoder */ + int chromaIntraLoaded; + int chromaNonIntraLoaded; + int haveDecoder; /* Does this context own decoder? */ + int attribChanged; /* Attributes have changed and need to + be uploaded to Xv at next frame + display */ + drmLockPtr hwLock; /* Virtual address Pointer to the + heavyweight drm hardware lock */ + unsigned xvMCPort; /* XvMC private port. Corresponds to + an Xv port, but not by number */ + ViaXvMCAttrHolder attrib; /* This contexts attributes and their + values */ + XvAttribute attribDesc[VIA_NUM_XVMC_ATTRIBUTES]; /* Attribute decriptions */ + int useAGP; /* Use the AGP ringbuffer to upload data to the chip */ + XvMCLowLevel xl; /* Lowlevel context. Opaque to us. */ + int haveXv; /* Have I initialized the Xv + connection for this surface? */ + XvImage *xvImage; /* Fake Xv Image used for command + buffer transport to the X server */ + GC gc; /* X GC needed for displaying */ + Drawable draw; /* Drawable to undisplay from */ + XvPortID port; /* Xv Port ID when displaying */ + int lastSrfDisplaying; + ContextRes resources; + CARD32 timeStamp; + unsigned chipId; +}ViaXvMCContext; + +typedef struct{ + pthread_mutex_t subMutex; /* Currently not used. */ + unsigned srfNo; /* XvMC private surface number */ + unsigned offset; /* Offset into frame-buffer area */ + unsigned stride; /* Storage stride */ + unsigned width; /* Width */ + unsigned height; /* Height */ + CARD32 palette[VIA_SUBPIC_PALETTE_SIZE]; /* YUV Palette */ + ViaXvMCContext *privContext; /* Pointer to context private data */ + int ia44; /* IA44 or AI44 format */ + int needsSync; + CARD32 timeStamp; +}ViaXvMCSubPicture; + + +typedef struct{ + pthread_mutex_t srfMutex; /* For multithreading. Not used. */ + pthread_cond_t bufferAvailable; /* For multithreading. Not used. */ + unsigned srfNo; /* XvMC private surface numbers */ + unsigned numBuffers; /* Number of picture buffers */ + unsigned curBuf; /* Which is the current buffer? */ + unsigned offsets[VIA_MAX_BUFS]; /* Offsets of picture buffers + into the frame-buffer area */ + unsigned yStride; /* Stride of YUV420 Y component. */ + unsigned width; /* Dimensions */ + unsigned height; + int progressiveSequence; /* Mpeg progressive picture? Hmm? */ + ViaXvMCContext *privContext; /* XvMC context private part. */ + ViaXvMCSubPicture *privSubPic; /* Subpicture to be blended when + displaying. NULL if none. */ + int needsSync; + int syncMode; + CARD32 timeStamp; +}ViaXvMCSurface; + +/* + * Take and release the global drm hardware lock. + */ + +#define HW_LOCK(ctx) \ + DRM_LOCK((ctx)->fd,(ctx)->hwLock,(ctx)->drmcontext,0) +#define HW_UNLOCK(ctx) \ + DRM_UNLOCK((ctx)->fd,(ctx->hwLock),(ctx)->drmcontext) + +/* + * Low-level Mpeg functions in viaLowLevel.c + */ + +extern void viaMpegReset(XvMCLowLevel *xl); +extern void viaMpegWriteSlice(XvMCLowLevel *xl, CARD8* slice, + int nBytes, CARD32 sCode); +extern void viaMpegSetSurfaceStride(XvMCLowLevel *xl, ViaXvMCContext *ctx); +extern void viaMpegSetFB(XvMCLowLevel *xl,unsigned i, unsigned yOffs, + unsigned uOffs, unsigned vOffs); +extern void viaMpegBeginPicture(XvMCLowLevel *xl, ViaXvMCContext *ctx,unsigned width, + unsigned height,const XvMCMpegControl *control); + +/* + * Low-level Video functions in viaLowLevel.c + */ + + +extern void viaBlit(XvMCLowLevel *xl,unsigned bpp,unsigned srcBase, + unsigned srcPitch,unsigned dstBase,unsigned dstPitch, + unsigned w,unsigned h,int xdir,int ydir, + unsigned blitMode, unsigned color); + +extern void viaVideoSWFlipLocked(XvMCLowLevel *xl, unsigned flags, + int progressiveSequence); +extern void viaVideoSetSWFLipLocked(XvMCLowLevel *xl,unsigned yOffs,unsigned uOffs, + unsigned vOffs); + +extern void viaVideoSubPictureLocked(XvMCLowLevel *xl,ViaXvMCSubPicture *pViaSubPic); +extern void viaVideoSubPictureOffLocked(XvMCLowLevel *xl); + + +#define VIABLIT_TRANSCOPY 0 +#define VIABLIT_COPY 1 +#define VIABLIT_FILL 2 + +#endif diff --git a/libxvmc/vldXvMC.h b/libxvmc/vldXvMC.h new file mode 100644 index 000000000000..aed1c6059b10 --- /dev/null +++ b/libxvmc/vldXvMC.h @@ -0,0 +1,181 @@ +/***************************************************************************** + * VLD Nonstandard XvMC extension. + * + * Copyright (c) 2004 The Unichrome Project. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Thomas Hellström, 2004. + */ + +#ifndef _VLDXVMC_H +#define _VLDXVMC_H + +#include <X11/Xlib.h> +#include <X11/extensions/XvMC.h> +#include <X11/extensions/XvMClib.h> + +/* + * New "Motion compensation type". + */ + +#define XVMC_VLD 0x0020000 + +/* + * Below Flags to be passed in the XvMCMpegControl structure 'flag' field. + */ + +#define XVMC_PROGRESSIVE_SEQUENCE 0x00000010 + +/* + * Zig-Zag Scan / Alternative Scan. + */ + +#define XVMC_ZIG_ZAG_SCAN 0x00000000 +#define XVMC_ALTERNATE_SCAN 0x00000100 + +/* + * Frame DCT and frame prediction are used. / + * Field prediction + */ + +#define XVMC_PRED_DCT_FRAME 0x00000040 +#define XVMC_PRED_DCT_FIELD 0x00000000 + +/* + * Top / Bottom field first + */ + +#define XVMC_TOP_FIELD_FIRST 0x00000080 +#define XVMC_BOTTOM_FIELD_FIRST 0x00000000 + +/* + * Motion vectors coded in intra macroblocks + */ + +#define XVMC_CONCEALMENT_MOTION_VECTORS 0x00000200 + +/* + * Which of two mappings between quantiser_scale_code + * and quantiser_scale shall apply. + */ + +#define XVMC_Q_SCALE_TYPE 0x00000400 + +/* + * Intra VLC Format: Bit = 0, Bit = 1 + * Intra blocks B-14 B-15 + * Non-intra blocks B-14 B-14 + */ +#define XVMC_INTRA_VLC_FORMAT 0x00000800 + +/* + * Also XVMC_SECOND_FIELD should be set in flags if active. + */ + +#define XVMC_I_PICTURE 1 +#define XVMC_P_PICTURE 2 +#define XVMC_B_PICTURE 3 + +typedef struct _XvMCMpegControl{ + unsigned + BVMV_range, /* Backward vertical motion vector range */ + BHMV_range, /* Backward horizontal motion vector range */ + FVMV_range, /* Forward vertical motion vector range */ + FHMV_range, /* Forward horizontal motion vector range */ + picture_structure, /* XVMC_TOP_FIELD, XVMC_BOTTOM_FIELD, + * XVMC_FRAME_PICTURE + */ + intra_dc_precision, /* 0x00 - 0x03 corresponds to 8 to 11 bits prec. */ + picture_coding_type,/* XVMC_X_PICTURE */ + mpeg_coding, /* XVMC_MPEG_2 */ + flags; /* See above */ +}XvMCMpegControl; + + +/* + * The following function is called BEFORE starting sending slices to the + * lib. It grabs the decoder hardware and prepares it for coming slices. + * The function XvMCSyncSurface will release the hardware for other contexts + * in addition to it's current functionality. + */ + +extern Status XvMCBeginSurface(Display *display, + XvMCContext *context, + XvMCSurface *target_surface, + XvMCSurface *past_surface, + XvMCSurface *future_surface, + const XvMCMpegControl *control); + + +/* + * The quantizer matrix structure. This should be filled in by the user and + * uploaded whenever a change is needed. The lib initializes with + * default matrices and will automatically load the hardware with new matrices + * on decoder context switches. To load data, set the corresponding load flag + * to true and fill in the values. The VIA MPEG2 engine only uses the + * intra_quantiser_matrix and the non_intra_quantiser_matrix. RFC: Are + * the other fields needed for future compatibility? + */ + +typedef struct _XvMCQMatrix { + int load_intra_quantiser_matrix; + int load_non_intra_quantiser_matrix; + int load_chroma_intra_quantiser_matrix; + int load_chroma_non_intra_quantiser_matrix; + unsigned char intra_quantiser_matrix[64]; + unsigned char non_intra_quantiser_matrix[64]; + unsigned char chroma_intra_quantiser_matrix[64]; + unsigned char chroma_non_intra_quantiser_matrix[64]; +} XvMCQMatrix; + +/* + * Upload a XvMCQMatrix structure to the clientlib. + * The hardware will start using it the next XvMCBeginSurface. + */ + +extern Status XvMCLoadQMatrix(Display *display, XvMCContext *context, + const XvMCQMatrix *qmx); + + +/* + * Put a slice to the decoder. The hardware will start processing it + * immediately. + */ + +extern Status XvMCPutSlice(Display *display,XvMCContext *context, + char *slice, int nBytes); +/* + * Put a slice without the slice start code to the decoder. + * The hardware will start processing it + * immediately. This function is for client optimization. + * XvMCPutSlice(display,context,slice,nBytes) is equivalent to + * XvMCPutSlice2(display,context,slice+4,nBytes-4,slice[3]); + */ + +extern Status XvMCPutSlice2(Display *display,XvMCContext *context, + char *slice, int nBytes, int sliceCode); + +/* + * Debug the XvMCControl structure. For convenience only. + */ + +extern void debugControl(const XvMCMpegControl *control); + +#endif diff --git a/unichrome/Imakefile b/unichrome/Imakefile new file mode 100644 index 000000000000..e2277a25d792 --- /dev/null +++ b/unichrome/Imakefile @@ -0,0 +1,214 @@ +#define IHaveModules +#include <Server.tmpl> + +XCOMM Check the version to see if we need anything special. +#ifdef XF86_VERSION_CURRENT +XCOMM We are using Xfree86 + +XCOMM This needs a seperate check though, debian dfsg-6 needs this +XCOMM but it's version is still 4.3.0.1 - see via_xvmc.c +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,3,0) +DEFXVPRIV = -DX_NEED_XVPRIV_H +#endif + +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,14,0) +DEFLINFB = -DX_USE_LINEARFB +#endif + +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,16,0) +DEFREGIONNULL = -DX_USE_REGION_NULL +#endif + +#if BuildXF86DRI +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,901,0) +X_DRM_H_LOCATION = -I$(XF86OSSRC)/shared/drm/kernel +#else +X_DRM_H_LOCATION = -I$(XF86OSSRC)/linux/drm/kernel +#endif +#endif + +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,2,0) +XCOMM for Imakefile only +#define X_NEED_NEWMODULETARGET 1 +#endif + +#if XF86_VERSION_CURRENT <= XF86_VERSION_NUMERIC(4,4,99,7,0) +XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here +XCOMM use drmLock instead +DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK +#else +#undef DEFXNEEDDRMLOCK +#endif + +#else +XCOMM We are using X.org +XCOMM The XF86_VERSION stuff just had to be renamed it seems. Why +XCOMM they kept XORG_VERSION at all I don't know, since they are +XCOMM apparently not bothering with altering it. Both the x.org +XCOMM release and a cvs checkout (3m after release) here are +XCOMM 6.7.0.0.0. Luckily, apart from the drm.h location, this is +XCOMM not a problem... yet. -- luc + +DEFXVPRIV = -DX_NEED_XVPRIV_H +DEFLINFB = -DX_USE_LINEARFB +DEFREGIONNULL = -DX_USE_REGION_NULL + +#if BuildXF86DRI +XCOMM Since we are unable to properly version, just include the lot. +X_DRM_H_LOCATION = -I$(DRMSRCDIR)/shared -I$(XF86OSSRC)/shared/drm/kernel +#endif + +XCOMM Include the Xorg changes concerning dlloader (by Adam Jackson). +XCOMM The current changes are not necessary yet, but I've backported +XCOMM them anyway. +#if MakeDllModules +DEFXAAGETROP = -DX_HAVE_XAAGETROP +#endif + +XCOMM We don't need X_NEED_NEWMODULETARGET with X.org +#undef X_NEED_NEWMODULETARGET + +XCOMM I2CBusses require the Start function attached from 6.8 and on +#if XORG_VERSION_MINOR > 7 +DEFI2CSTART = -DX_NEED_I2CSTART +#else +#undef DEFI2CSTART +#endif + +#if XORG_VERSION_MINOR < 7 +XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here +XCOMM use drmLock instead +DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK +#else +#undef DEFXNEEDDRMLOCK +#endif + +#endif + +#if BuildXF86DRI +DRISRCS = via_dri.c via_xvmc.c +DRIOBJS = via_dri.o via_xvmc.o +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ + $(X_DRM_H_LOCATION) -I$(TOP)/include +DRIDEFINES = $(GLX_DEFINES) +#endif + +SRCS = via_driver.c \ + via_accel.c \ + via_bandwidth.c \ + via_mode.c \ + via_cursor.c \ + via_shadow.c \ + via_dga.c \ + via_video.c \ + via_i2c.c \ + via_id.c \ + via_swov.c \ + via_memory.c \ + via_memcpy.c \ + via_vbe.c \ + via_vgahw.c \ + via_vt162x.c \ + $(DRISRCS) + +OBJS = via_driver.o \ + via_accel.o \ + via_bandwidth.o \ + via_mode.o \ + via_cursor.o \ + via_shadow.o \ + via_dga.o \ + via_video.o \ + via_i2c.o \ + via_id.o \ + via_swov.o \ + via_memory.o \ + via_memcpy.o \ + via_vbe.o \ + via_vgahw.o \ + via_vt162x.o \ + $(DRIOBJS) + +#if defined(XF86DriverSDK) +INCLUDES = -I. -I../../include +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ + -I$(XF86SRC)/xf24_32bpp -I$(SERVERSRC)/Xext \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(XF86SRC)/rac -I$(XF86SRC)/int10 -I$(SERVERSRC)/render \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \ + -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb \ + -I$(SERVERSRC)/fb $(DRIINCLUDES) +#endif + +DEFINES = $(DRIDEFINES) $(DEFXVPRIV) $(DEFLINFB) $(DEFREGIONNULL) \ + $(DEFXAAGETROP) $(DEFI2CSTART) $(DEFXNEEDDRMLOCK) + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +NormalAsmObjectRule() + +ModuleObjectRule() +#ifdef X_NEED_NEWMODULETARGET +ObjectModuleTarget(via, $(OBJS),drivers) +#else +ObjectModuleTarget(via, $(OBJS)) +#endif + +#ifdef InstallVideoObjectModule +InstallVideoObjectModule(via,$(MODULEDIR)) +#else +InstallObjectModule(via,$(MODULEDIR),drivers) +#endif + +#if !defined(XF86DriverSDK) +CppManTarget(via,) +InstallModuleManPage(via) +#endif + +DependTarget() + +InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_accel.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_bandwidth.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_bios.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dri.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dri.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_driver.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_driver.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_drm.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_drmclient.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_i2c.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_id.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_id.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memcpy.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memcpy.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_memory.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_mode.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_mode.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_priv.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_regs.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_shadow.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_swov.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_swov.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vbe.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vgahw.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vgahw.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_video.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_video.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vt162x.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_vt162x.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvmc.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvmc.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_xvpriv.h,$(DRIVERSDKDIR)/drivers/via) + +InstallDriverSDKObjectModule(via,$(DRIVERSDKMODULEDIR),drivers) diff --git a/unichrome/via.h b/unichrome/via.h new file mode 100644 index 000000000000..4038be1ea927 --- /dev/null +++ b/unichrome/via.h @@ -0,0 +1,639 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_H_ +#define _VIA_H_ 1 + +/* Video status flag */ + +#define VIDEO_MPEG_INUSE 0x08000000 /*Video is used with MPEG */ +#define VIDEO_HQV_INUSE 0x04000000 /*Video is used with HQV*/ +#define VIDEO_CAPTURE0_INUSE 0x02000000 /*Video is used with CAPTURE 0*/ +#define VIDEO_CAPTURE1_INUSE 0x00000000 /*Video is used with CAPTURE 1*/ +#define VIDEO_1_INUSE 0x01000000 /*Video 1 is used with software flip*/ +#define VIDEO_3_INUSE 0x00000000 /*Video 3 is used with software flip*/ +#define MPEG_USE_V1 0x00010000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/ +#define MPEG_USE_V3 0x00000000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/ +#define MPEG_USE_HQV 0x00020000 /*[17] : 1:MPEG use HQV,0:MPEG not use HQV*/ +#define MPEG_USE_HW_FLIP 0x00040000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/ +#define MPEG_USE_SW_FLIP 0x00000000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/ +#define CAP0_USE_V1 0x00001000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/ +#define CAP0_USE_V3 0x00000000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/ +#define CAP0_USE_HQV 0x00002000 /*[13] : 1:Capture 0 use HQV,0:Capture 0 not use HQV*/ +#define CAP0_USE_HW_FLIP 0x00004000 /*[14] : 1:Capture 0 use H/W flip,0:Capture 0 use S/W flip*/ +#define CAP0_USE_CCIR656 0x00008000 /*[15] : 1:Capture 0 use CCIR656,0:Capture 0 CCIR601*/ +#define CAP1_USE_V1 0x00000100 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/ +#define CAP1_USE_V3 0x00000000 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/ +#define CAP1_USE_HQV 0x00000200 /*[ 9] : 1:Capture 1 use HQV,0:Capture 1 not use HQV*/ +#define CAP1_USE_HW_FLIP 0x00000400 /*[10] : 1:Capture 1 use H/W flip,0:Capture 1 use S/W flip */ +#define SW_USE_V1 0x00000010 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */ +#define SW_USE_V3 0x00000000 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */ +#define SW_USE_HQV 0x00000020 /*[ 5] : 1:Capture 1 use HQV,0:Capture 1 not use HQV */ + +/* +#define VIDEO1_INUSE 0x00000010 //[ 4] : 1:Video 1 is used with S/W flip +#define VIDEO1_USE_HQV 0x00000020 //[ 5] : 1:Video 1 use HQV with S/W flip +#define VIDEO3_INUSE 0x00000001 //[ 0] : 1:Video 3 is used with S/W flip +#define VIDEO3_USE_HQV 0x00000002 //[ 1] : 1:Video 3 use HQV with S/W flip +*/ + +/* H/W registers for Video Engine */ + +/* + * bus master + */ +#define PCI_MASTER_ENABLE 0x01 +#define PCI_MASTER_SCATTER 0x00 +#define PCI_MASTER_SINGLE 0x02 +#define PCI_MASTER_GUI 0x00 +#define PCI_MASTER_VIDEO 0x04 +#define PCI_MASTER_INPUT 0x00 +#define PCI_MASTER_OUTPUT 0x08 + +/* + * video registers + */ +#define V_FLAGS 0x00 +#define V_CAP_STATUS 0x04 +#define V_FLIP_STATUS 0x04 +#define V_ALPHA_WIN_START 0x08 +#define V_ALPHA_WIN_END 0x0C +#define V_ALPHA_CONTROL 0x10 +#define V_CRT_STARTADDR 0x14 +#define V_CRT_STARTADDR_2 0x18 +#define V_ALPHA_STRIDE 0x1C +#define V_COLOR_KEY 0x20 +#define V_ALPHA_STARTADDR 0x24 +#define V_CHROMAKEY_LOW 0x28 +#define V_CHROMAKEY_HIGH 0x2C +#define V1_CONTROL 0x30 +#define V12_QWORD_PER_LINE 0x34 +#define V1_STARTADDR_1 0x38 +#define V1_STARTADDR_Y1 V1_STARTADDR_1 +#define V1_STRIDE 0x3C +#define V1_WIN_START_Y 0x40 +#define V1_WIN_START_X 0x42 +#define V1_WIN_END_Y 0x44 +#define V1_WIN_END_X 0x46 +#define V1_STARTADDR_2 0x48 +#define V1_STARTADDR_Y2 V1_STARTADDR_2 +#define V1_ZOOM_CONTROL 0x4C +#define V1_MINI_CONTROL 0x50 +#define V1_STARTADDR_0 0x54 +#define V1_STARTADDR_Y0 V1_STARTADDR_0 +#define V_FIFO_CONTROL 0x58 +#define V1_STARTADDR_3 0x5C +#define V1_STARTADDR_Y3 V1_STARTADDR_3 +#define HI_CONTROL 0x60 +#define SND_COLOR_KEY 0x64 +#define ALPHA_V3_PREFIFO_CONTROL 0x68 +#define V1_SOURCE_HEIGHT 0x6C +#define HI_TRANSPARENT_COLOR 0x70 +#define V_DISPLAY_TEMP 0x74 /* No use */ +#define ALPHA_V3_FIFO_CONTROL 0x78 +#define V3_SOURCE_WIDTH 0x7C +#define V3_COLOR_KEY 0x80 +#define V1_ColorSpaceReg_1 0x84 +#define V1_ColorSpaceReg_2 0x88 +#define V1_STARTADDR_CB0 0x8C +#define V1_OPAQUE_CONTROL 0x90 /* To be deleted */ +#define V3_OPAQUE_CONTROL 0x94 /* To be deleted */ +#define V_COMPOSE_MODE 0x98 +#define V3_STARTADDR_2 0x9C +#define V3_CONTROL 0xA0 +#define V3_STARTADDR_0 0xA4 +#define V3_STARTADDR_1 0xA8 +#define V3_STRIDE 0xAC +#define V3_WIN_START_Y 0xB0 +#define V3_WIN_START_X 0xB2 +#define V3_WIN_END_Y 0xB4 +#define V3_WIN_END_X 0xB6 +#define V3_ALPHA_QWORD_PER_LINE 0xB8 +#define V3_ZOOM_CONTROL 0xBC +#define V3_MINI_CONTROL 0xC0 +#define V3_ColorSpaceReg_1 0xC4 +#define V3_ColorSpaceReg_2 0xC8 +#define V3_DISPLAY_TEMP 0xCC /* No use */ +#define V1_STARTADDR_CB1 0xE4 +#define V1_STARTADDR_CB2 0xE8 +#define V1_STARTADDR_CB3 0xEC +#define V1_STARTADDR_CR0 0xF0 +#define V1_STARTADDR_CR1 0xF4 +#define V1_STARTADDR_CR2 0xF8 +#define V1_STARTADDR_CR3 0xFC + +/* Video Capture Engine Registers + * Capture Port 1 + */ +#define CAP0_MASKS 0x100 +#define CAP1_MASKS 0x104 +#define CAP0_CONTROL 0x110 +#define CAP0_H_RANGE 0x114 +#define CAP0_V_RANGE 0x118 +#define CAP0_SCAL_CONTROL 0x11C +#define CAP0_VBI_H_RANGE 0x120 +#define CAP0_VBI_V_RANGE 0x124 +#define CAP0_VBI_STARTADDR 0x128 +#define CAP0_VBI_STRIDE 0x12C +#define CAP0_ANCIL_COUNT 0x130 +#define CAP0_MAXCOUNT 0x134 +#define CAP0_VBIMAX_COUNT 0x138 +#define CAP0_DATA_COUNT 0x13C +#define CAP0_FB_STARTADDR0 0x140 +#define CAP0_FB_STARTADDR1 0x144 +#define CAP0_FB_STARTADDR2 0x148 +#define CAP0_STRIDE 0x150 +/* Capture Port 2 */ +#define CAP1_CONTROL 0x154 +#define CAP1_SCAL_CONTROL 0x160 +#define CAP1_VBI_H_RANGE 0x164 /*To be deleted*/ +#define CAP1_VBI_V_RANGE 0x168 /*To be deleted*/ +#define CAP1_VBI_STARTADDR 0x16C /*To be deleted*/ +#define CAP1_VBI_STRIDE 0x170 /*To be deleted*/ +#define CAP1_ANCIL_COUNT 0x174 /*To be deleted*/ +#define CAP1_MAXCOUNT 0x178 +#define CAP1_VBIMAX_COUNT 0x17C /*To be deleted*/ +#define CAP1_DATA_COUNT 0x180 +#define CAP1_FB_STARTADDR0 0x184 +#define CAP1_FB_STARTADDR1 0x188 +#define CAP1_STRIDE 0x18C + +/* SUBPICTURE Registers */ +#define SUBP_CONTROL_STRIDE 0x1C0 +#define SUBP_STARTADDR 0x1C4 +#define RAM_TABLE_CONTROL 0x1C8 +#define RAM_TABLE_READ 0x1CC + +/* HQV Registers */ +#define HQV_CONTROL 0x1D0 +#define HQV_SRC_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_SRC_FETCH_LINE 0x1E0 +#define HQV_FILTER_CONTROL 0x1E4 +#define HQV_MINIFY_CONTROL 0x1E8 +#define HQV_DST_STARTADDR0 0x1EC +#define HQV_DST_STARTADDR1 0x1F0 +#define HQV_DST_STARTADDR2 0x1FC +#define HQV_DST_STRIDE 0x1F4 +#define HQV_SRC_STRIDE 0x1F8 + + +/* + * Video command definition + */ +/* #define V_ALPHA_CONTROL 0x210 */ +#define ALPHA_WIN_EXPIRENUMBER_4 0x00040000 +#define ALPHA_WIN_CONSTANT_FACTOR_4 0x00004000 +#define ALPHA_WIN_CONSTANT_FACTOR_12 0x0000c000 +#define ALPHA_WIN_BLENDING_CONSTANT 0x00000000 +#define ALPHA_WIN_BLENDING_ALPHA 0x00000001 +#define ALPHA_WIN_BLENDING_GRAPHIC 0x00000002 +#define ALPHA_WIN_PREFIFO_THRESHOLD_12 0x000c0000 +#define ALPHA_WIN_FIFO_THRESHOLD_8 0x000c0000 +#define ALPHA_WIN_FIFO_DEPTH_16 0x00100000 + +/* V_CHROMAKEY_LOW 0x228 */ +#define V_CHROMAKEY_V3 0x80000000 + +/* V1_CONTROL 0x230 */ +#define V1_ENABLE 0x00000001 +#define V1_FULL_SCREEN 0x00000002 +#define V1_YUV422 0x00000000 +#define V1_RGB32 0x00000004 +#define V1_RGB15 0x00000008 +#define V1_RGB16 0x0000000C +#define V1_YCbCr420 0x00000010 +#define V1_COLORSPACE_SIGN 0x00000080 +#define V1_SRC_IS_FIELD_PIC 0x00000200 +#define V1_SRC_IS_FRAME_PIC 0x00000000 +#define V1_BOB_ENABLE 0x00400000 +#define V1_FIELD_BASE 0x00000000 +#define V1_FRAME_BASE 0x01000000 +#define V1_SWAP_SW 0x00000000 +#define V1_SWAP_HW_HQV 0x02000000 +#define V1_SWAP_HW_CAPTURE 0x04000000 +#define V1_SWAP_HW_MC 0x06000000 +/* #define V1_DOUBLE_BUFFERS 0x00000000 */ +/* #define V1_QUADRUPLE_BUFFERS 0x18000000 */ +#define V1_EXPIRE_NUM 0x00050000 +#define V1_EXPIRE_NUM_A 0x000a0000 +#define V1_EXPIRE_NUM_F 0x000f0000 /* jason */ +#define V1_FIFO_EXTENDED 0x00200000 +#define V1_ON_CRT 0x00000000 +#define V1_ON_SND_DISPLAY 0x80000000 +#define V1_FIFO_32V1_32V2 0x00000000 +#define V1_FIFO_48V1_32V2 0x00200000 + +/* V12_QWORD_PER_LINE 0x234 */ +#define V1_FETCH_COUNT 0x3ff00000 +#define V1_FETCHCOUNT_ALIGNMENT 0x0000000f +#define V1_FETCHCOUNT_UNIT 0x00000004 /* Doubld QWORD */ + +/* V1_STRIDE */ +#define V1_STRIDE_YMASK 0x00001fff +#define V1_STRIDE_UVMASK 0x1ff00000 + +/* V1_ZOOM_CONTROL 0x24C */ +#define V1_X_ZOOM_ENABLE 0x80000000 +#define V1_Y_ZOOM_ENABLE 0x00008000 + +/* V1_MINI_CONTROL 0x250 */ +#define V1_X_INTERPOLY 0x00000002 /* X interpolation */ +#define V1_Y_INTERPOLY 0x00000001 /* Y interpolation */ +#define V1_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */ +#define V1_X_DIV_2 0x01000000 +#define V1_X_DIV_4 0x03000000 +#define V1_X_DIV_8 0x05000000 +#define V1_X_DIV_16 0x07000000 +#define V1_Y_DIV_2 0x00010000 +#define V1_Y_DIV_4 0x00030000 +#define V1_Y_DIV_8 0x00050000 +#define V1_Y_DIV_16 0x00070000 + +/* V1_STARTADDR0 0x254 */ +#define SW_FLIP_ODD 0x08000000 + +/* V_FIFO_CONTROL 0x258 + * IA2 has 32 level FIFO for packet mode video format + * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable + * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable + * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122 + */ +#define V1_FIFO_DEPTH12 0x0000000B +#define V1_FIFO_DEPTH16 0x0000000F +#define V1_FIFO_DEPTH32 0x0000001F +#define V1_FIFO_DEPTH48 0x0000002F +#define V1_FIFO_DEPTH64 0x0000003F +#define V1_FIFO_THRESHOLD6 0x00000600 +#define V1_FIFO_THRESHOLD8 0x00000800 +#define V1_FIFO_THRESHOLD12 0x00000C00 +#define V1_FIFO_THRESHOLD16 0x00001000 +#define V1_FIFO_THRESHOLD24 0x00001800 +#define V1_FIFO_THRESHOLD32 0x00002000 +#define V1_FIFO_THRESHOLD40 0x00002800 +#define V1_FIFO_THRESHOLD48 0x00003000 +#define V1_FIFO_THRESHOLD56 0x00003800 +#define V1_FIFO_THRESHOLD61 0x00003D00 +#define V1_FIFO_PRETHRESHOLD10 0x0A000000 +#define V1_FIFO_PRETHRESHOLD12 0x0C000000 +#define V1_FIFO_PRETHRESHOLD29 0x1d000000 +#define V1_FIFO_PRETHRESHOLD40 0x28000000 +#define V1_FIFO_PRETHRESHOLD44 0x2c000000 +#define V1_FIFO_PRETHRESHOLD56 0x38000000 +#define V1_FIFO_PRETHRESHOLD61 0x3D000000 + +/* ALPHA_V3_FIFO_CONTROL 0x278 + * IA2 has 32 level FIFO for packet mode video format + * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable + * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable + * 8 level FIFO for ALPHA + * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122 + */ +#define V3_FIFO_DEPTH16 0x0000000F +#define V3_FIFO_DEPTH24 0x00000017 +#define V3_FIFO_DEPTH32 0x0000001F +#define V3_FIFO_DEPTH48 0x0000002F +#define V3_FIFO_DEPTH64 0x0000003F +#define V3_FIFO_THRESHOLD8 0x00000800 +#define V3_FIFO_THRESHOLD12 0x00000C00 +#define V3_FIFO_THRESHOLD16 0x00001000 +#define V3_FIFO_THRESHOLD24 0x00001800 +#define V3_FIFO_THRESHOLD29 0x00001D00 +#define V3_FIFO_THRESHOLD32 0x00002000 +#define V3_FIFO_THRESHOLD40 0x00002800 +#define V3_FIFO_THRESHOLD48 0x00003000 +#define V3_FIFO_THRESHOLD56 0x00003800 +#define V3_FIFO_THRESHOLD61 0x00003D00 +#define V3_FIFO_PRETHRESHOLD10 0x0000000A +#define V3_FIFO_PRETHRESHOLD12 0x0000000C +#define V3_FIFO_PRETHRESHOLD29 0x0000001d +#define V3_FIFO_PRETHRESHOLD40 0x00000028 +#define V3_FIFO_PRETHRESHOLD44 0x0000002c +#define V3_FIFO_PRETHRESHOLD56 0x00000038 +#define V3_FIFO_PRETHRESHOLD61 0x0000003D +#define V3_FIFO_MASK 0x0000007F +#define ALPHA_FIFO_DEPTH8 0x00070000 +#define ALPHA_FIFO_THRESHOLD4 0x04000000 +#define ALPHA_FIFO_MASK 0xffff0000 +#define ALPHA_FIFO_PRETHRESHOLD4 0x00040000 + +/* IA2 */ +#define ColorSpaceValue_1 0x140020f2 +#define ColorSpaceValue_2 0x0a0a2c00 + +#define ColorSpaceValue_1_3123C0 0x13000DED +#define ColorSpaceValue_2_3123C0 0x13171000 +#define ColorSpaceValue_1_32045 0x13000DED +#define ColorSpaceValue_2_32045 0x13171000 + +/* For TV setting */ +#define ColorSpaceValue_1TV 0x140020f2 +#define ColorSpaceValue_2TV 0x0a0a2c00 + +/* V_COMPOSE_MODE 0x298 */ +#define SELECT_VIDEO_IF_COLOR_KEY 0x00000001 /* select video if (color key),otherwise select graphics */ +#define SELECT_VIDEO3_IF_COLOR_KEY 0x00000020 /* For 3123C0, select video3 if (color key),otherwise select graphics */ +#define SELECT_VIDEO_IF_CHROMA_KEY 0x00000002 /* 0x0000000a //select video if (chroma key ),otherwise select graphics */ +#define ALWAYS_SELECT_VIDEO 0x00000000 /* always select video,Chroma key and Color key disable */ +#define COMPOSE_V1_V3 0x00000000 /* V1 on top of V3 */ +#define COMPOSE_V3_V1 0x00100000 /* V3 on top of V1 */ +#define COMPOSE_V1_TOP 0x00000000 +#define COMPOSE_V3_TOP 0x00100000 +#define V1_COMMAND_FIRE 0x80000000 /* V1 commands fire */ +#define V3_COMMAND_FIRE 0x40000000 /* V3 commands fire */ +#define V_COMMAND_LOAD 0x20000000 /* Video register always loaded */ +#define V_COMMAND_LOAD_VBI 0x10000000 /* Video register always loaded at vbi without waiting source flip */ +#define V3_COMMAND_LOAD 0x08000000 /* CLE_C0 Video3 register always loaded */ +#define V3_COMMAND_LOAD_VBI 0x00000100 /* CLE_C0 Video3 register always loaded at vbi without waiting source flip */ +#define SECOND_DISPLAY_COLOR_KEY_ENABLE 0x00010000 + +/* V3_ZOOM_CONTROL 0x2bc */ +#define V3_X_ZOOM_ENABLE 0x80000000 +#define V3_Y_ZOOM_ENABLE 0x00008000 + +/* V3_MINI_CONTROL 0x2c0 */ +#define V3_X_INTERPOLY 0x00000002 /* X interpolation */ +#define V3_Y_INTERPOLY 0x00000001 /* Y interpolation */ +#define V3_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */ +#define V3_X_DIV_2 0x01000000 +#define V3_X_DIV_4 0x03000000 +#define V3_X_DIV_8 0x05000000 +#define V3_X_DIV_16 0x07000000 +#define V3_Y_DIV_2 0x00010000 +#define V3_Y_DIV_4 0x00030000 +#define V3_Y_DIV_8 0x00050000 +#define V3_Y_DIV_16 0x00070000 + +/* SUBP_CONTROL_STRIDE 0x3c0 */ +#define SUBP_HQV_ENABLE 0x00010000 +#define SUBP_IA44 0x00020000 +#define SUBP_AI44 0x00000000 +#define SUBP_STRIDE_MASK 0x00001fff +#define SUBP_CONTROL_MASK 0x00070000 + +/* RAM_TABLE_CONTROL 0x3c8 */ +#define RAM_TABLE_RGB_ENABLE 0x00000007 + +/* CAPTURE0_CONTROL 0x310 */ +#define C0_ENABLE 0x00000001 +#define BUFFER_2_MODE 0x00000000 +#define BUFFER_3_MODE 0x00000004 +#define BUFFER_4_MODE 0x00000006 +#define SWAP_YUYV 0x00000000 +#define SWAP_UYVY 0x00000100 +#define SWAP_YVYU 0x00000200 +#define SWAP_VYUY 0x00000300 +#define IN_601_8 0x00000000 +#define IN_656_8 0x00000010 +#define IN_601_16 0x00000020 +#define IN_656_16 0x00000030 +#define DEINTER_ODD 0x00000000 +#define DEINTER_EVEN 0x00001000 +#define DEINTER_ODD_EVEN 0x00002000 +#define DEINTER_FRAME 0x00003000 +#define VIP_1 0x00000000 +#define VIP_2 0x00000400 +#define H_FILTER_2 0x00010000 +#define H_FILTER_4 0x00020000 +#define H_FILTER_8_1331 0x00030000 +#define H_FILTER_8_12221 0x00040000 +#define VIP_ENABLE 0x00000008 +#define EN_FIELD_SIG 0x00000800 +#define VREF_INVERT 0x00100000 +#define FIELD_INPUT_INVERSE 0x00400000 +#define FIELD_INVERSE 0x40000000 + +#define C1_H_MINI_EN 0x00000800 +#define C0_H_MINI_EN 0x00000800 +#define C1_V_MINI_EN 0x04000000 +#define C0_V_MINI_EN 0x04000000 +#define C1_H_MINI_2 0x00000400 + +/* CAPTURE1_CONTROL 0x354 */ +#define C1_ENABLE 0x00000001 + +/* V3_CONTROL 0x2A0 */ +#define V3_ENABLE 0x00000001 +#define V3_FULL_SCREEN 0x00000002 +#define V3_YUV422 0x00000000 +#define V3_RGB32 0x00000004 +#define V3_RGB15 0x00000008 +#define V3_RGB16 0x0000000C +#define V3_COLORSPACE_SIGN 0x00000080 +#define V3_EXPIRE_NUM 0x00040000 +#define V3_EXPIRE_NUM_F 0x000f0000 +#define V3_EXPIRE_NUM_3204 0x00100000 +#define V3_EXPIRE_NUM_3205 0x00080000 +#define V3_BOB_ENABLE 0x00400000 +#define V3_FIELD_BASE 0x00000000 +#define V3_FRAME_BASE 0x01000000 +#define V3_SWAP_SW 0x00000000 +#define V3_SWAP_HW_HQV 0x02000000 +#define V3_FLIP_HW_CAPTURE0 0x04000000 +#define V3_FLIP_HW_CAPTURE1 0x06000000 + +/* V3_ALPHA_FETCH_COUNT 0x2B8 */ +#define V3_FETCH_COUNT 0x3ff00000 +#define ALPHA_FETCH_COUNT 0x000003ff + +/* HQV_CONTROL 0x3D0 */ +#define HQV_RGB32 0x00000000 +#define HQV_RGB16 0x20000000 +#define HQV_RGB15 0x30000000 +#define HQV_YUV422 0x80000000 +#define HQV_YUV420 0xC0000000 +#define HQV_ENABLE 0x08000000 +#define HQV_SRC_SW 0x00000000 +#define HQV_SRC_MC 0x01000000 +#define HQV_SRC_CAPTURE0 0x02000000 +#define HQV_SRC_CAPTURE1 0x03000000 +#define HQV_FLIP_EVEN 0x00000000 +#define HQV_FLIP_ODD 0x00000020 +#define HQV_SW_FLIP 0x00000010 /* Write 1 to flip HQV buffer */ +#define HQV_DEINTERLACE 0x00010000 /* First line of odd field will be repeated 3 times */ +#define HQV_FIELD_2_FRAME 0x00020000 /* Src is field. Display each line 2 times */ +#define HQV_FRAME_2_FIELD 0x00040000 /* Src is field. Display field */ +#define HQV_FRAME_UV 0x00000000 /* Src is Non-interleaved */ +#define HQV_FIELD_UV 0x00100000 /* Src is interleaved */ +#define HQV_IDLE 0x00000008 +#define HQV_FLIP_STATUS 0x00000001 +#define HQV_DOUBLE_BUFF 0x00000000 +#define HQV_TRIPLE_BUFF 0x04000000 +#define HQV_SUBPIC_FLIP 0x00008000 +#define HQV_FIFO_STATUS 0x00001000 + +/* HQV_FILTER_CONTROL 0x3E4 */ +#define HQV_H_LOWPASS_2TAP 0x00000001 +#define HQV_H_LOWPASS_4TAP 0x00000002 +#define HQV_H_LOWPASS_8TAP1 0x00000003 /* To be deleted */ +#define HQV_H_LOWPASS_8TAP2 0x00000004 /* To be deleted */ +#define HQV_H_HIGH_PASS 0x00000008 +#define HQV_H_LOW_PASS 0x00000000 +#define HQV_V_LOWPASS_2TAP 0x00010000 +#define HQV_V_LOWPASS_4TAP 0x00020000 +#define HQV_V_LOWPASS_8TAP1 0x00030000 +#define HQV_V_LOWPASS_8TAP2 0x00040000 +#define HQV_V_HIGH_PASS 0x00080000 +#define HQV_V_LOW_PASS 0x00000000 +#define HQV_H_HIPASS_F1_DEFAULT 0x00000040 +#define HQV_H_HIPASS_F2_DEFAULT 0x00000000 +#define HQV_V_HIPASS_F1_DEFAULT 0x00400000 +#define HQV_V_HIPASS_F2_DEFAULT 0x00000000 +#define HQV_H_HIPASS_F1_2TAP 0x00000050 +#define HQV_H_HIPASS_F2_2TAP 0x00000100 +#define HQV_V_HIPASS_F1_2TAP 0x00500000 +#define HQV_V_HIPASS_F2_2TAP 0x01000000 +#define HQV_H_HIPASS_F1_4TAP 0x00000060 +#define HQV_H_HIPASS_F2_4TAP 0x00000200 +#define HQV_V_HIPASS_F1_4TAP 0x00600000 +#define HQV_V_HIPASS_F2_4TAP 0x02000000 +#define HQV_H_HIPASS_F1_8TAP 0x00000080 +#define HQV_H_HIPASS_F2_8TAP 0x00000400 +#define HQV_V_HIPASS_F1_8TAP 0x00800000 +#define HQV_V_HIPASS_F2_8TAP 0x04000000 +/* IA2 NEW */ +#define HQV_V_FILTER2 0x00080000 +#define HQV_H_FILTER2 0x00000008 +#define HQV_H_TAP2_11 0x00000041 +#define HQV_H_TAP4_121 0x00000042 +#define HQV_H_TAP4_1111 0x00000401 +#define HQV_H_TAP8_1331 0x00000221 +#define HQV_H_TAP8_12221 0x00000402 +#define HQV_H_TAP16_1991 0x00000159 +#define HQV_H_TAP16_141041 0x0000026A +#define HQV_H_TAP32 0x0000015A +#define HQV_V_TAP2_11 0x00410000 +#define HQV_V_TAP4_121 0x00420000 +#define HQV_V_TAP4_1111 0x04010000 +#define HQV_V_TAP8_1331 0x02210000 +#define HQV_V_TAP8_12221 0x04020000 +#define HQV_V_TAP16_1991 0x01590000 +#define HQV_V_TAP16_141041 0x026A0000 +#define HQV_V_TAP32 0x015A0000 +#define HQV_V_FILTER_DEFAULT 0x00420000 +#define HQV_H_FILTER_DEFAULT 0x00000040 + + + + +/* HQV_MINI_CONTROL 0x3E8 */ +#define HQV_H_MINIFY_ENABLE 0x00000800 +#define HQV_H_MINIFY_DOWN 0x00001000 +#define HQV_V_MINIFY_ENABLE 0x08000000 +#define HQV_V_MINIFY_DOWN 0x10000000 +#define HQV_VDEBLOCK_FILTER 0x80000000 +#define HQV_HDEBLOCK_FILTER 0x00008000 + + +#define CHROMA_KEY_LOW 0x00FFFFFF +#define CHROMA_KEY_HIGH 0x00FFFFFF + +/* V_CAP_STATUS */ +#define V_ST_UPDATE_NOT_YET 0x00000003 +#define V1_ST_UPDATE_NOT_YET 0x00000001 +#define V3_ST_UPDATE_NOT_YET 0x00000008 + +#define VBI_STATUS 0x00000002 + +/* + * Macros for Video MMIO + */ +#ifndef V4L2 +#define VIDInB(port) *((volatile CARD8 *)(pVia->VidMapBase + (port))) +#define VIDInW(port) *((volatile CARD16 *)(pVia->VidMapBase + (port))) +#define VIDInD(port) *((volatile CARD32 *)(pVia->VidMapBase + (port))) +#define VIDOutB(port, data) *((volatile CARD8 *)(pVia->VidMapBase + (port))) = (data) +#define VIDOutW(port, data) *((volatile CARD16 *)(pVia->VidMapBase + (port))) = (data) +#define VIDOutD(port, data) *((volatile CARD32 *)(pVia->VidMapBase + (port))) = (data) +#define MPGOutD(port, data) *((volatile CARD32 *)(pVia->MpegMapBase +(port))) = (data) +#define MPGInD(port) *((volatile CARD32 *)(pVia->MpegMapBase +(port))) +#endif + +/* + * Macros for GE MMIO + */ +#define GEInW(port) *((volatile CARD16 *)(lpGEMMIO + (port))) +#define GEInD(port) *((volatile CARD32 *)(lpGEMMIO + (port))) +#define GEOutW(port, data) *((volatile CARD16 *)(lpGEMMIO + (port))) = (data) +#define GEOutD(port, data) *((volatile CARD32 *)(lpGEMMIO + (port))) = (data) + +/* + * MPEG 1/2 Slice Engine (at 0xC00 relative to base) + */ + +#define MPG_CONTROL 0x00 +#define MPG_CONTROL_STRUCT 0x03 +#define MPG_CONTROL_STRUCT_TOP 0x01 +#define MPG_CONTROL_STRUCT_BOTTOM 0x02 +#define MPG_CONTROL_STRUCT_FRAME 0x03 + /* Use TOP if interlaced */ +#define MPG_CONTROL_TYPE 0x3C +#define MPG_CONTROL_TYPE_I (0x01 << 2) +#define MPG_CONTROL_TYPE_B (0x02 << 2) +#define MPG_CONTROL_TYPE_P (0x03 << 3) +#define MPG_CONTROL_ALTSCAN 0x40 +#define MPG_BLOCK 0x08 /* Unsure */ +#define MPG_COMMAND 0x0C +#define MPG_DATA1 0x10 +#define MPG_DATA2 0x14 +#define MPG_DATA3 0x18 +#define MPG_DATA4 0x1C + +#define MPG_YPHYSICAL(x) (0x20 + 12*(x)) +#define MPG_CbPHYSICAL(x) (0x24 + 12*(x)) +#define MPG_CrPHYSICAL(x) (0x28 + 12*(x)) + +#define MPG_PITCH 0x50 +#define MPG_STATUS 0x54 + +#define MPG_MATRIX_IDX 0x5C +#define MPG_MATRIX_IDX_INTRA 0x00 +#define MPG_MATRIX_IDX_NON 0x01 +#define MPG_MATRIX_DATA 0x60 + +#define MPG_SLICE_CTRL_1 0x90 +#define MPG_SLICE_MBAMAX 0x2FFF +#define MPG_SLICE_PREDICTIVE_DCT 0x4000 +#define MPG_SLICE_TOP_FIRST 0x8000 +#define MPG_SLICE_MACROBLOCK_WIDTH(x) ((x)<<18) /* in 64's */ +#define MPG_SLICE_CTRL_2 0x94 +#define MPG_SLICE_CONCEAL_MVEC 0x0000001 +#define MPG_SLICE_QSCALE_TYPE 0x0000002 +#define MPG_SLICE_DCPRECISION 0x000000C +#define MPG_SLICE_MACROBQUOT 0x0FFFFF0 +#define MPG_SLICE_INTRAVLC 0x1000000 +#define MPG_SLICE_CTRL_3 0x98 +#define MPG_SLICE_FHMVR 0x0000003 +#define MPG_SLICE_FVMVR 0x000000C +#define MPG_SLICE_BHMVR 0x0000030 +#define MPG_SLICE_BVMVR 0x00000C0 +#define MPG_SLICE_SECOND_FIELD 0x0100000 +#define MPG_SLICE_RESET 0x0400000 +#define MPG_SLICE_LENGTH 0x9C +#define MPG_SLICE_DATA 0xA0 + + + +#endif /* _VIA_H_ */ diff --git a/unichrome/via.man b/unichrome/via.man new file mode 100644 index 000000000000..69d8853dbf24 --- /dev/null +++ b/unichrome/via.man @@ -0,0 +1,150 @@ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH VIA __drivermansuffix__ __vendorversion__ +.SH NAME +via \- VIA unichrome graphics driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qvia\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B via +is an __xservername__ driver for VIA chipsets with onboard unichrome graphics. +.PP +The +.B via +driver supports the VIA CLE266, KM400/KN400 chipsets, including 2D +acceleration and the Xv video overlay extensions. Flat panel, TV and VGA +outputs are supported. +.PP +K8M800/K8N800, PM8X0 and CN400 support is still under development. +.PP +Direct rendering 3D is available using experimental drivers in Mesa, www.mesa3d.org. +Also there is an XvMC client library for hardware MPEG1 / MPEG2 decoding +acceleration available on the CLE266 and K8M/N800 chipsets that uses the Direct +Rendering Infrastructure, DRI. The XvMC client library implements a nonstandard +\*qVLD\*q extension to the XvMC standard. The current Direct Rendering Manager +Linux kernel module is available +at dri.sourceforge.net. +.PP +Only a limited number of resolutions are supported at 60, 75, 85, 100 and +120Hz (save memory bandwidth limitations): 640x480, 800x600, 1024x768, +1152x864, 1280x1024 and 1600x1200. Another range of resolutions is only +possible at 60Hz: 720x480, 720x576, 848x480, 856x480, 1024x512, 1024x576, +1280x768, 1280x960, 1400x1050 and 1440x1050. This behaviour will change in +the not too distant future. +.PP +.SH CONFIGURATION DETAILS +Please refer to __xconfigfile__(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The following driver +.B options +are supported +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disable or enable acceleration. Default: acceleration is enabled. +.TP +.BI "Option \*qHWCursor\*q \*q" boolean \*q +Disable or enable use of hardware cursors. The default is enabled. +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Disable or enable the use of a software cursor. The default is disabled. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Use a shadow frame buffer. This is required when rotating the display, +but otherwise defaults to disabled. +.TP +.BI "Option \*qVideoRAM\*q \*q" boolean \*q +Override the VideoRAM auto detection. This should never be needed. +.TP +.BI "Option \*qRotate\*q \*q" string \*q +Rotate the display either clockwise (\*qCW\*q) or counter clockwise (\*qCCW\*q). +Rotation is only supported unaccelerated. +.TP +.BI "Option \*qActiveDevice\*q \*q" string \*q +Specify the active device combination. Any string containing \*qCRT\*q, +\*qLCD\*q, \*qTV\*q should be possible. The default is to use what is +detected. The driver is currently unable to use LCD and TV simultaneously, +and will favour the LCD. +.TP +.BI "Option \*qLCDDualEdge\*q \*q" boolean \*q +Use dual edge mode to set the LCD. +.TP +.BI "Option \*qCenter\*q \*q" boolean \*q +Disable or enable image centering on DVI displays. +.TP +.BI "Option \*qPanelSize\*q \*q" string \*q +Specify the size (width x height) of the LCD panel attached to the +system. Sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050 +are supported. +.TP +.BI "Option \*qTVDotCrawl\*q \*q" boolean \*q +Disable or enable dotcrawl. +.TP +.BI "Option \*qTVDeflicker\*q \*q" integer \*q +Specify deflicker setting for TV output. Valid values are 0,1,2 +0) No deflicker, 1) 1:1:1 deflicker, 2) 1:2:1 deflicker. +.TP +.BI "Option \*qTVType\*q \*q" string \*q +Specify TV output format. The driver currently supports \*qNTSC\*q and +\*qPAL\*q timings only. +.TP +.BI "Option \*qTVOutput\*q \*q" string \*q +Specify which TV output to use. The driver supports \*qS-Video\*q, +\*qComposite\*q, \*qSC\*q, \*qRGB\*q and \*qYCbCr\*q outputs. Note that on some +EPIA boards the composite video port is shared with audio out and jumper +selected. +.TP +.BI "Option \*qDisableVQ\*q \*q" boolean \*q +Disable or enable the use of VQ. VQ is enabled by default. +.TP +.BI "Option \*qDRIXINERAMA\*q \*q" boolean \*q +Set DRI Xinerama mode. Currently unsupported. +.TP +.BI "Option \*qDisableIRQ\*q \*q" boolean \*q +Disables Vblank IRQ. A workaround for some mainboards that have +problems with IRQs from the unichrome chip. With IRQ disabled, +DRI clients have no way to sync drawing to Vblank. +.TP +.BI "Option \*qEnableAGPDMA\*q \*q" boolean \*q +Enable the AGP DMA functionality in DRM. This requires that DRI is enabled +and will force 2D, and 3D acceleration to use AGP DMA. The XvMC DRI client will also +make use of this on the CLE266 to consume much less CPU. +.TP +.BI "Option \*qNoAGPFor2D\*q \*q" boolean \*q +With this option on, 2D acceleration will not use AGP DMA even if it is enabled. + +.SH "Supported TV Encoders" +Unichromes tend to be paired with several different TV Encoders. +.TP +.BI "VIA Technologies VT1621" +Untested as no combination with Unichrome is known or available. +Supports the following normal modes: \*q640x480\*q and \*q800x600\*q. Use +\*q640x480Over\*q and \*q800x600Over\*q for vertical overscan. These modes +are made available by the driver and modelines provided in __xconfigfile__ +will not work. +.TP +.BI "VIA Technologies VT1622, VT1622A, VT1623" +Supports the following modes: \*q640x480\*q, \*q800x600\*q, \*q1024x768\*q, +\*q848x480\*q, \*q720x480\*q (NTSC only) and \*q720x576\*q (PAL only). Use +\*q640x480Over\*q, \*q800x600Over\*q, \*q1024x768Over\*q, \*q848x480Over\*q, +\*q720x480Over\*q (NTSC) and \*q720x576Over\*q (PAL) for vertical overscan. +The mode \*q720x576Noscale\*q (PAL) is provided for quality TV video output. +This mode turns off the scaling within the TV chip and sets the dot clock and +other registers for minimal overscan on a PAL TV. +These modes are made available by the driver and modelines provided in +__xconfigfile__ will not work. + +.SH "BUGS" +Switching virtual terminals when an OpenGL DRI client is running may cause +subsequent rendering errors or server crash. XvMC DRI does not suffer from this. +.SH "SEE ALSO" +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) +.SH AUTHORS +Authors include: ... diff --git a/unichrome/via_accel.c b/unichrome/via_accel.c new file mode 100644 index 000000000000..d5f60d130c4d --- /dev/null +++ b/unichrome/via_accel.c @@ -0,0 +1,1458 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/************************************************************************* + * + * File: via_accel.c + * Content: 2D acceleration function for VIA/S3G UniChrome + * + ************************************************************************/ + +#include "Xarch.h" +#include "xaalocal.h" +#include "xaarop.h" +#include "miline.h" + +#include "via_driver.h" +#include "via_regs.h" +#include "via_id.h" + +/* Forward declaration of functions used in the driver */ + +static void VIASetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int trans_color); + +static void VIASubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h); + +static void VIASetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned planemask); + +static void VIASubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h); + +static void VIASetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int fg, + int bg, + int rop, + unsigned planemask); + +static void VIASubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patOffx, + int patOffy, + int x, + int y, + int w, + int h); + +static void VIASetupForColor8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int rop, + unsigned planemask, + int trans_color); + +static void VIASubsequentColor8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patOffx, + int patOffy, + int x, + int y, + int w, + int h); + +static void VIASetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned planemask); + +static void VIASubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ +static void VIASetupForScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int bg, + int fg, + int rop, + unsigned planemask); + +static void VIASubsequentScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int srcx, + int srcy, + int offset); +#endif + + +static void VIASetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned planemask, + int trans_color, + int bpp, + int depth); + +static void VIASubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +static void +VIASetupForSolidLine( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned int planemask); + +static void +VIASubsequentSolidTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int flags); + +static void +VIASubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, + int y, + int len, + int dir); + +static void +VIASetupForDashedLine( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned int planemask, + int length, + unsigned char *pattern); + +static void +VIASubsequentDashedTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int flags, + int phase); + +static void VIASetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2); + +static void VIADisableClipping( ScrnInfoPtr ); + +void +VIAInitialize2DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwVQStartAddr, dwVQEndAddr; + CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; + CARD32 dwGEMode; + ViaTwodContext *tdc = &pVia->td; + + + /* init 2D engine regs to reset 2D engine */ + VIASETREG(0x04, 0x0); + VIASETREG(0x08, 0x0); + VIASETREG(0x0c, 0x0); + VIASETREG(0x10, 0x0); + VIASETREG(0x14, 0x0); + VIASETREG(0x18, 0x0); + VIASETREG(0x1c, 0x0); + VIASETREG(0x20, 0x0); + VIASETREG(0x24, 0x0); + VIASETREG(0x28, 0x0); + VIASETREG(0x2c, 0x0); + VIASETREG(0x30, 0x0); + VIASETREG(0x34, 0x0); + VIASETREG(0x38, 0x0); + VIASETREG(0x3c, 0x0); + VIASETREG(0x40, 0x0); + + /* Init AGP and VQ regs */ + VIASETREG(0x43c, 0x00100000); + VIASETREG(0x440, 0x00000000); + VIASETREG(0x440, 0x00333004); + VIASETREG(0x440, 0x60000000); + VIASETREG(0x440, 0x61000000); + VIASETREG(0x440, 0x62000000); + VIASETREG(0x440, 0x63000000); + VIASETREG(0x440, 0x64000000); + VIASETREG(0x440, 0x7D000000); + + VIASETREG(0x43c, 0xfe020000); + VIASETREG(0x440, 0x00000000); + + if (pVia->VQStart != 0) { + /* Enable VQ */ + dwVQStartAddr = pVia->VQStart; + dwVQEndAddr = pVia->VQEnd; + dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); + dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); + dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) | + ((dwVQEndAddr & 0xFF000000) >> 16); + dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3); + + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x080003fe); + VIASETREG(0x440, 0x0a00027c); + VIASETREG(0x440, 0x0b000260); + VIASETREG(0x440, 0x0c000274); + VIASETREG(0x440, 0x0d000264); + VIASETREG(0x440, 0x0e000000); + VIASETREG(0x440, 0x0f000020); + VIASETREG(0x440, 0x1000027e); + VIASETREG(0x440, 0x110002fe); + VIASETREG(0x440, 0x200f0060); + + VIASETREG(0x440, 0x00000006); + VIASETREG(0x440, 0x40008c0f); + VIASETREG(0x440, 0x44000000); + VIASETREG(0x440, 0x45080c04); + VIASETREG(0x440, 0x46800408); + + VIASETREG(0x440, dwVQStartEndH); + VIASETREG(0x440, dwVQStartL); + VIASETREG(0x440, dwVQEndL); + VIASETREG(0x440, dwVQLen); + } + else { + /* Diable VQ */ + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x00000004); + VIASETREG(0x440, 0x40008c0f); + VIASETREG(0x440, 0x44000000); + VIASETREG(0x440, 0x45080c04); + VIASETREG(0x440, 0x46800408); + } + + dwGEMode = 0; + + switch (pScrn->bitsPerPixel) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + + /* Set BPP and Pitch */ + tdc->mode = dwGEMode; +} + + +#define CLEAR_CBUFFER(buf, pVia) \ + (buf)->curPos = 0; \ + (pVia)->justSetup = 1; + +#define COND_CLEAR_CBUFFER(buf, pVia) \ + if ((pVia)->justSetup == 1) { \ + (pVia)->justSetup = 0; \ + } else { \ + (buf)->curPos = 0; \ + } + +#define CBUFFER(buf,offset,value) \ + (buf)->buffer[(buf)->curPos++] = ((offset) >> 2) | 0xF0000000; \ + (buf)->buffer[(buf)->curPos++] = (value); \ + + +static void dispatchCBuffer(VIAPtr pVia, ViaCBuffer *buf) +{ + unsigned size = buf->curPos >> 1; + int i; + register CARD32 *bp = buf->buffer; + unsigned loop = 0; + register unsigned offset; + register unsigned value; + + /* + * Not doing this wait will probably stall the processor + * for an unacceptable amount of time in VIASETREG while other high + * priority interrupts may be pending. + */ + + mem_barrier(); + + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)); + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY )) && + (loop++ < MAXLOOP)); + + for(i=0; i<size; ++i) { + offset = (*bp++ & 0x0FFFFFFF) << 2; + value = *bp++; + VIASETREG( offset , value); + } +} + +static void dispatchCBufferAGP(VIAPtr pVia, ViaCBuffer *buf) +{ +#ifdef XF86DRI + drm_via_cmdbuffer_t b; + + b.buf = (char *)(buf->buffer); + b.size = buf->curPos*sizeof(CARD32); + + if (pVia->directRenderingEnabled && pVia->agpEnable && pVia->dma2d) { + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + if (pVIADRI->ringBufActive) { + if (drmCommandWrite(pVia->drmFD,DRM_VIA_CMDBUFFER,&b,sizeof(b))) + dispatchCBuffer(pVia,buf); /* No success using AGP. Try PCI instead. */ + return; + } + } +#endif + /* + * No AGP ringbuffer or no DRI. + */ + + dispatchCBuffer(pVia,buf); +} + + +/* Acceleration init function, sets up pointers to our accelerated functions */ +Bool +VIAInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + XAAInfoRecPtr xaaptr; + BoxRec AvailFBArea; + unsigned long cacheEnd; + unsigned long cacheEndTmp; + + + pVia->VQStart = 0; + if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && + pVia->VQEnable) { + /* Reserved space for VQ */ + pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE; + pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1; + pVia->FBFreeEnd -= VIA_VQ_SIZE; + } + if (pVia->hwcursor) { + pVia->FBFreeEnd -= VIA_CURSOR_SIZE; + } + + VIAInitialize2DEngine(pScrn); + + if (pScrn->depth == 8) { + pVia->PlaneMask = 0xFF; + } + else if (pScrn->depth == 15) { + pVia->PlaneMask = 0x7FFF; + } + else if (pScrn->depth == 16) { + pVia->PlaneMask = 0xFFFF; + } + else if (pScrn->depth == 24) { + pVia->PlaneMask = 0xFFFFFF; + } + + /* General acceleration flags */ + if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec())) + return FALSE; + + xaaptr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER | + MICROSOFT_ZERO_LINE_BIAS | + 0; + + if (pScrn->bitsPerPixel == 8) + xaaptr->CachePixelGranularity = 128; + + /* Clipping */ + xaaptr->SetClippingRectangle = VIASetClippingRectangle; + xaaptr->DisableClipping = VIADisableClipping; + xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | + HARDWARE_CLIP_SOLID_LINE | + HARDWARE_CLIP_DASHED_LINE | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_COLOR_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | + 0; + + xaaptr->Sync = VIAAccelSync; + + /* ScreenToScreen copies */ + xaaptr->SetupForScreenToScreenCopy = VIASetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = VIASubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + /* Solid filled rectangles */ + xaaptr->SetupForSolidFill = VIASetupForSolidFill; + xaaptr->SubsequentSolidFillRect = VIASubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + /* Mono 8x8 pattern fills */ + xaaptr->SetupForMono8x8PatternFill = VIASetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + VIASubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST | + 0; + + /* Color 8x8 pattern fills */ + xaaptr->SetupForColor8x8PatternFill = VIASetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + VIASubsequentColor8x8PatternFillRect; + xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + 0; + +#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ + + /* Screen to Screen color expansion. */ + xaaptr->SetupForScreenToScreenColorExpandFill = + VIASetupForScreenToScreenColorExpand; + xaaptr->SubsequentScreenToScreenColorExpandFill = + VIASubsequentScreenToScreenColorExpand; + xaaptr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST | + ROP_NEEDS_SOURCE | + 0; +#endif + + /* Solid lines */ + xaaptr->SetupForSolidLine = VIASetupForSolidLine; + xaaptr->SubsequentSolidTwoPointLine = VIASubsequentSolidTwoPointLine; + xaaptr->SubsequentSolidHorVertLine = VIASubsequentSolidHorVertLine; + xaaptr->SolidBresenhamLineErrorTermBits = 14; + xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + /* dashed line */ + xaaptr->SetupForDashedLine = VIASetupForDashedLine; + xaaptr->SubsequentDashedTwoPointLine = VIASubsequentDashedTwoPointLine; + xaaptr->DashPatternMaxLength = 8; + xaaptr->DashedLineFlags = NO_PLANEMASK | + ROP_NEEDS_SOURCE | + LINE_PATTERN_POWER_OF_2_ONLY | + LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | + 0; + + /* CPU to Screen color expansion */ + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | + ROP_NEEDS_SOURCE | + 0; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + VIASetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + VIASubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->ColorExpandBase = pVia->BltBase; + xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; + + /* ImageWrite */ + xaaptr->ImageWriteFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | + ROP_NEEDS_SOURCE | + SYNC_AFTER_IMAGE_WRITE | + 0; + + /* + * CLE266 has fast direct processor access to the framebuffer. + * Therefore, disable the PCI GXcopy. + */ + + if (pVia->Chipset == VIA_CLE266) + xaaptr->ImageWriteFlags |= NO_GXCOPY; + + xaaptr->SetupForImageWrite = VIASetupForImageWrite; + xaaptr->SubsequentImageWriteRect = VIASubsequentImageWriteRect; + xaaptr->ImageWriteBase = pVia->BltBase; + xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; + + /* We reserve space for pixel cache */ + + cacheEnd = pVia->FBFreeEnd / pVia->Bpl; + cacheEndTmp = (pVia->FBFreeStart + VIA_PIXMAP_CACHE_SIZE + pVia->Bpl-1) + / pVia->Bpl; + + /* + * Use only requested pixmap size if it is less than available + * offscreen memory. + */ + + if(cacheEnd > cacheEndTmp) + cacheEnd = cacheEndTmp; + /* + * Clip to the blitter limit + */ + + if (cacheEnd > VIA_MAX_ACCEL_Y) + cacheEnd = VIA_MAX_ACCEL_Y; + + pVia->FBFreeStart = (cacheEnd + 1) *pVia->Bpl; + + /* + * Finally, we set up the video memory space available to the pixmap + * cache + */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = cacheEnd; + + xf86InitFBManager(pScreen, &AvailFBArea); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + AvailFBArea.y2 - pScrn->virtualY )); + + pVia->justSetup = 0; + return XAAInit(pScreen, xaaptr); +} + +/* + * The sync function for the GE + */ +void +VIAAccelSync(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int loop = 0; + + mem_barrier(); + + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) + ; + + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && + (loop++ < MAXLOOP)) + ; +} + +/* These are the ScreenToScreen bitblt functions. We support all ROPs, all + * directions. + * + */ + +static void +VIASetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_BLT | (XAAGetCopyROP(rop) << 24); +#else + cmd = VIA_GEC_BLT | (XAACopyROP[rop] << 24); +#endif + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + pVia->SavedCmd = cmd; + + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + if (trans_color != -1) { + /* Transparent Bitblt */ + CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color); + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000); + } + else { + /* Disable Transparent Bitblt */ + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); + } +} + +static void +VIASubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + CARD32 srcBase, dstBase; + + if (!w || !h) + return; + + srcBase = y1*pVia->Bpl + x1*pVia->Bpp; + dstBase = y2*pVia->Bpl + x2*pVia->Bpp; + + x1 = (srcBase & 31); + x2 = (dstBase & 31); + + switch (pScrn->bitsPerPixel) { + case 16: + x1 >>= 1; + x2 >>= 1; + break; + case 32: + x1 >>= 2; + x2 >>= 2; + break; + default: + break; + } + + y1 = 0; + y2 = 0; + + if (pVia->SavedCmd & VIA_GEC_DECX) { + x1 += (w - 1); + x2 += (w - 1); + } + + if (pVia->SavedCmd & VIA_GEC_DECY) { + y1 += (h - 1); + y2 += (h - 1); + } + + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode ); + /* Set Src and Dst base address and pitch, pitch is qword */ + CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~31) >> 3); + CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + (pVia->Bpl >> 3) | ((pVia->Bpl >> 3) << 16)); + CBUFFER(buf,VIA_REG_SRCPOS, ((y1 << 16) | x1)); + CBUFFER(buf,VIA_REG_DSTPOS, ((y2 << 16) | x2)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBufferAGP(pVia, buf); +} + + +/* + * SetupForSolidFill is also called to set up for lines. + */ + +static void +VIASetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + + cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | +#ifdef X_HAVE_XAAGETROP + (XAAGetPatternROP(rop) << 24); +#else + (XAAPatternROP[rop] << 24); +#endif + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = color; +} + + +static void +VIASubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + if (!w || !h) + return; + + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + /* Set Src and Dst base address and pitch, pitch is qword */ + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBufferAGP(pVia, buf); + +} + + +/* + * The meaning of the two pattern paremeters to Setup & Subsequent for + * Mono8x8Patterns varies depending on the flag bits. We specify + * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns + * without caching in the frame buffer. Thus, Setup gets the pattern bits. + * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify + * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated + * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, + * then Setup would get the unrotated pattern, and Subsequent gets the + * origin values. + */ + +static void +VIASetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int fg, + int bg, + int rop, + unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + + cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO | +#ifdef X_HAVE_XAAGETROP + (XAAGetPatternROP(rop) << 24); +#else + (XAAPatternROP[rop] << 24); +#endif + + if (bg == -1) { + /* transparent mono pattern */ + cmd |= VIA_GEC_MPAT_TRANS; + } + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = fg; + pVia->SavedBgColor = bg; + pVia->SavedPattern0 = pattern0; + pVia->SavedPattern1 = pattern1; +} + + +static void +VIASubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patOffx, + int patOffy, + int x, + int y, + int w, + int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwPatOffset; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + if (!w || !h) + return; + + dwPatOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + /* Set Src and Dst base address and pitch, pitch is qword */ + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_PATADDR, dwPatOffset); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); + CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0); + CBUFFER(buf,VIA_REG_MONOPAT1, pVia->SavedPattern1); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBufferAGP(pVia, buf); + +} + +static void +VIASetupForColor8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int rop, + unsigned planemask, + int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_BLT | (XAAGetPatternROP(rop) << 24); +#else + cmd = VIA_GEC_BLT | (XAAPatternROP[rop] << 24); +#endif + + pVia->SavedCmd = cmd; + pVia->SavedPatternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); +} + + +static void +VIASubsequentColor8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patOffx, + int patOffy, + int x, + int y, + int w, + int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwPatAddr; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + if (!w || !h) + return; + + dwPatAddr = (pVia->SavedPatternAddr >> 3) | + ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + + /* Set Src and Dst base address and pitch, pitch is qword */ + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_PATADDR, dwPatAddr); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBufferAGP(pVia, buf); + +} + +static void +VIASetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | +#ifdef X_HAVE_XAAGETROP + (XAAGetCopyROP(rop) << 24); +#else + (XAACopyROP[rop] << 24); +#endif + + if (bg == -1) { + cmd |= VIA_GEC_MSRC_TRANS; + } + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = fg; + pVia->SavedBgColor = bg; + + /* Disable Transparent Bitblt */ + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); +} + + +static void +VIASubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + /* XAA will be sending bitmap data next. */ + /* We should probably wait for empty/idle here. */ + + if (skipleft) { + VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); + } + + /* Set Src and Dst base address and pitch, pitch is qword */ + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + CBUFFER(buf,VIA_REG_SRCPOS, 0); + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBuffer(pVia, buf); + +} + +#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ +static void +VIASetupForScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned int planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCBuffer *buf = &pVia->cBuf; + +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_BLT | VIA_GEC_SRC_MONO | (XAAGetCopyROP(rop) << 24); +#else + cmd = VIA_GEC_BLT | VIA_GEC_SRC_MONO | (XAACopyROP[rop] << 24); +#endif + + if (bg == -1) { + cmd |= VIA_GEC_MSRC_TRANS; + } + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = fg; + pVia->SavedBgColor = bg; + + /* Disable Transparent Bitblt */ + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); +} + + +static void +VIASubsequentScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int srcx, + int srcy, + int offset) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + CARD32 srcBase,dstBase; + + srcBase = srcy*pVia->Bpl + srcx*pVia->Bpp; + dstBase = y*pVia->Bpl + x*pVia->Bpp; + + x = (dstBase & 31); + srcx = srcBase & 7; + + switch (pScrn->bitsPerPixel) { + case 16: + x >>= 1; + break; + case 32: + x >>= 2; + break; + default: + break; + } + + srcy = 0; + y = 0; + + /* Set Src and Dst base address and pitch, pitch is qword */ + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); + CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~7) >> 3); + CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + CBUFFER(buf,VIA_REG_SRCPOS, (srcx << 6) | offset); + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + + dispatchCBufferAGP(pVia, buf); +} + +#endif + +static void +VIASetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned planemask, + int trans_color, + int bpp, + int depth) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + /* We don't record bpp and depth because we assume bpp is equal to + bpp of screen. Is this assume correct ? */ + +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | (XAAGetCopyROP(rop) << 24); +#else + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | (XAACopyROP[rop] << 24); +#endif + + pVia->SavedCmd = cmd; + + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + if (trans_color != -1) { + /* Transparent Bitblt */ + CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color); + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000); + } + else { + /* Disable Transparent Bitblt */ + CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); + } +} + + +static void +VIASubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + if (skipleft) { + VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); + } + + /* Set Src and Dst base address and pitch, pitch is qword */ + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + CBUFFER(buf,VIA_REG_SRCPOS, 0); + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + dispatchCBuffer(pVia, buf); + +} + + +/* Setup for XAA solid lines. */ +static void +VIASetupForSolidLine( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned int planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + /* we move VIA_GEC_LINE from here to the place firing command */ +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); +#else + cmd = VIA_GEC_FIXCOLOR_PAT | (XAAPatternROP[rop] << 24); +#endif + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = color; + + /* set solid line pattern */ + CBUFFER(buf,VIA_REG_MONOPAT0, 0xFF); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + +} + + +static void +VIASubsequentSolidTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int flags) +{ + VIAPtr pVia = VIAPTR(pScrn); + int dx, dy, cmd, tmp, error = 1; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + cmd = pVia->SavedCmd | VIA_GEC_LINE; + + dx = x2 - x1; + if (dx < 0) { + dx = -dx; + cmd |= VIA_GEC_DECX; /* line will be drawn from right */ + error = 0; + } + + dy = y2 - y1; + if (dy < 0) { + dy = -dy; + cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + } + + if (dy > dx) { + tmp = dy; + dy = dx; + dx = tmp; /* Swap 'dx' and 'dy' */ + cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + } + + if (flags & OMIT_LAST) { + cmd |= VIA_GEC_LASTPIXEL_OFF; + } + + /* Set Src and Dst base address and pitch, pitch is qword */ + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ + /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ + /* Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) */ + CBUFFER(buf,VIA_REG_LINE_K1K2, ((((dy << 1) & 0x3fff) << 16)| + (((dy - dx) << 1) & 0x3fff))); + CBUFFER(buf,VIA_REG_LINE_XY, ((y1 << 16) | x1)); + CBUFFER(buf,VIA_REG_DIMENSION, dx); + CBUFFER(buf,VIA_REG_LINE_ERROR, (((dy << 1) - dx - error) & 0x3fff)); + CBUFFER(buf,VIA_REG_GECMD, cmd); + dispatchCBufferAGP(pVia, buf); + +} + + +/* Subsequent XAA solid horizontal and vertical lines */ +static void +VIASubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, + int y, + int len, + int dir) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + /* Set Src and Dst base address and pitch, pitch is qword */ + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + if (dir == DEGREES_0) { + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, (len - 1)); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); + } + else { + CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); + CBUFFER(buf,VIA_REG_DIMENSION, ((len - 1) << 16)); + CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); + } + dispatchCBufferAGP(pVia, buf); +} + +static void +VIASetupForDashedLine( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned int planemask, + int length, + unsigned char *pattern) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + CARD32 pat = *(CARD32 *)pattern; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + +#ifdef X_HAVE_XAAGETROP + cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); +#else + cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | (XAAPatternROP[rop] << 24); +#endif + + if (bg == -1) { + /* transparent mono pattern */ + cmd |= VIA_GEC_MPAT_TRANS; + } + + pVia->SavedCmd = cmd; + pVia->SavedFgColor = fg; + pVia->SavedBgColor = bg; + + switch (length) { + case 2: pat |= pat << 2; /* fall through */ + case 4: pat |= pat << 4; /* fall through */ + case 8: pat |= pat << 8; /* fall through */ + case 16: pat |= pat << 16; + } + + pVia->SavedPattern0 = pat; + CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); + CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0); + +} + + +static void +VIASubsequentDashedTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int flags, + int phase) +{ + VIAPtr pVia = VIAPTR(pScrn); + int dx, dy, cmd, tmp, error = 1; + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + COND_CLEAR_CBUFFER( buf, pVia); + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); + CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + cmd = pVia->SavedCmd; + + dx = x2 - x1; + if (dx < 0) { + dx = -dx; + cmd |= VIA_GEC_DECX; /* line will be drawn from right */ + error = 0; + } + + dy = y2 - y1; + if (dy < 0) { + dy = -dy; + cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + } + + if (dy > dx) { + tmp = dy; + dy = dx; + dx = tmp; /* Swap 'dx' and 'dy' */ + cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + } + + if (flags & OMIT_LAST) { + cmd |= VIA_GEC_LASTPIXEL_OFF; + } + + /* Set Src and Dst base address and pitch, pitch is qword */ + CBUFFER(buf,VIA_REG_SRCBASE, 0x0); + CBUFFER(buf,VIA_REG_DSTBASE, 0x0); + CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | + (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + + /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ + /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ + /* Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) */ + CBUFFER(buf,VIA_REG_LINE_K1K2, ((((dy << 1) & 0x3fff) << 16)| + (((dy - dx) << 1) & 0x3fff))); + CBUFFER(buf,VIA_REG_LINE_XY, ((y1 << 16) | x1)); + CBUFFER(buf,VIA_REG_DIMENSION, dx); + CBUFFER(buf,VIA_REG_LINE_ERROR, (((dy << 1) - dx - error) & 0x3fff) | 0xFF0000); + CBUFFER(buf,VIA_REG_GECMD, cmd); + dispatchCBufferAGP(pVia, buf); +} + + +static void +VIASetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCBuffer *buf = &pVia->cBuf; + ViaTwodContext *tdc = &pVia->td; + + COND_CLEAR_CBUFFER( buf, pVia); + pVia->justSetup = 0; + CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); +#ifdef DEBUG_EXTRA + ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); +#endif + + CBUFFER(buf,VIA_REG_CLIPTL, ((y1 << 16) | x1)); + CBUFFER(buf,VIA_REG_CLIPBR, ((y2 << 16) | x2)); + pVia->SavedCmd |= VIA_GEC_CLIP_ENABLE; + dispatchCBufferAGP(pVia, buf); + +} + + +static void VIADisableClipping(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + +#ifdef DEBUG_EXTRA + ErrorF("Kill ClipRect\n"); +#endif + + pVia->SavedCmd &= ~VIA_GEC_CLIP_ENABLE; +} + +/* + * + */ +void +ViaVQDisable(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIASETREG(VIA_REG_TRANSET, 0x00FE0000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000004); +} diff --git a/unichrome/via_bandwidth.c b/unichrome/via_bandwidth.c new file mode 100644 index 000000000000..ad0732cc288b --- /dev/null +++ b/unichrome/via_bandwidth.c @@ -0,0 +1,342 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_id.h" + +/* + * Now that via_bios is no longer such a behemoth and the relevant + * code is moved via_mode.c, this code should be moved to via_mode.c too + * especially as output abstraction will trim via_mode.c down further + */ + +/* + * + */ +static void +ViaSetCLE266APrimaryFIFO(ScrnInfoPtr pScrn, Bool Enable) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwGE230, dwGE298; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetCLE266APrimaryFIFO: %d\n", Enable)); + + dwGE298 = VIAGETREG(0x298); + VIASETREG(0x298, dwGE298 | 0x20000000); + + dwGE230 = VIAGETREG(0x230); + if (Enable) + dwGE230 |= 0x00200000; + else + dwGE230 &= ~0x00200000; + VIASETREG(0x230, dwGE230); + + dwGE298 = VIAGETREG(0x298); + VIASETREG(0x298, dwGE298 & ~0x20000000); +} + +/* + * + */ +typedef struct { + CARD16 X; + CARD16 Y; + CARD16 Bpp; + CARD8 bRamClock; + CARD8 bTuningValue; +} ViaExpireNumberTable; + +static ViaExpireNumberTable CLE266AExpireNumber[] = { + {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x3}, + {1600,1200,16,0x03,0x4}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, + {1400,1050,16,0x03,0x3}, {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, + { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} +}; + +static ViaExpireNumberTable CLE266CExpireNumber[] = { + {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x4}, + {1600,1200,32,0x03,0x3}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, + {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, + { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} +}; + +static ViaExpireNumberTable KM400ExpireNumber[]={ + {1280,1024,32,0x03,0x3}, {1280,1024,32,0x04,0x9}, {1280, 768,32,0x03,0x3}, + {1280, 768,32,0x04,0x9}, {1400,1050,32,0x03,0x3}, {1400,1050,32,0x04,0x9}, + {1600,1200,32,0x03,0x4}, {1600,1200,32,0x04,0xA}, { 0, 0, 0, 0, 0} +}; + +/* + * + */ +static void +ViaSetPrimaryExpireNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ViaExpireNumberTable *Expire) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryExpireNumber\n")); + + for (; Expire->X; Expire++) + if ((Expire->X == mode->CrtcHDisplay) && + (Expire->Y == mode->CrtcVDisplay) && + (Expire->Bpp == pScrn->bitsPerPixel) && + (Expire->bRamClock == pVia->MemClk)) { + ViaSeqMask(hwp, 0x22, Expire->bTuningValue, 0x1F); + return; + } +} + +/* + * + */ +void +ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryFIFO\n")); + + /* standard values */ + ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); + + if (mode->CrtcHDisplay >= 1600) { + ViaSeqMask(hwp, 0x16, 0x0F, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4F, 0xFF); + } else if (mode->CrtcHDisplay >= 1024) { + ViaSeqMask(hwp, 0x16, 0x0C, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4C, 0xFF); + } else { + ViaSeqMask(hwp, 0x16, 0x08, 0xBF); + ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); + } + + switch(pVia->Chipset) { + case VIA_CLE266: + if (CLE266_REV_IS_CX(pVia->ChipRev)) { + if (pVia->HasSecondary) { /* SAMM or DuoView case */ + if (mode->HDisplay >= 1024) { + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + } + } else { /* Single view or Simultaneous case */ + if (mode->HDisplay > 1024) { + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ + } + } + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, CLE266CExpireNumber); + } else { + if ((mode->HDisplay > 1024) && pVia->HasSecondary) { + ViaSetCLE266APrimaryFIFO(pScrn, TRUE); + + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } + + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, CLE266AExpireNumber); + } + break; + case VIA_KM400: + if (pVia->HasSecondary) { /* SAMM or DuoView case */ + if ((mode->HDisplay >= 1600) && + (pVia->MemClk <= VIA_MEM_DDR200)) { + ViaSeqMask(hwp, 0x16, 0x09, 0x3F); /* 9 */ + hwp->writeSeq(hwp, 0x17, 0x1C); /* 28 */ + } else { + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + } + } else { + if ((mode->HDisplay > 1280)) + ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ + else if (mode->HDisplay > 1024) + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + else + ViaSeqMask(hwp, 0x16, 0x10, 0x3F); /* 16 */ + hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ + } + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + + /* originally when setting secondary */ + ViaSetPrimaryExpireNumber(pScrn, mode, KM400ExpireNumber); + break; +#ifdef HAVE_K8M800 + case VIA_K8M800: + hwp->writeSeq(hwp, 0x17, 0xBF); /* 384/2 - 1 = 191 (orig via comment: 384/8) */ + ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52*/ + ViaSeqMask(hwp, 0x18, 0x8a, 0xBF); /* 74 */ + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ + else + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); /* 128/4 = overflow = 0 */ + break; +#endif /* HAVE_K8M800 */ +#ifdef HAVE_PM800 + case VIA_PM800: + hwp->writeSeq(hwp, 0x17, 0x5F); /* 95 */ + ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 32 */ + ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 16 */ + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ + else + ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 31 */ + break; +#endif /* HAVE_PM800 */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO:" + " Chipset %d not implemented\n", pVia->Chipset); + break; + + } +} + +/* + * I've thrown out the LCD requirement. Size > 1024 is not supported + * by any currently known TV encoder anyway. -- Luc. + * + */ +void +ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetSecondaryFIFO\n")); + + switch (pVia->Chipset) { + case VIA_CLE266: + if (CLE266_REV_IS_CX(pVia->ChipRev)) { + if (mode->HDisplay >= 1024) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + } else { + if ((pScrn->bitsPerPixel >= 24) && + (((mode->VDisplay > 768) && (pVia->MemClk <= VIA_MEM_DDR200)) || + ((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR266)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + } + break; + case VIA_KM400: + if ((mode->HDisplay >= 1600) && (pVia->MemClk <= VIA_MEM_DDR200)) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xEB); /* depth: 14, threshold: 11 */ + } else if ((pScrn->bitsPerPixel == 32) && + (((mode->HDisplay > 1024) && (pVia->MemClk <= VIA_MEM_DDR333)) || + ((mode->HDisplay >= 1024) && (pVia->MemClk <= VIA_MEM_DDR200)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xCA); /* depth: 12, threshold: 10 */ + } else if ((pScrn->bitsPerPixel == 16) && + (((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR333)) || + ((mode->HDisplay >= 1280) && (pVia->MemClk <= VIA_MEM_DDR200)))) { + ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); + hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */ + } else { + ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); + hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */ + } + break; +#ifdef HAVE_K8M800 + case VIA_K8M800: + /* depth: (384 /8 -1 -1) = 46 = 0x2E */ + ViaCrtcMask(hwp, 0x68, 0xE0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x80, 0x80); + + /* threshold: (328/4) = 82 = 0x52 */ + ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x50, 0x70); + + /* preq: 74 = 0x4A */ + ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x04, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ + break; +#endif /* HAVE_K8M800 */ +#ifdef HAVE_PM800 + case VIA_PM800: + /* depth: 12 - 1 = 0x0B */ + ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + /* threshold: 16 = 0x10 */ + ViaCrtcMask(hwp, 0x68, 0x00, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + /* preq: 8 = 0x08 */ + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ + break; +#endif /* HAVE_PM800 */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO:" + " Chipset %d not implemented\n", pVia->Chipset); + break; + } +} + +/* + * Wrap around ViaSetCLE266APrimaryFIFO + */ +void +ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisablePrimaryFIFO\n")); + + /* Cause of exit XWindow will dump back register value, others chipset no + * need to set extended fifo value */ + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev) && + ((pScrn->currentMode->HDisplay > 1024) || pVia->HasSecondary)) + ViaSetCLE266APrimaryFIFO(pScrn, FALSE); +} diff --git a/unichrome/via_bios.h b/unichrome/via_bios.h new file mode 100644 index 000000000000..af383d907f5a --- /dev/null +++ b/unichrome/via_bios.h @@ -0,0 +1,163 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_BIOS_H_ +#define _VIA_BIOS_H_ 1 + +#define VIA_PANEL6X4 0 +#define VIA_PANEL8X6 1 +#define VIA_PANEL10X7 2 +#define VIA_PANEL12X7 3 +#define VIA_PANEL12X10 4 +#define VIA_PANEL14X10 5 +#define VIA_PANEL16X12 6 +#define VIA_PANEL_INVALID 255 + +#define TVTYPE_NONE 0x00 +#define TVTYPE_NTSC 0x01 +#define TVTYPE_PAL 0x02 + +#define TVOUTPUT_NONE 0x00 +#define TVOUTPUT_COMPOSITE 0x01 +#define TVOUTPUT_SVIDEO 0x02 +#define TVOUTPUT_RGB 0x04 +#define TVOUTPUT_YCBCR 0x08 +#define TVOUTPUT_SC 0x16 + +#define VIA_NONETV 0 +#define VIA_VT1621 1 /* TV2PLUS */ +#define VIA_VT1622 2 /* TV3 */ +#define VIA_VT1623 3 /* also VT1622A */ +#define VIA_VT1625 4 + +#define VIA_TVNORMAL 0 +#define VIA_TVOVER 1 + +#define VIA_DEVICE_NONE 0x00 +#define VIA_DEVICE_CRT 0x01 +#define VIA_DEVICE_LCD 0x02 +#define VIA_DEVICE_TV 0x04 +#define VIA_DEVICE_DFP 0x08 + +/* System Memory CLK */ +#define VIA_MEM_SDR66 0x00 +#define VIA_MEM_SDR100 0x01 +#define VIA_MEM_SDR133 0x02 +#define VIA_MEM_DDR200 0x03 +#define VIA_MEM_DDR266 0x04 +#define VIA_MEM_DDR333 0x05 +#define VIA_MEM_DDR400 0x06 +#define VIA_MEM_END 0x07 +#define VIA_MEM_NONE 0xFF + +/* Digital Output Bus Width */ +#define VIA_DI_12BIT 0x00 +#define VIA_DI_24BIT 0x01 + +typedef struct _VIABIOSINFO { + int scrnIndex; + + Bool CrtPresent; + Bool CrtActive; + + CARD16 ResolutionIndex; + CARD32 Clock; /* register value for the dotclock */ + Bool ClockExternal; + CARD32 Bandwidth; /* available memory bandwidth */ + + /* Panel/LCD entries */ + Bool PanelPresent; + Bool PanelActive; + Bool ForcePanel; + int PanelIndex; + int PanelSize; + Bool LCDDualEdge; /* mean add-on card is 2CH or Dual or DDR */ + Bool Center; + CARD8 BusWidth; /* Digital Output Bus Width */ + Bool SetDVI; + /* LCD Simultaneous Expand Mode HWCursor Y Scale */ + Bool scaleY; + int panelX; + int panelY; + int resY; + + /* TV entries */ + int TVEncoder; + int TVOutput; + Bool TVActive; + I2CDevPtr TVI2CDev; + int TVType; + Bool TVDotCrawl; + int TVDeflicker; + CARD8 TVRegs[0xFF]; + + /* TV Callbacks */ + void (*TVSave) (ScrnInfoPtr pScrn); + void (*TVRestore) (ScrnInfoPtr pScrn); + Bool (*TVDACSense) (ScrnInfoPtr pScrn); + ModeStatus (*TVModeValid) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVModeI2C) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVModeCrtc) (ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*TVPower) (ScrnInfoPtr pScrn, Bool On); + DisplayModePtr TVModes; + void (*TVPrintRegs) (ScrnInfoPtr pScrn); + +} VIABIOSInfoRec, *VIABIOSInfoPtr; + +/* Function prototypes */ +/* via_vbe.c */ +void ViaVbeAdjustFrame(int scrnIndex, int x, int y, int flags); +Bool ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); +Bool ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); +Bool ViaVbeModePreInit(ScrnInfoPtr pScrn); +void ViaVbeDPMS(ScrnInfoPtr pScrn, int mode, int flags); +void ViaVbeDoDPMS(ScrnInfoPtr pScrn, int mode); + +/* via_mode.c */ +void ViaOutputsDetect(ScrnInfoPtr pScrn); +Bool ViaOutputsSelect(ScrnInfoPtr pScrn); +void ViaModesAttach(ScrnInfoPtr pScrn, MonPtr monitorp); +CARD32 ViaGetMemoryBandwidth(ScrnInfoPtr pScrn); +ModeStatus ViaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +void ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaLCDPower(ScrnInfoPtr pScrn, Bool On); +void ViaTVPower(ScrnInfoPtr pScrn, Bool On); +void ViaTVSave(ScrnInfoPtr pScrn); +void ViaTVRestore(ScrnInfoPtr pScrn); +#ifdef HAVE_DEBUG +void ViaTVPrintRegs(ScrnInfoPtr pScrn); +#endif + +/* in via_bandwidth.c */ +void ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode); +void ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn); + +/* via_vt162x.c */ +I2CDevPtr ViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); +void ViaVT162xInit(ScrnInfoPtr pScrn); + +#endif /* _VIA_BIOS_H_ */ diff --git a/unichrome/via_cursor.c b/unichrome/via_cursor.c new file mode 100644 index 000000000000..294bcac98c8a --- /dev/null +++ b/unichrome/via_cursor.c @@ -0,0 +1,223 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/************************************************************************* + * + * File: via_cursor.c + * Content: Hardware cursor support for VIA/S3G UniChrome + * + ************************************************************************/ + +#include "via_driver.h" + +static void VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); +static void VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); + +#define MAX_CURS 32 + +Bool +VIAHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + xf86CursorInfoPtr infoPtr; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAHWCursorInit\n")); + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) + return FALSE; + + pVia->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = MAX_CURS; + infoPtr->MaxHeight = MAX_CURS; + infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + /*HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |*/ + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST| + 0; + + infoPtr->SetCursorColors = VIASetCursorColors; + infoPtr->SetCursorPosition = VIASetCursorPosition; + infoPtr->LoadCursorImage = VIALoadCursorImage; + infoPtr->HideCursor = VIAHideCursor; + infoPtr->ShowCursor = VIAShowCursor; + infoPtr->UseHWCursor = NULL; + + if (!pVia->CursorStart) { + pVia->CursorStart = pVia->FBFreeEnd - VIA_CURSOR_SIZE; + pVia->FBFreeEnd -= VIA_CURSOR_SIZE; + + /* Set cursor location in frame buffer. */ + VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorStart); + } + + return xf86InitCursor(pScreen, infoPtr); +} + + + +void +VIAShowCursor(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwCursorMode; + + dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); + + /* Turn on Hardware Cursor */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode | 0x3); +} + + +void +VIAHideCursor(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwCursorMode; + + dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); + + /* Turn cursor off. */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE); +} + + +static void +VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char* src) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 dwCursorMode; + + VIAAccelSync(pScrn); + + dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); + + /* Turn cursor off. */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE); + + /* Upload the cursor image to the frame buffer. */ + memcpy(pVia->FBBase + pVia->CursorStart, src, MAX_CURS * MAX_CURS / 8 * 2); + + /* Restore cursor status */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode); +} + +static void +VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + unsigned char xoff, yoff; + CARD32 dwCursorMode; + + if (x < 0) { + xoff = ((-x) & 0xFE); + x = 0; + } else { + xoff = 0; + } + + if (y < 0) { + yoff = ((-y) & 0xFE); + y = 0; + } else { + yoff = 0; + /* LCD Expand Mode Cursor Y Position Re-Calculated */ + if (pBIOSInfo->scaleY) { + y = (int)(((pBIOSInfo->panelY * y) + (pBIOSInfo->resY >> 1)) / pBIOSInfo->resY); + } + } + + /* Hide cursor before set cursor position in order to avoid ghost cursor + * image when directly set cursor position. It should be a HW bug but + * we can use patch by SW. */ + dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); + + /* Turn cursor off. */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE); + + VIASETREG(VIA_REG_CURSOR_ORG, ((xoff << 16) | (yoff & 0x003f))); + VIASETREG(VIA_REG_CURSOR_POS, ((x << 16) | (y & 0x07ff))); + + /* Restore cursor status */ + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode); +} + + +static void +VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + VIAPtr pVia = VIAPTR(pScrn); + + VIASETREG(VIA_REG_CURSOR_FG, fg); + VIASETREG(VIA_REG_CURSOR_BG, bg); + +} + +/* + * + */ +void +ViaCursorStore(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorStore\n")); + + if (pVia->CursorImage) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCursorStore: stale image left.\n"); + xfree(pVia->CursorImage); + } + + pVia->CursorImage = xcalloc(1, 0x1000); + memcpy(pVia->CursorImage, pVia->FBBase + pVia->CursorStart, 0x1000); + pVia->CursorFG = (CARD32)VIAGETREG(VIA_REG_CURSOR_FG); + pVia->CursorBG = (CARD32)VIAGETREG(VIA_REG_CURSOR_BG); + pVia->CursorMC = (CARD32)VIAGETREG(VIA_REG_CURSOR_MODE); +} + +/* + * + */ +void +ViaCursorRestore(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorRestore\n")); + + if (pVia->CursorImage) { + memcpy(pVia->FBBase + pVia->CursorStart, pVia->CursorImage, 0x1000); + VIASETREG(VIA_REG_CURSOR_FG, pVia->CursorFG); + VIASETREG(VIA_REG_CURSOR_BG, pVia->CursorBG); + VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorMC); + xfree(pVia->CursorImage); + pVia->CursorImage = NULL; + } else + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCursorRestore: No cursor image stored.\n"); +} diff --git a/unichrome/via_dga.c b/unichrome/via_dga.c new file mode 100644 index 000000000000..0028a1965077 --- /dev/null +++ b/unichrome/via_dga.c @@ -0,0 +1,354 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#include "xaalocal.h" +#include "via_driver.h" +#include "dgaproc.h" + + +static Bool VIADGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool VIADGASetMode(ScrnInfoPtr, DGAModePtr); +static int VIADGAGetViewport(ScrnInfoPtr); +static void VIADGASetViewport(ScrnInfoPtr, int, int, int); +static void VIADGAFillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void VIADGABlitRect(ScrnInfoPtr, int, int, int, int, int, int); + + +static +DGAFunctionRec VIADGAFuncs = { + VIADGAOpenFramebuffer, + NULL, /* CloseFrameBuffer */ + VIADGASetMode, + VIADGASetViewport, + VIADGAGetViewport, + VIAAccelSync, + VIADGAFillRect, + VIADGABlitRect, + NULL /* BlitTransRect */ +}; + +#define DGATRACE 4 + + +static DGAModePtr +VIASetupDGAMode( + ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass +) +{ + VIAPtr pVia = VIAPTR(pScrn); + DGAModePtr mode, newmodes = NULL; + DisplayModePtr pMode, firstMode; + int otherPitch, Bpp = bitsPerPixel >> 3; + Bool oneMore; + + xf86ErrorFVerb(DGATRACE, " VIASetupDGAMode\n"); + + pMode = firstMode = pScrn->modes; + + /* + * DGA 1.0 would only provide modes where the depth and stride + * matched the current desktop. Some DGA apps might still expect + * this, so we provide them, too. + */ + + while (pMode) { + + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if (pMode->HDisplay != otherPitch) { + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } + else { + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if (!newmodes) { + xfree(modes); + return NULL; + } + + modes = newmodes; + +SECOND_PASS: + + mode = modes + *num; + (*num)++; + + mode->mode = pMode; + mode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + + if(!pVia->NoAccel) + mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + + if (pMode->Flags & V_DBLSCAN) + mode->flags |= DGA_DOUBLESCAN; + + if (pMode->Flags & V_INTERLACE) + mode->flags |= DGA_INTERLACED; + + mode->byteOrder = pScrn->imageByteOrder; + mode->depth = depth; + mode->bitsPerPixel = bitsPerPixel; + mode->red_mask = red; + mode->green_mask = green; + mode->blue_mask = blue; + mode->visualClass = visualClass; + mode->viewportWidth = pMode->HDisplay; + mode->viewportHeight = pMode->VDisplay; + mode->xViewportStep = 2; + mode->yViewportStep = 1; + mode->viewportFlags = DGA_FLIP_RETRACE; + mode->offset = 0; + mode->address = pVia->FBBase; + + xf86ErrorFVerb(DGATRACE, + "VIADGAInit vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n", + mode->viewportWidth, + mode->viewportHeight, + Bpp, + mode->bitsPerPixel); + + if (oneMore) { /* first one is narrow width */ + mode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + mode->imageWidth = pMode->HDisplay; + mode->imageHeight = pMode->VDisplay; + mode->pixmapWidth = mode->imageWidth; + mode->pixmapHeight = mode->imageHeight; + mode->maxViewportX = mode->imageWidth - mode->viewportWidth; + + /* this might need to get clamped to some maximum */ + mode->maxViewportY = mode->imageHeight - mode->viewportHeight; + oneMore = FALSE; + + xf86ErrorFVerb(DGATRACE, + "VIADGAInit 1 imgHgt=%d, stride=%d\n", + mode->imageHeight, + mode->bytesPerScanline ); + + goto SECOND_PASS; + } + else { + mode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; + mode->imageWidth = pScrn->displayWidth; + mode->imageHeight = pVia->videoRambytes / mode->bytesPerScanline; + mode->pixmapWidth = mode->imageWidth; + mode->pixmapHeight = mode->imageHeight; + mode->maxViewportX = mode->imageWidth - mode->viewportWidth; + /* this might need to get clamped to some maximum */ + mode->maxViewportY = mode->imageHeight - mode->viewportHeight; + + xf86ErrorFVerb(DGATRACE, + "VIADGAInit 2 imgHgt=%d, stride=%d\n", + mode->imageHeight, + mode->bytesPerScanline); + } + + pMode = pMode->next; + + if (pMode == firstMode) + break; + } + + return modes; +} + + +Bool +VIADGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + xf86ErrorFVerb(DGATRACE, " VIADGAInit\n"); + + /* 8 */ + modes = VIASetupDGAMode(pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, + 0, 0, 0, PseudoColor); + + /* 16 */ + modes = VIASetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, TrueColor); + + modes = VIASetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, DirectColor); + + /* 24-in-32 */ + modes = VIASetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = VIASetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + pVia->numDGAModes = num; + pVia->DGAModes = modes; + + return DGAInit(pScreen, &VIADGAFuncs, modes, num); +} + + +static Bool +VIADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) +{ + int index = pScrn->pScreen->myNum; + VIAPtr pVia = VIAPTR(pScrn); + + if (!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + + pScrn->displayWidth = pVia->DGAOldDisplayWidth; + pScrn->bitsPerPixel = pVia->DGAOldBitsPerPixel; + pScrn->depth = pVia->DGAOldDepth; + + pScrn->SwitchMode(index, pScrn->currentMode, 0); + if (pVia->hwcursor) + VIAShowCursor(pScrn); + + pVia->DGAactive = FALSE; + } + else { +#if 0 + ErrorF("pScrn->bitsPerPixel %d, pScrn->depth %d\n", + pScrn->bitsPerPixel, pScrn->depth); + ErrorF(" want bitsPerPixel %d, want depth %d\n", + pMode->bitsPerPixel, pMode->depth); +#endif + + if (pVia->hwcursor) + VIAHideCursor(pScrn); + + if (!pVia->DGAactive) { /* save the old parameters */ + pVia->DGAOldDisplayWidth = pScrn->displayWidth; + pVia->DGAOldBitsPerPixel = pScrn->bitsPerPixel; + pVia->DGAOldDepth = pScrn->depth; + + pVia->DGAactive = TRUE; + } + + pScrn->bitsPerPixel = pMode->bitsPerPixel; + pScrn->depth = pMode->depth; + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + + pScrn->SwitchMode(index, pMode->mode, 0); + } + + return TRUE; +} + + +static int +VIADGAGetViewport(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + return pVia->DGAViewportStatus; +} + + +static void +VIADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + VIAPtr pVia = VIAPTR(pScrn); + + pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pVia->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */ +} + + +static void +VIADGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) +{ + VIAPtr pVia = VIAPTR(pScrn); + + if (pVia->AccelInfoRec) { + (*pVia->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*pVia->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(pVia->AccelInfoRec); + } +} + + +static void +VIADGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + VIAPtr pVia = VIAPTR(pScrn); + + if (pVia->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pVia->AccelInfoRec->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pVia->AccelInfoRec->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pVia->AccelInfoRec); + } +} + + +static Bool +VIADGAOpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags) +{ + VIAPtr pVia = VIAPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)pVia->FrameBufferBase; + *size = pVia->videoRambytes; + *offset = 0; + *flags = DGA_NEED_ROOT; + + return TRUE; +} diff --git a/unichrome/via_dri.c b/unichrome/via_dri.c new file mode 100644 index 000000000000..6a37577c6a86 --- /dev/null +++ b/unichrome/via_dri.c @@ -0,0 +1,863 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Priv.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#define _XF86DRI_SERVER_ +#include "GL/glxtokens.h" +#include "sarea.h" + +#include "via_driver.h" +#include "via_drm.h" +#include "via_dri.h" +#include "via_id.h" +#include "xf86drm.h" + +extern void GlxSetVisualConfigs( + int nconfigs, + __GLXvisualConfig *configs, + void **configprivs +); + +#define VIDEO 0 +#define AGP 1 +#define AGP_PAGE_SIZE 4096 +#define AGP_PAGES 8192 +#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES) +#define AGP_CMDBUF_PAGES 512 +#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) + +static char VIAKernelDriverName[] = "via"; +static char VIAClientDriverName[] = "unichrome"; +int test_alloc_FB(ScreenPtr pScreen, VIAPtr pVia, int Size); +int test_alloc_AGP(ScreenPtr pScreen, VIAPtr pVia, int Size); +static Bool VIAInitVisualConfigs(ScreenPtr pScreen); +static Bool VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia); +static Bool VIADRIPciInit(ScreenPtr pScreen, VIAPtr pVia); +static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia); +static Bool VIADRIKernelInit(ScreenPtr pScreen, VIAPtr pVia); +static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia); + +static Bool VIACreateContext(ScreenPtr pScreen, VisualPtr visual, + drm_context_t hwContext, void *pVisualConfigPriv, + DRIContextType contextStore); +static void VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, + DRIContextType contextStore); +static void VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType readContextType, + void *readContextStore, + DRIContextType writeContextType, + void *writeContextStore); +static void VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); +static void VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index); + + +static void VIADRIIrqInit( ScrnInfoPtr pScrn , VIADRIPtr pVIADRI) +{ + VIAPtr pVia = VIAPTR(pScrn); + + pVIADRI->irqEnabled = drmGetInterruptFromBusID + (pVia->drmFD, + ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, + ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, + ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum); + if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[drm] Failure adding irq handler. " + "Falling back to irq-free operation.\n"); + pVIADRI->irqEnabled = 0; + } + + if (pVIADRI->irqEnabled) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Irq handler installed, using IRQ %d.\n", + pVIADRI->irqEnabled); +} + +static void VIADRIIrqExit( ScrnInfoPtr pScrn , VIADRIPtr pVIADRI) { + + VIAPtr pVia = VIAPTR(pScrn); + + if (pVIADRI->irqEnabled) { + if (drmCtlUninstHandler(pVia->drmFD)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[drm] Irq handler uninstalled.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] Could not uninstall irq handler.\n"); + } + } +} + +void +VIADRIRingBufferCleanup(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + if (pVIADRI->ringBufActive) { + drm_via_dma_init_t ringBufInit; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Cleaning up DMA ring-buffer.\n"); + ringBufInit.func = VIA_CLEANUP_DMA; + if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit, + sizeof(ringBufInit))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[drm] Failed to clean up DMA ring-buffer: %d\n", errno); + } + pVIADRI->ringBufActive = 0; + } +} + +Bool +VIADRIRingBufferInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + if (pVIADRI->ringBufActive) + return TRUE; + + if (pVia->agpEnable) { + drm_via_dma_init_t ringBufInit; + drmVersionPtr drmVer; + + if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { + return FALSE; + } + + if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) { + return FALSE; + } + + /* + * Info frome code-snippet on DRI-DEVEL list; Erdi Chen. + */ + + switch (pVia->ChipId) { + case PCI_CHIP_VT3259: + pVIADRI->reg_pause_addr = 0x40c; + break; + default: + pVIADRI->reg_pause_addr = 0x418; + break; + } + + ringBufInit.offset = pVia->agpSize; + ringBufInit.size = AGP_CMDBUF_SIZE; + ringBufInit.reg_pause_addr = pVIADRI->reg_pause_addr; + ringBufInit.func = VIA_INIT_DMA; + if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit, + sizeof(ringBufInit))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] Failed to initialize DMA ring-buffer: %d\n", errno); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n", + ringBufInit.size, ringBufInit.offset); + + pVIADRI->ringBufActive = 1; + } + return TRUE; +} + + +static Bool VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia) +{ + unsigned long agp_phys; + drmAddress agpaddr; + VIADRIPtr pVIADRI; + DRIInfoPtr pDRIInfo; + pDRIInfo = pVia->pDRIInfo; + pVIADRI = pDRIInfo->devPrivate; + pVia->agpSize = 0; + + if (drmAgpAcquire(pVia->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno); + return FALSE; + } + + if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n"); + return FALSE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n"); + + if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAgpAlloc failed\n"); + drmAgpRelease(pVia->drmFD); + return FALSE; + } + + if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAgpBind failed\n"); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + drmAgpRelease(pVia->drmFD); + + return FALSE; + } + + /* + * Place the ring-buffer last in the AGP region, and restrict the + * public map not to include the buffer for security reasons. + */ + + pVia->agpSize = AGP_SIZE - AGP_CMDBUF_SIZE; + pVia->agpAddr = drmAgpBase(pVia->drmFD); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr); + + pVIADRI->agp.size = pVia->agpSize; + if (drmAddMap(pVia->drmFD, (drm_handle_t)0, + pVIADRI->agp.size, DRM_AGP, 0, + &pVIADRI->agp.handle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to map public agp area\n"); + pVIADRI->agp.size = 0; + drmAgpUnbind(pVia->drmFD, pVia->agpHandle); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + drmAgpRelease(pVia->drmFD); + return FALSE; + } + /* Map AGP from kernel to Xserver - Not really needed */ + drmMap(pVia->drmFD, pVIADRI->agp.handle, pVIADRI->agp.size, &agpaddr); + pVia->agpMappedAddr = agpaddr; + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpBase = %p\n", pVia->agpBase); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpSize = 0x%08x\n", pVia->agpSize); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agp physical addr = 0x%08lx\n", agp_phys); + + { + drm_via_agp_t agp; + agp.offset = 0; + agp.size = AGP_SIZE-AGP_CMDBUF_SIZE; + if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp, + sizeof(drm_via_agp_t)) < 0) { + drmUnmap(agpaddr,pVia->agpSize); + drmRmMap(pVia->drmFD,pVIADRI->agp.handle); + drmAgpUnbind(pVia->drmFD, pVia->agpHandle); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + drmAgpRelease(pVia->drmFD); + return FALSE; + } + } + + return TRUE; + +} +static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia) +{ + int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart; + int FBOffset = pVia->FBFreeStart; + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + pVIADRI->fbOffset = FBOffset; + pVIADRI->fbSize = pVia->videoRambytes; + + { + drm_via_fb_t fb; + fb.offset = FBOffset; + fb.size = FBSize; + + if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb, + sizeof(drm_via_fb_t)) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] failed to init frame buffer area\n"); + return FALSE; + } else { + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x " + "FBSize= 0x%08x\n", + pVia->FBFreeStart, pVia->FBFreeEnd, FBSize); + return TRUE; + } + } +} + +static Bool VIADRIPciInit(ScreenPtr pScreen, VIAPtr pVia) +{ + return TRUE; +} + +static Bool +VIAInitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = 0; + VIAConfigPrivPtr pVIAConfigs = 0; + VIAConfigPrivPtr *pVIAConfigPtrs = 0; + int i, db, stencil, accum; + + switch (pScrn->bitsPerPixel) { + case 8: + case 24: + break; + case 16: + numConfigs = 12; + if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig), + numConfigs))) + return FALSE; + if (!(pVIAConfigs = (VIAConfigPrivPtr)xcalloc(sizeof(VIAConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pVIAConfigPtrs = (VIAConfigPrivPtr*)xcalloc(sizeof(VIAConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pVIAConfigs); + return FALSE; + } + for (i=0; i<numConfigs; i++) + pVIAConfigPtrs[i] = &pVIAConfigs[i]; + + i = 0; + for (accum = 0; accum <= 1; accum++) { + /* 32bpp depth buffer disabled, as Mesa has limitations */ + for (stencil=0; stencil<=2; stencil++) { + for (db = 0; db <= 1; db++) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = -1; + pConfigs[i].greenSize = -1; + pConfigs[i].blueSize = -1; + pConfigs[i].redMask = -1; + pConfigs[i].greenMask = -1; + pConfigs[i].blueMask = -1; + pConfigs[i].alphaSize = 0; + pConfigs[i].alphaMask = 0; + + if (accum) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } + else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (!db) + pConfigs[i].doubleBuffer = TRUE; + else + pConfigs[i].doubleBuffer = FALSE; + + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = -1; + + switch (stencil) { + case 0: + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + break; + case 1: + pConfigs[i].depthSize = 16; + pConfigs[i].stencilSize = 0; + break; + case 2: + pConfigs[i].depthSize = 0; + pConfigs[i].stencilSize = 0; + break; + case 3: + pConfigs[i].depthSize = 32; + pConfigs[i].stencilSize = 0; + break; + } + + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum) { + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + } else { + pConfigs[i].visualRating = GLX_NONE_EXT; + } + pConfigs[i].transparentPixel = GLX_NONE_EXT; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + + if (i != numConfigs) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] Incorrect initialization of visuals. Disabling DRI.\n"); + return FALSE; + } + break; + + case 32: + numConfigs = 12; + if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig), + numConfigs))) + return FALSE; + if (!(pVIAConfigs = (VIAConfigPrivPtr)xcalloc(sizeof(VIAConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pVIAConfigPtrs = (VIAConfigPrivPtr*)xcalloc(sizeof(VIAConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pVIAConfigs); + return FALSE; + } + for (i=0; i<numConfigs; i++) + pVIAConfigPtrs[i] = &pVIAConfigs[i]; + + i = 0; + for (accum = 0; accum <= 1; accum++) { + /* 32bpp depth buffer disabled, as Mesa has limitations */ + for (stencil=0; stencil<=2; stencil++) { + for (db = 0; db <= 1; db++) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = -1; + pConfigs[i].greenSize = -1; + pConfigs[i].blueSize = -1; + pConfigs[i].redMask = -1; + pConfigs[i].greenMask = -1; + pConfigs[i].blueMask = -1; + pConfigs[i].alphaSize = 8; + pConfigs[i].alphaMask = 0xFF000000; + + if (accum) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 16; + } + else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (!db) + pConfigs[i].doubleBuffer = TRUE; + else + pConfigs[i].doubleBuffer = FALSE; + + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = -1; + + switch (stencil) { + case 0: + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + break; + case 1: + pConfigs[i].depthSize = 16; + pConfigs[i].stencilSize = 0; + break; + case 2: + pConfigs[i].depthSize = 0; + pConfigs[i].stencilSize = 0; + break; + case 3: + pConfigs[i].depthSize = 32; + pConfigs[i].stencilSize = 0; + break; + } + + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum) + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + else + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = GLX_NONE_EXT; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + + if (i != numConfigs) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] Incorrect initialization of visuals. Disabling DRI.\n"); + return FALSE; + } + + break; + } + + pVia->numVisualConfigs = numConfigs; + pVia->pVisualConfigs = pConfigs; + pVia->pVisualConfigsPriv = pVIAConfigs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pVIAConfigPtrs); + + return TRUE; +} + +Bool VIADRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + DRIInfoPtr pDRIInfo; + VIADRIPtr pVIADRI; + + /* if symbols or version check fails, we still want this to be NULL */ + pVia->pDRIInfo = NULL; + + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for canonical symbols in each module. */ + if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; + if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] VIADRIScreenInit failed (libdri.a too old)\n"); + return FALSE; + } + + /* Check the DRI version */ + { + int major, minor, patch; + DRIQueryVersion(&major, &minor, &patch); + if (major != 4 || minor < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] VIADRIScreenInit failed because of a version mismatch.\n" + "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n" + "[dri] Disabling DRI.\n", + major, minor, patch); + return FALSE; + } + } + + pVia->pDRIInfo = DRICreateInfoRec(); + if (!pVia->pDRIInfo) + return FALSE; + + pDRIInfo = pVia->pDRIInfo; + pDRIInfo->drmDriverName = VIAKernelDriverName; + pDRIInfo->clientDriverName = VIAClientDriverName; + pDRIInfo->busIdString = xalloc(64); + sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", + ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, + ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, + ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum); + pDRIInfo->ddxDriverMajorVersion = VIA_DRI_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = VIA_DRI_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = PATCHLEVEL; + pDRIInfo->frameBufferPhysicalAddress = pVia->FrameBufferBase; + pDRIInfo->frameBufferSize = pVia->videoRambytes; + + pDRIInfo->frameBufferStride = (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + pDRIInfo->ddxDrawableTableEntry = VIA_MAX_DRAWABLES; + + if (SAREA_MAX_DRAWABLES < VIA_MAX_DRAWABLES) + pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; + else + pDRIInfo->maxDrawableTableEntry = VIA_MAX_DRAWABLES; + +#ifdef NOT_DONE + /* FIXME need to extend DRI protocol to pass this size back to client + * for SAREA mapping that includes a device private record + */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + /* + shared memory device private rec */ +#else + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + if (sizeof(XF86DRISAREARec)+sizeof(VIASAREAPriv) > SAREA_MAX) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Data does not fit in SAREA\n"); + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; + return FALSE; + } + pDRIInfo->SAREASize = SAREA_MAX; +#endif + + if (!(pVIADRI = (VIADRIPtr)xcalloc(sizeof(VIADRIRec),1))) { + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; + return FALSE; + } + pDRIInfo->devPrivate = pVIADRI; + pDRIInfo->devPrivateSize = sizeof(VIADRIRec); + pDRIInfo->contextSize = sizeof(VIADRIContextRec); + + pDRIInfo->CreateContext = VIACreateContext; + pDRIInfo->DestroyContext = VIADestroyContext; + pDRIInfo->SwapContext = VIADRISwapContext; + pDRIInfo->InitBuffers = VIADRIInitBuffers; + pDRIInfo->MoveBuffers = VIADRIMoveBuffers; + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + + if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmFD)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] DRIScreenInit failed. Disabling DRI.\n"); + xfree(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; + pVia->drmFD = -1; + return FALSE; + } + + + if (!(VIAInitVisualConfigs(pScreen))) { + VIADRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n" ); + + /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ + if (!VIADRIMapInit(pScreen, pVia)) { + VIADRICloseScreen(pScreen); + return FALSE; + } + pVIADRI->regs.size = VIA_MMIO_REGSIZE; + pVIADRI->regs.map = 0; + pVIADRI->regs.handle = pVia->registerHandle; + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n", + pVIADRI->regs.handle); + + pVIADRI->drixinerama = pVia->drixinerama; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" ); + + return TRUE; +} + +void +VIADRICloseScreen(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI; + + VIADRIRingBufferCleanup(pScrn); + if (pVia->agpSize) { + drmUnmap(pVia->agpMappedAddr,pVia->agpSize); + drmRmMap(pVia->drmFD,pVia->agpHandle); + drmAgpUnbind(pVia->drmFD, pVia->agpHandle); + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n"); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n"); + drmAgpRelease(pVia->drmFD); + } + + + DRICloseScreen(pScreen); + + if (pVia->pDRIInfo) { + if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) { + VIADRIIrqExit(pScrn, pVIADRI); + xfree(pVIADRI); + pVia->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; + } + + if (pVia->pVisualConfigs) { + xfree(pVia->pVisualConfigs); + pVia->pVisualConfigs = NULL; + } + if (pVia->pVisualConfigsPriv) { + xfree(pVia->pVisualConfigsPriv); + pVia->pVisualConfigsPriv = NULL; + } +} + +/* TODO: xserver receives driver's swapping event and does something + * according the data initialized in this function. + */ +static Bool +VIACreateContext(ScreenPtr pScreen, VisualPtr visual, + drm_context_t hwContext, void *pVisualConfigPriv, + DRIContextType contextStore) +{ + return TRUE; +} + +static void +VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, + DRIContextType contextStore) +{ +} + +Bool +VIADRIFinishScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI; + + pVia->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + + pVia->IsPCI = !VIADRIAgpInit(pScreen, pVia); + + if (pVia->IsPCI) { + VIADRIPciInit(pScreen, pVia); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" ); + } + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" ); + + if (!(VIADRIFBInit(pScreen, pVia))) { + VIADRICloseScreen(pScreen); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialization failed.\n" ); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" ); + + DRIFinishScreenInit(pScreen); + + if (!VIADRIKernelInit(pScreen, pVia)) { + VIADRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n"); + + /* set SAREA value */ + { + VIASAREAPriv *saPriv; + + saPriv=(VIASAREAPriv*)DRIGetSAREAPrivate(pScreen); + assert(saPriv); + memset(saPriv, 0, sizeof(*saPriv)); + saPriv->ctxOwner = -1; + } + pVIADRI=(VIADRIPtr)pVia->pDRIInfo->devPrivate; + pVIADRI->deviceID=pVia->Chipset; + pVIADRI->width=pScrn->virtualX; + pVIADRI->height=pScrn->virtualY; + pVIADRI->mem=pScrn->videoRam*1024; + pVIADRI->bytesPerPixel= (pScrn->bitsPerPixel+7) / 8; + pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + /* TODO */ + pVIADRI->scrnX=pVIADRI->width; + pVIADRI->scrnY=pVIADRI->height; + + /* Initialize IRQ */ + if (pVia->DRIIrqEnable) + VIADRIIrqInit(pScrn, pVIADRI); + + pVIADRI->ringBufActive = 0; + VIADRIRingBufferInit(pScrn); + return TRUE; +} + +static void +VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType oldContextType, void *oldContext, + DRIContextType newContextType, void *newContext) +{ + /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + */ + return; +} + +static void +VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) +{ + /*ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + */ + return; +} + +static void +VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index) +{ + /*ScreenPtr pScreen = pParent->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + */ + return; +} + +/* Initialize the kernel data structures. */ +static Bool VIADRIKernelInit(ScreenPtr pScreen, VIAPtr pVia) +{ + drm_via_init_t drmInfo; + memset(&drmInfo, 0, sizeof(drm_via_init_t)); + drmInfo.func = VIA_INIT_MAP; + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.fb_offset = pVia->FrameBufferBase; + drmInfo.mmio_offset = pVia->registerHandle; + if (pVia->IsPCI) + drmInfo.agpAddr = (CARD32)NULL; + else + drmInfo.agpAddr = (CARD32)pVia->agpAddr; + + if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo, + sizeof(drm_via_init_t))) < 0) + return FALSE; + + + return TRUE; +} +/* Add a map for the MMIO registers */ +static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia) +{ + int flags = DRM_READ_ONLY; + + if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE, + DRM_REGISTERS, flags, &pVia->registerHandle) < 0) { + return FALSE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] register handle = 0x%08lx\n", pVia->registerHandle); + + return TRUE; +} diff --git a/unichrome/via_dri.h b/unichrome/via_dri.h new file mode 100644 index 000000000000..c1ac77c0eb6e --- /dev/null +++ b/unichrome/via_dri.h @@ -0,0 +1,89 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_DRI_H_ +#define _VIA_DRI_H_ 1 + +#include "drm.h" +#include "xf86drm.h" +#include "via_drm.h" + +#define VIA_MAX_DRAWABLES 256 + +#define VIA_DRI_VERSION_MAJOR 4 +#define VIA_DRI_VERSION_MINOR 1 + +typedef drm_via_sarea_t VIASAREAPriv; + +typedef struct { + drm_handle_t handle; + drmSize size; + drmAddress map; +} viaRegion, *viaRegionPtr; + +typedef struct { + viaRegion regs, agp; + int deviceID; + int width; + int height; + int mem; + int bytesPerPixel; + int priv1; + int priv2; + int fbOffset; + int fbSize; + Bool drixinerama; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int irqEnabled; + unsigned int scrnX, scrnY; + int sarea_priv_offset; + int ringBufActive; + unsigned int reg_pause_addr; +} VIADRIRec, *VIADRIPtr; + +typedef struct { + int dummy; +} VIAConfigPrivRec, *VIAConfigPrivPtr; + +typedef struct { + int dummy; +} VIADRIContextRec, *VIADRIContextPtr; + +#ifdef XFree86Server + +#include "screenint.h" + +Bool VIADRIScreenInit(ScreenPtr pScreen); +void VIADRICloseScreen(ScreenPtr pScreen); +Bool VIADRIFinishScreenInit(ScreenPtr pScreen); +void VIADRIRingBufferCleanup(ScrnInfoPtr pScrn); +Bool VIADRIRingBufferInit(ScrnInfoPtr pScrn); + + + +#endif /* XFree86Server */ +#endif /* _VIA_DRI_H_ */ diff --git a/unichrome/via_driver.c b/unichrome/via_driver.c new file mode 100644 index 000000000000..2c23f2a4ce82 --- /dev/null +++ b/unichrome/via_driver.c @@ -0,0 +1,2555 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/************************************************************************* + * + * File: via_driver.c + * Content: XFree86 4.0 for VIA/S3G UniChrome + * + ************************************************************************/ + +#include "xf86RAC.h" +#include "shadowfb.h" + +#include "globals.h" +#define DPMS_SERVER +#include "extensions/dpms.h" + + +#include "via_driver.h" +#include "via_video.h" + +#include "via.h" + +#ifdef XF86DRI +#include "dri.h" +#endif +#include "via_vgahw.h" +#include "via_id.h" + +/* + * prototypes + */ + +static void VIAIdentify(int flags); +static Bool VIAProbe(DriverPtr drv, int flags); +static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags); +static Bool VIAEnterVT(int scrnIndex, int flags); +static void VIALeaveVT(int scrnIndex, int flags); +static void VIASave(ScrnInfoPtr pScrn); +static void VIARestore(ScrnInfoPtr pScrn); +static Bool VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool VIASaveScreen(ScreenPtr pScreen, int mode); +static Bool VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, + char **argv); +static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen); +static void VIAFreeScreen(int scrnIndex, int flags); +static Bool VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static void VIAAdjustFrame(int scrnIndex, int y, int x, int flags); +static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags); +static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid); + +static Bool VIAMapMMIO(ScrnInfoPtr pScrn); +static Bool VIAMapFB(ScrnInfoPtr pScrn); +static void VIAUnmapMem(ScrnInfoPtr pScrn); + +DriverRec VIA = +{ + VIA_VERSION, + DRIVER_NAME, + VIAIdentify, + VIAProbe, + VIAAvailableOptions, + NULL, + 0 +}; + + +/* Supported chipsets */ + +static SymTabRec VIAChipsets[] = { + {VIA_CLE266, "CLE266"}, + {VIA_KM400, "KM400/KN400"}, + {VIA_K8M800, "K8M800"}, + {VIA_PM800, "PM800/PM880/CN400"}, + {-1, NULL } +}; + +/* This table maps a PCI device ID to a chipset family identifier. */ +static PciChipsets VIAPciChipsets[] = { + /* {VIA_CLE266, PCI_CHIP_CLE3022, RES_SHARED_VGA}, */ + {VIA_CLE266, PCI_CHIP_CLE3122, RES_SHARED_VGA}, + {VIA_KM400, PCI_CHIP_VT3205, RES_SHARED_VGA}, + {VIA_K8M800, PCI_CHIP_VT3204, RES_SHARED_VGA}, + {VIA_PM800, PCI_CHIP_VT3259, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; + +int gVIAEntityIndex = -1; + +typedef enum { +#ifdef HAVE_DEBUG + OPTION_PRINTVGAREGS, + OPTION_PRINTTVREGS, + OPTION_I2CSCAN, + OPTION_VBEMODES, +#endif /* HAVE_DEBUG */ + OPTION_PCI_BURST, + OPTION_PCI_RETRY, + OPTION_NOACCEL, + OPTION_SWCURSOR, + OPTION_HWCURSOR, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_VIDEORAM, + OPTION_ACTIVEDEVICE, + OPTION_LCDDUALEDGE, + OPTION_BUSWIDTH, + OPTION_CENTER, + OPTION_PANELSIZE, + OPTION_FORCEPANEL, + OPTION_TVDOTCRAWL, + OPTION_TVTYPE, + OPTION_TVOUTPUT, + OPTION_DISABLEVQ, + OPTION_DRIXINERAMA, + OPTION_DISABLEIRQ, + OPTION_INSECUREDRI, + OPTION_TVDEFLICKER, + OPTION_AGP_DMA, + OPTION_2D_DMA +} VIAOpts; + + +static OptionInfoRec VIAOptions[] = +{ +#ifdef HAVE_DEBUG /* Don't document these */ + {OPTION_PRINTVGAREGS, "PrintVGARegs", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_PRINTTVREGS, "PrintTVRegs", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_I2CSCAN, "I2CScan", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_VBEMODES, "VBEModes", OPTV_BOOLEAN, {0}, FALSE}, +#endif /* HAVE_DEBUG */ + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE}, + {OPTION_ACTIVEDEVICE, "ActiveDevice", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_LCDDUALEDGE, "LCDDualEdge", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_BUSWIDTH, "BusWidth", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_CENTER, "Center", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_PANELSIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_FORCEPANEL, "ForcePanel", OPTV_BOOLEAN, {0}, FALSE}, /* last resort - don't doc */ + {OPTION_TVDOTCRAWL, "TVDotCrawl", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TVDEFLICKER,"TVDeflicker", OPTV_INTEGER, {0}, FALSE}, + {OPTION_TVTYPE, "TVType", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVOUTPUT, "TVOutput", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_DISABLEVQ, "DisableVQ", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DRIXINERAMA, "DRIXINERAMA", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_AGP_DMA, "EnableAGPDMA", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_2D_DMA, "NoAGPFor2D", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + + +static const char *vgaHWSymbols[] = { + "vgaHWGetHWRec", + "vgaHWSetMmioFuncs", + "vgaHWSetStdFuncs", + "vgaHWGetIOBase", + "vgaHWSave", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWMapMem", + "vgaHWUnmapMem", + "vgaHWInit", + "vgaHWSaveScreen", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWFreeHWRec", + NULL +}; + + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +static const char *vbeSymbols[] = { + "vbeDoEDID", + "VBEDPMSSet", + "VBEExtendedInit", + "vbeFree", + "VBEGetVBEInfo", + "VBEGetVBEMode", + "VBEGetModePool", + "VBEInit", + "VBEPrintModes", + "VBESaveRestore", + "VBESetDisplayStart", + "VBESetGetLogicalScanlineLength", + "VBESetLogicalScanline", + "VBESetModeNames", + "VBESetModeParameters", + "VBESetVBEMode", + "VBEValidateModes", + "xf86ExecX86int10", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC2", + "xf86SetDDCproperties", + NULL +}; + + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + "xf86CreateI2CDevRec", + "xf86I2CDevInit", + "xf86I2CWriteRead", + "xf86I2CProbeAddress", + "xf86DestroyI2CDevRec", + "xf86I2CReadByte", + "xf86I2CWriteByte", + NULL +}; + +static const char *xaaSymbols[] = { +#ifdef X_HAVE_XAAGETROP + "XAAGetCopyROP", + "XAAGetCopyROP_PM", + "XAAGetPatternROP", +#else + "XAACopyROP", + "XAACopyROP_PM", + "XAAPatternROP", +#endif + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAInit", + "XAAFillSolidRects", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb24_32ScreenInit", + "cfb32ScreenInit", + "cfb16BresS", + "cfb24BresS", + NULL +}; +#endif + +#ifdef XFree86LOADER +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAgpAcquire", + "drmAgpAlloc", + "drmAgpBase", + "drmAgpBind", + "drmAgpDeviceId", + "drmAgpEnable", + "drmAgpFree", + "drmAgpGetMode", + "drmAgpRelease", + "drmAgpVendorId", + "drmCtlInstHandler", + "drmCtlUninstHandler", + "drmCommandNone", + "drmCommandWrite", + "drmFreeVersion", + "drmGetInterruptFromBusID", + "drmGetLibVersion", + "drmGetVersion", + "drmMap", + "drmMapBufs", + "drmUnmap", + "drmUnmapBufs", + "drmAgpUnbind", + "drmRmMap", + "drmCreateContext", + "drmAuthMagic", + "drmDestroyContext", + "drmSetContextFlags", + NULL +}; + +static const char *driSymbols[] = { + "DRICloseScreen", + "DRICreateInfoRec", + "DRIDestroyInfoRec", + "DRIFinishScreenInit", + "DRIGetSAREAPrivate", + "DRILock", + "DRIQueryVersion", + "DRIScreenInit", + "DRIUnlock", + "DRIOpenConnection", + "DRICloseConnection", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static MODULESETUPPROTO(VIASetup); + +static XF86ModuleVersionInfo VIAVersRec = { + "via", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +XF86ModuleData viaModuleData = {&VIAVersRec, VIASetup, NULL}; + +static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&VIA, module, 0); + LoaderRefSymLists(vgaHWSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + ramdacSymbols, + xaaSymbols, + shadowSymbols, + vbeSymbols, + i2cSymbols, + ddcSymbols, +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + NULL); + + return (pointer) 1; + } + else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + + return NULL; + } +} /* VIASetup */ + +#endif /* XFree86LOADER */ + +static Bool VIAGetRec(ScrnInfoPtr pScrn) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetRec\n")); + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(VIARec), 1); + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo = + xnfcalloc(sizeof(VIABIOSInfoRec), 1); + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->scrnIndex = + pScrn->scrnIndex; + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->TVI2CDev = NULL; + + ((VIARec *)(pScrn->driverPrivate))->CursorImage = NULL; + + return TRUE; + +} /* VIAGetRec */ + + +static void VIAFreeRec(ScrnInfoPtr pScrn) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAFreeRec\n")); + if (!pScrn->driverPrivate) + return; + + if (VIAPTR(pScrn)->pVbe) + vbeFree(VIAPTR(pScrn)->pVbe); + + if (((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->TVI2CDev) + xf86DestroyI2CDevRec((((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->TVI2CDev), TRUE); + xfree(((VIARec *)(pScrn->driverPrivate))->pBIOSInfo); + + VIAUnmapMem(pScrn); + + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} /* VIAFreeRec */ + + + +static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid) +{ + + return VIAOptions; + +} /* VIAAvailableOptions */ + + +static void VIAIdentify(int flags) +{ + xf86PrintChipsets("VIA", "driver for VIA chipsets", VIAChipsets); +} /* VIAIdentify */ + + +static Bool VIAProbe(DriverPtr drv, int flags) +{ + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + int i; + + /* sanity checks */ + if ((numDevSections = xf86MatchDevice(DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + if (xf86GetPciVideoInfo() == NULL) + return FALSE; + + numUsed = xf86MatchPciInstances(DRIVER_NAME, + PCI_VIA_VENDOR_ID, + VIAChipsets, + VIAPciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + xfree(devSections); + + if (numUsed <= 0) + return FALSE; + + xf86Msg(X_NOTICE, "VIA Technologies does not support or endorse this driver in any way.\n"); + xf86Msg(X_NOTICE, "For support, please refer to http://unichrome.sourceforge.net/ or\n"); + xf86Msg(X_NOTICE, "your X vendor.\n"); + + if (flags & PROBE_DETECT) { + foundScreen = TRUE; + } + else { + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + EntityInfoPtr pEnt; + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + VIAPciChipsets, 0, 0, 0, 0, 0))) + { + pScrn->driverVersion = VIA_VERSION; + pScrn->driverName = DRIVER_NAME; + pScrn->name = "VIA"; + pScrn->Probe = VIAProbe; + pScrn->PreInit = VIAPreInit; + pScrn->ScreenInit = VIAScreenInit; + pScrn->SwitchMode = VIASwitchMode; + pScrn->AdjustFrame = VIAAdjustFrame; + pScrn->EnterVT = VIAEnterVT; + pScrn->LeaveVT = VIALeaveVT; + pScrn->FreeScreen = VIAFreeScreen; + pScrn->ValidMode = ViaValidMode; + foundScreen = TRUE; + } + /* + xf86ConfigActivePciEntity(pScrn, + usedChips[i], + VIAPciChipsets, + NULL, + NULL, + NULL, + NULL, + NULL); + */ + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* CLE266 card support Dual-Head, mark the entity as sharable*/ + if(pEnt->chipset == VIA_CLE266 || pEnt->chipset == VIA_KM400) + { + static int instance = 0; + DevUnion* pPriv; + + xf86SetEntitySharable(usedChips[i]); + xf86SetEntityInstanceForScreen(pScrn, + pScrn->entityList[0], instance); + + if(gVIAEntityIndex < 0) + { + gVIAEntityIndex = xf86AllocateEntityPrivateIndex(); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + + if (!pPriv->ptr) + { + VIAEntPtr pVIAEnt; + pPriv->ptr = xnfcalloc(sizeof(VIAEntRec), 1); + pVIAEnt = pPriv->ptr; + pVIAEnt->IsDRIEnabled = FALSE; + pVIAEnt->BypassSecondary = FALSE; + pVIAEnt->HasSecondary = FALSE; + pVIAEnt->IsSecondaryRestored = FALSE; + } + } + instance++; + } + xfree(pEnt); + } + } + + xfree(usedChips); + + return foundScreen; + +} /* VIAProbe */ + +#ifdef XF86DRI +static void kickVblank(ScrnInfoPtr pScrn) +{ + /* + * Switching mode will clear registers that make vblank + * interrupts happen. If the driver thinks interrupts + * are enabled, make sure vblank interrupts go through. + * registers are not documented in VIA docs. + */ + + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + if (pVIADRI->irqEnabled) { + hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x30); + } +} +#endif + +static int LookupChipSet(PciChipsets *pset, int chipSet) +{ + while (pset->numChipset >= 0) { + if (pset->numChipset == chipSet) return pset->PCIid; + pset++; + } + return -1; +} + + +static int LookupChipID(PciChipsets* pset, int ChipID) +{ + /* Is there a function to do this for me? */ + while (pset->numChipset >= 0) + { + if (pset->PCIid == ChipID) + return pset->numChipset; + + pset++; + } + + return -1; + +} /* LookupChipID */ + +static void +VIAProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags) +{ + EntityInfoPtr pEnt; + VIAPtr pVia; + VIABIOSInfoPtr pBIOSInfo; + MessageType from = X_DEFAULT; + ClockRangePtr clockRanges; + char *s = NULL; +#ifndef USE_FB + char *mod = NULL; + const char *reqSym = NULL; +#endif + vgaHWPtr hwp; + int i, bMemSize = 0; + Bool UseVBEModes = FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAPreInit\n")); + + if (pScrn->numEntities > 1) + return FALSE; + + if (flags & PROBE_DETECT) + return FALSE; + + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgaHWSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + +#if 0 + /* Here we can alter the number of registers saved and restored by the + * standard vgaHWSave and Restore routines. + */ + vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, VGA_NUM_ATTR); +#endif + + if (!VIAGetRec(pScrn)) { + return FALSE; + } + + pVia = VIAPTR(pScrn); + pBIOSInfo = pVia->pBIOSInfo; + + pVia->IsSecondary = FALSE; + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pEnt->resources) { + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + + pVia->EntityIndex = pEnt->index; + + if(xf86IsEntityShared(pScrn->entityList[0])) + { + if(xf86IsPrimInitDone(pScrn->entityList[0])) + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + + pVia->IsSecondary = TRUE; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + if (pVIAEnt->BypassSecondary) { + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + pVIAEnt->pSecondaryScrn = pScrn; + pVIAEnt->HasSecondary = TRUE; + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + pVia1->HasSecondary = TRUE; + pVia->sharedData = pVia1->sharedData; + } + else + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + + xf86SetPrimInitDone(pScrn->entityList[0]); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1); + pVIAEnt = pPriv->ptr; + pVIAEnt->pPrimaryScrn = pScrn; + pVIAEnt->IsDRIEnabled = FALSE; + pVIAEnt->BypassSecondary = FALSE; + pVIAEnt->HasSecondary = FALSE; + pVIAEnt->RestorePrimary = FALSE; + pVIAEnt->IsSecondaryRestored = FALSE; + } + } else { + pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1); + } + + if (flags & PROBE_DETECT) { + VIAProbeDDC(pScrn, pVia->EntityIndex); + return TRUE; + } + + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * We support depths of 8, 16 and 24. + * We support bpp of 8, 16, and 32. + */ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + else { + switch (pScrn->depth) { + case 8: + case 16: + case 24: + case 32: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + } + + xf86PrintDepthBpp(pScrn); + + if (pScrn->depth == 32) { + pScrn->depth = 24; + } + + if (pScrn->depth > 8) { + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } else { + /* TODO check weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } + else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + } + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + xf86CollectOptions(pScrn, NULL); + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) + pScrn->rgbBits = 6; + + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions); + +#ifdef XF86DRI + pVia->drixinerama = FALSE; + if (xf86IsOptionSet(VIAOptions, OPTION_DRIXINERAMA)) + pVia->drixinerama = TRUE; +#else + if (xf86IsOptionSet(VIAOptions, OPTION_DRIXINERAMA)) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: drixinerama ignored, no DRI support compiled into driver.\n"); +#endif + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_BURST, FALSE)) { + pVia->pci_burst = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: pci_burst - PCI burst read enabled\n"); + } + else { + pVia->pci_burst = FALSE; + } + + pVia->NoPCIRetry = 1; /* default */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_RETRY, FALSE)) { + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_BURST, FALSE)) { + pVia->NoPCIRetry = 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"pci_retry\" option requires \"pci_burst\"\n"); + } + } + + if (xf86IsOptionSet(VIAOptions, OPTION_SHADOW_FB)) { + pVia->shadowFB = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ShadowFB %s.\n", + pVia->shadowFB ? "enabled" : "disabled"); + } + else { + pVia->shadowFB = FALSE; + } + + if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATE))) { + if (!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + pVia->shadowFB = TRUE; + pVia->rotate = 1; + pVia->hwcursor = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } + else if(!xf86NameCmp(s, "CCW")) { + pVia->shadowFB = TRUE; + pVia->rotate = -1; + pVia->hwcursor = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" + "counter clockwise - acceleration disabled\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" + "value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_NOACCEL, FALSE)) { + pVia->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: NoAccel -Acceleration Disabled\n"); + } + else { + pVia->NoAccel = FALSE; + } + + if (pVia->shadowFB && !pVia->NoAccel) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "HW acceleration not supported with \"shadowFB\".\n"); + pVia->NoAccel = TRUE; + } + + /* + * The SWCursor setting takes priority over HWCursor. The default + * if neither is specified is HW. + */ + + from = X_DEFAULT; + pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE; + if (xf86GetOptValBool(VIAOptions, OPTION_HWCURSOR, &pVia->hwcursor)) + from = X_CONFIG; + + if (xf86ReturnOptValBool(VIAOptions, OPTION_SWCURSOR, FALSE)) { + pVia->hwcursor = FALSE; + from = X_CONFIG; + } + + if (pVia->IsSecondary) pVia->hwcursor = FALSE; + + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pVia->hwcursor ? "HW" : "SW"); + + from = X_DEFAULT; + + pScrn->videoRam = 0; + if(xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM, &pScrn->videoRam)) { + xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, + "Option: VideoRAM %dkB\n", pScrn->videoRam ); + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_DISABLEVQ, FALSE)) { + pVia->VQEnable = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: DisableVQ -VQ Disabled\n"); + } + else { + pVia->VQEnable = TRUE; + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_DISABLEIRQ, FALSE)) { + pVia->DRIIrqEnable = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: DisableIRQ - DRI IRQ Disabled\n"); + } + else { + pVia->DRIIrqEnable = TRUE; + } + + + if (xf86ReturnOptValBool(VIAOptions, OPTION_AGP_DMA, FALSE)) { + pVia->agpEnable = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: EnableAGPDMA - Enabling AGP DMA\n"); + } else { + pVia->agpEnable = FALSE; + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_2D_DMA, FALSE)) { + pVia->dma2d = FALSE; + if (pVia->agpEnable) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: NoAGPFor2D - AGP DMA is not used for 2D " + "acceleration\n"); + } + } else { + pVia->dma2d = TRUE; + } + +#ifdef HAVE_DEBUG + if (xf86ReturnOptValBool(VIAOptions, OPTION_VBEMODES, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: VBEModes - Using BIOS modes\n"); + UseVBEModes = TRUE; + } +#endif /* HAVE_DEBUG */ + + /* ActiveDevice Option for device selection */ + pVia->ActiveDevice = 0x00; + if ((s = xf86GetOptValString(VIAOptions, OPTION_ACTIVEDEVICE))) { + if (xf86strstr(s, "CRT")) + pVia->ActiveDevice |= VIA_DEVICE_CRT; + if (xf86strstr(s, "LCD")) + pVia->ActiveDevice |= VIA_DEVICE_LCD; + if (xf86strstr(s, "DFP")) /* just treat this the same as LCD */ + pVia->ActiveDevice |= VIA_DEVICE_LCD; + if (xf86strstr(s, "TV")) + pVia->ActiveDevice |= VIA_DEVICE_TV; + } + + /* LCDDualEdge Option */ + pBIOSInfo->LCDDualEdge = FALSE; + if (xf86ReturnOptValBool(VIAOptions, OPTION_LCDDUALEDGE, FALSE)) { + pBIOSInfo->LCDDualEdge = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: Using Dual Edge mode to set LCD\n"); + } + else { + pBIOSInfo->LCDDualEdge = FALSE; + } + + /* Digital Output Bus Width Option */ + pBIOSInfo->BusWidth = VIA_DI_12BIT; + if ((s = xf86GetOptValString(VIAOptions, OPTION_BUSWIDTH))) { + if (!xf86NameCmp(s, "12BIT")) { + pBIOSInfo->BusWidth = VIA_DI_12BIT; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Digital Output Bus Width is 12BIT\n"); + } + else if (!xf86NameCmp(s, "24BIT")) { + pBIOSInfo->BusWidth = VIA_DI_24BIT; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Digital Output Bus Width is 24BIT\n"); + } + } + + /* LCD Center/Expend Option */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_CENTER, FALSE)) { + pBIOSInfo->Center = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DVI Center is On\n"); + } + else { + pBIOSInfo->Center = FALSE; + } + + /* Panel Size Option */ + pBIOSInfo->PanelSize = VIA_PANEL_INVALID; + if ((s = xf86GetOptValString(VIAOptions, OPTION_PANELSIZE))) { + if (!xf86NameCmp(s, "640x480")) { + pBIOSInfo->PanelSize = VIA_PANEL6X4; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 640x480\n"); + } + else if (!xf86NameCmp(s, "800x600")) { + pBIOSInfo->PanelSize = VIA_PANEL8X6; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 800x600\n"); + } + else if(!xf86NameCmp(s, "1024x768")) { + pBIOSInfo->PanelSize = VIA_PANEL10X7; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1024x768\n"); + } + else if (!xf86NameCmp(s, "1280x768")) { + pBIOSInfo->PanelSize = VIA_PANEL12X7; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1280x768\n"); + } + else if (!xf86NameCmp(s, "1280x1024")) { + pBIOSInfo->PanelSize = VIA_PANEL12X10; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1280x1024\n"); + } + else if (!xf86NameCmp(s, "1400x1050")) { + pBIOSInfo->PanelSize = VIA_PANEL14X10; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1400x1050\n"); + } + } + + /* Force the use of the Panel? */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_FORCEPANEL, FALSE)) + pBIOSInfo->ForcePanel = TRUE; + else + pBIOSInfo->ForcePanel = FALSE; + + /* TV DotCrawl Enable Option */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_TVDOTCRAWL, FALSE)) { + pBIOSInfo->TVDotCrawl = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DotCrawl is Enable\n"); + } + else { + pBIOSInfo->TVDotCrawl = FALSE; + } + + /* TV Deflicker */ + pBIOSInfo->TVDeflicker = 0; + if(xf86GetOptValInteger(VIAOptions, OPTION_TVDEFLICKER, &pBIOSInfo->TVDeflicker)) { + xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, "Option: TVDeflicker %d\n", pBIOSInfo->TVDeflicker ); + } + + pBIOSInfo->TVType = TVTYPE_NONE; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVTYPE))) { + if (!xf86NameCmp(s, "NTSC")) { + pBIOSInfo->TVType = TVTYPE_NTSC; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is NTSC\n"); + } + else if(!xf86NameCmp(s, "PAL")) { + pBIOSInfo->TVType = TVTYPE_PAL; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is PAL\n"); + } + } + + /* TV out put signal Option */ + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVOUTPUT))) { + if (!xf86NameCmp(s, "S-Video")) { + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is S-Video\n"); + } + else if(!xf86NameCmp(s, "Composite")) { + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is Composite\n"); + } + else if(!xf86NameCmp(s, "SC")) { + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is SC\n"); + } + else if(!xf86NameCmp(s, "RGB")) { + pBIOSInfo->TVOutput = TVOUTPUT_RGB; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is RGB\n"); + } + else if(!xf86NameCmp(s, "YCbCr")) { + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is YCbCr\n"); + } + } + + pVia->PciInfo = xf86GetPciInfoForEntity(pEnt->index); + xf86RegisterResources(pEnt->index, NULL, ResNone); + /* + xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr); + */ + + if (pEnt->device->chipset && *pEnt->device->chipset) { + pScrn->chipset = pEnt->device->chipset; + pVia->Chipset = xf86StringToToken(VIAChipsets, pScrn->chipset); + pVia->ChipId = pEnt->device->chipID = LookupChipSet(VIAPciChipsets, pVia->Chipset); + from = X_CONFIG; + } else if (pEnt->device->chipID >= 0) { + pVia->ChipId = pEnt->device->chipID; + pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId); + pScrn->chipset = (char *)xf86TokenToString(VIAChipsets, + pVia->Chipset); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pEnt->device->chipID); + } else { + from = X_PROBED; + pVia->ChipId = pVia->PciInfo->chipType; + pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId); + pScrn->chipset = (char *)xf86TokenToString(VIAChipsets, + pVia->Chipset); + } + + if (pEnt->device->chipRev >= 0) { + pVia->ChipRev = pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pVia->ChipRev); + } + else { + /*pVia->ChipRev = pVia->PciInfo->chipRev;*/ + /* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip rev. */ + pVia->ChipRev = pciReadByte(pciTag(0, 0, 0), 0xF6); + } + + if (pEnt->device->videoRam != 0) { + if (!pScrn->videoRam) + pScrn->videoRam = pEnt->device->videoRam; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video Memory Size in Option is %d KB, Detect is %d KB!", + pScrn->videoRam, pEnt->device->videoRam); + } + } + + xfree(pEnt); + + VIAVidHWDiffInit(pScrn); + + /* maybe throw in some more sanity checks here */ + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + +#ifndef HAVE_K8M800 + if (pVia->Chipset == VIA_K8M800) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "This device seems to be a VIA Unichrome Pro K8M800.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "There is no specific support for this device yet in this driver.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Please contact unichrome.sourceforge.net ASAP to resolve this.\n"); + } +#endif /* HAVE_K8M800 */ +#ifndef HAVE_PM800 + if (pVia->Chipset == VIA_PM800) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "This device seems to be a VIA Unichrome Pro PM800, PM880 or CN400.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "There is no specific support for this device yet in this driver.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Please contact unichrome.sourceforge.net ASAP to resolve this.\n"); + } +#endif /* HAVE_PM800 */ + + pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, + pVia->PciInfo->func); + + if (!VIAMapMMIO(pScrn)) { + VIAFreeRec(pScrn); + return FALSE; + } + hwp = VGAHWPTR(pScrn); + +#ifdef HAVE_DEBUG + if (xf86ReturnOptValBool(VIAOptions, OPTION_PRINTVGAREGS, FALSE)) { + pVia->PrintVGARegs = TRUE; + ViaVgahwPrint(VGAHWPTR(pScrn)); /* Do this as early as possible */ + } else + pVia->PrintVGARegs = FALSE; + + if (xf86ReturnOptValBool(VIAOptions, OPTION_PRINTTVREGS, FALSE)) + pVia->PrintTVRegs = TRUE; + else + pVia->PrintTVRegs = FALSE; + + if (xf86ReturnOptValBool(VIAOptions, OPTION_I2CSCAN, FALSE)) + pVia->I2CScan = TRUE; + else + pVia->I2CScan = FALSE; +#endif /* HAVE_DEBUG */ + + if (pVia->Chipset == VIA_CLE266) + ViaDoubleCheckCLE266Revision(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset Rev.: %d\n", pVia->ChipRev); + + ViaCheckCardId(pScrn); + + /* read memory bandwidth from registers */ + pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected MemClk %d\n", pVia->MemClk)); + if (pVia->MemClk >= VIA_MEM_END) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Memory clock: %d\n", pVia->MemClk); + pVia->MemClk = VIA_MEM_END - 1; + } + pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); + + if (pBIOSInfo->TVType == TVTYPE_NONE) { + /* use jumper to determine TV Type */ + + if (hwp->readCrtc(hwp, 0x3B) & 0x02) { + pBIOSInfo->TVType = TVTYPE_PAL; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected TV Standard: PAL.\n")); + } + else { + pBIOSInfo->TVType = TVTYPE_NTSC; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected TV Standard: NTSC.\n")); + } + } + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + VIAFreeRec(pScrn); + return FALSE; + } + } + + /* detect amount of installed ram */ + if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { + if(pVia->Chipset == VIA_CLE266) + bMemSize = hwp->readSeq(hwp, 0x34); + else + bMemSize = hwp->readSeq(hwp, 0x39); + + if (bMemSize > 16 && bMemSize <= 128) + pScrn->videoRam = (bMemSize + 1) << 9; + else if (bMemSize > 0 && bMemSize < 31) + pScrn->videoRam = bMemSize << 12; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Memory size detection failed: using 16MB\n"); + pScrn->videoRam = 16 << 10; /* Assume the base 16Mb */ + } + } + + /* Split FB for SAMM */ + /* FIXME: For now, split FB into two equal sections. This should + * be able to be adjusted by user with a config option. */ + if (pVia->IsSecondary) { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + pScrn->videoRam = pScrn->videoRam >> 1; + pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + pVia1->videoRambytes = pScrn->videoRam << 10; + pVia->FrameBufferBase += (pScrn->videoRam << 10); + } + + pVia->videoRambytes = pScrn->videoRam << 10; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED,"videoram = %dk\n", + pScrn->videoRam); + + if (!xf86LoadSubModule(pScrn, "i2c")) { + VIAFreeRec(pScrn); + return FALSE; + } + else { + xf86LoaderReqSymLists(i2cSymbols,NULL); + ViaI2CInit(pScrn); + } + + if (!xf86LoadSubModule(pScrn, "ddc")) { + VIAFreeRec(pScrn); + return FALSE; + } else { + xf86LoaderReqSymLists(ddcSymbols, NULL); + + if (pVia->pI2CBus1) { + pVia->DDC1 = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus1); + if (pVia->DDC1) { + xf86PrintEDID(pVia->DDC1); + xf86SetDDCproperties(pScrn, pVia->DDC1); + } + } + } + + ViaOutputsDetect(pScrn); + if (!ViaOutputsSelect(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No outputs possible.\n"); + VIAFreeRec(pScrn); + return FALSE; + } + + if (pBIOSInfo->PanelActive && ((pVia->Chipset == VIA_K8M800) || + (pVia->Chipset == VIA_PM800))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Panel on K8M800 or PM800 is" + " currently not supported.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Using VBE to set modes to" + " work around this.\n"); + UseVBEModes = TRUE; + } + + pVia->pVbe = NULL; + if (UseVBEModes) { + /* VBE doesn't properly initialise int10 itself */ + if (xf86LoadSubModule(pScrn, "int10") && xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + pVia->pVbe = VBEExtendedInit(NULL, pVia->EntityIndex, + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); + } + + if (!pVia->pVbe) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialisation failed." + " Using builtin code to set modes.\n"); + } + + if (pVia->pVbe) { + + if (!ViaVbeModePreInit( pScrn )) { + VIAFreeRec(pScrn); + return FALSE; + } + + } else { + /* Add own Modes */ + ViaModesAttach(pScrn, pScrn->monitor); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + + clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges->next = NULL; + clockRanges->minClock = 20000; + clockRanges->maxClock = 230000; + + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our VIAValidMode() already takes + * care of this, we don't worry about setting them here. + * + * CLE266A: + * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) + * Max Height: 4096 (and beyond) + * + * CLE266A: primary AdjustFrame only is able to use 24bits, so we are + * limited to 12x11bits; 4080x2048 (~2:1), 3344x2508 (4:3) or 2896x2896 + * (1:1). + * Test CLE266Cx, KM400, KM400A, K8M800, PM800, CN400 please. + * + * We should be able to limit the memory available for a mode to 32MB, + * yet xf86ValidateModes (or miScanLineWidth) fails to catch this properly + * (apertureSize). + */ + + /* Select valid modes from those available */ + i = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, /* availModes */ + pScrn->display->modes, /* modeNames */ + clockRanges, /* list of clock ranges */ + NULL, /* list of line pitches */ + 256, /* mini line pitch */ + 3344, /* max line pitch */ + 16 * pScrn->bitsPerPixel, /* pitch inc (bits) */ + 128, /* min height */ + 2508, /* max height */ + pScrn->display->virtualX, /* virtual width */ + pScrn->display->virtualY, /* virtual height */ + pVia->videoRambytes, /* apertureSize */ + LOOKUP_BEST_REFRESH); /* lookup mode flags */ + + + if (i == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86ValidateModes failure\n"); + VIAFreeRec(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + VIAFreeRec(pScrn); + return FALSE; + } + + } + + /* Set up screen parameters. */ + pVia->Bpp = pScrn->bitsPerPixel >> 3; + pVia->Bpl = pScrn->displayWidth * pVia->Bpp; + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + xf86SetDpi(pScrn, 0, 0); + +#ifdef USE_FB + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + VIAFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + +#else + /* load bpp-specific modules */ + switch (pScrn->bitsPerPixel) { + case 8: + mod = "cfb"; + reqSym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSym = "cfb16ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSym = "cfb32ScreenInit"; + break; + } + + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + VIAFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymbols(reqSym, NULL); +#endif + + if (!pVia->NoAccel) { + if(!xf86LoadSubModule(pScrn, "xaa")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + if (pVia->hwcursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + + if (pVia->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + VIAUnmapMem(pScrn); + + return TRUE; +} + + +static Bool VIAEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + Bool ret; + + /* FIXME: Rebind AGP memory here */ + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAEnterVT\n")); + + if (pVia->pVbe) { + ViaVbeSaveRestore(pScrn, MODE_SAVE); + ret = ViaVbeSetMode(pScrn, pScrn->currentMode); + } else { + VIASave(pScrn); + ret = VIAWriteMode(pScrn, pScrn->currentMode); + } + vgaHWUnlock(hwp); + + /* Patch for APM suspend resume, HWCursor has garbage */ + if (pVia->hwcursor) + ViaCursorRestore(pScrn); + + /* restore video status */ + if (!pVia->IsSecondary) + viaRestoreVideo(pScrn); + + +#ifdef XF86DRI + kickVblank(pScrn); + if (pVia->directRenderingEnabled) { + VIADRIRingBufferInit(pScrn); + DRIUnlock(screenInfo.screens[scrnIndex]); + } +#endif + + return ret; +} + + +static void VIALeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIALeaveVT\n")); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + DRILock(screenInfo.screens[scrnIndex], 0); +#endif + + VIAAccelSync(pScrn); + + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + + /* + * Next line apparently helps fix 3D hang on VT switch. + * No idea why. Taken from VIA's binary drivers. + */ + + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); + + VIADRIRingBufferCleanup(pScrn); + } +#endif + + if (pVia->VQEnable) + ViaVQDisable(pScrn); + + /* Save video status and turn off all video activities */ + + if (!pVia->IsSecondary) + viaSaveVideo(pScrn); + + if (pVia->hwcursor) + ViaCursorStore(pScrn); + + if (pVia->pVbe) + ViaVbeSaveRestore(pScrn, MODE_RESTORE); + else + VIARestore(pScrn); + + vgaHWLock(hwp); + +} + + +static void +VIASave(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + VIARegPtr Regs = &pVia->SavedReg; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASave\n")); + + if(pVia->IsSecondary) + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + vgaHWPtr hwp1; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + hwp1 = VGAHWPTR(pVIAEnt->pPrimaryScrn); + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + hwp->SavedReg = hwp1->SavedReg; + pVia->SavedReg = pVia1->SavedReg; + } + else { + vgaHWProtect(pScrn, TRUE); + + if (xf86IsPrimaryPci(pVia->PciInfo)) + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); + else + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); + + /* Unlock Extended Regs */ + hwp->writeSeq(hwp, 0x10, 0x01); + Regs->SR14 = hwp->readSeq(hwp, 0x14); + Regs->SR15 = hwp->readSeq(hwp, 0x15); + Regs->SR16 = hwp->readSeq(hwp, 0x16); + Regs->SR17 = hwp->readSeq(hwp, 0x17); + Regs->SR18 = hwp->readSeq(hwp, 0x18); + Regs->SR19 = hwp->readSeq(hwp, 0x19); + Regs->SR1A = hwp->readSeq(hwp, 0x1A); + Regs->SR1B = hwp->readSeq(hwp, 0x1B); + Regs->SR1C = hwp->readSeq(hwp, 0x1C); + Regs->SR1D = hwp->readSeq(hwp, 0x1D); + Regs->SR1E = hwp->readSeq(hwp, 0x1E); + Regs->SR1F = hwp->readSeq(hwp, 0x1F); + + Regs->SR22 = hwp->readSeq(hwp, 0x22); + Regs->SR23 = hwp->readSeq(hwp, 0x23); + Regs->SR24 = hwp->readSeq(hwp, 0x24); + Regs->SR25 = hwp->readSeq(hwp, 0x25); + Regs->SR26 = hwp->readSeq(hwp, 0x26); + Regs->SR27 = hwp->readSeq(hwp, 0x27); + Regs->SR28 = hwp->readSeq(hwp, 0x28); + Regs->SR29 = hwp->readSeq(hwp, 0x29); + Regs->SR2A = hwp->readSeq(hwp, 0x2A); + Regs->SR2B = hwp->readSeq(hwp, 0x2B); + + Regs->SR2E = hwp->readSeq(hwp, 0x2E); + + Regs->SR44 = hwp->readSeq(hwp, 0x44); + Regs->SR45 = hwp->readSeq(hwp, 0x45); + Regs->SR46 = hwp->readSeq(hwp, 0x46); + Regs->SR47 = hwp->readSeq(hwp, 0x47); + + Regs->CR13 = hwp->readCrtc(hwp, 0x13); + + Regs->CR32 = hwp->readCrtc(hwp, 0x32); + Regs->CR33 = hwp->readCrtc(hwp, 0x33); + Regs->CR34 = hwp->readCrtc(hwp, 0x34); + Regs->CR35 = hwp->readCrtc(hwp, 0x35); + Regs->CR36 = hwp->readCrtc(hwp, 0x36); + + if (pBIOSInfo->TVI2CDev) + ViaTVSave(pScrn); + + /* Save LCD control regs */ + for (i = 0; i < 68; i++) + Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50); + + vgaHWProtect(pScrn, FALSE); + } +} + +static void +VIARestore(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + VIARegPtr Regs = &pVia->SavedReg; + int i; + CARD8 tmp; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIARestore\n")); + + /* Secondary? */ + + vgaHWProtect(pScrn, TRUE); + /* Unlock Extended Regs */ + hwp->writeSeq(hwp, 0x10, 0x01); + + hwp->writeCrtc(hwp, 0x6A, 0x00); + hwp->writeCrtc(hwp, 0x6B, 0x00); + hwp->writeCrtc(hwp, 0x6C, 0x00); + + if (pBIOSInfo->TVI2CDev) + ViaTVRestore(pScrn); + + /* restore the standard vga regs */ + if (xf86IsPrimaryPci(pVia->PciInfo)) + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL); + else + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE); + + /* restore extended regs */ + hwp->writeSeq(hwp, 0x14, Regs->SR14); + hwp->writeSeq(hwp, 0x15, Regs->SR15); + hwp->writeSeq(hwp, 0x16, Regs->SR16); + hwp->writeSeq(hwp, 0x17, Regs->SR17); + hwp->writeSeq(hwp, 0x18, Regs->SR18); + hwp->writeSeq(hwp, 0x19, Regs->SR19); + hwp->writeSeq(hwp, 0x1A, Regs->SR1A); + hwp->writeSeq(hwp, 0x1B, Regs->SR1B); + hwp->writeSeq(hwp, 0x1C, Regs->SR1C); + hwp->writeSeq(hwp, 0x1D, Regs->SR1D); + hwp->writeSeq(hwp, 0x1E, Regs->SR1E); + hwp->writeSeq(hwp, 0x1F, Regs->SR1F); + + hwp->writeSeq(hwp, 0x22, Regs->SR22); + hwp->writeSeq(hwp, 0x23, Regs->SR23); + hwp->writeSeq(hwp, 0x24, Regs->SR24); + hwp->writeSeq(hwp, 0x25, Regs->SR25); + hwp->writeSeq(hwp, 0x26, Regs->SR26); + hwp->writeSeq(hwp, 0x27, Regs->SR27); + hwp->writeSeq(hwp, 0x28, Regs->SR28); + hwp->writeSeq(hwp, 0x29, Regs->SR29); + hwp->writeSeq(hwp, 0x2A, Regs->SR2A); + hwp->writeSeq(hwp, 0x2B, Regs->SR2B); + + hwp->writeSeq(hwp, 0x2E, Regs->SR2E); + + hwp->writeSeq(hwp, 0x44, Regs->SR44); + hwp->writeSeq(hwp, 0x45, Regs->SR45); + hwp->writeSeq(hwp, 0x46, Regs->SR46); + hwp->writeSeq(hwp, 0x47, Regs->SR47); + + /* reset dotclocks */ + ViaSeqMask(hwp, 0x40, 0x06, 0x06); + ViaSeqMask(hwp, 0x40, 0x00, 0x06); + + hwp->writeCrtc(hwp, 0x13, Regs->CR13); + hwp->writeCrtc(hwp, 0x32, Regs->CR32); + hwp->writeCrtc(hwp, 0x33, Regs->CR33); + hwp->writeCrtc(hwp, 0x34, Regs->CR34); + hwp->writeCrtc(hwp, 0x35, Regs->CR35); + hwp->writeCrtc(hwp, 0x36, Regs->CR36); + + /* Restore LCD control regs */ + for (i = 0; i < 68; i++) + hwp->writeCrtc(hwp, i + 0x50, Regs->CRTCRegs[i]); + + if (pBIOSInfo->PanelActive) + ViaLCDPower(pScrn, TRUE); + + ViaDisablePrimaryFIFO(pScrn); + + /* Reset clock */ + tmp = hwp->readMiscOut(hwp); + hwp->writeMiscOut(hwp, tmp); + + vgaHWProtect(pScrn, FALSE); +} + +static Bool +VIAMapMMIO(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n")); + + pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; + pVia->MmioBase = pVia->PciInfo->memBase[1]; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping MMIO @ 0x%lx with size 0x%x\n", + pVia->MmioBase, VIA_MMIO_REGSIZE); + + pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, + pVia->MmioBase, VIA_MMIO_REGSIZE); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n", + pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE); + + pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, + pVia->MmioBase + VIA_MMIO_BLTBASE, + VIA_MMIO_BLTSIZE); + + if (!pVia->MapBase || !pVia->BltBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: cound not map registers\n"); + return FALSE; + } + + /* Memory mapped IO for Video Engine */ + pVia->VidMapBase = pVia->MapBase + 0x200; + /* Memory mapped IO for Mpeg Engine */ + pVia->MpegMapBase = pVia->MapBase + 0xc00; + + /* Set up MMIO vgaHW */ + { + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD8 val; + + vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); + + val = hwp->readEnable(hwp); + hwp->writeEnable(hwp, val | 0x01); + + val = hwp->readMiscOut(hwp); + hwp->writeMiscOut(hwp, val | 0x01); + + /* Unlock Extended IO Space */ + hwp->writeSeq(hwp, 0x10, 0x01); + + /* Enable MMIO */ + if (pVia->IsSecondary) + ViaSeqMask(hwp, 0x1A, 0x38, 0x38); + else + ViaSeqMask(hwp, 0x1A, 0x68, 0x68); + + vgaHWGetIOBase(hwp); + } + + return TRUE; +} + + +static Bool VIAMapFB(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n")); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping framebuffer @ 0x%lx with size 0x%lx\n", + pVia->FrameBufferBase, pVia->videoRambytes); + + if (pVia->videoRambytes) { + + /* + * FIXME: This is a hack to get rid of offending wrongly sized + * MTRR regions set up by the VIA BIOS. Should be taken care of + * in the OS support layer. + */ + + unsigned char *tmp; + tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pVia->PciTag, pVia->FrameBufferBase, + pVia->videoRambytes); + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)tmp, + pVia->videoRambytes); + + /* + * And, as if this wasn't enough, 2.6 series kernels doesn't + * remove MTRR regions on the first attempt. Try again. + */ + + tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pVia->PciTag, pVia->FrameBufferBase, + pVia->videoRambytes); + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)tmp, + pVia->videoRambytes); + + /* + * End of hack. + */ + + pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pVia->PciTag, pVia->FrameBufferBase, + pVia->videoRambytes); + + if (!pVia->FBBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map framebuffer\n"); + return FALSE; + } + + pVia->FBFreeStart = (pScrn->displayWidth * pScrn->bitsPerPixel >> 3) * + pScrn->virtualY; + pVia->FBFreeEnd = pVia->videoRambytes; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Frame buffer start: %p, free start: 0x%x end: 0x%x\n", + pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd); + } + + pScrn->memPhysBase = pVia->PciInfo->memBase[0]; + pScrn->fbOffset = 0; + if(pVia->IsSecondary) pScrn->fbOffset = pScrn->videoRam << 10; + + return TRUE; +} + + +static void +VIAUnmapMem(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAUnmapMem\n")); + + /* Disable MMIO */ + ViaSeqMask(VGAHWPTR(pScrn), 0x1A, 0x00, 0x60); + + if (pVia->MapBase) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->MapBase, VIA_MMIO_REGSIZE); + + if (pVia->BltBase) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->BltBase, VIA_MMIO_BLTSIZE); + + if (pVia->FBBase) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->FBBase, pVia->videoRambytes); +} + +/* + * + */ +static void +VIALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + int i, index; + int SR1A, SR1B, CR67, CR6A; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadPalette\n")); + + if (pScrn->bitsPerPixel != 8) + return; + + SR1A = hwp->readSeq(hwp, 0x1A); + SR1B = hwp->readSeq(hwp, 0x1B); + CR67 = hwp->readCrtc(hwp, 0x67); + CR6A = hwp->readCrtc(hwp, 0x6A); + + if (pVia->IsSecondary) { + ViaSeqMask(hwp, 0x1A, 0x01, 0x01); + ViaSeqMask(hwp, 0x1B, 0x80, 0x80); + ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); + ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); + } + + for (i = 0; i < numColors; i++) { + index = indices[i]; + hwp->writeDacWriteAddr(hwp, index); + hwp->writeDacData(hwp, colors[index].red); + hwp->writeDacData(hwp, colors[index].green); + hwp->writeDacData(hwp, colors[index].blue); + } + + if (pVia->IsSecondary) { + hwp->writeSeq(hwp, 0x1A, SR1A); + hwp->writeSeq(hwp, 0x1B, SR1B); + hwp->writeCrtc(hwp, 0x67, CR67); + hwp->writeCrtc(hwp, 0x6A, CR6A); + + /* Screen 0 palette was changed by mode setting of Screen 1, + * so load again */ + for (i = 0; i < numColors; i++) { + index = indices[i]; + hwp->writeDacWriteAddr(hwp, index); + hwp->writeDacData(hwp, colors[index].red); + hwp->writeDacData(hwp, colors[index].green); + hwp->writeDacData(hwp, colors[index].blue); + } + } +} + +/* + * + */ +static Bool +VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n")); + + if (!VIAMapFB(pScrn)) + return FALSE; + + if (!VIAMapMMIO(pScrn)) + return FALSE; + + if (pVia->pVbe) + ViaVbeSaveRestore(pScrn, MODE_SAVE); + else + VIASave(pScrn); + + vgaHWUnlock(hwp); + + pVia->FirstInit = TRUE; + if (pVia->pVbe) { + ViaVbeDoDPMS(pScrn, DPMSModeStandby); + if (!ViaVbeSetMode(pScrn, pScrn->currentMode)) { + ViaVbeDoDPMS(pScrn, DPMSModeOn); + return FALSE; + } + } else { + vgaHWBlankScreen(pScrn, FALSE); + if (!VIAWriteMode(pScrn, pScrn->currentMode)) { + vgaHWBlankScreen(pScrn, TRUE); + return FALSE; + } + } + pVia->FirstInit = FALSE; + + /* Darken the screen for aesthetic reasons and set the viewport */ + VIASaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Blanked\n")); + + miClearVisualTypes(); + + if (pScrn->bitsPerPixel > 8 && !pVia->IsSecondary) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + } + +#ifdef XF86DRI + pVia->directRenderingEnabled = VIADRIScreenInit(pScreen); +#endif + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Visuals set up\n")); + + if (!VIAInternalScreenInit(scrnIndex, pScreen)) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- B & W\n")); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + +#ifdef USE_FB + /* must be after RGB ordering fixed */ + fbPictureInit(pScreen, 0, 0); +#endif + + if (!pVia->NoAccel) { + VIAInitAccel(pScreen); + } +#ifdef X_USE_LINEARFB + else { + /* + * This is needed because xf86InitFBManagerLinear in VIAInitLinear + * needs xf86InitFBManager to have been initialized, and + * xf86InitFBManager needs at least one line of free memory to + * work. This is only for Xv in Noaccel part, and since Xv is in some + * sense accelerated, it might be a better idea to disable it + * altogether. + */ + BoxRec AvailFBArea; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pScrn->virtualY + 1; + /* + * Update FBFreeStart also for other memory managers, since + * we steal one line to make xf86InitFBManager work. + */ + pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; + xf86InitFBManager(pScreen, &AvailFBArea); + } +#endif /* X_USE_LINEARFB */ + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + /*xf86SetSilkenMouse(pScreen);*/ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Backing store set up\n")); + + if(!pVia->shadowFB) /* hardware cursor needs to wrap this layer */ + VIADGAInit(pScreen); + + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n")); + + if (pVia->hwcursor) { + if (!VIAHWCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + } + + if (pVia->shadowFB) + ViaShadowFBInit(pScrn, pScreen); + + if (!miCreateDefColormap(pScreen)) + return FALSE; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Def Color map set up\n")); + + if (!xf86HandleColormaps(pScreen, 256, 6, VIALoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH + | CMAP_PALETTED_TRUECOLOR)) + return FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n")); + + if (pVia->pVbe) + ViaVbeDoDPMS(pScrn, DPMSModeOn); + else + vgaHWBlankScreen(pScrn, TRUE); + + pVia->CloseScreen = pScreen->CloseScreen; + pScreen->SaveScreen = VIASaveScreen; + pScreen->CloseScreen = VIACloseScreen; + + xf86DPMSInit(pScreen, VIADPMS, 0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n")); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n")); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen); + + if (pVia->directRenderingEnabled) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); + else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); + VIAInitLinear(pScreen); + } +#else + VIAInitLinear(pScreen); +#endif + + viaInitVideo(pScreen); + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#ifdef HAVE_DEBUG + if (pVia->PrintVGARegs) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit: Printing VGA registers.\n"); + ViaVgahwPrint(VGAHWPTR(pScrn)); + } + + if (pVia->PrintTVRegs) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit: Printing TV registers.\n"); + ViaTVPrintRegs(pScrn); + } +#endif + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Done\n")); + return TRUE; +} + + +static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + int width, height, displayWidth; + unsigned char *FBStart; + + xf86DrvMsg(scrnIndex, X_INFO, "VIAInternalScreenInit\n"); + + displayWidth = pScrn->displayWidth; + + if (pVia->rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + + if (pVia->shadowFB) { + pVia->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pVia->ShadowPtr = xalloc(pVia->ShadowPitch * height); + displayWidth = pVia->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pVia->ShadowPtr; + } + else { + pVia->ShadowPtr = NULL; + FBStart = pVia->FBBase; + } + +#ifdef USE_FB + return fbScreenInit(pScreen, FBStart, width, height, + pScrn->xDpi, pScrn->yDpi, displayWidth, + pScrn->bitsPerPixel); +#else + switch (pScrn->bitsPerPixel) { + case 8: + return cfbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + case 16: + return cfb16ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + case 32: + return cfb32ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + default: + xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) in " + "VIAInternalScreenInit\n", pScrn->bitsPerPixel); + return FALSE; + } +#endif +} + +static Bool +VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n")); + + pVia->OverlaySupported = FALSE; + + if (!vgaHWInit(pScrn, mode)) + return FALSE; + + pScrn->vtSema = TRUE; + + /* FIXME - need DRI lock for this bit - see i810 */ + if (!pVia->IsSecondary) + ViaModePrimary(pScrn, mode); + else + ViaModeSecondary(pScrn, mode); + + /* Enable the graphics engine. */ + if (!pVia->NoAccel) + VIAInitialize2DEngine(pScrn); + +#ifdef XF86DRI + VIAInitialize3DEngine(pScrn); +#endif + + VIAAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + + +static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIACloseScreen\n")); + + /* Is the display currently visible ? */ + if(pScrn->vtSema) + { + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + DRILock(screenInfo.screens[scrnIndex], 0); +#endif + /* Wait Hardware Engine idle to exit graphical mode */ + VIAAccelSync(pScrn); + + +#ifdef XF86DRI + /* Fix 3D Hang after X restart */ + + if (pVia->directRenderingEnabled) + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); +#endif + + if (!pVia->IsSecondary) { + /* Turn off all video activities */ + viaExitVideo(pScrn); + + VIAHideCursor(pScrn); + } + + if (pVia->VQEnable) + ViaVQDisable(pScrn); + } +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + VIADRICloseScreen(pScreen); +#endif + if (pVia->AccelInfoRec) { + XAADestroyInfoRec(pVia->AccelInfoRec); + pVia->AccelInfoRec = NULL; + } + if (pVia->CursorInfoRec) { + xf86DestroyCursorInfoRec(pVia->CursorInfoRec); + pVia->CursorInfoRec = NULL; + } + if (pVia->ShadowPtr) { + xfree(pVia->ShadowPtr); + pVia->ShadowPtr = NULL; + } + if (pVia->DGAModes) { + xfree(pVia->DGAModes); + pVia->DGAModes = NULL; + } + + if (pScrn->vtSema) { + if (pVia->pVbe) + ViaVbeSaveRestore(pScrn, MODE_RESTORE); + else + VIARestore(pScrn); + + vgaHWLock(hwp); + VIAUnmapMem(pScrn); + } + pScrn->vtSema = FALSE; + pScreen->CloseScreen = pVia->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +/* + * This only gets called when a screen is being deleted. It does not + * get called routinely at the end of a server generation. + */ +static void VIAFreeScreen(int scrnIndex, int flags) +{ + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAFreeScreen\n")); + + VIAFreeRec(xf86Screens[scrnIndex]); + + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); +} + +static Bool VIASaveScreen(ScreenPtr pScreen, int mode) +{ + return vgaHWSaveScreen(pScreen, mode); +} + +static void +VIAAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + CARD32 Base; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAAdjustFrame\n")); + + if (pVia->pVbe) { + ViaVbeAdjustFrame(scrnIndex, x, y, flags); + return; + } + + Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); + + /* now program the start address registers */ + if (pVia->IsSecondary) { + Base = (Base + pScrn->fbOffset) >> 3; + ViaCrtcMask(hwp, 0x62, (Base & 0x7F) << 1 , 0xFE); + hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7); + hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15); + } + else { + Base = Base >> 1; + hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); + hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); + hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16); +#if 0 + /* The CLE266A doesn't have this implemented, it seems. -- Luc */ + ViaCrtcMask(hwp, 0x48, Base >> 24, 0x03); +#endif + } + + VIAVidAdjustFrame(pScrn, x, y); +} + + +static Bool +VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + Bool ret; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIASwitchMode\n")); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + DRILock(screenInfo.screens[scrnIndex], 0); +#endif + + VIAAccelSync(pScrn); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + VIADRIRingBufferCleanup(pScrn); +#endif + + if (pVia->VQEnable) + ViaVQDisable(pScrn); + + if (pVia->pVbe) + ret = ViaVbeSetMode(pScrn, mode); + else + ret = VIAWriteMode(pScrn, mode); + +#ifdef XF86DRI + kickVblank(pScrn); + if (pVia->directRenderingEnabled) { + VIADRIRingBufferInit(pScrn); + DRIUnlock(screenInfo.screens[scrnIndex]); + } +#endif + return ret; + +} + + +static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + CARD8 val; + + if (pVia->pVbe) { + ViaVbeDPMS(pScrn, mode, flags); + return; + } + + /* Clear DPMS setting */ + val = hwp->readCrtc(hwp, 0x36); + val &= 0xCF; + + /* Turn Off CRT, if user doesn't want crt on */ + if (!pVia->IsSecondary && !pBIOSInfo->CrtActive) + val |= 0x30; + + switch (mode) { + case DPMSModeOn: + if (pBIOSInfo->PanelActive) + ViaLCDPower(pScrn, TRUE); + + if (pBIOSInfo->TVActive) + ViaTVPower(pScrn, TRUE); + + hwp->writeCrtc(hwp, 0x36, val); + break; + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + if (pBIOSInfo->PanelActive) + ViaLCDPower(pScrn, FALSE); + + if (pBIOSInfo->TVActive) + ViaTVPower(pScrn, FALSE); + + val |= 0x30; + hwp->writeCrtc(hwp, 0x36, val); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); + break; + } + return; +} + +#ifdef XF86DRI +void +VIAInitialize3DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i; + + /* + * FIXME: Reinitializing the 3D engine after VT switch seems to be the way + * to go to avoid hangs and rendering errors. But what happens with secondary? + * Test this for a while, but keep the old code in case... + */ + + if (!pVia->sharedData->b3DRegsInitialized) + { + + VIASETREG(0x43C, 0x00010000); + + for (i = 0; i <= 0x7D; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00020000); + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + + VIASETREG(0x43C, 0x01020000); + + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + VIASETREG(0x43C, 0xfe020000); + + for (i = 0; i <= 0x03; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00030000); + + for (i = 0; i <= 0xff; i++) + { + VIASETREG(0x440, 0); + } + VIASETREG(0x43C, 0x00100000); + VIASETREG(0x440, 0x00333004); + VIASETREG(0x440, 0x10000002); + VIASETREG(0x440, 0x60000000); + VIASETREG(0x440, 0x61000000); + VIASETREG(0x440, 0x62000000); + VIASETREG(0x440, 0x63000000); + VIASETREG(0x440, 0x64000000); + + VIASETREG(0x43C, 0x00fe0000); + + if (pVia->ChipRev >= 3 ) + VIASETREG(0x440,0x40008c0f); + else + VIASETREG(0x440,0x4000800f); + + VIASETREG(0x440,0x44000000); + VIASETREG(0x440,0x45080C04); + VIASETREG(0x440,0x46800408); + VIASETREG(0x440,0x50000000); + VIASETREG(0x440,0x51000000); + VIASETREG(0x440,0x52000000); + VIASETREG(0x440,0x53000000); + + pVia->sharedData->b3DRegsInitialized = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "3D Engine has been initialized.\n"); + } + + VIASETREG(0x43C,0x00fe0000); + VIASETREG(0x440,0x08000001); + VIASETREG(0x440,0x0A000183); + VIASETREG(0x440,0x0B00019F); + VIASETREG(0x440,0x0C00018B); + VIASETREG(0x440,0x0D00019B); + VIASETREG(0x440,0x0E000000); + VIASETREG(0x440,0x0F000000); + VIASETREG(0x440,0x10000000); + VIASETREG(0x440,0x11000000); + VIASETREG(0x440,0x20000000); +} +#endif diff --git a/unichrome/via_driver.h b/unichrome/via_driver.h new file mode 100644 index 000000000000..cac5be0226bd --- /dev/null +++ b/unichrome/via_driver.h @@ -0,0 +1,389 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_DRIVER_H_ +#define _VIA_DRIVER_H_ 1 + +#define HAVE_DEBUG + +#ifdef HAVE_DEBUG +#define DEBUG(x) x +#else +#define DEBUG(x) +#endif + +#include "vgaHW.h" +#include "xf86.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86Cursor.h" +#include "mipointer.h" +#include "micmap.h" +#include "fourcc.h" + +#define USE_FB +#ifdef USE_FB +#include "fb.h" +#else +#include "cfb.h" +#include "cfb16.h" +#include "cfb32.h" +#endif + +#include "xf86cmap.h" +#include "vbe.h" +#include "xaa.h" + +#include "via_regs.h" +#include "via_bios.h" +#include "via_priv.h" +#include "via_swov.h" + +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "sarea.h" +#include "dri.h" +#include "GL/glxint.h" +#include "via_dri.h" +#endif + +#define DRIVER_NAME "via" +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define PATCHLEVEL 0 +#define VIA_VERSION ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL) + +#define VIA_MAX_ACCEL_X (2047) +#define VIA_MAX_ACCEL_Y (2047) +#ifdef X_USE_LINEARFB +#define VIA_PIXMAP_CACHE_SIZE (4 * (VIA_MAX_ACCEL_X + 1) * (VIA_MAX_ACCEL_Y +1)) +#else +#define VIA_PIXMAP_CACHE_SIZE (256 * 1024) +#endif /* X_USE_LINEARFB */ +#define VIA_CURSOR_SIZE (4 * 1024) +#define VIA_VQ_SIZE (256 * 1024) +#define VIA_CBUFFERSIZE 512 + +typedef struct { + CARD8 SR08, SR0A, SR0F; + + /* extended Sequencer registers */ + CARD8 SR10, SR11, SR12, SR13,SR14,SR15,SR16; + CARD8 SR17, SR18, SR19, SR1A,SR1B,SR1C,SR1D,SR1E; + CARD8 SR1F, SR20, SR21, SR22,SR23,SR24,SR25,SR26; + CARD8 SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E; + CARD8 SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41; + CARD8 SR42, SR43, SR44, SR45,SR46,SR47; + + /* extended CRTC registers */ + CARD8 CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36; + CARD8 CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43; + CARD8 CR44, CR45, CR46, CR47, CR48, CR49, CR4A; + CARD8 CRTCRegs[68]; +/* CARD8 LCDRegs[0x40];*/ +} VIARegRec, *VIARegPtr; + +/* + * varables that need to be shared among different screens. + */ +typedef struct { + Bool b3DRegsInitialized; +} ViaSharedRec, *ViaSharedPtr; + +#ifdef XF86DRI + +#define VIA_XVMC_MAX_BUFFERS 2 +#define VIA_XVMC_MAX_CONTEXTS 4 +#define VIA_XVMC_MAX_SURFACES 20 + + +typedef struct { + VIAMem memory_ref; + unsigned long offsets[VIA_XVMC_MAX_BUFFERS]; +} ViaXvMCSurfacePriv; + +typedef struct { + drm_context_t drmCtx; +} ViaXvMCContextPriv; + +typedef struct { + XID contexts[VIA_XVMC_MAX_CONTEXTS]; + XID surfaces[VIA_XVMC_MAX_SURFACES]; + ViaXvMCSurfacePriv *sPrivs[VIA_XVMC_MAX_SURFACES]; + ViaXvMCContextPriv *cPrivs[VIA_XVMC_MAX_CONTEXTS]; + int nContexts,nSurfaces; + drm_handle_t mmioBase,fbBase,sAreaBase; + unsigned sAreaSize; + drmAddress sAreaAddr; + unsigned activePorts; +}ViaXvMC, *ViaXvMCPtr; + +#endif + +typedef struct _twodContext { + CARD32 mode; +} ViaTwodContext; + +typedef struct{ + unsigned curPos; + CARD32 buffer[VIA_CBUFFERSIZE]; + int status; +} ViaCBuffer; + +typedef struct{ + /* textMode */ + CARD8 *state, *pstate; /* SVGA state */ + int statePage, stateSize, stateMode; + + /* vbe version */ + int major, minor; +} ViaVbeModeInfo; + +typedef struct _VIA { + VIARegRec SavedReg; + xf86CursorInfoPtr CursorInfoRec; + int Bpp, Bpl; + unsigned PlaneMask; + + Bool FirstInit; + unsigned long videoRambytes; + int videoRamKbytes; + int FBFreeStart; + int FBFreeEnd; + int CursorStart; + int VQStart; + int VQEnd; + + /* These are physical addresses. */ + unsigned long FrameBufferBase; + unsigned long MmioBase; + + /* These are linear addresses. */ + unsigned char* MapBase; + unsigned char* VidMapBase; + unsigned char* MpegMapBase; + unsigned char* BltBase; + unsigned char* MapBaseDense; + unsigned char* FBBase; + CARD8 MemClk; + + /* Private memory pool management */ + int SWOVUsed[MEM_BLOCKS]; /* Free map for SWOV pool */ + unsigned long SWOVPool; /* Base of SWOV pool */ + unsigned long SWOVSize; /* Size of SWOV blocks */ + + /* Here are all the Options */ + Bool VQEnable; + Bool pci_burst; + Bool NoPCIRetry; + Bool hwcursor; + Bool NoAccel; + Bool shadowFB; + int rotate; + + CloseScreenProcPtr CloseScreen; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + int ChipId; + int ChipRev; + int EntityIndex; + + /* vbe */ + vbeInfoPtr pVbe; + ViaVbeModeInfo vbeMode; + + /* Support for shadowFB and rotation */ + unsigned char* ShadowPtr; + int ShadowPitch; + void (*PointerMoved)(int index, int x, int y); + + /* Support for XAA acceleration */ + XAAInfoRecPtr AccelInfoRec; + xRectangle Rect; + CARD32 SavedCmd; + CARD32 SavedFgColor; + CARD32 SavedBgColor; + CARD32 SavedPattern0; + CARD32 SavedPattern1; + CARD32 SavedPatternAddr; + int justSetup; + ViaTwodContext td; + ViaCBuffer cBuf; + + /* BIOS Info Ptr */ + VIABIOSInfoPtr pBIOSInfo; + struct ViaCardIdStruct* Id; + + /* Support for DGA */ + int numDGAModes; + DGAModePtr DGAModes; + Bool DGAactive; + int DGAViewportStatus; + int DGAOldDisplayWidth; + int DGAOldBitsPerPixel; + int DGAOldDepth; + + /* I2C & DDC */ + I2CBusPtr pI2CBus1; + I2CBusPtr pI2CBus2; + I2CBusPtr pI2CBus3; + xf86MonPtr DDC1; + xf86MonPtr DDC2; + + /* MHS */ + Bool IsSecondary; + Bool HasSecondary; + Bool SAMM; + +#ifdef XF86DRI + Bool directRenderingEnabled; + Bool XvMCEnabled; + DRIInfoPtr pDRIInfo; + int drmFD; + int numVisualConfigs; + __GLXvisualConfig* pVisualConfigs; + VIAConfigPrivPtr pVisualConfigsPriv; + unsigned long agpHandle; + unsigned long registerHandle; + unsigned long agpAddr; + drmAddress agpMappedAddr; + unsigned char *agpBase; + unsigned int agpSize; + Bool IsPCI; + Bool drixinerama; + ViaXvMC xvmc; +#endif + Bool DRIIrqEnable; + Bool agpEnable; + Bool dma2d; + + CARD8 ActiveDevice; /* Option */ + unsigned char *CursorImage; + CARD32 CursorFG; + CARD32 CursorBG; + CARD32 CursorMC; + + /* Video */ + swovRec swov; + CARD32 VideoStatus; + VIAHWDiff HWDiff; + unsigned long dwV1, dwV3; + unsigned long OverlaySupported; + unsigned long dwFrameNum; + + CARD32* VidRegBuffer; /* Temporary buffer for video overlay registers. */ + unsigned long VidRegCursor; /* Write cursor for VidRegBuffer. */ + + unsigned long old_dwUseExtendedFIFO; + + ViaSharedPtr sharedData; + +#ifdef HAVE_DEBUG + Bool DumpVGAROM; + Bool PrintVGARegs; + Bool PrintTVRegs; + Bool I2CScan; +#endif /* HAVE_DEBUG */ +} VIARec, *VIAPtr; + +#define VIAPTR(p) ((VIAPtr)((p)->driverPrivate)) + +typedef struct +{ + Bool IsDRIEnabled; + + Bool HasSecondary; + Bool BypassSecondary; + /*These two registers are used to make sure the CRTC2 is + retored before CRTC_EXT, otherwise it could lead to blank screen.*/ + Bool IsSecondaryRestored; + Bool RestorePrimary; + + ScrnInfoPtr pSecondaryScrn; + ScrnInfoPtr pPrimaryScrn; +} VIAEntRec, *VIAEntPtr; + +/* Prototypes. */ +#ifdef XF86DRI +void VIAInitialize3DEngine(ScrnInfoPtr pScrn); +#endif + +/* In via_cursor.c. */ +Bool VIAHWCursorInit(ScreenPtr pScreen); +void VIAShowCursor(ScrnInfoPtr); +void VIAHideCursor(ScrnInfoPtr); +void ViaCursorStore(ScrnInfoPtr pScrn); +void ViaCursorRestore(ScrnInfoPtr pScrn); + +/* In via_accel.c. */ +Bool VIAInitAccel(ScreenPtr); +void VIAInitialize2DEngine(ScrnInfoPtr); +void VIAAccelSync(ScrnInfoPtr); +void ViaVQDisable(ScrnInfoPtr pScrn); + +/* In via_shadow.c */ +void ViaShadowFBInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); + +/* In via_dga.c */ +Bool VIADGAInit(ScreenPtr); + +/*In via_video.c*/ +void viaInitVideo(ScreenPtr pScreen); +void viaExitVideo(ScrnInfoPtr pScrn); +void viaSaveVideo(ScrnInfoPtr pScrn); +void viaRestoreVideo(ScrnInfoPtr pScrn); +void viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness, int contrast, + Bool reset); +void VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y); + +/* In via_memory.c */ +void VIAFreeLinear(VIAMemPtr); +unsigned long VIAAllocLinear(VIAMemPtr, ScrnInfoPtr, unsigned long); +void VIAInitLinear(ScreenPtr pScreen); + +/* In via_xwmc.c */ + +#ifdef XF86DRI +/* Basic init and exit functions */ +void ViaInitXVMC(ScreenPtr pScreen); +void ViaCleanupXVMC(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr *XvAdaptors, int XvAdaptorCount); +int viaXvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt); + +/* Returns the size of the fake Xv Image used as XvMC command buffer to the X server*/ +unsigned long viaXvMCPutImageSize(ScrnInfoPtr pScrn); + + + +#endif + +/* via_i2c.c */ +void ViaI2CInit(ScrnInfoPtr pScrn); + +#endif /* _VIA_DRIVER_H_ */ diff --git a/unichrome/via_drm.h b/unichrome/via_drm.h new file mode 100644 index 000000000000..f7a5a1e4794f --- /dev/null +++ b/unichrome/via_drm.h @@ -0,0 +1,243 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_DRM_H_ +#define _VIA_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +#ifndef _VIA_DEFINES_ +#define _VIA_DEFINES_ + +#ifndef __KERNEL__ +#include "via_drmclient.h" +#endif + +#define VIA_NR_SAREA_CLIPRECTS 8 +#define VIA_NR_XVMC_PORTS 10 +#define VIA_NR_XVMC_LOCKS 5 +#define VIA_MAX_CACHELINE_SIZE 64 +#define XVMCLOCKPTR(saPriv,lockNo) \ + ((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \ + (VIA_MAX_CACHELINE_SIZE - 1)) & \ + ~(VIA_MAX_CACHELINE_SIZE - 1)) + \ + VIA_MAX_CACHELINE_SIZE*(lockNo))) + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define VIA_NR_TEX_REGIONS 64 +#define VIA_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ +#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ +#define VIA_UPLOAD_CTX 0x4 +#define VIA_UPLOAD_BUFFERS 0x8 +#define VIA_UPLOAD_TEX0 0x10 +#define VIA_UPLOAD_TEX1 0x20 +#define VIA_UPLOAD_CLIPRECTS 0x40 +#define VIA_UPLOAD_ALL 0xff + +/* VIA specific ioctls */ +#define DRM_VIA_ALLOCMEM 0x00 +#define DRM_VIA_FREEMEM 0x01 +#define DRM_VIA_AGP_INIT 0x02 +#define DRM_VIA_FB_INIT 0x03 +#define DRM_VIA_MAP_INIT 0x04 +#define DRM_VIA_DEC_FUTEX 0x05 +#define NOT_USED +#define DRM_VIA_DMA_INIT 0x07 +#define DRM_VIA_CMDBUFFER 0x08 +#define DRM_VIA_FLUSH 0x09 +#define DRM_VIA_PCICMD 0x0a +#define DRM_VIA_CMDBUF_SIZE 0x0b +#define NOT_USED +#define DRM_VIA_WAIT_IRQ 0x0d + +#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) +#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) +#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t) +#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t) +#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t) +#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t) +#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t) +#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t) +#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH) +#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t) +#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ + drm_via_cmdbuf_size_t) +#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +#define VIA_TEX_SETUP_SIZE 8 + +/* Flags for clear ioctl + */ +#define VIA_FRONT 0x1 +#define VIA_BACK 0x2 +#define VIA_DEPTH 0x4 +#define VIA_STENCIL 0x8 +#define VIDEO 0 +#define AGP 1 +typedef struct { + uint32_t offset; + uint32_t size; +} drm_via_agp_t; + +typedef struct { + uint32_t offset; + uint32_t size; +} drm_via_fb_t; + +typedef struct { + uint32_t context; + uint32_t type; + uint32_t size; + unsigned long index; + unsigned long offset; +} drm_via_mem_t; + +typedef struct _drm_via_init { + enum { + VIA_INIT_MAP = 0x01, + VIA_CLEANUP_MAP = 0x02 + } func; + + unsigned long sarea_priv_offset; + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long agpAddr; +} drm_via_init_t; + +typedef struct _drm_via_futex { + enum { + VIA_FUTEX_WAIT = 0x00, + VIA_FUTEX_WAKE = 0X01 + } func; + uint32_t ms; + uint32_t lock; + uint32_t val; +} drm_via_futex_t; + +typedef struct _drm_via_dma_init { + enum { + VIA_INIT_DMA = 0x01, + VIA_CLEANUP_DMA = 0x02, + VIA_DMA_INITIALIZED = 0x03 + } func; + + unsigned long offset; + unsigned long size; + unsigned long reg_pause_addr; +} drm_via_dma_init_t; + +typedef struct _drm_via_cmdbuffer { + char *buf; + unsigned long size; +} drm_via_cmdbuffer_t; + +/* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +typedef struct _drm_via_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char inUse; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} drm_via_tex_region_t; + +typedef struct _drm_via_sarea { + unsigned int dirty; + unsigned int nbox; + drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS]; + drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1]; + int texAge; /* last time texture was uploaded */ + int ctxOwner; /* last context to upload state */ + int vertexPrim; + + /* + * Below is for XvMC. + * We want the lock integers alone on, and aligned to, a cache line. + * Therefore this somewhat strange construct. + */ + + char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)]; + + unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS]; + unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS]; + unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */ + +} drm_via_sarea_t; + +typedef struct _drm_via_cmdbuf_size { + enum { + VIA_CMDBUF_SPACE = 0x01, + VIA_CMDBUF_LAG = 0x02 + } func; + int wait; + uint32_t size; +} drm_via_cmdbuf_size_t; + +typedef enum { + VIA_IRQ_ABSOLUTE = 0x0, + VIA_IRQ_RELATIVE = 0x1, + VIA_IRQ_SIGNAL = 0x10000000, + VIA_IRQ_FORCE_SEQUENCE = 0x20000000 +} via_irq_seq_type_t; + +#define VIA_IRQ_FLAGS_MASK 0xF0000000 + +struct drm_via_wait_irq_request{ + unsigned irq; + via_irq_seq_type_t type; + uint32_t sequence; + uint32_t signal; +}; + +typedef union drm_via_irqwait { + struct drm_via_wait_irq_request request; + struct drm_wait_vblank_reply reply; +} drm_via_irqwait_t; + +#ifdef __KERNEL__ + +int via_fb_init(DRM_IOCTL_ARGS); +int via_mem_alloc(DRM_IOCTL_ARGS); +int via_mem_free(DRM_IOCTL_ARGS); +int via_agp_init(DRM_IOCTL_ARGS); +int via_map_init(DRM_IOCTL_ARGS); +int via_decoder_futex(DRM_IOCTL_ARGS); +int via_dma_init(DRM_IOCTL_ARGS); +int via_cmdbuffer(DRM_IOCTL_ARGS); +int via_flush_ioctl(DRM_IOCTL_ARGS); +int via_pci_cmdbuffer(DRM_IOCTL_ARGS); +int via_cmdbuf_size(DRM_IOCTL_ARGS); +int via_wait_irq(DRM_IOCTL_ARGS); + +#endif +#endif /* _VIA_DRM_H_ */ diff --git a/unichrome/via_drmclient.h b/unichrome/via_drmclient.h new file mode 100644 index 000000000000..6538af4d1a5e --- /dev/null +++ b/unichrome/via_drmclient.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2005 The Unichrome Project, All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_DRMCLIENT_H +#define _VIA_DRMCLIENT_H + +#include "drm.h" +#include "xf86drm.h" + +typedef CARD32 uint32_t; + +#ifdef X_NEED_DRMLOCK +#define drm_hw_lock_t drmLock +#endif + +#define UNICHROME_LOCK(fd, lockNo, saPriv, context, lastcontext, ret) \ + do { \ + volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo)); \ + unsigned lockVal; \ + DRM_CAS_RESULT(__ret); \ + \ + ret = 0; \ + lockVal = lockPtr->lock & ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_CAS(lockPtr, lockVal, (context) | DRM_LOCK_HELD, __ret); \ + if (__ret) { \ + drm_via_futex_t fx; \ + \ + lockVal = lockPtr->lock; \ + if (! (lockVal & DRM_LOCK_HELD)) continue; \ + if ((lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT) ) \ + == (context)) { \ + lastcontext = lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + break; \ + } \ + fx.val = lockVal | DRM_LOCK_CONT; \ + DRM_CAS( lockPtr, lockVal, fx.val, __ret); \ + lockVal = lockPtr->lock; \ + if (__ret) continue; \ + fx.func = VIA_FUTEX_WAIT; \ + fx.lock = (lockNo); \ + fx.ms = 10; \ + ret = drmCommandWrite((fd), DRM_VIA_DEC_FUTEX, \ + &fx,sizeof(fx)); \ + lastcontext = lockVal; \ + if (ret) break; \ + continue; \ + } else { \ + lastcontext = lockVal; \ + break; \ + } \ + } while (1) \ + +#define UNICHROME_UNLOCK(fd, lockNo, saPriv, context) \ + do { \ + volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo)); \ + \ + if ((lockPtr->lock & ~DRM_LOCK_CONT) == \ + ((context) | DRM_LOCK_HELD)) { \ + DRM_CAS_RESULT(__ret); \ + DRM_CAS(lockPtr,(context) | DRM_LOCK_HELD, context, __ret); \ + if (__ret) { \ + drm_via_futex_t fx; \ + fx.func = VIA_FUTEX_WAKE; \ + fx.lock = lockNo; \ + DRM_CAS(lockPtr, (context) | DRM_LOCK_HELD | \ + DRM_LOCK_CONT, \ + context, __ret); \ + drmCommandWrite((fd), DRM_VIA_DEC_FUTEX, &fx, \ + sizeof(fx)); \ + } \ + } \ + } while (0) \ + +#define UNICHROME_LOCK_DECODER1 0 +#define UNICHROME_LOCK_DECODER2 1 +#define UNICHROME_LOCK_HQV 4 + +#endif diff --git a/unichrome/via_i2c.c b/unichrome/via_i2c.c new file mode 100644 index 000000000000..529dfeccb6bb --- /dev/null +++ b/unichrome/via_i2c.c @@ -0,0 +1,416 @@ +/* + * Copyright 2004 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Implements three i2c busses through registers SR26, SR2c and SR31 + */ +#include "via_driver.h" +#include "via_vgahw.h" + +#define SDA_READ 0x04 +#define SCL_READ 0x08 +#define SDA_WRITE 0x10 +#define SCL_WRITE 0x20 + +/* + * + * CRT I2C + * + */ +/* + * + */ +static void +ViaI2C1PutBits(I2CBusPtr Bus, int clock, int data) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]); + CARD8 value = 0x01; /* Enable */ + + if (clock) + value |= SCL_WRITE; + + if (data) + value |= SDA_WRITE; + + ViaSeqMask(hwp, 0x26, value, 0x01 | SCL_WRITE | SDA_WRITE); +} + +/* + * + */ +static void +ViaI2C1GetBits(I2CBusPtr Bus, int *clock, int *data) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]); + CARD8 value = hwp->readSeq(hwp, 0x26); + + *clock = (value & SCL_READ) != 0; + *data = (value & SDA_READ) != 0; +} + +/* + * + */ +static I2CBusPtr +ViaI2CBus1Init(int scrnIndex) +{ + I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2CBus1Init\n")); + + if (!pI2CBus) + return NULL; + + pI2CBus->BusName = "I2C bus 1"; + pI2CBus->scrnIndex = scrnIndex; + pI2CBus->I2CPutBits = ViaI2C1PutBits; + pI2CBus->I2CGetBits = ViaI2C1GetBits; + + if (!xf86I2CBusInit(pI2CBus)) { + xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); + return NULL; + } + + return pI2CBus; +} + +/* + * + * First data bus I2C: tends to have TV-encoders + * + */ +/* + * + */ +static void +ViaI2C2PutBits(I2CBusPtr Bus, int clock, int data) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]); + CARD8 value = 0x01; /* Enable */ + + if (clock) + value |= SCL_WRITE; + + if (data) + value |= SDA_WRITE; + + ViaSeqMask(hwp, 0x31, value, 0x01 | SCL_WRITE | SDA_WRITE); +} + +/* + * + */ +static void +ViaI2C2GetBits(I2CBusPtr Bus, int *clock, int *data) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]); + CARD8 value = hwp->readSeq(hwp, 0x31); + + *clock = (value & SCL_READ) != 0; + *data = (value & SDA_READ) != 0; +} + +/* + * + */ +static I2CBusPtr +ViaI2CBus2Init(int scrnIndex) +{ + I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2cBus2Init\n")); + + if (!pI2CBus) + return NULL; + + pI2CBus->BusName = "I2C bus 2"; + pI2CBus->scrnIndex = scrnIndex; + pI2CBus->I2CPutBits = ViaI2C2PutBits; + pI2CBus->I2CGetBits = ViaI2C2GetBits; + + if (!xf86I2CBusInit(pI2CBus)) { + xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); + return NULL; + } + + return pI2CBus; +} + +/* + * A third I2C bus implemented by a few IO pins. + * Requires higher level functions to be used properly. + * Former via_gpioi2c. + * + */ +/* + * + */ +static Bool +ViaI2C3Start(I2CBusPtr b, int timeout) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + + ViaSeqMask(hwp, 0x2C, 0xF0, 0xF0); + b->I2CUDelay(b, b->RiseFallTime); + + ViaSeqMask(hwp, 0x2C, 0x00, 0x10); + b->I2CUDelay(b, b->HoldTime); + ViaSeqMask(hwp, 0x2C, 0x00, 0x20); + b->I2CUDelay(b, b->HoldTime); + + return TRUE; +} + +/* + * + */ +static Bool +ViaI2C3Address(I2CDevPtr d, I2CSlaveAddr addr) +{ + I2CBusPtr b = d->pI2CBus; + +#ifdef X_NEED_I2CSTART + if (b->I2CStart(d->pI2CBus, d->StartTimeout)) { +#else + if (ViaI2C3Start(d->pI2CBus, d->StartTimeout)) { +#endif + if (b->I2CPutByte(d, addr & 0xFF)) { + if ((addr & 0xF8) != 0xF0 && + (addr & 0xFE) != 0x00) + return TRUE; + + if (b->I2CPutByte(d, (addr >> 8) & 0xFF)) + return TRUE; + } + + b->I2CStop(d); + } + + return FALSE; +} + +/* + * + */ +static void +ViaI2C3Stop(I2CDevPtr d) +{ + I2CBusPtr b = d->pI2CBus; + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + + ViaSeqMask(hwp, 0x2C, 0xC0, 0xF0); + b->I2CUDelay(b, b->RiseFallTime); + + ViaSeqMask(hwp, 0x2C, 0x20, 0x20); + b->I2CUDelay(b, b->HoldTime); + + ViaSeqMask(hwp, 0x2C, 0x10, 0x10); + b->I2CUDelay(b, b->HoldTime); + + ViaSeqMask(hwp, 0x2C, 0x00, 0x20); + b->I2CUDelay(b, b->HoldTime); +} + +/* + * + */ +static void +ViaI2C3PutBit(I2CBusPtr b, Bool sda, int timeout) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + + if (sda) + ViaSeqMask(hwp, 0x2C, 0x50, 0x50); + else + ViaSeqMask(hwp, 0x2C, 0x40, 0x50); + b->I2CUDelay(b, b->RiseFallTime/5); + + ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); + b->I2CUDelay(b, b->HoldTime); + b->I2CUDelay(b, timeout); + + ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); + b->I2CUDelay(b, b->RiseFallTime/5); +} + +/* + * + */ +static Bool +ViaI2C3PutByte(I2CDevPtr d, I2CByte data) +{ + I2CBusPtr b = d->pI2CBus; + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + Bool ret; + int i; + + for (i = 7; i >= 0; i--) + ViaI2C3PutBit(b, (data >> i) & 0x01, b->BitTimeout); + + /* raise first to avoid false positives */ + ViaSeqMask(hwp, 0x2C, 0x50, 0x50); + ViaSeqMask(hwp, 0x2C, 0x00, 0x40); + b->I2CUDelay(b, b->RiseFallTime); + ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); + + if (hwp->readSeq(hwp, 0x2C) & 0x04) + ret = FALSE; + else + ret = TRUE; + + ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); + b->I2CUDelay(b, b->RiseFallTime); + + return ret; +} + +/* + * + */ +static Bool +ViaI2C3GetBit(I2CBusPtr b, int timeout) +{ + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + Bool ret; + + ViaSeqMask(hwp, 0x2C, 0x00, 0x40); + b->I2CUDelay(b, b->RiseFallTime/5); + + ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); + + if (hwp->readSeq(hwp, 0x2C) & 0x04) + ret = TRUE; + else + ret = FALSE; + + ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); + b->I2CUDelay(b, b->RiseFallTime/5); + + return ret; +} + +/* + * + */ +static Bool +ViaI2C3GetByte(I2CDevPtr d, I2CByte *data, Bool last) +{ + I2CBusPtr b = d->pI2CBus; + vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]); + int i; + + *data = 0x00; + + for (i = 7; i >= 0; i--) + if (ViaI2C3GetBit(b, b->BitTimeout)) + *data |= 0x01 << i; + + if (last) /* send NACK */ + ViaSeqMask(hwp, 0x2C, 0x50, 0x50); + else /* send ACK */ + ViaSeqMask(hwp, 0x2C, 0x40, 0x50); + + ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); + b->I2CUDelay(b, b->HoldTime); + + ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); + + return TRUE; +} + +/* + * + */ +static I2CBusPtr +ViaI2CBus3Init(int scrnIndex) +{ + I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2CBus3Init\n")); + + if (!pI2CBus) + return NULL; + + pI2CBus->BusName = "I2C bus 3"; + pI2CBus->scrnIndex = scrnIndex; + pI2CBus->I2CAddress = ViaI2C3Address; +#ifdef X_NEED_I2CSTART + pI2CBus->I2CStart = ViaI2C3Start; +#endif + pI2CBus->I2CStop = ViaI2C3Stop; + pI2CBus->I2CPutByte = ViaI2C3PutByte; + pI2CBus->I2CGetByte = ViaI2C3GetByte; + + if (!xf86I2CBusInit(pI2CBus)) { + xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); + return NULL; + } + + return pI2CBus; +} + +#ifdef HAVE_DEBUG +/* + * + */ +static void +ViaI2CScan(I2CBusPtr Bus) +{ + CARD8 i; + + xf86DrvMsg(Bus->scrnIndex, X_INFO, "ViaI2CScan: Scanning %s\n", + Bus->BusName); + + for (i = 0x10; i < 0xF0; i += 2) + if (xf86I2CProbeAddress(Bus, i)) + xf86DrvMsg(Bus->scrnIndex, X_PROBED, "Found slave on %s " + "- 0x%02X\n", Bus->BusName, i); +} +#endif + +/* + * + * + * + */ +void +ViaI2CInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaI2CInit\n")); + + pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex); + pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex); + pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex); + +#ifdef HAVE_DEBUG + if (pVia->I2CScan) { + if (pVia->pI2CBus2) + ViaI2CScan(pVia->pI2CBus2); + if (pVia->pI2CBus3) + ViaI2CScan(pVia->pI2CBus3); + } +#endif +} diff --git a/unichrome/via_id.c b/unichrome/via_id.c new file mode 100644 index 000000000000..229186b2876f --- /dev/null +++ b/unichrome/via_id.c @@ -0,0 +1,187 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "via_driver.h" +#include "via_id.h" + +/* + * Since we are going to hold a rather big structure with + * basic card-id information, we might as well seperate this + * into its own file. + * + */ + +/* + * Known missing devices: + * cle266: + * Biostar M6VLQ Grand + * Biostar M6VLQ Pro + * PcChips M789CLU (with C3 onboard) + * PcChips M791G + * Soltek SL-B6A-F800 (C3 800Mhz onboard) + * Soltek SL-B6A-F1000 (Qbic IQ3601 | C3 1Ghz onboard) + * + loads of semi-embedded devices. + * + * km400: + * Abit VA-20: ? km400 vs km400a ? + * ECS KM400-M + * ECS KM400-M2 + * ECS KM400A-M2 + * PcChips M851G + * PcChips M851AG + * Soltek SL-B7C-FGR (Qbic EQ3704 | km400a) + * Soyo SY-K7VMP + * Soyo SY-K7VMP2 + * + * k8m800: + * Abit KV8-MAX3 + * Abit KV8 + * Biostar Ideq 210V (km400a) + * Biostar M7VIZ + * Chaintech MK8M800 + * ECS k8m800-m2 + * Epox EP-8KMM5I (km400a) + * MSI K8M Neo-V + * PcChips M861G + * Soltek SL-B9C-FGR (Qbic EQ3802-300P) + * Soltek SL-K8M800I-R + * + * pm800: + * Asrock P4VM8 + * Biostar Ideq 210M + * Biostar P4VMA-M + * Biostar P4M80-M7 (is this even a unichrome?) + * Chaintech MPM800 + * Gigabyte 8VM800M + * PcChips M955G + * PcChips M957G + * Soltek SL-PM800I + * Soltek SL-PM800I-R + * Soltek SL-PM800 + * Soyo SY-P4VM800 + * + */ +/* + * There's no reason for this to be known outside of via_id.o + * Only a pointer to an single entry will ever be used outside. + * + */ +static struct ViaCardIdStruct ViaCardId[] = { + /* CLE266 */ + {"ECS G320", VIA_CLE266, 0x1019, 0xB320, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"VIA EPIA M/MII/...", VIA_CLE266, 0x1106, 0x3122, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + /* KM400 */ + {"Acer Aspire 135x", VIA_KM400, 0x1025, 0x0033, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Asustek A7V8X-MX", VIA_KM400, 0x1043, 0x80ED, VIA_DEVICE_CRT}, + {"Asustek A7V8X-MX SE/A7V400-MX", VIA_KM400, 0x1043, 0x8118, VIA_DEVICE_CRT}, + {"Mitac 8375X", VIA_KM400, 0x1071, 0x8375, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka UMAX 585T */ + {"Soltek SL-75MIV2", VIA_KM400, 0x1106, 0x0000, VIA_DEVICE_CRT}, /* VIA/0x0000 */ + {"Biostar iDEQ 200V/Chaintech 7VIF4", VIA_KM400, 0x1106, 0x7205, VIA_DEVICE_CRT}, /* VIA/KM400 -- 2 distinct devices */ + {"Shuttle FX43", VIA_KM400, 0x1297, 0xF643, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Giga-byte 7VM400(A)M", VIA_KM400, 0x1458, 0xD000, VIA_DEVICE_CRT}, /* 7VM400M, GA-7VM400AM */ + {"MSI KM4(A)M-V", VIA_KM400, 0x1462, 0x7061, VIA_DEVICE_CRT}, /* aka "DFI KM400-MLV" */ + {"MSI KM4(A)M-L", VIA_KM400, 0x1462, 0x7348, VIA_DEVICE_CRT}, + {"Abit VA-10 (1)", VIA_KM400, 0x147B, 0x140B, VIA_DEVICE_CRT}, + {"Abit VA-10 (2)", VIA_KM400, 0x147B, 0x140C, VIA_DEVICE_CRT}, /* VA-10/VA-20 id difference is not confirmed */ + {"Averatec 322x", VIA_KM400, 0x14FF, 0x030D, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Uniwill 755CI", VIA_KM400, 0x1584, 0x800A, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "Gericom hummer advance", "Maxdata M-Book 1200X" */ + {"Epox EP-8KMM3I", VIA_KM400, 0x1695, 0x9023, VIA_DEVICE_CRT}, + {"ASRock Inc. K7VM2/3/4", VIA_KM400, 0x1849, 0x7205, VIA_DEVICE_CRT}, + {"Soyo K7VME", VIA_KM400, 0xA723, 0x10FD, VIA_DEVICE_CRT}, + /* K8M800 */ + {"Acer Aspire 136x", VIA_K8M800, 0x1025, 0x006E, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Mitac 8399", VIA_K8M800, 0x1071, 0x8399, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "pogolinux konabook 3100" */ + {"DFI K8M800-MLVF", VIA_K8M800, 0x1106, 0x3108, VIA_DEVICE_CRT}, /* VIA/K8M800 -- ??? PciInfo Alignment issue ??? */ + {"Shuttle FX83", VIA_K8M800, 0x1297, 0xF683, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Sharp Actius AL27", VIA_K8M800, 0x13BD, 0x1044, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Giga-byte GA-K8VM800M", VIA_K8M800, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI K8M Neo-V", VIA_K8M800, 0x1462, 0x0320, VIA_DEVICE_CRT}, + {"MSI K8MM-ILSR", VIA_K8M800, 0x1462, 0x7410, VIA_DEVICE_CRT}, + {"Abit KV-80", VIA_K8M800, 0x147B, 0x1419, VIA_DEVICE_CRT}, + {"Averatec 54xx", VIA_K8M800, 0x1509, 0x3930, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar K8VGA-M", VIA_K8M800, 0x1565, 0x1203, VIA_DEVICE_CRT}, + /* PM800 */ + {"ECS PM800-M2", VIA_PM800, 0x1106, 0x3118, VIA_DEVICE_CRT}, /* VIA/PM800 */ + {"Biostar P4VMA-M", VIA_PM800, 0x1565, 0x1202, VIA_DEVICE_CRT}, + {"Fujitsu/Siemens Amilo Pro V2010", VIA_PM800, 0x1734, 0x1078, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + /* keep this */ + {NULL, VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE} +}; + +/* + * Fancy little routine stolen from fb + * We don't do anything but warn really. + */ +void +ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + /* Crtc 0x4F is only defined in CLE266Cx */ + CARD8 tmp = hwp->readCrtc(hwp, 0x4F); + + hwp->writeCrtc(hwp, 0x4F, 0x55); + + if (hwp->readCrtc(hwp, 0x4F) == 0x55) { + if (CLE266_REV_IS_AX(pVia->ChipRev)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems" + " to be Cx, yet %d was detected previously.\n", pVia->ChipRev); + } else { + if (CLE266_REV_IS_CX(pVia->ChipRev)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems" + " to be Ax, yet %d was detected previously.\n", pVia->ChipRev); + } + hwp->writeCrtc(hwp, 0x4F, tmp); +} + +/* + * + */ +void +ViaCheckCardId(ScrnInfoPtr pScrn) +{ + struct ViaCardIdStruct *Id; + VIAPtr pVia = VIAPTR(pScrn); + + if ((pVia->PciInfo->subsysVendor == pVia->PciInfo->vendor) && + (pVia->PciInfo->subsysCard == pVia->PciInfo->chipType)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Manufacturer plainly copied main PCI" + " ids to Subsystem/Card ids.\n"); + + for (Id = ViaCardId; Id->String; Id++) { + if ((Id->Chip == pVia->Chipset) && + (Id->Vendor == pVia->PciInfo->subsysVendor) && + (Id->Device == pVia->PciInfo->subsysCard)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %s.\n", Id->String); + pVia->Id = Id; + return; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unknown Card-Ids (%4X|%4X), report this to unichrome-devel@lists.sf.net ASAP\n" + , pVia->PciInfo->subsysVendor, pVia->PciInfo->subsysCard); + pVia->Id = NULL; +} + diff --git a/unichrome/via_id.h b/unichrome/via_id.h new file mode 100644 index 000000000000..65ee15fe4bae --- /dev/null +++ b/unichrome/via_id.h @@ -0,0 +1,98 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_ID_H_ +#define _VIA_ID_H_ 1 + +/* + * K8M800 and PM800/PM880/CN400 are currently untested + * and support is disabled. + */ + +#define HAVE_K8M800 +#define HAVE_PM800 + + +/* Chip tags. These are used to group the adapters into + * related families. + */ +enum VIACHIPTAGS { + VIA_UNKNOWN = 0, + VIA_CLE266, + VIA_KM400, + VIA_K8M800, + VIA_PM800, + VIA_LAST +}; + + +#define PCI_VIA_VENDOR_ID 0x1106 + +/* + * I have disabled CLE3022. This way anyone using this device + * will have to read this comment or at least complain + * someplace. There is also the possibility that it just does + * not exist in the wild. + * + * Contact unichrome-devel@lists.sf.net asap if you can + * provide any further information. + * + */ +/* #define PCI_CHIP_CLE3022 0x3022 */ /* CLE266??? */ +#define PCI_CHIP_VT3204 0x3108 /* K8M800 */ +#define PCI_CHIP_VT3259 0x3118 /* PM800/PM880/CN400 */ +#define PCI_CHIP_CLE3122 0x3122 /* CLE266 */ +#define PCI_CHIP_VT3205 0x7205 /* KM400 */ + +/* + * There is also quite some conflicting information on the + * 2 major revisions of the CLE266, oft labelled as Ax and Cx + * It seems to center around + * ChipRev > 15 == Cx + * and + * ChipRev < 15 == Ax + * There is only one case in original xfree86 code where 15 is + * handled; in via_bandwidth.c: + * if (pBIOSInfo->ChipRev > 14) { // For 3123Cx + * While setting the primary fifo, the secondary is > 15 again. + * + * So does this rule out the existence of CLE266B? + * + * It seems to be 0x10, anything from that and up is Cx, anything + * below is Ax + */ +#define CLE266_REV_IS_CX(x) ((x) >= 0x10) +#define CLE266_REV_IS_AX(x) ((x) < 0x10) + +struct ViaCardIdStruct { + char* String; /* Full identification string. */ + CARD8 Chip; /* Which unichrome device? */ + CARD16 Vendor; /* PCI Card/Subsystem vendor id */ + CARD16 Device; /* PCI Card/Subsystem device id */ + CARD8 Outputs; /* ORed list of VIA_DEVICE_CRT, VIA_DEVICE_LCD, VIA_DEVICE_TV */ +}; + +void ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn); +void ViaCheckCardId(ScrnInfoPtr pScrn); + +#endif /* _VIA_ID_H_ */ diff --git a/unichrome/via_memcpy.c b/unichrome/via_memcpy.c new file mode 100644 index 000000000000..c74621f5e07c --- /dev/null +++ b/unichrome/via_memcpy.c @@ -0,0 +1,691 @@ +/* + * Copyright (C) 2004 Thomas Hellstrom, All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "via_driver.h" +#include "via_memcpy.h" +#include "compiler.h" + + +#define BSIZ 2048 /* Size of /proc/cpuinfo buffer */ +#define BSIZW 720 /* Typical Copy Width (YUV420) Copy. */ +#define BSIZA 736 /* Multiple of 32 bytes */ +#define BSIZH 576 /* Typical Copy Hight */ + +#define SSE_PREFETCH " prefetchnta " +#define FENCE __asm__ __volatile__ ("sfence":::"memory"); +#define FENCEMMS __asm__ __volatile__ ("\t" \ + "sfence\n\t" \ + "emms\n\t" \ + :::"memory"); +#define FEMMS __asm__ __volatile__("femms":::"memory"); +#define EMMS __asm__ __volatile__("emms":::"memory"); + +#define NOW_PREFETCH " prefetch " + + +#define PREFETCH1(arch_prefetch,from) \ + __asm__ __volatile__ ( \ + "1: " arch_prefetch "(%0)\n" \ + arch_prefetch "32(%0)\n" \ + arch_prefetch "64(%0)\n" \ + arch_prefetch "96(%0)\n" \ + arch_prefetch "128(%0)\n" \ + arch_prefetch "160(%0)\n" \ + arch_prefetch "192(%0)\n" \ + arch_prefetch "256(%0)\n" \ + arch_prefetch "288(%0)\n" \ + "2:\n" \ + : : "r" (from) ); + +#define PREFETCH2(arch_prefetch,from) \ + __asm__ __volatile__ ( \ + arch_prefetch "320(%0)\n" \ + : : "r" (from) ); +#define PREFETCH3(arch_prefetch,from) \ + __asm__ __volatile__ ( \ + arch_prefetch "288(%0)\n" \ + : : "r" (from) ); + + + +#define small_memcpy(to,from,n) \ + { \ + __asm__ __volatile__( \ + "movl %2,%%ecx\n\t" \ + "sarl $2,%%ecx\n\t" \ + "rep ; movsl\n\t" \ + "testb $2,%b2\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b2\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + :"=&D" (to), "=&S" (from) \ + :"q" (n),"0" ((long) to),"1" ((long) from) \ + : "%ecx","memory"); \ + } + + +#define SSE_CPY(prefetch,from,to,dummy,lcnt) \ + if ((unsigned long) from & 15) { \ + __asm__ __volatile__ ( \ + "1:\n" \ + prefetch "320(%1)\n" \ + " movups (%1), %%xmm0\n" \ + " movups 16(%1), %%xmm1\n" \ + " movntps %%xmm0, (%0)\n" \ + " movntps %%xmm1, 16(%0)\n" \ + prefetch "352(%1)\n" \ + " movups 32(%1), %%xmm2\n" \ + " movups 48(%1), %%xmm3\n" \ + " movntps %%xmm2, 32(%0)\n" \ + " movntps %%xmm3, 48(%0)\n" \ + " addl $64,%0\n" \ + " addl $64,%1\n" \ + " decl %2\n" \ + " jne 1b\n" \ + :"=&D"(to), "=&S"(from), "=&r"(dummy) \ + :"0" (to), "1" (from), "2" (lcnt): "memory"); \ + } else { \ + __asm__ __volatile__ ( \ + "2:\n" \ + prefetch "320(%1)\n" \ + " movaps (%1), %%xmm0\n" \ + " movaps 16(%1), %%xmm1\n" \ + " movntps %%xmm0, (%0)\n" \ + " movntps %%xmm1, 16(%0)\n" \ + prefetch "352(%1)\n" \ + " movaps 32(%1), %%xmm2\n" \ + " movaps 48(%1), %%xmm3\n" \ + " movntps %%xmm2, 32(%0)\n" \ + " movntps %%xmm3, 48(%0)\n" \ + " addl $64,%0\n" \ + " addl $64,%1\n" \ + " decl %2\n" \ + " jne 2b\n" \ + :"=&D"(to), "=&S"(from), "=&r"(dummy) \ + :"0" (to), "1" (from), "2" (lcnt): "memory"); \ + } + +#define MMX_CPY(prefetch,from,to,dummy,lcnt) \ + __asm__ __volatile__ ( \ + "1:\n" \ + prefetch "320(%1)\n" \ + "2: movq (%1), %%mm0\n" \ + " movq 8(%1), %%mm1\n" \ + " movq 16(%1), %%mm2\n" \ + " movq 24(%1), %%mm3\n" \ + " movq %%mm0, (%0)\n" \ + " movq %%mm1, 8(%0)\n" \ + " movq %%mm2, 16(%0)\n" \ + " movq %%mm3, 24(%0)\n" \ + prefetch "352(%1)\n" \ + " movq 32(%1), %%mm0\n" \ + " movq 40(%1), %%mm1\n" \ + " movq 48(%1), %%mm2\n" \ + " movq 56(%1), %%mm3\n" \ + " movq %%mm0, 32(%0)\n" \ + " movq %%mm1, 40(%0)\n" \ + " movq %%mm2, 48(%0)\n" \ + " movq %%mm3, 56(%0)\n" \ + " addl $64,%0\n" \ + " addl $64,%1\n" \ + " decl %2\n" \ + " jne 1b\n" \ + :"=&D"(to), "=&S"(from), "=&r"(dummy) \ + :"0" (to), "1" (from), "2" (lcnt) : "memory"); + +#define MMXEXT_CPY(prefetch,from,to,dummy,lcnt) \ + __asm__ __volatile__ ( \ + ".p2align 4,,7\n" \ + "1:\n" \ + prefetch "320(%1)\n" \ + " movq (%1), %%mm0\n" \ + " movq 8(%1), %%mm1\n" \ + " movq 16(%1), %%mm2\n" \ + " movq 24(%1), %%mm3\n" \ + " movntq %%mm0, (%0)\n" \ + " movntq %%mm1, 8(%0)\n" \ + " movntq %%mm2, 16(%0)\n" \ + " movntq %%mm3, 24(%0)\n" \ + prefetch "352(%1)\n" \ + " movq 32(%1), %%mm0\n" \ + " movq 40(%1), %%mm1\n" \ + " movq 48(%1), %%mm2\n" \ + " movq 56(%1), %%mm3\n" \ + " movntq %%mm0, 32(%0)\n" \ + " movntq %%mm1, 40(%0)\n" \ + " movntq %%mm2, 48(%0)\n" \ + " movntq %%mm3, 56(%0)\n" \ + " addl $64,%0\n" \ + " addl $64,%1\n" \ + " decl %2\n" \ + " jne 1b\n" \ + :"=&D"(to), "=&S"(from), "=&r"(dummy) \ + :"0" (to), "1" (from), "2" (lcnt) : "memory"); + + +#define PREFETCH_FUNC(prefix,itype,ptype,begin,fence) \ + \ + static void prefix##_YUV42X(unsigned char *to, \ + const unsigned char *from, \ + int dstPitch, \ + int w, \ + int h, \ + int yuv422) \ + \ + { \ + int \ + dadd,rest,count,hc,lcnt; \ + register int dummy; \ + PREFETCH1(ptype##_PREFETCH,from); \ + begin; \ + count = 2; \ + \ + /* \ + * If destination pitch and width ar equal, do it all in one go. \ + */ \ + \ + if ( yuv422 ) { \ + w <<= 1; \ + if (w == dstPitch) { \ + w *= h; \ + h = 1; \ + dstPitch = w; \ + count = 0; \ + } else { \ + h -= 1; \ + count = 1; \ + } \ + } else if (w == dstPitch) { \ + w = h*(w + (w >> 1)); \ + count = 0; \ + h = 1; \ + dstPitch = w; \ + } \ + \ + lcnt = w >> 6; \ + rest = w & 63; \ + while(count--) { \ + hc = h; \ + lcnt = w >> 6; \ + rest = w & 63; \ + dadd = dstPitch - w; \ + while(hc--) { \ + if (lcnt) { \ + itype##_CPY(ptype##_PREFETCH,from,to,dummy, \ + lcnt); \ + } \ + if (rest) { \ + PREFETCH2(ptype##_PREFETCH,from); \ + small_memcpy(to, from, rest); \ + PREFETCH3(ptype##_PREFETCH,from); \ + } \ + to += dadd; \ + } \ + w >>= 1; \ + dstPitch >>= 1; \ + h -= 1; \ + } \ + if (lcnt > 5) { \ + lcnt -= 5; \ + itype##_CPY(ptype##_PREFETCH,from,to,dummy,lcnt); \ + lcnt = 5; \ + } \ + if (lcnt) { \ + itype##_CPY("#",from,to,dummy,lcnt); \ + } \ + if (rest) small_memcpy(to, from, rest); \ + fence; \ + } + +#define NOPREFETCH_FUNC(prefix,itype,begin,fence) \ + static void prefix##_YUV42X(unsigned char *to, \ + const unsigned char *from, \ + int dstPitch, \ + int w, \ + int h, \ + int yuv422) \ + \ + { \ + int \ + dadd,rest,count,hc,lcnt; \ + register int dummy; \ + begin; \ + count = 2; \ + \ + /* \ + * If destination pitch and width ar equal, do it all in one go. \ + */ \ + \ + if ( yuv422 ) { \ + w <<= 1; \ + count = 1; \ + if (w == dstPitch) { \ + w *= h; \ + h = 1; \ + dstPitch = w; \ + } \ + } else if (w == dstPitch) { \ + w = h*(w + (w >> 1)); \ + count = 1; \ + h = 1; \ + dstPitch = w; \ + } \ + \ + lcnt = w >> 6; \ + rest = w & 63; \ + while(count--) { \ + hc = h; \ + dadd = dstPitch - w; \ + lcnt = w >> 6; \ + rest = w & 63; \ + while(hc--) { \ + if (lcnt) { \ + itype##_CPY("#",from,to,dummy,lcnt); \ + } \ + if (rest) small_memcpy(to, from, rest); \ + to += dadd; \ + } \ + w >>= 1; \ + dstPitch >>= 1; \ + } \ + fence; \ + } \ + +#if !defined(__i386__) || (defined(linux) && defined(__i386__)) + +static void libc_YUV42X(unsigned char *dst, + const unsigned char *src, + int dstPitch, + int w, + int h, int yuv422) { + if ( yuv422 ) w <<= 1; + if (dstPitch == w) { + int size = h*((yuv422) ? w : (w + (w >> 1))); + xf86memcpy(dst, src, size); + return; + } else { + int count; + + /* copy Y component to video memory */ + + count = h; + while(count--) { + xf86memcpy(dst, src, w); + src += w; + dst += dstPitch; + } + + /* UV component is 1/2 of Y */ + + if (! yuv422 ) { + + w >>= 1; + dstPitch >>= 1; + + /* copy V(Cr),U(Cb) components to video memory */ + + count = h; + while(count--) { + xf86memcpy(dst, src, w); + src += w; + dst += dstPitch; + } + } + } +} +#endif + +#ifdef __i386__ + + + +/* linux kernel __memcpy */ +static __inline void * __memcpy(void * to, const void * from, size_t n) +{ + int d1,d2,d3; + + __asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d1), "=&D" (d2), "=&S" (d3) + :"0" (n >> 2), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); + + return (to); +} + + +static void kernel_YUV42X(unsigned char *dst, + const unsigned char *src, + int dstPitch, + int w, + int h, int yuv422) { + + if ( yuv422 ) w <<= 1; + if (dstPitch == w) { + int size = h*((yuv422) ? w : (w + (w >> 1))); + __memcpy(dst, src, size); + return; + } else { + int count; + + /* copy Y component to video memory */ + + count = h; + while(count--) { + __memcpy(dst, src, w); + src += w; + dst += dstPitch; + } + + /* UV component is 1/2 of Y */ + + if (! yuv422 ) { + + w >>= 1; + dstPitch >>= 1; + + /* copy V(Cr),U(Cb) components to video memory */ + + count = h; + while(count--) { + __memcpy(dst, src, w); + src += w; + dst += dstPitch; + } + } + } +} + +#ifdef linux + +PREFETCH_FUNC(sse,SSE,SSE,,FENCE) +PREFETCH_FUNC(mmxext,MMXEXT,SSE,EMMS,FENCEMMS) +PREFETCH_FUNC(now,MMX,NOW,FEMMS,FEMMS) +NOPREFETCH_FUNC(mmx,MMX,EMMS,EMMS) + + +static void * kernel_memcpy(void * to, const void * from, size_t len) { + return __memcpy(to, from, len); +} + +static unsigned fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" + "pushl %%ebx\n\t" + "cpuid\n\t" + ".byte 0x0f, 0x31\n\t" + "popl %%ebx\n" + : "=a" (eax) + : "0"(0) + : "ecx","edx","cc"); + return eax; +} + + + +static unsigned time_function(vidCopyFunc mf,unsigned char *buf1, + unsigned char *buf2) { + unsigned t,t2; + + t = fastrdtsc(); + + (*mf)(buf1,buf2,BSIZA,BSIZW,BSIZH,0); + + t2 = fastrdtsc(); + return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 -1)); +} + +enum {libc=0,kernel,sse,mmx,now,mmxext,totNum}; + + +typedef struct { + vidCopyFunc mFunc; + char *mName,**cpuFlag; +} McFuncData; + +static char *libc_cpuflags[] = {" ",0}; +static char *kernel_cpuflags[] = {" ",0}; +static char *sse_cpuflags[] = {" sse ",0}; +static char *mmx_cpuflags[] = {" mmx ",0}; +static char *now_cpuflags[] = {" 3dnow ",0}; +static char *mmx2_cpuflags[] = {" mmxext ", " sse ",0}; + +static McFuncData mcFunctions[totNum] = + {{libc_YUV42X,"libc",libc_cpuflags}, + {kernel_YUV42X,"kernel",kernel_cpuflags}, + {sse_YUV42X,"SSE",sse_cpuflags}, + {mmx_YUV42X,"MMX",mmx_cpuflags}, + {now_YUV42X,"3DNow!",now_cpuflags}, + {mmxext_YUV42X,"MMX2",mmx2_cpuflags}}; + + +static int flagValid(const char *cpuinfo, char *flag) { + + const char *flagLoc,*nextProc; + int located = 0; + + while ((cpuinfo = strstr(cpuinfo, "processor\t:"))) { + located = 1; + cpuinfo += 11; + if ((flagLoc = strstr(cpuinfo,flag))) { + if ((nextProc = strstr(cpuinfo,"processor\t:"))) { + if (nextProc < flagLoc) return 0; + } + } else { + return 0; + } + } + return located; +} + + +static int cpuValid(const char *cpuinfo, char **flags) { + + + for(; *flags != 0; flags++) { + if (flagValid(cpuinfo, *flags)) return 1; + } + return 0; +} +#endif + + +vidCopyFunc viaVidCopyInit( char *copyType, + ScreenPtr pScreen ) { + + /* + * Benchmark the video copy routines using a relevant benchmark + * and choose the fastest. + */ + + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#ifdef linux + char buf[BSIZ]; + unsigned char *buf1,*buf2,*buf3; + char *tmpBuf,*endBuf; + int count,j,bestSoFar; + unsigned best,tmp,testSize,alignSize,tmp2; + VIAMem tmpFbBuffer; + McFuncData *curData; + FILE *cpuInfoFile; + double cpuFreq; + VIAPtr pVia = VIAPTR(pScrn); + + pScrn->pScreen = pScreen; + if (NULL == (cpuInfoFile = fopen("/proc/cpuinfo","r"))) { + return libc_YUV42X; + } + count = fread(buf,1,BSIZ,cpuInfoFile); + if (ferror(cpuInfoFile)) { + fclose(cpuInfoFile); + return libc_YUV42X; + } + fclose(cpuInfoFile); + if (BSIZ == count) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "\"/proc/cpuinfo\" file too long. " + "Using Linux kernel memcpy.\n"); + return libc_YUV42X; + } + buf[count] = 0; + + while(count--) + if ('\n' == buf[count]) buf[count] = ' '; + + /* + * Extract the cpu frequency. + */ + + cpuFreq = 0.; + + if (NULL != (tmpBuf = strstr(buf,"cpu MHz"))) { + if (NULL != (tmpBuf = strstr(tmpBuf,":") + 1)) { + cpuFreq = strtod(tmpBuf,&endBuf); + if (endBuf == tmpBuf) tmpBuf = NULL; + } + } + + alignSize = BSIZH*(BSIZA + (BSIZA >> 1)); + testSize = BSIZH*(BSIZW + (BSIZW >> 1)); + tmpFbBuffer.pool = 0; + + /* + * Allocate an area of offscreen FB memory, (buf1), a simulated video + * player buffer (buf2) and a pool of uninitialized "video" data (buf3). + */ + + if (VIAAllocLinear(&tmpFbBuffer, pScrn, alignSize + 31)) + return libc_YUV42X; + if (NULL == (buf2 = (unsigned char *)xalloc(testSize))) { + VIAFreeLinear(&tmpFbBuffer); + return libc_YUV42X; + } + if (NULL == (buf3 = (unsigned char *)xalloc(testSize))) { + xfree(buf2); + VIAFreeLinear(&tmpFbBuffer); + return libc_YUV42X; + } + buf1 = (unsigned char *)pVia->FBBase + tmpFbBuffer.base; + + /* + * Align the frame buffer destination memory to a 32 byte boundary. + */ + + if ((unsigned long)buf1 & 31) + buf1 += (32 - ((unsigned long)buf1 & 31)); + + bestSoFar = 0; + best = 0xFFFFFFFFU; + + /* + * Make probable buf1 and buf2 are not paged out by + * referencing them. + */ + + libc_YUV42X(buf1,buf2,BSIZA,BSIZW,BSIZH,0); + + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Benchmarking %s copy. Less is better.\n",copyType); + for (j=0; j<totNum; ++j) { + curData = mcFunctions + j; + + if (cpuValid(buf,curData->cpuFlag)) { + + /* + * Simulate setup of the video buffer. + */ + + kernel_memcpy(buf2,buf3,testSize); + + /* + * Copy the video buffer to frame-buffer memory. + */ + + tmp = time_function(curData->mFunc,buf1,buf2); + + /* + * Do it again to avoid context switch effects. + */ + + kernel_memcpy(buf2,buf3,testSize); + tmp2 = time_function(curData->mFunc,buf1,buf2); + tmp = (tmp2 < tmp) ? tmp2 : tmp; + + if (NULL == tmpBuf) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Timed %6s YUV420 copy... %u.\n",curData->mName,tmp); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Timed %6s YUV420 copy... %u. " + "Throughput: %.1f MiB/s.\n",curData->mName,tmp, + cpuFreq * 1.e6 * (double)testSize / + ((double)(tmp) * (double)(0x100000))); + } + if (tmp < best) { + best = tmp; + bestSoFar = j; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Ditch %6s YUV420 copy... Not supported by CPU.\n", + curData->mName); + + } + } + xfree(buf3); + xfree(buf2); + VIAFreeLinear(&tmpFbBuffer); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using %s YUV42X copy for %s.\n",mcFunctions[bestSoFar].mName, + copyType); + return mcFunctions[bestSoFar].mFunc; +#endif + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using copy of Linux kernel memcpy for video.\n"); + return kernel_YUV42X; +} + +#else + +vidCopyFunc viaVidCopyInit( char *copyType, + ScreenPtr pScreen ) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using default xfree86 memcpy for video.\n"); + return libc_YUV42X; +} + +#endif + diff --git a/unichrome/via_memcpy.h b/unichrome/via_memcpy.h new file mode 100644 index 000000000000..bc908e44c57b --- /dev/null +++ b/unichrome/via_memcpy.h @@ -0,0 +1,31 @@ +/* + * Copyright 2004 Thomas Hellstrom, All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_MEMCPY_H_ +#define _VIA_MEMCPY_H_ +#include "xf86.h" + +typedef void (*vidCopyFunc)(unsigned char *, const unsigned char *, + int, int, int, int); +extern vidCopyFunc viaVidCopyInit( char *copyType, ScreenPtr pScreen ); + +#endif diff --git a/unichrome/via_memory.c b/unichrome/via_memory.c new file mode 100644 index 000000000000..6872a8c555ef --- /dev/null +++ b/unichrome/via_memory.c @@ -0,0 +1,203 @@ +/* + * Copyright 2003 Red Hat, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86fbman.h" + +#include "via.h" +#include "xf86drm.h" + +#include "via_driver.h" +#include "via_priv.h" +#include "via_swov.h" +#include "via_drm.h" + + +/* + * Isolate the wonders of X memory allocation, DRI memory allocation + * and 4.3 or 4.4 differences in once abstraction + * + * The pool code indicates who provided the memory + * 0 - nobody + * 1 - xf86 linear (Used in 4.4 only) + * 2 - DRM + * 3 - Preallocated buffer (Used in 4.3 only) + */ + +void VIAFreeLinear(VIAMemPtr mem) +{ + VIAPtr pVia; + DEBUG(ErrorF("Freed %lu (pool %d)\n", mem->base, mem->pool)); + switch(mem->pool) + { + case 0: + return; + case 1: + xf86FreeOffscreenLinear(mem->linear); + mem->linear = NULL; + mem->pool = 0; + return; + case 2: +#ifdef XF86DRI + if(drmCommandWrite(mem->drm_fd, DRM_VIA_FREEMEM, + &mem->drm, sizeof(drm_via_mem_t)) < 0) + ErrorF("DRM module failed free.\n"); +#endif + mem->pool = 0; + return; + case 3: + mem->pool = 0; + pVia = mem->pVia; + pVia->SWOVUsed[mem->slot] = 0; + return; + } +} + +#ifdef X_USE_LINEARFB +static unsigned long offScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, + unsigned long size) { + + int depth = (pScrn->bitsPerPixel + 7) >> 3; + /* Make sure we don't truncate requested size */ + mem->linear = xf86AllocateOffscreenLinear(pScrn->pScreen, + ( size + depth - 1 ) / depth, + 32, NULL, NULL, NULL); + if(mem->linear == NULL) + return BadAlloc; + mem->base = mem->linear->offset * depth; + mem->pool = 1; + return Success; + +} +#endif /* X_USE_LINEARFB */ + +unsigned long VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size) +{ +#if defined(XF86DRI) || !defined(X_USE_LINEARFB) + VIAPtr pVia = VIAPTR(pScrn); +#endif + +#ifdef XF86DRI + int ret; + + + if(mem->pool) + ErrorF("VIA Double Alloc.\n"); + + if(pVia->directRenderingEnabled) { + mem->drm_fd = pVia->drmFD; + mem->drm.context = 1; + mem->drm.size = size; + mem->drm.type = VIDEO; + ret = drmCommandWrite(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm, + sizeof(drm_via_mem_t)); + if (ret || (size != mem->drm.size)) { +#ifdef X_USE_LINEARFB + /* + * Try XY Fallback before failing. + */ + + if (Success == offScreenLinear(mem, pScrn, size)) + return Success; +#endif /* X_USE_LINEARFB */ + ErrorF("DRM memory allocation failed\n"); + return BadAlloc; + } + + mem->base = mem->drm.offset; + mem->pool = 2; + DEBUG(ErrorF("Fulfilled via DRI at %lu\n", mem->base)); + return 0; + } +#endif /* XF86DRI */ + +#ifdef X_USE_LINEARFB + { + if (Success == offScreenLinear(mem, pScrn, size)) + return Success; + ErrorF("Linear memory allocation failed\n"); + return BadAlloc; + } +#else /* X_USE_LINEARFB */ + { + int i; + if(size > pVia->SWOVSize) + return BadAccess; + for(i = 0; i < MEM_BLOCKS; i++) { + if(!pVia->SWOVUsed[i]) { + pVia->SWOVUsed[i] = 1; + mem->pool = 3; + mem->base = pVia->SWOVPool + pVia->SWOVSize * i; + mem->pVia = pVia; + mem->slot = i; + DEBUG(ErrorF("Fulfilled via pool at %lu\n", mem->base)); + return 0; + } + } + } + ErrorF("Out of pools.\n"); + return BadAlloc; +#endif /* X_USE_LINEARFB */ +} + +#ifndef X_USE_LINEARFB +static void +VIAInitPool(VIAPtr pVia, unsigned long offset, unsigned long size) +{ + DEBUG(ErrorF("VIAInitPool %lu bytes at %lu\n", size, offset)); + + size /= 4; + + DEBUG(ErrorF("VIAInitPool %d pools of %lu bytes\n", MEM_BLOCKS, size)); + pVia->SWOVPool = offset; + pVia->SWOVSize = size; +} + +#endif /* !X_USE_LINEARFB */ + +void VIAInitLinear(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); +#ifdef X_USE_LINEARFB + /* + * In the 44 path we must take care not to truncate offset and size so + * that we get overlaps. If there is available memory below line 2048 + * we use it. + */ + unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp; + unsigned long size = pVia->FBFreeEnd / pVia->Bpp - offset; + if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size); +#else + /* + * In the 43 path we don't have to care about truncation. just use + * all available memory, also below line 2048. The drm module uses + * pVia->FBFreeStart as offscreen available start. We do it to. + */ + unsigned long offset = pVia->FBFreeStart; + unsigned long size = pVia->FBFreeEnd - offset; + if (size > 0 ) VIAInitPool(pVia, offset, size); +#endif /* X_USE_LINEARFB */ +} + diff --git a/unichrome/via_mode.c b/unichrome/via_mode.c new file mode 100644 index 000000000000..d300ed7a965c --- /dev/null +++ b/unichrome/via_mode.c @@ -0,0 +1,1869 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * via_mode.c + * + * Everything to do with setting and changing modes. + * + */ + +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_id.h" + +/* + * Modetable nonsense. + * + */ +#include "via_mode.h" + +/* + * + * TV specific code. + * + */ + +/* + * + */ +static Bool +ViaTVDetect(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIATVDetect\n")); + + /* preset some pBIOSInfo TV related values -- move up */ + pBIOSInfo->TVEncoder = VIA_NONETV; + pBIOSInfo->TVI2CDev = NULL; + pBIOSInfo->TVSave = NULL; + pBIOSInfo->TVRestore = NULL; + pBIOSInfo->TVDACSense = NULL; + pBIOSInfo->TVModeValid = NULL; + pBIOSInfo->TVModeI2C = NULL; + pBIOSInfo->TVModeCrtc = NULL; + pBIOSInfo->TVPower = NULL; + pBIOSInfo->TVModes = NULL; + pBIOSInfo->TVPrintRegs = NULL; + + if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0x40)) + pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus2, 0x40); + else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0x40)) + pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus3, 0x40); + + if (pBIOSInfo->TVI2CDev) + return TRUE; + return FALSE; +} + +/* + * + */ +static Bool +ViaTVInit(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVInit\n")); + + switch (pBIOSInfo->TVEncoder){ + case VIA_VT1621: + case VIA_VT1622: + case VIA_VT1623: + ViaVT162xInit(pScrn); + break; + default: + return FALSE; + break; + } + + if (!pBIOSInfo->TVSave || !pBIOSInfo->TVRestore || + !pBIOSInfo->TVDACSense || !pBIOSInfo->TVModeValid || + !pBIOSInfo->TVModeI2C || !pBIOSInfo->TVModeCrtc || + !pBIOSInfo->TVPower || !pBIOSInfo->TVModes || + !pBIOSInfo->TVPrintRegs) { + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaTVInit: TVEncoder was not " + "properly initialised."); + + xf86DestroyI2CDevRec(pBIOSInfo->TVI2CDev, TRUE); + pBIOSInfo->TVI2CDev = NULL; + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + pBIOSInfo->TVEncoder = VIA_NONETV; + pBIOSInfo->TVI2CDev = NULL; + pBIOSInfo->TVSave = NULL; + pBIOSInfo->TVRestore = NULL; + pBIOSInfo->TVDACSense = NULL; + pBIOSInfo->TVModeValid = NULL; + pBIOSInfo->TVModeI2C = NULL; + pBIOSInfo->TVModeCrtc = NULL; + pBIOSInfo->TVPower = NULL; + pBIOSInfo->TVModes = NULL; + pBIOSInfo->TVPrintRegs = NULL; + + return FALSE; + } + + /* Save now */ + pBIOSInfo->TVSave(pScrn); + +#ifdef HAVE_DEBUG + if (VIAPTR(pScrn)->PrintTVRegs) + pBIOSInfo->TVPrintRegs(pScrn); +#endif + + return TRUE; +} + +void +ViaTVSave(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVSave) + pBIOSInfo->TVSave(pScrn); +} + +void +ViaTVRestore(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVRestore) + pBIOSInfo->TVRestore(pScrn); +} + +static Bool +ViaTVDACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVDACSense) + return pBIOSInfo->TVDACSense(pScrn); + return FALSE; +} + +static void +ViaTVSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVModeI2C) + pBIOSInfo->TVModeI2C(pScrn, mode); + + if (pBIOSInfo->TVModeCrtc) + pBIOSInfo->TVModeCrtc(pScrn, mode); +} + +void +ViaTVPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + +#ifdef HAVE_DEBUG + if (On) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: On.\n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: Off.\n"); +#endif + + if (pBIOSInfo->TVPower) + pBIOSInfo->TVPower(pScrn, On); +} + +#ifdef HAVE_DEBUG +void +ViaTVPrintRegs(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVPrintRegs) + pBIOSInfo->TVPrintRegs(pScrn); +} +#endif /* HAVE_DEBUG */ + +/* + * + */ +static ModeStatus +ViaTVModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (pBIOSInfo->TVModeValid) + return pBIOSInfo->TVModeValid(pScrn, mode); + return MODE_OK; +} + +/* + * + */ +void +ViaOutputsDetect(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsDetect\n")); + + pBIOSInfo->CrtPresent = FALSE; + pBIOSInfo->PanelPresent = FALSE; + + /* Panel */ + if (pBIOSInfo->ForcePanel) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling panel from config.\n"); + pBIOSInfo->PanelPresent = TRUE; + } else if (pVia->Id && (pVia->Id->Outputs & VIA_DEVICE_LCD)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling panel from" + " PCI-Subsystem Id information.\n"); + pBIOSInfo->PanelPresent = TRUE; + } + + /* Crt */ + if (pVia->DDC1) + pBIOSInfo->CrtPresent = TRUE; + /* If any of the unichromes support this, add CRT detection here */ + else if (!pBIOSInfo->PanelPresent) { + /* Make sure that at least CRT is enabled. */ + if (!pVia->Id || (pVia->Id->Outputs & VIA_DEVICE_CRT)) + pBIOSInfo->CrtPresent = TRUE; + } + + /* TV encoder */ + if (ViaTVDetect(pScrn) && ViaTVInit(pScrn)) { + if (!pBIOSInfo->TVOutput) /* Config might've set this already */ + ViaTVDACSense(pScrn); + } else if (pVia->Id && (pVia->Id->Outputs & VIA_DEVICE_TV)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "This device is supposed to have a" + " TV encoder but we are unable to detect it (support missing?).\n"); + pBIOSInfo->TVOutput = 0; + } +} + +#ifdef HAVE_DEBUG +/* + * Returns: + * Bit[7] 2nd Path + * Bit[6] 1/0 MHS Enable/Disable + * Bit[5] 0 = Bypass Callback, 1 = Enable Callback + * Bit[4] 0 = Hot-Key Sequence Control (OEM Specific) + * Bit[3] LCD + * Bit[2] TV + * Bit[1] CRT + * Bit[0] DVI + */ +static CARD8 +VIAGetActiveDisplay(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD8 tmp; + + tmp = (hwp->readCrtc(hwp, 0x3E) >> 4); + tmp |= ((hwp->readCrtc(hwp, 0x3B) & 0x18) << 3); + + return tmp; +} +#endif /* HAVE_DEBUG */ + +/* + * + */ +Bool +ViaOutputsSelect(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + if (pVia->IsSecondary) { /* we just abort for now */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaOutputsSelect:" + " Not handling secondary.\n"); + return FALSE; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect\n")); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: X" + " Configuration: 0x%02x\n", pVia->ActiveDevice)); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: BIOS" + " Initialised register: 0x%02x\n", + VIAGetActiveDisplay(pScrn))); + + pBIOSInfo->PanelActive = FALSE; + pBIOSInfo->CrtActive = FALSE; + pBIOSInfo->TVActive = FALSE; + + if (!pVia->ActiveDevice) { + /* always enable the panel when present */ + if (pBIOSInfo->PanelPresent) + pBIOSInfo->PanelActive = TRUE; + else if (pBIOSInfo->TVOutput != TVOUTPUT_NONE) /* cable is attached! */ + pBIOSInfo->TVActive = TRUE; + + /* CRT can be used with everything when present */ + if (pBIOSInfo->CrtPresent) + pBIOSInfo->CrtActive = TRUE; + } else { + if (pVia->ActiveDevice & VIA_DEVICE_LCD) { + if (pBIOSInfo->PanelPresent) + pBIOSInfo->PanelActive = TRUE; + else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate" + " panel: no panel is present.\n"); + } + + if (pVia->ActiveDevice & VIA_DEVICE_TV) { + if (!pBIOSInfo->TVI2CDev) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate" + " TV encoder: no TV encoder present.\n"); + else if (pBIOSInfo->TVOutput == TVOUTPUT_NONE) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate" + " TV encoder: no cable attached.\n"); + else if (pBIOSInfo->PanelActive) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate" + " TV encoder and panel simultaneously. Not using" + " TV encoder.\n"); + else + pBIOSInfo->TVActive = TRUE; + } + + if ((pVia->ActiveDevice & VIA_DEVICE_CRT) || + (!pBIOSInfo->PanelActive && !pBIOSInfo->TVActive)) { + pBIOSInfo->CrtPresent = TRUE; + pBIOSInfo->CrtActive = TRUE; + } + } + +#ifdef HAVE_DEBUG + if (pBIOSInfo->CrtActive) + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: CRT.\n")); + if (pBIOSInfo->PanelActive) + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: Panel.\n")); + if (pBIOSInfo->TVActive) + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: TV.\n")); +#endif + return TRUE; /* !Secondary always has at least CRT */ +} + +/* + * Try to interprete EDID ourselves. + */ +static Bool +ViaGetPanelSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon, int *size) +{ + int i, max = 0; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromEDID\n")); + + /* !!! Why are we not checking VESA modes? */ + + /* checking standard timings */ + for (i = 0; i < 8; i++) + if ((pMon->timings2[i].hsize > 256) && (pMon->timings2[i].hsize > max)) + max = pMon->timings2[i].hsize; + + if (max != 0) { + *size = max; + return TRUE; + } + + /* checking detailed monitor section */ + + /* !!! skip Ranges and standard timings */ + + /* check detailed timings */ + for (i = 0; i < DET_TIMINGS; i++) + if (pMon->det_mon[i].type == DT) { + struct detailed_timings timing = pMon->det_mon[i].section.d_timings; + /* ignore v_active for now */ + if ((timing.clock > 15000000) && (timing.h_active > max)) + max = timing.h_active; + } + + if (max != 0) { + *size = max; + return TRUE; + } + + return FALSE; +} + +/* + * + */ +static Bool +VIAGetPanelSizeFromDDCv1(ScrnInfoPtr pScrn, int *size) +{ + VIAPtr pVia = VIAPTR(pScrn); + xf86MonPtr pMon; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv1\n")); + + if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0)) + return FALSE; + + pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2); + if (!pMon) + return FALSE; + + pVia->DDC2 = pMon; + + if (!pVia->DDC1) { + xf86PrintEDID(pMon); + xf86SetDDCproperties(pScrn, pMon); + } + + if (!ViaGetPanelSizeFromEDID(pScrn, pMon, size)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to read PanelSize from EDID information\n"); + return FALSE; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv1: %d\n", *size)); + return TRUE; +} + +/* + * + */ +static Bool +VIAGetPanelSizeFromDDCv2(ScrnInfoPtr pScrn, int *size) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD8 W_Buffer[1]; + CARD8 R_Buffer[2]; + I2CDevPtr dev; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv2\n")); + + if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA2)) + return FALSE; + + dev = xf86CreateI2CDevRec(); + if (!dev) + return FALSE; + + dev->DevName = "EDID2"; + dev->SlaveAddr = 0xA2; + dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ + dev->StartTimeout = 550; + dev->BitTimeout = 40; + dev->ByteTimeout = 40; + dev->AcknTimeout = 40; + dev->pI2CBus = pVia->pI2CBus2; + + if (!xf86I2CDevInit(dev)) { + xf86DestroyI2CDevRec(dev,TRUE); + return FALSE; + } + + xf86I2CReadByte(dev, 0x00, R_Buffer); + if (R_Buffer[0] != 0x20) { + xf86DestroyI2CDevRec(dev,TRUE); + return FALSE; + } + + /* Found EDID2 Table */ + + W_Buffer[0] = 0x76; + xf86I2CWriteRead(dev, W_Buffer,1, R_Buffer,2); + xf86DestroyI2CDevRec(dev,TRUE); + + *size = R_Buffer[0] | (R_Buffer[1] << 8); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv2: %d\n", *size)); + return TRUE; +} + +/* + * + */ +static void +VIAGetPanelSize(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + char *PanelSizeString[7] = {"640x480", "800x600", "1024x768", "1280x768" + "1280x1024", "1400x1050", "1600x1200"}; + int size = 0; + Bool ret; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSize\n")); + + ret = VIAGetPanelSizeFromDDCv1(pScrn, &size); + if (!ret) + ret = VIAGetPanelSizeFromDDCv2(pScrn, &size); + + if (ret) { + switch (size) { + case 640: + pBIOSInfo->PanelSize = VIA_PANEL6X4; + break; + case 800: + pBIOSInfo->PanelSize = VIA_PANEL8X6; + break; + case 1024: + pBIOSInfo->PanelSize = VIA_PANEL10X7; + break; + case 1280: + pBIOSInfo->PanelSize = VIA_PANEL12X10; + break; + case 1400: + pBIOSInfo->PanelSize = VIA_PANEL14X10; + break; + case 1600: + pBIOSInfo->PanelSize = VIA_PANEL16X12; + break; + default: + pBIOSInfo->PanelSize = VIA_PANEL_INVALID; + break; + } + } else { + pBIOSInfo->PanelSize = hwp->readCrtc(hwp, 0x3F) >> 4; + if (pBIOSInfo->PanelSize == 0) { + /* VIA_PANEL6X4 == 0, but that value equals unset */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to " + "retrieve PanelSize: using default (1024x768)\n"); + pBIOSInfo->PanelSize = VIA_PANEL10X7; + return; + } + } + + if (pBIOSInfo->PanelSize < 7) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using panel at %s.\n", + PanelSizeString[pBIOSInfo->PanelSize]); + else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown panel size " + "detected: %d.\n", pBIOSInfo->PanelSize); +} + +/* + * + */ +static Bool +ViaGetResolutionIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex\n")); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex: Looking" + " for %dx%d\n", mode->CrtcHDisplay, mode->CrtcVDisplay)); + for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++) { + if ((ViaResolutionTable[i].X == mode->CrtcHDisplay) && + (ViaResolutionTable[i].Y == mode->CrtcVDisplay)){ + pBIOSInfo->ResolutionIndex = ViaResolutionTable[i].Index; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex:" + " %d\n", pBIOSInfo->ResolutionIndex)); + return TRUE; + } + } + + pBIOSInfo->ResolutionIndex = VIA_RES_INVALID; + return FALSE; +} + +/* + * + */ +static int +ViaGetVesaMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int i; + + for (i = 0; ViaVesaModes[i].Width; i++) + if ((ViaVesaModes[i].Width == mode->CrtcHDisplay) && + (ViaVesaModes[i].Height == mode->CrtcVDisplay)) { + switch (pScrn->bitsPerPixel) { + case 8: + return ViaVesaModes[i].mode_8b; + case 16: + return ViaVesaModes[i].mode_16b; + case 24: + case 32: + return ViaVesaModes[i].mode_32b; + default: + return 0xFFFF; + } + } + return 0xFFFF; +} + +/* + * + * ViaResolutionTable[i].PanelIndex is pBIOSInfo->PanelSize + * pBIOSInfo->PanelIndex is the index to lcdTable. + * + */ +static Bool +ViaPanelGetIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex\n")); + + pBIOSInfo->PanelIndex = VIA_BIOS_NUM_PANEL; + + if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) { + VIAGetPanelSize(pScrn); + if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaPanelGetIndex:" + " PanelSize not set.\n"); + return FALSE; + } + } + + if ((mode->PrivSize != sizeof(struct ViaModePriv)) || + (mode->Private != (void *)&ViaPanelPrivate)){ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:" + " Mode not supported by Panel.\n"); + return FALSE; + } + + if (!ViaGetResolutionIndex(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel does not support this" + " resolution: %s\n", mode->name); + return FALSE; + } + + for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++) + if (ViaResolutionTable[i].PanelIndex == pBIOSInfo->PanelSize) { + pBIOSInfo->panelX = ViaResolutionTable[i].X; + pBIOSInfo->panelY = ViaResolutionTable[i].Y; + break; + } + + if (ViaResolutionTable[i].Index == VIA_RES_INVALID) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable" + " to find matching PanelSize in ViaResolutionTable.\n"); + return FALSE; + } + + if ((pBIOSInfo->panelX != mode->CrtcHDisplay) || + (pBIOSInfo->panelY != mode->CrtcVDisplay)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Non-native" + "resolutions are broken.\n"); + return FALSE; + } + + for (i = 0; i < VIA_BIOS_NUM_PANEL; i++) + if (lcdTable[i].fpSize == pBIOSInfo->PanelSize) { + int modeNum, tmp; + + modeNum = ViaGetVesaMode(pScrn, mode); + if (modeNum == 0xFFFF) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaPanelGetIndex: " + "Unable to determine matching VESA modenumber.\n"); + return FALSE; + } + + tmp = 0x01 << (modeNum & 0xF); + if ((CARD16)(tmp) & lcdTable[i].SuptMode[(modeNum >> 4)]) { + pBIOSInfo->PanelIndex = i; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:" + "index: %d (%dx%d)\n", pBIOSInfo->PanelIndex, + pBIOSInfo->panelX, pBIOSInfo->panelY)); + return TRUE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable" + " to match given mode with this PanelSize.\n"); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable" + " to match PanelSize with an lcdTable entry.\n"); + return FALSE; +} + +/* + * Stolen from xf86Config.c's addDefaultModes + */ +static void +ViaModesAttachHelper(ScrnInfoPtr pScrn, MonPtr monitorp, DisplayModePtr Modes) +{ + DisplayModePtr mode; + DisplayModePtr last = monitorp->Last; + int i; + + for (i = 0; Modes[i].name; i++) { + mode = xnfalloc(sizeof(DisplayModeRec)); + memcpy(mode, &Modes[i], sizeof(DisplayModeRec)); + mode->name = xnfstrdup(Modes[i].name); + if (last) { + mode->prev = last; + last->next = mode; + } else { /* this is the first mode */ + monitorp->Modes = mode; + mode->prev = NULL; + } + last = mode; + } + monitorp->Last = last; +} + +/* + * + */ +void +ViaModesAttach(ScrnInfoPtr pScrn, MonPtr monitorp) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesAttach\n")); + + if (pBIOSInfo->PanelActive) + ViaModesAttachHelper(pScrn, monitorp, ViaPanelModes); + if (pBIOSInfo->TVActive && pBIOSInfo->TVModes) + ViaModesAttachHelper(pScrn, monitorp, pBIOSInfo->TVModes); +} + +/* + * + */ +CARD32 +ViaGetMemoryBandwidth(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetMemoryBandwidth\n")); + + switch (pVia->Chipset) { + case VIA_CLE266: + if (CLE266_REV_IS_AX(pVia->ChipRev)) + return ViaBandwidthTable[VIA_BW_CLE266A].Bandwidth[pVia->MemClk]; + else + return ViaBandwidthTable[VIA_BW_CLE266C].Bandwidth[pVia->MemClk]; + case VIA_KM400: + if (pVia->ChipRev < 0x8F) + return ViaBandwidthTable[VIA_BW_KM400].Bandwidth[pVia->MemClk]; + else + return ViaBandwidthTable[VIA_BW_KM400A].Bandwidth[pVia->MemClk]; + case VIA_K8M800: + return ViaBandwidthTable[VIA_BW_K8M800].Bandwidth[pVia->MemClk]; + case VIA_PM800: + return ViaBandwidthTable[VIA_BW_PM800].Bandwidth[pVia->MemClk]; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaBandwidthAllowed: Unknown Chipset.\n"); + return VIA_BW_MIN; + } +} + +/* + * Checks for limitations imposed by the available VGA timing registers. + * + */ +static ModeStatus +ViaModePrimaryVGAValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGAValid\n")); + + if (mode->CrtcHTotal > 4100) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal out of range.\n"); + return MODE_BAD_HVALUE; + } + + if (mode->CrtcHDisplay > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay out of range.\n"); + return MODE_BAD_HVALUE; + } + + if (mode->CrtcHBlankStart > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart out of range.\n"); + return MODE_BAD_HVALUE; + } + + if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd out of range.\n"); + return MODE_HBLANK_WIDE; + } + + if (mode->CrtcHSyncStart > 4095) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart out of range.\n"); + return MODE_BAD_HVALUE; + } + + if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd out of range.\n"); + return MODE_HSYNC_WIDE; + } + + if (mode->CrtcVTotal > 2049) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal out of range.\n"); + return MODE_BAD_VVALUE; + } + + if (mode->CrtcVDisplay > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay out of range.\n"); + return MODE_BAD_VVALUE; + } + + if (mode->CrtcVSyncStart > 2047) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart out of range.\n"); + return MODE_BAD_VVALUE; + } + + if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd out of range.\n"); + return MODE_VSYNC_WIDE; + } + + if (mode->CrtcVBlankStart > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart out of range.\n"); + return MODE_BAD_VVALUE; + } + + if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd out of range.\n"); + return MODE_VBLANK_WIDE; + } + + return MODE_OK; +} + +/* + * + */ +static ModeStatus +ViaModeSecondaryVGAValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondaryVGAValid\n")); + + if (mode->CrtcHTotal > 4096) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal out of range.\n"); + return MODE_BAD_HVALUE; + } + + if (mode->CrtcHDisplay > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay out of range.\n"); + return MODE_BAD_HVALUE; + } + + if (mode->CrtcHBlankStart > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart out of range.\n"); + return MODE_BAD_HVALUE; + } + + if (mode->CrtcHBlankEnd > 4096) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd out of range.\n"); + return MODE_HBLANK_WIDE; + } + + if (mode->CrtcHSyncStart > 2047) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart out of range.\n"); + return MODE_BAD_HVALUE; + } + + if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd out of range.\n"); + return MODE_HSYNC_WIDE; + } + + if (mode->CrtcVTotal > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal out of range.\n"); + return MODE_BAD_VVALUE; + } + + if (mode->CrtcVDisplay > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay out of range.\n"); + return MODE_BAD_VVALUE; + } + + if (mode->CrtcVBlankStart > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart out of range.\n"); + return MODE_BAD_VVALUE; + } + + if (mode->CrtcVBlankEnd > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd out of range.\n"); + return MODE_VBLANK_WIDE; + } + + if (mode->CrtcVSyncStart > 2047) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart out of range.\n"); + return MODE_BAD_VVALUE; + } + + if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd out of range.\n"); + return MODE_VSYNC_WIDE; + } + + return MODE_OK; +} + + +static CARD32 ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode); + +/* + * + */ +ModeStatus +ViaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + ModeStatus ret; + CARD32 temp; + + if (pVia->pVbe) + return MODE_OK; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaValidMode: Validating %s (%d)\n", + mode->name, mode->Clock)); + + if (mode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; + + if (pVia->IsSecondary) + ret = ViaModeSecondaryVGAValid(pScrn, mode); + else + ret = ViaModePrimaryVGAValid(pScrn, mode); + + if (ret != MODE_OK) + return ret; + + if (pBIOSInfo->TVActive) { + ret = ViaTVModeValid(pScrn, mode); + if (ret != MODE_OK) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode \"%s\" not supported by" + " TV encoder.\n", mode->name); + return ret; + } + } else if (pBIOSInfo->PanelActive && !ViaPanelGetIndex(pScrn, mode)) + return MODE_BAD; + else if (!ViaModeDotClockTranslate(pScrn, mode)) + return MODE_NOCLOCK; + + temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * + (pScrn->bitsPerPixel >> 3); + if (pBIOSInfo->Bandwidth < temp) { + xf86DrvMsg(scrnIndex, X_INFO, "Required bandwidth is not available. (%u > %u)\n", + (unsigned) temp, (unsigned) pBIOSInfo->Bandwidth); + return MODE_CLOCK_HIGH; /* since there is no MODE_BANDWIDTH */ + } + + return MODE_OK; +} + +/* + * + * Some very common abstractions. + * + */ + +/* + * Standard vga call really. + * Needs to be called to reset the dotclock (after SR40:2/1 reset) + */ +static void +ViaSetUseExternalClock(vgaHWPtr hwp) +{ + CARD8 data; + + DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetUseExternalClock\n")); + + data = hwp->readMiscOut(hwp); + hwp->writeMiscOut(hwp, data | 0x0C); +} + +/* + * + */ +static void +ViaSetPrimaryDotclock(ScrnInfoPtr pScrn, CARD32 clock) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetPrimaryDotclock to 0x%lX\n", clock)); + + if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) { + hwp->writeSeq(hwp, 0x46, clock >> 8); + hwp->writeSeq(hwp, 0x47, clock & 0xFF); + } else { /* unichrome pro */ + hwp->writeSeq(hwp, 0x44, clock >> 16); + hwp->writeSeq(hwp, 0x45, (clock >> 8) & 0xFF); + hwp->writeSeq(hwp, 0x46, clock & 0xFF); + } + + ViaSeqMask(hwp, 0x40, 0x02, 0x02); + ViaSeqMask(hwp, 0x40, 0x00, 0x02); +} + +/* + * + */ +static void +ViaSetSecondaryDotclock(ScrnInfoPtr pScrn, CARD32 clock) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetSecondaryDotclock to 0x%lX\n", clock)); + + if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) { + hwp->writeSeq(hwp, 0x44, clock >> 8); + hwp->writeSeq(hwp, 0x45, clock & 0xFF); + } else { /* unichrome pro */ + hwp->writeSeq(hwp, 0x4A, clock >> 16); + hwp->writeSeq(hwp, 0x4B, (clock >> 8) & 0xFF); + hwp->writeSeq(hwp, 0x4C, clock & 0xFF); + } + + ViaSeqMask(hwp, 0x40, 0x04, 0x04); + ViaSeqMask(hwp, 0x40, 0x00, 0x04); +} + +/* + * Broken, only does native mode decently. I (Luc) personally broke this. + */ +static void +VIASetLCDMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + VIALCDModeTableRec Table = lcdTable[pBIOSInfo->PanelIndex]; + CARD8 modeNum = 0; + int resIdx; + int port, offset, data; + int i, j, misc; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetLCDMode\n")); + + if (pBIOSInfo->PanelSize == VIA_PANEL12X10) + hwp->writeCrtc(hwp, 0x89, 0x07); + + /* LCD Expand Mode Y Scale Flag */ + pBIOSInfo->scaleY = FALSE; + + /* Set LCD InitTb Regs */ + if (pBIOSInfo->BusWidth == VIA_DI_12BIT) { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Table.InitTb.LCDClk_12Bit; + else { + pBIOSInfo->Clock = Table.InitTb.VClk_12Bit; + /* for some reason still to be defined this is neccessary */ + ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk_12Bit); + } + } else { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Table.InitTb.LCDClk; + else { + pBIOSInfo->Clock = Table.InitTb.VClk; + ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk); + } + + } + + ViaSetUseExternalClock(hwp); + + for (i = 0; i < Table.InitTb.numEntry; i++) { + port = Table.InitTb.port[i]; + offset = Table.InitTb.offset[i]; + data = Table.InitTb.data[i]; + ViaVgahwWrite(hwp, 0x300+port, offset, 0x301+port, data); + } + + if ((mode->CrtcHDisplay != pBIOSInfo->panelX) || + (mode->CrtcVDisplay != pBIOSInfo->panelY)) { + VIALCDModeEntryPtr Main; + VIALCDMPatchEntryPtr Patch1, Patch2; + int numPatch1, numPatch2; + + resIdx = VIA_RES_INVALID; + + /* Find MxxxCtr & MxxxExp Index and + * HWCursor Y Scale (PanelSize Y / Res. Y) */ + pBIOSInfo->resY = mode->CrtcVDisplay; + switch (pBIOSInfo->ResolutionIndex) { + case VIA_RES_640X480: + resIdx = 0; + break; + case VIA_RES_800X600: + resIdx = 1; + break; + case VIA_RES_1024X768: + resIdx = 2; + break; + case VIA_RES_1152X864: + resIdx = 3; + break; + case VIA_RES_1280X768: + case VIA_RES_1280X960: + case VIA_RES_1280X1024: + if (pBIOSInfo->PanelSize == VIA_PANEL12X10) + resIdx = VIA_RES_INVALID; + else + resIdx = 4; + break; + default: + resIdx = VIA_RES_INVALID; + break; + } + + if ((mode->CrtcHDisplay == 640) && + (mode->CrtcVDisplay == 400)) + resIdx = 0; + + if (resIdx == VIA_RES_INVALID) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIASetLCDMode: Failed " + "to find a suitable Panel Size index.\n"); + return; + } + + if (pBIOSInfo->Center) { + Main = &(Table.MCtr[resIdx]); + Patch1 = Table.MPatchDP1Ctr; + numPatch1 = Table.numMPatchDP1Ctr; + Patch2 = Table.MPatchDP2Ctr; + numPatch2 = Table.numMPatchDP2Ctr; + } else { /* expand! */ + /* LCD Expand Mode Y Scale Flag */ + pBIOSInfo->scaleY = TRUE; + Main = &(Table.MExp[resIdx]); + Patch1 = Table.MPatchDP1Exp; + numPatch1 = Table.numMPatchDP1Exp; + Patch2 = Table.MPatchDP2Exp; + numPatch2 = Table.numMPatchDP2Exp; + } + + /* Set Main LCD Registers */ + for (i = 0; i < Main->numEntry; i++){ + ViaVgahwWrite(hwp, 0x300 + Main->port[i], Main->offset[i], + 0x301 + Main->port[i], Main->data[i]); + } + + if (pBIOSInfo->BusWidth == VIA_DI_12BIT) { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Main->LCDClk_12Bit; + else + pBIOSInfo->Clock = Main->VClk_12Bit; + } else { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Main->LCDClk; + else + pBIOSInfo->Clock = Main->VClk; + } + + j = ViaGetVesaMode(pScrn, mode); + if (j == 0xFFFF) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIASetLCDMode: " + "Unable to determine matching VESA modenumber.\n"); + return; + } + for (i = 0; i < modeFix.numEntry; i++) { + if (modeFix.reqMode[i] == j) { + modeNum = modeFix.fixMode[i]; + break; + } + } + + /* Set LCD Mode patch registers. */ + for (i = 0; i < numPatch2; i++, Patch2++) { + if (Patch2->Mode == modeNum) { + if (!pBIOSInfo->Center && (mode->CrtcHDisplay == pBIOSInfo->panelX)) + pBIOSInfo->scaleY = FALSE; + + for (j = 0; j < Patch2->numEntry; j++){ + ViaVgahwWrite(hwp, 0x300 + Patch2->port[j], Patch2->offset[j], + 0x301 + Patch2->port[j], Patch2->data[j]); + } + + if (pBIOSInfo->BusWidth == VIA_DI_12BIT) { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Patch2->LCDClk_12Bit; + else + pBIOSInfo->Clock = Patch2->VClk_12Bit; + } else { + if (pVia->IsSecondary) + pBIOSInfo->Clock = Patch2->LCDClk; + else + pBIOSInfo->Clock = Patch2->VClk; + } + break; + } + } + + + /* Set LCD Secondary Mode Patch registers. */ + if (pVia->IsSecondary) { + for (i = 0; i < numPatch1; i++, Patch1++) { + if (Patch1->Mode == modeNum) { + for (j = 0; j < Patch1->numEntry; j++) { + ViaVgahwWrite(hwp, 0x300 + Patch1->port[j], Patch1->offset[j], + 0x301 + Patch1->port[j], Patch1->data[j]); + } + break; + } + } + } + } + + /* LCD patch 3D5.02 */ + misc = hwp->readCrtc(hwp, 0x01); + hwp->writeCrtc(hwp, 0x02, misc); + + /* Enable LCD */ + if (!pVia->IsSecondary) { + /* CRT Display Source Bit 6 - 0: CRT, 1: LCD */ + ViaSeqMask(hwp, 0x16, 0x40, 0x40); + + /* Enable Simultaneous */ + if (pBIOSInfo->BusWidth == VIA_DI_12BIT) { + hwp->writeCrtc(hwp, 0x6B, 0xA8); + + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) + hwp->writeCrtc(hwp, 0x93, 0xB1); + else + hwp->writeCrtc(hwp, 0x93, 0xAF); + } else { + ViaCrtcMask(hwp, 0x6B, 0x08, 0x08); + hwp->writeCrtc(hwp, 0x93, 0x00); + } + hwp->writeCrtc(hwp, 0x6A, 0x48); + } else { + /* CRT Display Source Bit 6 - 0: CRT, 1: LCD */ + ViaSeqMask(hwp, 0x16, 0x00, 0x40); + + /* Enable SAMM */ + if (pBIOSInfo->BusWidth == VIA_DI_12BIT) { + ViaCrtcMask(hwp, 0x6B, 0x20, 0x20); + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) + hwp->writeCrtc(hwp, 0x93, 0xB1); + else + hwp->writeCrtc(hwp, 0x93, 0xAF); + } else { + hwp->writeCrtc(hwp, 0x6B, 0x00); + hwp->writeCrtc(hwp, 0x93, 0x00); + } + hwp->writeCrtc(hwp, 0x6A, 0xC8); + } +} + +/* + * + */ +static void +ViaModePrimaryVGA(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD16 temp; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGA\n")); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGA: " + "Setting up %s\n", mode->name)); + + ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */ + ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */ + hwp->writeSeq(hwp, 0x10, 0x01); /* unlock extended registers */ + ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */ + + /* Set Misc Register */ + temp = 0x23; + if (mode->Flags & V_NHSYNC) + temp |= 0x40; + if (mode->Flags & V_NHSYNC) + temp |= 0x80; + temp |= 0x0C; /* Undefined/external clock */ + hwp->writeMiscOut(hwp, temp); + + /* Sequence registers */ + hwp->writeSeq(hwp, 0x00, 0x00); + + /* if (mode->Flags & V_CLKDIV2) + hwp->writeSeq(hwp, 0x01, 0x09); + else */ + hwp->writeSeq(hwp, 0x01, 0x01); + + hwp->writeSeq(hwp, 0x02, 0x0F); + hwp->writeSeq(hwp, 0x03, 0x00); + hwp->writeSeq(hwp, 0x04, 0x0E); + + ViaSeqMask(hwp, 0x15, 0x02, 0x02); + + /* bpp */ + switch (pScrn->bitsPerPixel) { + case 8: + ViaSeqMask(hwp, 0x15, 0x20, 0xFC); + break; + case 16: + ViaSeqMask(hwp, 0x15, 0xB4, 0xFC); + break; + case 24: + case 32: + ViaSeqMask(hwp, 0x15, 0xAC, 0xFC); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n", + pScrn->bitsPerPixel); + break; + } + + ViaSeqMask(hwp, 0x16, 0x08, 0xBF); + ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); + ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); + ViaSeqMask(hwp, 0x1A, 0x08, 0xFD); + + /* graphics registers */ + hwp->writeGr(hwp, 0x00, 0x00); + hwp->writeGr(hwp, 0x01, 0x00); + hwp->writeGr(hwp, 0x02, 0x00); + hwp->writeGr(hwp, 0x03, 0x00); + hwp->writeGr(hwp, 0x04, 0x00); + hwp->writeGr(hwp, 0x05, 0x40); + hwp->writeGr(hwp, 0x06, 0x05); + hwp->writeGr(hwp, 0x07, 0x0F); + hwp->writeGr(hwp, 0x08, 0xFF); + + ViaGrMask(hwp, 0x20, 0, 0xFF); + ViaGrMask(hwp, 0x21, 0, 0xFF); + ViaGrMask(hwp, 0x22, 0, 0xFF); + + /* attribute registers */ + hwp->writeAttr(hwp, 0x00, 0x00); + hwp->writeAttr(hwp, 0x01, 0x01); + hwp->writeAttr(hwp, 0x02, 0x02); + hwp->writeAttr(hwp, 0x03, 0x03); + hwp->writeAttr(hwp, 0x04, 0x04); + hwp->writeAttr(hwp, 0x05, 0x05); + hwp->writeAttr(hwp, 0x06, 0x06); + hwp->writeAttr(hwp, 0x07, 0x07); + hwp->writeAttr(hwp, 0x08, 0x08); + hwp->writeAttr(hwp, 0x09, 0x09); + hwp->writeAttr(hwp, 0x0A, 0x0A); + hwp->writeAttr(hwp, 0x0B, 0x0B); + hwp->writeAttr(hwp, 0x0C, 0x0C); + hwp->writeAttr(hwp, 0x0D, 0x0D); + hwp->writeAttr(hwp, 0x0E, 0x0E); + hwp->writeAttr(hwp, 0x0F, 0x0F); + hwp->writeAttr(hwp, 0x10, 0x41); + hwp->writeAttr(hwp, 0x11, 0xFF); + hwp->writeAttr(hwp, 0x12, 0x0F); + hwp->writeAttr(hwp, 0x13, 0x00); + hwp->writeAttr(hwp, 0x14, 0x00); + + /* Crtc registers */ + /* horizontal total : 4100 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%03X\n", + mode->CrtcHTotal)); + temp = (mode->CrtcHTotal >> 3) - 5; + hwp->writeCrtc(hwp, 0x00, temp & 0xFF); + ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08); + + /* horizontal address : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%03X\n", + mode->CrtcHDisplay)); + temp = (mode->CrtcHDisplay >> 3) - 1; + hwp->writeCrtc(hwp, 0x01, temp & 0xFF); + + /* horizontal blanking start : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%03X\n", + mode->CrtcHBlankStart)); + if (mode->CrtcHBlankStart != mode->CrtcHDisplay) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (HBlankStart).\n"); + temp = (mode->CrtcHDisplay >> 3) - 1; + hwp->writeCrtc(hwp, 0x02, temp & 0xFF); + /* If HblankStart has more bits anywhere, add them here */ + + /* horizontal blanking end : start + 1025 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%03X\n", + mode->CrtcHBlankEnd)); + if (mode->CrtcHBlankEnd != mode->CrtcHTotal) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (HBlankEnd).\n"); + temp = (mode->CrtcHTotal >> 3) - 1; + ViaCrtcMask(hwp, 0x03, temp, 0x1F); + ViaCrtcMask(hwp, 0x05, temp << 2, 0x80); + ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20); + + /* CrtcHSkew ??? */ + + /* horizontal sync start : 4095 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%03X\n", + mode->CrtcHSyncStart)); + temp = mode->CrtcHSyncStart >> 3; + hwp->writeCrtc(hwp, 0x04, temp & 0xFF); + ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10); + + /* horizontal sync end : start + 256 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%03X\n", + mode->CrtcHSyncEnd)); + temp = mode->CrtcHSyncEnd >> 3; + ViaCrtcMask(hwp, 0x05, temp, 0x1F); + + /* vertical total : 2049 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%03X\n", + mode->CrtcVTotal)); + temp = mode->CrtcVTotal - 2; + hwp->writeCrtc(hwp, 0x06, temp & 0xFF); + ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01); + ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20); + ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01); + + /* vertical address : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%03X\n", + mode->CrtcVDisplay)); + temp = mode->CrtcVDisplay - 1; + hwp->writeCrtc(hwp, 0x12, temp & 0xFF); + ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02); + ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40); + ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04); + + /* Primary starting address -> 0x00, adjustframe does the rest */ + hwp->writeCrtc(hwp, 0x0C, 0x00); + hwp->writeCrtc(hwp, 0x0D, 0x00); + hwp->writeCrtc(hwp, 0x34, 0x00); + ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */ + + /* vertical sync start : 2047 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%03X\n", + mode->CrtcVSyncStart)); + temp = mode->CrtcVSyncStart; + hwp->writeCrtc(hwp, 0x10, temp & 0xFF); + ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04); + ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80); + ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02); + + /* vertical sync end : start + 16 -- other bits someplace? */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%03X\n", + mode->CrtcVSyncEnd)); + ViaCrtcMask(hwp, 0x11, mode->CrtcVSyncEnd, 0x0F); + + /* line compare: We are not doing splitscreen so 0x3FFF */ + hwp->writeCrtc(hwp, 0x18, 0xFF); + ViaCrtcMask(hwp, 0x07, 0x10, 0x10); + ViaCrtcMask(hwp, 0x09, 0x40, 0x40); + ViaCrtcMask(hwp, 0x33, 0x07, 0x06); + ViaCrtcMask(hwp, 0x35, 0x10, 0x10); + + /* zero Maximum scan line */ + ViaCrtcMask(hwp, 0x09, 0x00, 0x1F); + hwp->writeCrtc(hwp, 0x14, 0x00); + + /* vertical blanking start : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%03X\n", + mode->CrtcVBlankStart)); + if (mode->CrtcVBlankStart != mode->CrtcVDisplay) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (VBlankStart).\n"); + temp = mode->CrtcVDisplay - 1; + hwp->writeCrtc(hwp, 0x15, temp & 0xFF); + ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08); + ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20); + ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08); + + /* vertical blanking end : start + 257 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%03X\n", + mode->CrtcVBlankEnd)); + if (mode->CrtcVBlankEnd != mode->CrtcVTotal) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (VBlankEnd).\n"); + temp = mode->CrtcVTotal - 1; + hwp->writeCrtc(hwp, 0x16, temp); + + /* some leftovers */ + hwp->writeCrtc(hwp, 0x08, 0x00); + ViaCrtcMask(hwp, 0x32, 0, 0xFF); /* ? */ + ViaCrtcMask(hwp, 0x33, 0, 0xC8); + + /* offset */ + temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; + /* Make sure that this is 32byte aligned */ + if (temp & 0x03) { + temp += 0x03; + temp &= ~0x03; + } + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset: 0x%03X\n", temp)); + hwp->writeCrtc(hwp, 0x13, temp & 0xFF); + ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0); + + /* fetch count */ + temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3; + /* Make sure that this is 32byte aligned */ + if (temp & 0x03) { + temp += 0x03; + temp &= ~0x03; + } + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fetch Count: 0x%03X\n", temp)); + hwp->writeSeq(hwp, 0x1C, (temp >> 1) & 0xFF); + ViaSeqMask(hwp, 0x1D, temp >> 9, 0x03); + + /* some leftovers */ + ViaCrtcMask(hwp, 0x32, 0, 0xFF); + ViaCrtcMask(hwp, 0x33, 0, 0xC8); +} + +/* + * + */ +static CARD32 +ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i; + + for (i = 0; ViaDotClocks[i].DotClock; i++) + if (ViaDotClocks[i].DotClock == mode->Clock) { + if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) + return ViaDotClocks[i].UniChrome; + else + return ViaDotClocks[i].UniChromePro; + } + return 0x0000; +} + +/* + * + */ +void +ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimary\n")); + + /* Turn off Screen */ + ViaCrtcMask(hwp, 0x17, 0x00, 0x80); + + /* Clean Second Path Status */ + hwp->writeCrtc(hwp, 0x6A, 0x00); + hwp->writeCrtc(hwp, 0x6B, 0x00); + hwp->writeCrtc(hwp, 0x6C, 0x00); + hwp->writeCrtc(hwp, 0x93, 0x00); + + ViaModePrimaryVGA(pScrn, mode); + pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, mode); + pBIOSInfo->ClockExternal = FALSE; + + /* Don't do this before the Sequencer is set: locks up KM400 and K8M800 */ + if (pVia->FirstInit) + memset(pVia->FBBase, 0x00, pVia->videoRambytes); + + /* Enable MMIO & PCI burst (1 wait state) */ + ViaSeqMask(hwp, 0x1A, 0x06, 0x06); + + if (!pBIOSInfo->CrtActive) + ViaCrtcMask(hwp, 0x36, 0x30, 0x30); + + if (pBIOSInfo->PanelActive && ViaPanelGetIndex(pScrn, mode)) { + VIASetLCDMode(pScrn, mode); + ViaLCDPower(pScrn, TRUE); + } else if (pBIOSInfo->PanelPresent) + ViaLCDPower(pScrn, FALSE); + + if (pBIOSInfo->TVActive) { + /* Quick 'n dirty workaround for non-primary case until TVCrtcMode + is removed -- copy from clock handling code below */ + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) + ViaSetPrimaryDotclock(pScrn, 0x471C); /* CLE266Ax use 2x XCLK */ + else + ViaSetPrimaryDotclock(pScrn, 0x871C); + ViaSetUseExternalClock(hwp); + + ViaTVSetMode(pScrn, mode); + } else + ViaTVPower(pScrn, FALSE); + + ViaSetPrimaryFIFO(pScrn, mode); + + if (pBIOSInfo->ClockExternal) { + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) + ViaSetPrimaryDotclock(pScrn, 0x471C); /* CLE266Ax use 2x XCLK */ + else + ViaSetPrimaryDotclock(pScrn, 0x871C); + ViaCrtcMask(hwp, 0x6B, 0x01, 0x01); + } else { + ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock); + ViaSetUseExternalClock(hwp); + ViaCrtcMask(hwp, 0x6B, 0x00, 0x01); + } + + /* Enable CRT Controller (3D5.17 Hardware Reset) */ + ViaCrtcMask(hwp, 0x17, 0x80, 0x80); + + hwp->disablePalette(hwp); +} + +/* + * + */ +static void +ViaModeSecondaryVGA(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD16 temp; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondaryVGA\n")); + + /* bpp */ + switch (pScrn->bitsPerPixel) { + case 8: + ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); + break; + case 16: + ViaCrtcMask(hwp, 0x67, 0x40, 0xC0); + break; + case 24: + case 32: + ViaCrtcMask(hwp, 0x67, 0x80, 0xC0); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n", + pScrn->bitsPerPixel); + break; + } + + /* Crtc registers */ + /* horizontal total : 4096 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%03X\n", + mode->CrtcHTotal)); + temp = mode->CrtcHTotal - 1; + hwp->writeCrtc(hwp, 0x50, temp & 0xFF); + ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F); + + /* horizontal address : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%03X\n", + mode->CrtcHDisplay)); + temp = mode->CrtcHDisplay - 1; + hwp->writeCrtc(hwp, 0x51, temp & 0xFF); + ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70); + + /* horizontal blanking start : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%03X\n", + mode->CrtcHBlankStart)); + if (mode->CrtcHBlankStart != mode->CrtcHDisplay) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (HBlankStart).\n"); + temp = mode->CrtcHDisplay - 1; + hwp->writeCrtc(hwp, 0x52, temp & 0xFF); + ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07); + + /* horizontal blanking end : 4096 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%03X\n", + mode->CrtcHBlankEnd)); + if (mode->CrtcHBlankEnd != mode->CrtcHTotal) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (HBlankEnd).\n"); + temp = mode->CrtcHTotal - 1; + hwp->writeCrtc(hwp, 0x53, temp & 0xFF); + ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38); + ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40); + + /* horizontal sync start : 2047 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%03X\n", + mode->CrtcHSyncStart)); + temp = mode->CrtcHSyncStart; + hwp->writeCrtc(hwp, 0x56, temp & 0xFF); + ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0); + ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80); + + /* horizontal sync end : sync start + 512 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%03X\n", + mode->CrtcHSyncEnd)); + temp = mode->CrtcHSyncEnd; + hwp->writeCrtc(hwp, 0x57, temp & 0xFF); + ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40); + + /* vertical total : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%03X\n", + mode->CrtcVTotal)); + temp = mode->CrtcVTotal - 1; + hwp->writeCrtc(hwp, 0x58, temp & 0xFF); + ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07); + + /* vertical address : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%03X\n", + mode->CrtcVDisplay)); + temp = mode->CrtcVDisplay - 1; + hwp->writeCrtc(hwp, 0x59, temp & 0xFF); + ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38); + + /* vertical blanking start : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%03X\n", + mode->CrtcVBlankStart)); + if (mode->CrtcVBlankStart != mode->CrtcVDisplay) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (VBlankStart).\n"); + temp = mode->CrtcVDisplay - 1; + hwp->writeCrtc(hwp, 0x5A, temp & 0xFF); + ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07); + + /* vertical blanking end : 2048 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%03X\n", + mode->CrtcVBlankEnd)); + if (mode->CrtcVBlankEnd != mode->CrtcVTotal) /* FIX ME */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around an old VGA " + "limitation (VBlankEnd).\n"); + temp = mode->CrtcVTotal - 1; + hwp->writeCrtc(hwp, 0x5B, temp & 0xFF); + ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38); + + /* vertical sync start : 2047 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%03X\n", + mode->CrtcVSyncStart)); + temp = mode->CrtcVSyncStart; + hwp->writeCrtc(hwp, 0x5E, temp & 0xFF); + ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0); + + /* vertical sync end : start + 32 */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%03X\n", + mode->CrtcVSyncEnd)); + temp = mode->CrtcVSyncEnd; + ViaCrtcMask(hwp, 0x5F, temp, 0x1F); + + /* offset */ + temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; + if (temp & 0x03) { /* Make sure that this is 32byte aligned */ + temp += 0x03; + temp &= ~0x03; + } + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset: 0x%03X\n", temp)); + hwp->writeCrtc(hwp, 0x66, temp & 0xFF); + ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03); + + /* fetch count */ + temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3; + /* Make sure that this is 32byte aligned */ + if (temp & 0x03) { + temp += 0x03; + temp &= ~0x03; + } + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fetch Count: 0x%03X\n", temp)); + hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF); + ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C); +} + +/* + * + */ +void +ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondary\n")); + + /* Turn off Screen */ + ViaCrtcMask(hwp, 0x17, 0x00, 0x80); + + ViaModeSecondaryVGA(pScrn, mode); + + if (pBIOSInfo->TVActive) + ViaTVSetMode(pScrn, mode); + + /* CLE266A2 apparently doesn't like this */ + if ((pVia->Chipset != VIA_CLE266) || (pVia->ChipRev != 0x02)) + ViaCrtcMask(hwp, 0x6C, 0x00, 0x1E); + + if (pBIOSInfo->PanelActive && (pBIOSInfo->PanelIndex != VIA_BIOS_NUM_PANEL)) { + pBIOSInfo->SetDVI = TRUE; + VIASetLCDMode(pScrn, mode); + ViaLCDPower(pScrn, TRUE); + } else if (pBIOSInfo->PanelPresent) + ViaLCDPower(pScrn, FALSE); + + ViaSetSecondaryFIFO(pScrn, mode); + + ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock); + ViaSetUseExternalClock(hwp); + + ViaCrtcMask(hwp, 0x17, 0x80, 0x80); + + hwp->disablePalette(hwp); +} + +/* + * + */ +static void +ViaLCDPowerSequence(vgaHWPtr hwp, VIALCDPowerSeqRec Sequence) +{ + int i; + + for (i = 0; i < Sequence.numEntry; i++) { + ViaVgahwMask(hwp, 0x300 + Sequence.port[i], Sequence.offset[i], + 0x301 + Sequence.port[i], Sequence.data[i], + Sequence.mask[i]); + usleep(Sequence.delay[i]); + } +} + +/* + * + */ +void +ViaLCDPower(ScrnInfoPtr pScrn, Bool On) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + int i; + +#ifdef HAVE_DEBUG + if (On) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaLCDPower: On.\n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaLCDPower: Off.\n"); +#endif + + /* Enable LCD */ + if (On) + ViaCrtcMask(hwp, 0x6A, 0x08, 0x08); + else + ViaCrtcMask(hwp, 0x6A, 0x00, 0x08); + + /* Find Panel Size Index for PowerSeq Table */ + if (pVia->Chipset == VIA_CLE266) { + if (pBIOSInfo->PanelSize != VIA_PANEL_INVALID) { + for (i = 0; i < NumPowerOn; i++) { + if (lcdTable[pBIOSInfo->PanelIndex].powerSeq == powerOn[i].powerSeq) + break; + } + } else + i = 0; + } else /* KM and K8M use PowerSeq Table index 2. */ + i = 2; + + usleep(1); + if (On) + ViaLCDPowerSequence(hwp, powerOn[i]); + else + ViaLCDPowerSequence(hwp, powerOff[i]); + usleep(1); +} diff --git a/unichrome/via_mode.h b/unichrome/via_mode.h new file mode 100644 index 000000000000..6e476bd02a49 --- /dev/null +++ b/unichrome/via_mode.h @@ -0,0 +1,911 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_MODE_H_ +#define _VIA_MODE_H_ 1 + +/* + * Bandwidth + * + */ +/* used for impossible entries: allow a minimum bandwidth in case this does happen */ +#define VIA_BW_MIN 74000000 /* > 640x480@60Hz@32bpp */ + +/* index to table */ +#define VIA_BW_CLE266A 0 +#define VIA_BW_CLE266C 1 +#define VIA_BW_KM400 2 +#define VIA_BW_KM400A 3 +#define VIA_BW_K8M800 4 +#define VIA_BW_PM800 5 +#define VIA_BW_ALL 6 + +/* + * 393216000 is for SDR133 in via_refresh.h + * 460800000 is for DDR266 + */ +static struct { + CARD8 Device; /* equal to index */ + CARD32 Bandwidth[VIA_MEM_END]; +} ViaBandwidthTable[VIA_BW_ALL] = { + { VIA_BW_CLE266A, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, VIA_BW_MIN, VIA_BW_MIN } }, + { VIA_BW_CLE266C, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, VIA_BW_MIN, VIA_BW_MIN } }, + { VIA_BW_KM400, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, VIA_BW_MIN } }, + { VIA_BW_KM400A, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000 } }, + { VIA_BW_K8M800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000 } }, + { VIA_BW_PM800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000 } } +}; + +/* + * simple lookup table for dotclocks + * + */ +static struct ViaDotClock { + int DotClock; + CARD16 UniChrome; + CARD32 UniChromePro; +} ViaDotClocks[] = { + { 25200, 0x513C, 0x230013 }, + { 25312, 0xC763, 0 }, + { 26591, 0x471A, 0 }, + { 31500, 0xC558, 0xB70428 }, + { 31704, 0x471F, 0 }, + { 32663, 0xC449, 0 }, + { 33750, 0x4721, 0 }, + { 35500, 0x5877, 0x89041A }, + { 36000, 0x5879, 0xD10813 }, + { 39822, 0xC459, 0 }, + { 40000, 0x515F, 0x950419 }, + { 41164, 0x4417, 0 }, + { 46981, 0x5069, 0 }, + { 49500, 0xC353, 0x2B000B }, + { 50000, 0xC354, 0x8D0027 }, + { 56300, 0x4F76, 0xA30028 }, + { 57284, 0x4E70, 0x4E0803 }, + { 64995, 0x0D3B, 0x620409 }, + { 65000, 0x0D3B, 0x300009 }, + { 65028, 0x866D, 0 }, + { 75000, 0x156E, 0x810017 }, + { 78800, 0x442C, 0xEB0029 }, + { 81135, 0x0622, 0 }, + { 81613, 0x4539, 0 }, + { 94500, 0x4542, 0xB7001A }, + { 108000, 0x0B53, 0x510009 }, /* this is a 0.332 ratio that gives the best image */ + { 108280, 0x4879, 0 }, + { 122000, 0x0D6F, 0x8F000F }, + { 122726, 0x073C, 0 }, + { 135000, 0x0742, 0x820405 }, + { 148500, 0x0853, 0x85000B }, + { 155800, 0x0857, 0xCD0011 }, + { 157500, 0x422C, 0x8D000B },/* couldn't generate*/ + { 161793, 0x4571, 0 }, + { 162000, 0x0A71, 0x6F0008 }, + { 175500, 0x4231, 0xCE000F }, + { 189000, 0x0542, 0xB7000C }, + { 202500, 0x0763, 0x6F0006 }, + { 204800, 0x0764, 0x620005 }, + { 218300, 0x043D, 0x870007 }, + { 229500, 0x0660, 0x8E0007 },/* couldn't generate */ + { 0, 0, 0 }, +}; + +/* + * + * Panel + * + */ +/* + * Since mode->PrivFlags is overwritten to support the antique Tseng + * this is the only way to flag a selfdefined mode as such. + */ +struct ViaModePriv { + char id[12]; /* "Unichrome" */ +}; + +static struct ViaModePriv ViaPanelPrivate = { + { 'U', 'n', 'i', 'c', 'h', 'r', 'o', 'm', 'e', 0, 0, 0 }, +}; + +#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT +#define MODESUFFIX 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct ViaModePriv),(void *)&ViaPanelPrivate,0,0.0,0.0 + +static DisplayModeRec ViaPanelModes[] = { + { MODEPREFIX("640x480"), 25312, 640, 656, 752, 800, 0, 480, 489, 491, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, + { MODEPREFIX("800x600"), 39822, 800, 840, 968, 1056, 0, 600, 600, 604, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x768"), 65028, 1024, 1048, 1184, 1344, 0, 768, 770, 776, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, + { MODEPREFIX("1152x864"), 81613, 1152, 1216, 1336, 1520, 0, 864, 864, 867, 895, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1280x1024"), 108280, 1280, 1328, 1440, 1688, 0, 1024, 1024, 1027, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1600x1200"), 161793, 1600, 1664, 1856, 2160, 0, 1200, 1200, 1203, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1280x768"), 81135, 1280, 1328, 1440, 1688, 0, 768, 770, 776, 802, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, + { MODEPREFIX("1280x960"), 108280, 1280, 1376, 1488, 1800, 0, 960, 960, 963, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("848x480"), 33750, 848, 864, 976, 1088, 0, 480, 485, 493, 517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1400x1050"), 122726, 1400, 1488, 1640, 1880, 0, 1050, 1050, 1053, 1087, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("720x480"), 26591, 720, 736, 808, 896, 0, 480, 480, 483, 497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("720x576"), 32663, 720, 744, 816, 912, 0, 576, 576, 579, 597, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x512"), 41164, 1024, 1056, 1160, 1296, 0, 512, 512, 515, 531, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("856x480"), 31704, 856, 872, 960, 1064, 0, 480, 480, 483, 497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x576"), 46981, 1024, 1064, 1168, 1312, 0, 576, 576, 579, 597, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX }, +}; + +#define VIA_RES_640X480 0 +#define VIA_RES_800X600 1 +#define VIA_RES_1024X768 2 +#define VIA_RES_1152X864 3 +#define VIA_RES_1280X1024 4 +#define VIA_RES_1600X1200 5 +#define VIA_RES_1440X1050 6 +#define VIA_RES_1280X768 7 +#define VIA_RES_1280X960 8 +#define VIA_RES_1920X1440 9 +#define VIA_RES_848X480 10 +#define VIA_RES_1400X1050 11 +#define VIA_RES_720X480 12 +#define VIA_RES_720X576 13 +#define VIA_RES_1024X512 14 +#define VIA_RES_856X480 15 +#define VIA_RES_1024X576 16 +#define VIA_RES_INVALID 0xFF + +/* + * simple lookuptable for PanelIndex selection + */ + +static struct { + int Index; + int PanelIndex; + int X; + int Y; +} ViaResolutionTable[] = { + {VIA_RES_640X480, VIA_PANEL6X4, 640, 480}, + {VIA_RES_800X600, VIA_PANEL8X6, 800, 600}, + {VIA_RES_1024X768, VIA_PANEL10X7, 1024, 768}, + {VIA_RES_1152X864, VIA_PANEL_INVALID, 1152, 864}, + {VIA_RES_1280X1024, VIA_PANEL12X10, 1280, 1024}, + {VIA_RES_1600X1200, VIA_PANEL16X12, 1600, 1200}, + {VIA_RES_1440X1050, VIA_PANEL_INVALID, 1440, 1050}, + {VIA_RES_1280X768, VIA_PANEL12X7, 1280, 768}, + {VIA_RES_1280X960, VIA_PANEL_INVALID, 1280, 960}, + /* {VIA_RES_1920X1440, VIA_PANEL_INVALID, 1920, 1140}, */ + {VIA_RES_848X480, VIA_PANEL_INVALID, 848, 480}, + {VIA_RES_1400X1050, VIA_PANEL14X10, 1400, 1050}, + {VIA_RES_720X480, VIA_PANEL_INVALID, 720, 480}, + {VIA_RES_720X576, VIA_PANEL_INVALID, 720, 576}, + {VIA_RES_1024X512, VIA_PANEL_INVALID, 1024, 512}, + {VIA_RES_856X480, VIA_PANEL_INVALID, 856, 480}, + {VIA_RES_1024X576, VIA_PANEL_INVALID, 1024, 576}, + {VIA_RES_INVALID, VIA_PANEL_INVALID, 0, 0} +}; + +static struct { + CARD16 Width; + CARD16 Height; + CARD8 mode_8b; + CARD8 mode_16b; + CARD8 mode_32b; +} ViaVesaModes[] = { + { 400, 300, 0x22, 0x23, 0x24 }, + { 512, 384, 0x25, 0x26, 0x27 }, + { 640, 400, 0x30, 0x2E, 0x2F }, + { 640, 480, 0x31, 0x33, 0x34 }, + { 800, 600, 0x36, 0x38, 0x39 }, + { 1024, 768, 0x3B, 0x3D, 0x3E }, + { 1152, 864, 0x40, 0x42, 0x43 }, + { 1280, 1024, 0x45, 0x47, 0x48 }, + { 1600, 1200, 0x4A, 0x4C, 0x4D }, + { 1440, 1050, 0x50, 0x52, 0x53 }, + { 1280, 768, 0x54, 0x56, 0x57 }, + { 1280, 960, 0x58, 0x5A, 0x5B }, + { 320, 200, 0x5C, 0x5D, 0x5E }, + { 1920, 1440, 0x60, 0x61, 0x62 }, + { 848, 480, 0x63, 0x64, 0x65 }, + { 1400, 1050, 0x66, 0x67, 0x68 }, + { 720, 480, 0x70, 0x71, 0x72 }, + { 720, 576, 0x73, 0x74, 0x75 }, + { 1024, 512, 0x76, 0x77, 0x78 }, + { 856, 480, 0x79, 0x7A, 0x7B }, + { 320, 240, 0x7C, 0x7D, 0x7E }, + { 0, 0, 0, 0, 0 }, +}; + +#define VIA_BIOS_REG_LCD_MAX_NUM 48 +#define VIA_BIOS_NUM_LCD_SUPPORT_MASK 8 +#define VIA_BIOS_NUM_PANEL 7 +#define VIA_BIOS_MAX_NUM_MPATCH2 18 +#define VIA_BIOS_MAX_NUM_MPATCH1 9 +#define VIA_BIOS_MAX_NUM_CTREXP 5 + +typedef struct _VIALCDMODEENTRY { + CARD16 LCDClk; + CARD16 VClk; + CARD16 LCDClk_12Bit; + CARD16 VClk_12Bit; + CARD8 port[VIA_BIOS_REG_LCD_MAX_NUM]; + CARD8 offset[VIA_BIOS_REG_LCD_MAX_NUM]; + CARD8 data[VIA_BIOS_REG_LCD_MAX_NUM]; + int numEntry; +} VIALCDModeEntry, *VIALCDModeEntryPtr; + + +typedef struct _VIALCDMPATCHENTRY { + CARD8 Mode; + CARD16 LCDClk; + CARD16 VClk; + CARD16 LCDClk_12Bit; + CARD16 VClk_12Bit; + CARD8 port[VIA_BIOS_REG_LCD_MAX_NUM]; + CARD8 offset[VIA_BIOS_REG_LCD_MAX_NUM]; + CARD8 data[VIA_BIOS_REG_LCD_MAX_NUM]; + int numEntry; +} VIALCDMPatchEntry, *VIALCDMPatchEntryPtr; + + +typedef struct _VIALCDMODETABLE { + CARD8 fpIndex; + CARD8 fpSize; + CARD8 powerSeq; + int numMPatchDP2Ctr; + int numMPatchDP2Exp; + int numMPatchDP1Ctr; + int numMPatchDP1Exp; + CARD16 SuptMode[VIA_BIOS_NUM_LCD_SUPPORT_MASK]; + VIALCDModeEntry FPconfigTb; + VIALCDModeEntry InitTb; + VIALCDMPatchEntry MPatchDP2Ctr[VIA_BIOS_MAX_NUM_MPATCH2]; + VIALCDMPatchEntry MPatchDP2Exp[VIA_BIOS_MAX_NUM_MPATCH2]; + VIALCDMPatchEntry MPatchDP1Ctr[VIA_BIOS_MAX_NUM_MPATCH1]; + VIALCDMPatchEntry MPatchDP1Exp[VIA_BIOS_MAX_NUM_MPATCH1]; + VIALCDModeEntry LowResCtr; + VIALCDModeEntry LowResExp; + VIALCDModeEntry MCtr[VIA_BIOS_MAX_NUM_CTREXP]; + VIALCDModeEntry MExp[VIA_BIOS_MAX_NUM_CTREXP]; +} VIALCDModeTableRec, *VIALCDModePtr; + +static const VIALCDModeTableRec lcdTable[] = { + { 0, 0, 0X1, 13, 13, 5, 5, + { 0XE0FF, 0XF, 0XC0FC, 0X1B, 0, 0X7000, 0, 0X7000 }, + { 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7A, 0X7B, 0X7C, 0X7D, 0X7E, 0X7F, 0X80, 0X81, 0X82, 0X83, 0X84, 0X85, 0X86, 0X87, 0X88, 0X89, 0X8A, 0X8B, 0X8C, 0X8D, 0X8E, 0X8F, 0X90, 0X68, 0X69, 0X92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X2, 0X3, 0X4, 0X7, 0XA, 0XD, 0X13, 0X16, 0X19, 0X1C, 0X1D, 0X1E, 0X1F, 0, 0, 0X88, 0XD, 0X5D, 0X79, 0XFF, 0X10, 0XB, 0X67, 0, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 26 }, + { 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X7F, 0X7F, 0X1F, 0X9A, 0X23, 0X87, 0XE7, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XE1, 0X23, 0XA0, 0X50, 0, 0X5F, 0X63, 0XB, 0XDF, 0X12, 0XDF, 0XC, 0X12, 0XE2, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0X2, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X6, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XD, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0XE, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XF, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X10, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X13, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X5C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XC7, 0X53, 0X80, 0X9, 0X2, 0X55, 0X37, 0X50, 0XC7, 0X2, 0XC7, 0X2, 0X56, 0X18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XEF, 0X67, 0X94, 0X9, 0X2, 0X69, 0X2B, 0X50, 0XEF, 0X2, 0XEF, 0X2, 0X6A, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X7, 0XA7, 0X92, 0X13, 0XF, 0X6F, 0X2B, 0X85, 0XB2, 0X9, 0XA, 0X87, 0X29, 0X64, 0X2B, 0X2B, 0X88, 0X1A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 19 }, + { 0X25, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X3F, 0XDF, 0X92, 0X13, 0X47, 0XA7, 0X7F, 0XAF, 0XDC, 0X9, 0XA, 0XB1, 0X34, 0X80, 0X7F, 0X7F, 0XB2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0X2, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X6, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XD, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0XE, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XF, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X10, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X13, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X5C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XC7, 0X53, 0X80, 0X9, 0X2, 0X55, 0X37, 0X50, 0XC7, 0X2, 0XC7, 0X2, 0X56, 0X18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XEF, 0X67, 0X94, 0X9, 0X2, 0X69, 0X2B, 0X50, 0XEF, 0X2, 0XEF, 0X2, 0X6A, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X7, 0XA7, 0X92, 0X13, 0XF, 0X6F, 0X2B, 0X85, 0XB2, 0X9, 0XA, 0X87, 0X29, 0X64, 0X2B, 0X2B, 0X88, 0X1A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 19 }, + { 0X25, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X3F, 0XDF, 0X92, 0X13, 0X47, 0XA7, 0X7F, 0XAF, 0XDC, 0X9, 0XA, 0XB1, 0X34, 0X80, 0X7F, 0X7F, 0XB2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2, 0, 0, 0, 0, { 0XC4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X11, 0X4, 0X5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X6E, 0X52, 0X9E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 4 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X3D, 0X89, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X3D, 0X89, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2, 0, 0, 0, 0, { 0XC4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X11, 0X4, 0X5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X6E, 0X52, 0X9E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 4 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X3D, 0X89, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X3D, 0X89, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + } + }, + { 0X1, 0X1, 0X1, 14, 13, 4, 4, + { 0XE0FF, 0XF, 0XC1FC, 0X37B, 0, 0X7000, 0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X1F, 0X1F, 0X1F, 0XE3, 0X34, 0X47, 0XC7, 0X73, 0X57, 0X57, 0X73, 0X52, 0X12, 0X58, 0X5C, 0XC8, 0X6E, 0, 0X7F, 0X83, 0X72, 0X57, 0X22, 0X57, 0X73, 0X22, 0X59, 0X2D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X65, 0X66, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X25, 0XCF, 0XF7, 0XF7, 0XDA, 0X1F, 0X9F, 0XB4, 0X6E, 0X36, 0X3A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X2, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XF3, 0XF, 0X51, 0XF4, 0X38, 0XA2, 0X7F, 0X83, 0X8F, 0X8F, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 13 }, + { 0X6, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XF3, 0XF, 0X51, 0XF4, 0X38, 0X8F, 0X8F, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XD, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XE, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XF3, 0XF, 0X51, 0XF4, 0X38, 0X8F, 0X8F, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XF, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XDA, 0XF6, 0X49, 0XDB, 0X3F, 0X5D, 0X5D, 0XDC, 0X10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X10, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XDA, 0XF6, 0X49, 0XDB, 0X3F, 0XA2, 0X5D, 0X5D, 0XDC, 0X10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X13, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XF3, 0XF, 0X51, 0XF4, 0X38, 0XA2, 0X8F, 0X8F, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X28, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1C, 0XCF, 0XF7, 0XF7, 0XDA, 0X1F, 0X9F, 0XB4, 0X70, 0X74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XF3, 0XF, 0X51, 0XF4, 0X38, 0X8F, 0X8F, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X5C, 0XC459, 0XC459, 0XC259, 0XC259, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X2F, 0X2F, 0X14, 0X57, 0XD7, 0XC7, 0X8F, 0XAB, 0X9, 0X2, 0X90, 0X34, 0X50, 0XC7, 0X2, 0XC7, 0X2, 0X91, 0X15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 20 }, + { 0X7C, 0XC459, 0XC459, 0XC259, 0XC259, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X2F, 0X2F, 0X14, 0X57, 0XD7, 0XEF, 0XA3, 0XBF, 0X9, 0X2, 0XA4, 0X28, 0X50, 0XEF, 0X2, 0XEF, 0X2, 0XA5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 20 }, + { 0X22, 0XC459, 0XC459, 0XC259, 0XC259, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X57, 0X57, 0X14, 0X7F, 0XFF, 0X2B, 0XC1, 0XDD, 0X9, 0XC2, 0X26, 0X64, 0X2B, 0X2B, 0XC3, 0X17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0X25, 0XC459, 0XC459, 0XC259, 0XC259, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X8F, 0X8F, 0X14, 0XB7, 0X37, 0X7F, 0XEB, 0X7, 0X51, 0XEC, 0X30, 0X80, 0X7F, 0X7F, 0XED, 0X11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X8643, 0X86B9, 0X4643, 0X46B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X21, 0X21, 0XB4, 0X66, 0X98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 }, + { 0X2, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X66, 0X6D, 0X6E, 0X6F, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X2F, 0X2F, 0X73, 0X61, 0X65, 0X72, 0X33, 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X6, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XE, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XF, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X54, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X10, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X54, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X13, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X28, 0X8643, 0X86B9, 0X4643, 0X46B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X21, 0X21, 0XB4, 0X72, 0X98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 }, + { 0X30, 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X5C, 0XC459, 0XC7BB, 0XC259, 0XC776, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X1F, 0X50, 0X5A, 0X2D, 0X31, 0X98, 0X54, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X7C, 0XC459, 0XC7BB, 0XC259, 0XC776, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X1F, 0X50, 0X55, 0X2D, 0X31, 0X98, 0X98, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X22, 0XC459, 0XC643, 0XC259, 0X8643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1B, 0X1B, 0X64, 0X5A, 0X3D, 0X41, 0, 0, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X25, 0XC459, 0X4511, 0XC259, 0X8544, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X23, 0X23, 0X80, 0X61, 0X4C, 0X50, 0X8E, 0X8E, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X4B, 0X9B, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X4B, 0X9B, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XCF, 0XCF, 0X9A, 0X24, 0XF7, 0X77, 0X8F, 0XF3, 0XF, 0X51, 0XA, 0XF4, 0X38, 0XA0, 0X68, 0X3D, 0X41, 0X8F, 0X12, 0X8F, 0X12, 0XF5, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 24 }, + { 0X8643, 0X86B2, 0X4643, 0X46B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X2F, 0X2F, 0XA0, 0X5F, 0X2D, 0X31, 0X32, 0XAA, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { + { 0X8643, 0X8643, 0X4643, 0X4643, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XCF, 0XCF, 0X9A, 0X24, 0XF7, 0X77, 0XDF, 0X1B, 0X37, 0XA, 0X1C, 0X40, 0XA0, 0XDF, 0X12, 0XDF, 0X12, 0X1D, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 20 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X8643, 0X86B3, 0X4643, 0X46B3, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1A, 0X1A, 0XA0, 0X5F, 0X63, 0X33, 0X32, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + } + }, + { 0X2, 0X2, 0X1, 13, 14, 4, 4, + { 0XE0FF, 0XF, 0XC1FC, 0X6F7B, 0, 0X7000, 0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XFF, 0XFF, 0X3F, 0X2B, 0X35, 0X17, 0X9F, 0X25, 0XFF, 0XFF, 0X25, 0X9A, 0X13, 0, 0X62, 0, 0X96, 0X4, 0XA3, 0XA7, 0X24, 0XFF, 0X23, 0XFF, 0X25, 0X23, 0X3, 0X39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X5C, 0X65, 0X66, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X45, 0XCF, 0X67, 0XA7, 0XE3, 0X7F, 0X7, 0X12, 0XB4, 0X87, 0X46, 0X4A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 }, + { 0X2, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X66, 0X70, 0X72, 0X73, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X84, 0XD4, 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0XA2, 0XA0, 0X8E, 0X8E, 0X6E, 0X12, 0X4A, 0X20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 15 }, + { 0X6, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XE, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XF, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X2E, 0X54, 0X31, 0X57, 0X5D, 0X5D, 0X32, 0X28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X10, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X2E, 0X54, 0X31, 0X57, 0XA2, 0X5D, 0X5D, 0X32, 0X28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X13, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0XA2, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X28, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X56, 0X57, 0X5C, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X45, 0XCF, 0X67, 0XA7, 0X7F, 0X7, 0X12, 0XB4, 0X91, 0X95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X5C, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X9F, 0XDF, 0X9A, 0X15, 0XB7, 0X3F, 0XC7, 0XE3, 0X9, 0X51, 0X3, 0XE6, 0X2C, 0X50, 0XC7, 0X3, 0XC7, 0X3, 0XE7, 0X1D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X9F, 0XDF, 0X9A, 0X15, 0XB7, 0X3F, 0XEF, 0XF7, 0X1D, 0X51, 0X3, 0XFA, 0X20, 0X50, 0XEF, 0X3, 0XEF, 0X3, 0XFB, 0X11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0X7, 0XA2, 0X15, 0XDF, 0X67, 0X2B, 0X15, 0X3B, 0X18, 0X5E, 0X64, 0X2B, 0X2B, 0X19, 0X2F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0X25, 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0XFF, 0X3F, 0XE2, 0X15, 0X17, 0X9F, 0X7F, 0X3F, 0X65, 0X42, 0X48, 0X80, 0X7F, 0X7F, 0X43, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X86ED, 0X875A, 0X46ED, 0X475A, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X43, 0X43, 0XB4, 0X82, 0X30, 0X34, 0XD0, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X2, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X73, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0X62, 0XA2, 0XFE, 0XFE, 0X24, 0X80, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X6, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XD, 0X86ED, 0XC5ED, 0X46ED, 0X85ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X66, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X4F, 0X4F, 0X82, 0X2E, 0X32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 }, + { 0XE, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XF, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0XD2, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 3 }, + { 0X10, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X80, 0XD2, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 4 }, + { 0X13, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X80, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 3 }, + { 0X28, 0X86ED, 0X472B, 0X46ED, 0X72B, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X3F, 0XB4, 0X87, 0XD0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 }, + { 0X30, 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0X86ED, 0XC5B5, 0X46ED, 0X85B5, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X3F, 0X50, 0X78, 0X2C, 0X30, 0X40, 0XA, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X7C, 0X86ED, 0XC5B5, 0X46ED, 0X85B5, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X3F, 0X50, 0X7C, 0X2C, 0X30, 0X40, 0X40, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X22, 0X86ED, 0XC4B9, 0X46ED, 0X84B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X41, 0X41, 0X64, 0X73, 0X3D, 0X41, 0X90, 0X90, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X25, 0X86ED, 0XC447, 0X46ED, 0X8447, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3E, 0X3E, 0X80, 0X8E, 0X4D, 0X51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X57, 0X88, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X57, 0X88, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X3F, 0X7F, 0XE3, 0X25, 0X57, 0XDF, 0X8F, 0X47, 0X6D, 0X52, 0XB, 0X4A, 0X50, 0XA0, 0, 0X4F, 0X53, 0X8F, 0X13, 0X8F, 0X13, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 24 }, + { 0X86ED, 0X842B, 0X46ED, 0X442B, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X47, 0X47, 0XA0, 0X7D, 0, 0X2D, 0X31, 0X80, 0X10, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { + { 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X3F, 0X7F, 0XE3, 0X25, 0X57, 0XDF, 0XDF, 0X6F, 0X95, 0X52, 0XB, 0X72, 0X58, 0XA0, 0, 0XDF, 0X13, 0XDF, 0X13, 0X73, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X86ED, 0X86ED, 0X46ED, 0X46ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X8F, 0XCF, 0XE3, 0XA7, 0X2F, 0X57, 0XAB, 0XD1, 0X12, 0XAE, 0X54, 0XC8, 0, 0X57, 0X57, 0XAF, 0X25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X86ED, 0X874C, 0X46ED, 0X474C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X47, 0X47, 0XA0, 0X8C, 0, 0X60, 0X64, 0X81, 0X80, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X86ED, 0X84B9, 0X46ED, 0X44B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X37, 0X37, 0XC8, 0X8C, 0, 0X7E, 0X82, 0X21, 0X20, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + } + }, + { 0X3, 0X3, 0X1, 12, 13, 8, 4, + { 0XE0FF, 0XF, 0XC0FC, 0X6F7B, 0, 0X70D0, 0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X97, 0XFF, 0XFF, 0X97, 0X74, 0X46, 0X2F, 0X9F, 0X25, 0XFF, 0XFF, 0X25, 0XDA, 0X13, 0X2, 0X68, 0X40, 0XBE, 0X4, 0XCE, 0XD2, 0X24, 0XFF, 0X23, 0XFF, 0X25, 0X23, 0X3, 0X39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X5C, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9B, 0XCF, 0XE7, 0X7F, 0X2B, 0X17, 0X87, 0X92, 0XB4, 0X59, 0X5D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X2, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X52, 0X53, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0X4F, 0X8F, 0X47, 0X6D, 0X4A, 0X4B, 0XA2, 0XCD, 0XD1, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 15 }, + { 0X6, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XE, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XF, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X2E, 0X54, 0X31, 0X57, 0X5D, 0X5D, 0X32, 0X28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X10, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X2E, 0X54, 0X31, 0X57, 0XA2, 0X5D, 0X5D, 0X32, 0X28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X13, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0XA2, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0X6D, 0X4A, 0X50, 0X8F, 0X8F, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X5C, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X1F, 0XB7, 0XE3, 0X16, 0X4F, 0XBF, 0XC7, 0XE3, 0X9, 0X51, 0X3, 0XE6, 0X2C, 0X50, 0XC7, 0X3, 0XC7, 0X3, 0XE7, 0X1D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X1F, 0XB7, 0XE3, 0X16, 0X4F, 0XBF, 0XEF, 0XF7, 0X1D, 0X51, 0X3, 0XFA, 0X20, 0X50, 0XEF, 0X3, 0XEF, 0X3, 0XFB, 0X11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0XDF, 0XE3, 0X16, 0X77, 0XE7, 0X2B, 0X15, 0X3B, 0X52, 0X18, 0X5E, 0X64, 0X2B, 0X2B, 0X19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0X25, 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X7F, 0X17, 0X16, 0X1F, 0X1F, 0X7F, 0X3F, 0X65, 0X42, 0X48, 0X80, 0X7F, 0X7F, 0X43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 15 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X45B9, 0X853D, 0X5B9, 0X453D, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X91, 0XFF, 0XFF, 0X91, 0X74, 0X46, 0X2F, 0X9F, 0XFF, 0XFF, 0X25, 0XDA, 0X13, 0X2, 0X68, 0XB4, 0XA0, 0X2D, 0X31, 0XFF, 0X23, 0XFF, 0X23, 0X3, 0X39, 0X40, 0X14, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 28 }, + { 0X2, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA9, 0XA9, 0XA2, 0XB8, 0X60, 0X64, 0X1, 0X14, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X6, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X55, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X26, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XD, 0X45B9, 0XC5ED, 0X5B9, 0X85ED, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X66, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAA, 0XFF, 0XFF, 0XAA, 0X74, 0X46, 0X2F, 0X9F, 0XFF, 0XFF, 0X25, 0XDA, 0X13, 0X2, 0X68, 0XA0, 0X2E, 0X32, 0XFF, 0X23, 0XFF, 0X23, 0X3, 0X39, 0X10, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 26 }, + { 0XE, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X75, 0X76, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X4, 0X49, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 3 }, + { 0XF, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XD2, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X10, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X1, 0XD2, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 4 }, + { 0X13, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X67, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0, 0X1, 0X14, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 }, + { 0X30, 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0X45B9, 0X851B, 0X5B9, 0X85B6, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X8C, 0X2D, 0X31, 0XA, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X7C, 0X45B9, 0X851B, 0X5B9, 0X85B6, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X8C, 0X2D, 0X31, 0X40, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X22, 0X45B9, 0XC4B9, 0X5B9, 0X84B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X99, 0X99, 0X64, 0XB0, 0X3D, 0X41, 0X40, 0X90, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X25, 0X45B9, 0X471F, 0X5B9, 0X877C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0X4D, 0X51, 0X98, 0, 0X97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X29, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2A, 0, 0, 0, 0, { 0XD4, 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XC7, 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X2B, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2C, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X6A, 0X98, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X6A, 0X98, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9F, 0X7F, 0XBF, 0X57, 0XEB, 0X26, 0XEF, 0X5F, 0X8F, 0X47, 0X6D, 0X12, 0XB, 0X4A, 0X50, 0XA0, 0, 0X65, 0X69, 0X8F, 0X13, 0X8F, 0X13, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 25 }, + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9F, 0X7F, 0XBF, 0X57, 0XEB, 0X26, 0XEF, 0X5F, 0X8F, 0X47, 0X6D, 0X12, 0XB, 0X4A, 0X50, 0XA0, 0, 0X65, 0X69, 0X8F, 0X13, 0X8F, 0X13, 0X4B, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 25 }, + { + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XBF, 0X57, 0XEB, 0X26, 0XEF, 0X5F, 0XDF, 0X6F, 0X95, 0X12, 0XB, 0X72, 0X58, 0XA0, 0, 0XDF, 0X13, 0XDF, 0X13, 0X73, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0XF, 0XA7, 0X2C, 0X36, 0X3F, 0XAF, 0X57, 0XAB, 0XD1, 0X92, 0XAE, 0X54, 0XC8, 0, 0X57, 0X57, 0XAF, 0X25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 19 }, + { 0X45B9, 0X45B9, 0X5B9, 0X5B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X17, 0X34, 0X36, 0XAF, 0X1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X45B9, 0X451B, 0X5B9, 0X51B, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA9, 0XA9, 0XA0, 0XB8, 0, 0X60, 0X64, 0, 0X80, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X45B9, 0X84B9, 0X5B9, 0X44B9, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0XBF, 0XC8, 0XBB, 0, 0X82, 0X86, 0X80, 0X20, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X45B9, 0X8448, 0X5B9, 0X4448, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X65, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X87, 0XFF, 0XFF, 0X87, 0X74, 0X46, 0X2F, 0X9F, 0, 0, 0, 0XC3, 0X1B, 0, 0XA0, 0XA4, 0, 0X33, 0, 0X33, 0X34, 0XFF, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 23 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + } + }, + { 0X4, 0X4, 0X1, 14, 15, 8, 4, + { 0XE0FF, 0XF, 0XC0FC, 0X6F7B, 0X1B0, 0X7DD0, 0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X97, 0XFF, 0XFF, 0X97, 0X74, 0X46, 0X2F, 0X9F, 0X29, 0XFF, 0XFF, 0X29, 0XE3, 0X1C, 0, 0X83, 0X40, 0XBE, 0X4, 0XCE, 0XD2, 0X28, 0XFF, 0X34, 0XFF, 0X29, 0X34, 0X1, 0X44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X5C, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9B, 0XCF, 0XE7, 0X7F, 0X2B, 0X17, 0X87, 0X92, 0XB4, 0X59, 0X5D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X2, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0XF1, 0X12, 0XC8, 0X4B, 0XA2, 0X8F, 0X8F, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X6, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0XF1, 0X12, 0XC8, 0X4B, 0X8F, 0X8F, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XE, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0XF1, 0X12, 0XC8, 0X4B, 0X8F, 0X8F, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XF, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XAE, 0XD8, 0X12, 0XAF, 0X52, 0X5D, 0X5D, 0XB0, 0X23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X10, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XAE, 0XD8, 0X12, 0XAF, 0X52, 0XA2, 0X5D, 0X5D, 0XB0, 0X23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X13, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0XF1, 0X12, 0XC8, 0X4B, 0XA2, 0X8F, 0X8F, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X30, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XC7, 0XF1, 0X12, 0XC8, 0X4B, 0X8F, 0X8F, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X54, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X71, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XA9, 0XDB, 0X14, 0X80, 0X63, 0X24, 0X24, 0X81, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X58, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0XDF, 0X9, 0XE0, 0X63, 0XBF, 0XBF, 0XE1, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X5C, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X1F, 0XB7, 0XE3, 0X16, 0X4F, 0XBF, 0XC7, 0X63, 0X8D, 0X52, 0X4, 0X64, 0X47, 0X50, 0XC7, 0X4, 0XC7, 0X4, 0X65, 0X28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X1F, 0XB7, 0XE3, 0X16, 0X4F, 0XBF, 0XEF, 0X77, 0XA1, 0X52, 0X4, 0X78, 0X5B, 0X50, 0XEF, 0X4, 0XEF, 0X4, 0X79, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X47, 0XDF, 0XE3, 0X16, 0X77, 0XE7, 0X2B, 0X95, 0XBF, 0X52, 0X96, 0X59, 0X64, 0X2B, 0X2B, 0X97, 0X2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X25, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X7F, 0X17, 0X16, 0XAF, 0X1F, 0X7F, 0XBF, 0XE9, 0X12, 0XC0, 0X43, 0X80, 0X7F, 0X7F, 0XC1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 16 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X8479, 0X8663, 0X4479, 0X4441, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X92, 0X92, 0XB4, 0XA8, 0X2E, 0X32, 0X40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0X2, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0XBF, 0XA2, 0XB5, 0X61, 0X65, 0X1, 0X90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X6, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XAE, 0X90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0XD, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XE, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XF, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X10, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X5E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X13, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X30, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X54, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X71, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XA9, 0XDB, 0X14, 0X80, 0X63, 0X24, 0X24, 0X81, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X58, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0XDF, 0X9, 0XE0, 0X63, 0XBF, 0XBF, 0XE1, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X5C, 0X8479, 0X4719, 0X4479, 0X87E4, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X82, 0X2D, 0X31, 0XC8, 0X17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X7C, 0X8479, 0X4719, 0X4479, 0X87E4, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X82, 0X2D, 0X31, 0XF0, 0X17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X22, 0X8479, 0X4721, 0X4479, 0X4742, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X64, 0X3D, 0X41, 0X40, 0X2C, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X25, 0X8479, 0X4729, 0X4479, 0X4752, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0X4D, 0X51, 0X98, 0X7F, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X29, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2A, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2B, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2C, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X6A, 0X98, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X6A, 0X98, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9F, 0X7F, 0XBF, 0X57, 0XEB, 0X26, 0XEF, 0X5F, 0X8F, 0XC7, 0XF1, 0X12, 0XC, 0XC8, 0X4B, 0XA0, 0, 0X65, 0X69, 0X8F, 0X14, 0X8F, 0X14, 0XC9, 0X2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 25 }, + { 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XA0, 0X91, 0, 0X2D, 0X31, 0X90, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XBF, 0X57, 0XEB, 0X26, 0XEF, 0X5F, 0XDF, 0XEF, 0X19, 0X1A, 0XC, 0XF0, 0X53, 0XA0, 0, 0XDF, 0X14, 0XDF, 0X14, 0XF1, 0X24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0XF, 0XA7, 0X2C, 0X36, 0X3F, 0XAF, 0X57, 0X2B, 0X55, 0X9B, 0X14, 0X2C, 0X6F, 0XC8, 0, 0X57, 0X24, 0X57, 0X24, 0X2D, 0X30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X71, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X17, 0X34, 0X36, 0XAF, 0X1F, 0X7F, 0XA9, 0XDB, 0X14, 0X80, 0X63, 0, 0X24, 0X24, 0X81, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XA0, 0XAA, 0, 0X5F, 0X63, 0XE0, 0X67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X8479, 0X721, 0X4479, 0X742, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XC8, 0, 0X7F, 0X83, 0X81, 0X58, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X8479, 0X51E, 0X4479, 0X53C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X6D, 0X6E, 0X77, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0, 0XA3, 0XA7, 0X34, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + } + }, + { 0X5, 0X5, 0X1, 14, 14, 8, 10, + { 0XE0FF, 0XF, 0XC0FC, 0X6F7B, 0X1B0, 0X7DD0, 0X1C0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X97, 0X77, 0X77, 0X97, 0X75, 0X56, 0XA7, 0X17, 0X29, 0X19, 0X19, 0X29, 0XA4, 0X24, 0X1A, 0X9D, 0X5E, 0XBE, 0X4, 0XCE, 0XD2, 0X28, 0X19, 0X44, 0X19, 0X29, 0X44, 0X1B, 0X4E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9B, 0XCF, 0X23, 0X43, 0X2C, 0X53, 0XC3, 0XB4, 0X59, 0X5D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X2, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X8F, 0XD4, 0XE4, 0X92, 0XD5, 0X58, 0XA2, 0XCD, 0XD1, 0X8F, 0X8F, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 14 }, + { 0X6, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X66, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XD4, 0XE4, 0X92, 0XD5, 0X58, 0XC3, 0X8F, 0X8F, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0XE, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XD4, 0XE4, 0X92, 0XD5, 0X58, 0X8F, 0X8F, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0XF, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XBB, 0XCB, 0X92, 0XBC, 0X5F, 0X5D, 0X5D, 0XBD, 0X20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X10, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0XBB, 0XCB, 0X92, 0XBC, 0X5F, 0XA2, 0X5D, 0X5D, 0XBD, 0X20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X13, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XD4, 0XE4, 0X92, 0XD5, 0X58, 0XA2, 0X8F, 0X8F, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X30, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XD4, 0XE4, 0X92, 0XD5, 0X58, 0X8F, 0X8F, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X54, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X71, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8C, 0X9C, 0XDB, 0X14, 0X8D, 0X70, 0X24, 0X24, 0X8E, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X58, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0XEC, 0XFC, 0XDB, 0XED, 0X70, 0XBF, 0XBF, 0XEE, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X5C, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X5B, 0X7B, 0XE3, 0X16, 0X8B, 0XFB, 0XC7, 0X70, 0X80, 0X52, 0X4, 0X71, 0X54, 0X50, 0XC7, 0X4, 0XC7, 0X4, 0X72, 0X25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X5B, 0X7B, 0XE3, 0X16, 0X8B, 0XFB, 0XEF, 0X84, 0X94, 0X52, 0X4, 0X85, 0X48, 0X50, 0XEF, 0X4, 0XEF, 0X4, 0X86, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X83, 0XA3, 0XE3, 0X16, 0XB3, 0X23, 0X2B, 0XA2, 0XB2, 0X12, 0XA3, 0X46, 0X64, 0X2B, 0X2B, 0XA4, 0X27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X25, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0XBB, 0XDB, 0XE3, 0X16, 0XEB, 0X5B, 0X7F, 0XCC, 0XDC, 0X12, 0XCD, 0X50, 0X80, 0X7F, 0X7F, 0XCE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 17 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X6, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XE, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XF, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X10, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X13, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X30, 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X54, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XCA, 0XEC, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 3 }, + { 0X58, 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X66, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XCA, 0XA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X5C, 0X8479, 0X4719, 0X4479, 0X87E4, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X8C, 0X2D, 0X31, 0XEA, 0XC2, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0X7C, 0X8479, 0X4719, 0X4479, 0X87E4, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X8C, 0X2D, 0X31, 0XEA, 0XEA, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0X22, 0X8479, 0X4721, 0X4479, 0X4742, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X64, 0XAA, 0X3D, 0X41, 0X24, 0X24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0X25, 0X8479, 0X4729, 0X4479, 0X4752, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X80, 0XAA, 0X4D, 0X51, 0X76, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 6 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X29, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2A, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2B, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2C, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X71, 0X9F, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X71, 0X9F, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X28, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X29, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2A, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2B, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X2C, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6C, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0XDE, 0X10, 0X40, 0XC9, 0XEC, 0XC7, 0XC7, 0XDF, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X11, 0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6, 0X7, 0X9, 0X10, 0X11, 0X12, 0X15, 0X16, 0X33, 0X35, 0X36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7, 0X2D, 0X27, 0X27, 0X91, 0X2A, 0X90, 0X5, 0X11, 0X40, 0XF5, 0X87, 0XEF, 0XEF, 0X6, 0X6, 0, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 } + }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9F, 0X7F, 0XFB, 0X1B, 0X2B, 0X26, 0X2B, 0X9B, 0X8F, 0XD4, 0XE4, 0X92, 0XC, 0XD5, 0X58, 0XA0, 0, 0X65, 0X69, 0X8F, 0X14, 0X8F, 0X14, 0XD6, 0X29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 25 }, + { 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XA0, 0XA0, 0, 0X2D, 0X31, 0XD4, 0X86, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0XFB, 0X1B, 0X2B, 0X26, 0X2B, 0X9B, 0XDF, 0XFC, 0XC, 0X9A, 0XC, 0XFD, 0X40, 0XA0, 0, 0XDF, 0X14, 0XDF, 0X14, 0XFE, 0X21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X4B, 0X6B, 0X2C, 0X36, 0X7B, 0XEB, 0X57, 0X38, 0X48, 0X9B, 0X14, 0X39, 0X7C, 0XC8, 0, 0X57, 0X24, 0X57, 0X29, 0X24, 0X3A, 0X3D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 23 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0XBB, 0XDB, 0X2C, 0X36, 0XEB, 0X5B, 0XFF, 0X8C, 0X9C, 0XDB, 0X14, 0X8D, 0X70, 0, 0XFF, 0X24, 0XFF, 0X24, 0X8E, 0X31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X3B, 0X5B, 0X46, 0X6B, 0XDB, 0XFF, 0XC, 0X1C, 0XE4, 0X1C, 0XD, 0X90, 0X40, 0XFF, 0X34, 0XFF, 0X34, 0XE, 0X41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 20 } + }, + { + { 0X8479, 0X719, 0X4479, 0X7B2, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XA0, 0, 0X5F, 0X63, 0XD4, 0XD4, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X8479, 0X721, 0X4479, 0X742, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X67, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0XC8, 0, 0X7F, 0X83, 0X48, 0X48, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X8479, 0X51E, 0X4479, 0X53C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X53, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9D, 0X9D, 0, 0XC3, 0XA3, 0XA7, 0XEC, 0XEC, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X8479, 0X8479, 0X4479, 0X4479, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X66, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X40, 0XC9, 0XA8, 0XE6, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 5 } + } + }, + { 0X6, 0X6, 0X1, 15, 15, 4, 4, + { 0XE0FF, 0XF, 0XC0FC, 0X6F7B, 0X37B0, 0X7DDD, 0X1C0, 0X7000 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6F, 0X3F, 0X3F, 0, 0X86, 0X68, 0X7F, 0X3F, 0XE1, 0XAF, 0XAF, 0XE1, 0XE4, 0X24, 0XB0, 0X93, 0X90, 0XFA, 0X4, 0X9, 0XD, 0XE0, 0XAF, 0X4C, 0XAF, 0XE1, 0X44, 0XB1, 0X44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 }, + { + { 0, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X56, 0X57, 0X65, 0X6D, 0X6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XCF, 0X87, 0XB7, 0X34, 0XC7, 0X87, 0XB4, 0X73, 0X77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X2, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X55, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA8, 0X8F, 0X1F, 0X51, 0X20, 0X73, 0XA2, 0X8F, 0X8F, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 11 }, + { 0X6, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X1F, 0X51, 0X20, 0X63, 0X8F, 0X8F, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XE, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X1F, 0X51, 0X20, 0X63, 0X8F, 0X8F, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0XF, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X6, 0X38, 0X7, 0X6A, 0X5D, 0X5D, 0X8, 0X3B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X10, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X6, 0X38, 0X7, 0X6A, 0XA2, 0X5D, 0X5D, 0X8, 0X3B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X13, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X1F, 0X51, 0X20, 0X63, 0XA2, 0X8F, 0X8F, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X30, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X1F, 0X51, 0X20, 0X63, 0X8F, 0X8F, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0X54, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X71, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XD7, 0X9, 0XA3, 0X14, 0XD8, 0X7B, 0X2C, 0X24, 0XD9, 0X3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X58, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5E, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XBF, 0X37, 0X69, 0X38, 0XBF, 0XBF, 0X39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0X5C, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XBF, 0XEF, 0XEB, 0X18, 0XFF, 0XBF, 0XC7, 0XBB, 0XED, 0X12, 0X4, 0XBC, 0X5F, 0X50, 0XC7, 0XC, 0XC7, 0X4, 0XBD, 0X20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X7C, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XBF, 0XEF, 0XEB, 0X18, 0XFF, 0XBF, 0XEF, 0XCF, 0X1, 0X1A, 0X4, 0XD0, 0X53, 0X50, 0XEF, 0XC, 0XEF, 0X4, 0XD1, 0X24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0X22, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XE7, 0X17, 0X33, 0X18, 0X27, 0XE7, 0X2B, 0XED, 0X1F, 0X9A, 0XC, 0XEE, 0X51, 0X64, 0X2B, 0X2B, 0XEF, 0X22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 19 }, + { 0X25, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X1F, 0X4F, 0X18, 0X5F, 0X1F, 0X7F, 0X17, 0X49, 0X18, 0X7B, 0X80, 0X7F, 0X7F, 0X19, 0X3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 16 }, + { 0X66, 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X77, 0XDB, 0XFF, 0XBD, 0X58, 0X1B, 0XDB, 0X19, 0X64, 0X96, 0XA4, 0X65, 0X88, 0X5E, 0X19, 0X19, 0X66, 0X49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0, 0X4571, 0X8671, 0X571, 0X4671, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0X3F, 0, 0X86, 0X68, 0X7F, 0X3F, 0XAF, 0XAF, 0XE1, 0XE4, 0X24, 0XB0, 0X93, 0XB4, 0XBE, 0X2D, 0X31, 0XAF, 0X44, 0XAF, 0X44, 0XB1, 0X44, 0XCC, 0X54, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 27 }, + { 0X2, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X9A, 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 3 }, + { 0X6, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XE, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0XF, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X10, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X13, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XA2, 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X30, 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X54, 0X4571, 0X477C, 0X571, 0X77C, { 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8E, 0XB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 2 }, + { 0X58, 0X4571, 0X477C, 0X571, 0X77C, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0X4571, 0X873D, 0X571, 0X877A, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6D, 0X50, 0XC8, 0X2F, 0X33, 0XCC, 0XAA, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X7C, 0X4571, 0X873D, 0X571, 0X877A, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X6D, 0X50, 0XC8, 0X2F, 0X33, 0XCC, 0XCC, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X22, 0X4571, 0XC56F, 0X571, 0X856F, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0X64, 0XBE, 0X3D, 0X41, 0, 0, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X25, 0X4571, 0X8760, 0X571, 0X4760, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X6D, 0X6E, 0X77, 0X78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X71, 0X80, 0XC8, 0X4D, 0X51, 0X46, 0X46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 7 }, + { 0X66, 0X4571, 0X45E5, 0X571, 0X5E5, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X6D, 0X6E, 0X71, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X75, 0X5E, 0XED, 0XF1, 0X44, 0X80, 0X80, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { + { 0X2, 0, 0, 0, 0, { 0XC4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X5C, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X7C, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0X22, 0, 0, 0, 0, { 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 } + }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X5F, 0X8F, 0X34, 0X28, 0X9F, 0X5F, 0X8F, 0X1F, 0X51, 0XDB, 0XC, 0X20, 0X63, 0XA0, 0, 0X82, 0X86, 0X8F, 0X14, 0X8F, 0X14, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 24 }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X6D, 0X6E, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X5F, 0X8F, 0X34, 0X28, 0X9F, 0X5F, 0X8F, 0X1F, 0X51, 0XDB, 0XC, 0X20, 0X63, 0XA0, 0, 0X82, 0X86, 0X8F, 0X14, 0X8F, 0X14, 0X21, 0X34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 24 }, + { + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7F, 0X5F, 0X8F, 0X34, 0X28, 0X9F, 0X5F, 0XDF, 0X47, 0X79, 0XDB, 0XC, 0X48, 0X6B, 0XA0, 0, 0XDF, 0X1C, 0XDF, 0X14, 0X49, 0X3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X67, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0XAF, 0XDF, 0X34, 0X38, 0XEF, 0XAF, 0X57, 0X83, 0XB5, 0XDB, 0X14, 0X84, 0X67, 0XC8, 0, 0X57, 0X2C, 0X57, 0X24, 0X85, 0X38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X1F, 0X4F, 0X7D, 0X38, 0X5F, 0X1F, 0XFF, 0XD7, 0X9, 0XA3, 0X14, 0XD8, 0X7B, 0, 0XFF, 0X2C, 0XFF, 0X24, 0XD9, 0X3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X4571, 0X4571, 0X571, 0X571, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X9F, 0XCF, 0X7D, 0X48, 0XDF, 0X9F, 0XFF, 0X57, 0X89, 0XA4, 0X1C, 0X58, 0X9B, 0X40, 0XFF, 0X3C, 0XFF, 0X34, 0X59, 0X4C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 } + }, + { + { 0X4571, 0XC47F, 0X571, 0X847F, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X71, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X73, 0XA0, 0XD8, 0, 0X5A, 0X5E, 0X44, 0X98, 0X98, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 }, + { 0X4571, 0X856F, 0X571, 0X456F, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X71, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0XC8, 0XE1, 0, 0X7F, 0X83, 0X44, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 }, + { 0X4571, 0X454A, 0X571, 0X54A, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X66, 0X6D, 0X6E, 0X71, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X65, 0, 0XF0, 0XAB, 0XAF, 0X44, 0X8E, 0X8E, 0XA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 9 }, + { 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 0X4571, 0X477C, 0X571, 0X77C, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X65, 0X6D, 0X6E, 0X71, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7D, 0X40, 0XD0, 0XD4, 0X44, 0X32, 0X68, 0XF7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8 } + } + } +}; + +static const int NumPowerOn = 2; + +static const int NumPowerOff = 2; + +typedef struct _VIALCDPOWERSEQUENCE { + CARD8 powerSeq; + CARD8 port[4]; + CARD8 offset[4]; + CARD8 mask[4]; + CARD8 data[4]; + CARD16 delay[4]; + int numEntry; +} VIALCDPowerSeqRec, *VIALCDPowerSeqRecPtr; + +#define VIA_BIOS_NUM_LCD_POWER_SEQ 4 + +static const VIALCDPowerSeqRec powerOn[] = { + { 0, { 0XD4, 0XD4, 0, 0 }, { 0X91, 0X91, 0, 0 }, { 0X10, 0X8, 0, 0 }, { 0X10, 0X8, 0, 0 }, { 0X19, 0X64, 0, 0 }, 2 }, + { 1, { 0XD4, 0XD4, 0XD4, 0 }, { 0X91, 0X91, 0X91, 0 }, { 0X10, 0X8, 0X6, 0 }, { 0X10, 0X8, 0X6, 0 }, { 0X19, 0X1FE, 0X1, 0 }, 3 }, + { 2, { 0XC4, 0XD4, 0XC4, 0 }, { 0X3D, 0X91, 0X3D, 0 }, { 0X10, 0X8, 0X20, 0 }, { 0X10, 0X8, 0X20, 0 }, { 0X19, 0X1FE, 0X1, 0 }, 3 }, + { 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0 } +}; + +static const VIALCDPowerSeqRec powerOff[] = { + { 0, { 0XD4, 0, 0, 0 }, { 0X91, 0, 0, 0 }, { 0X18, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0X1, 0, 0, 0 }, 1 }, + { 1, { 0XD4, 0XD4, 0XD4, 0 }, { 0X91, 0X91, 0X91, 0 }, { 0X6, 0X8, 0X10, 0 }, { 0, 0, 0, 0 }, { 0XD2, 0X19, 0X1, 0 }, 3 }, + { 2, { 0XC4, 0XD4, 0XC4, 0 }, { 0X3D, 0X91, 0X3D, 0 }, { 0X20, 0X8, 0X10, 0 }, { 0, 0, 0, 0 }, { 0XD2, 0X19, 0X1, 0 }, 3 }, + { 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0 } +}; + +typedef struct _VIALCDMODEFIX { + CARD8 reqMode[32]; + CARD8 fixMode[32]; + int numEntry; +} VIALCDModeFixRec, *VIALCDModeFixRecPtr; + +static const VIALCDModeFixRec modeFix = { + { 0X1, 0X3, 0X7, 0X5, 0X2E, 0X2F, 0X52, 0X53, 0X56, 0X57, 0X5A, 0X5B, 0X67, 0X68, 0X5D, 0X5E, 0X7D, 0X7E, 0X23, 0X24, 0X26, 0X27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0X2, 0X2, 0X4, 0X30, 0X30, 0X50, 0X50, 0X54, 0X54, 0X58, 0X58, 0X66, 0X66, 0X5C, 0X5C, 0X7C, 0X7C, 0X22, 0X22, 0X25, 0X25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 22 }; + + +#endif /* _VIA_MODE_H_ */ diff --git a/unichrome/via_priv.h b/unichrome/via_priv.h new file mode 100644 index 000000000000..af79623f9b39 --- /dev/null +++ b/unichrome/via_priv.h @@ -0,0 +1,161 @@ +#ifndef _VIA_PRIV_H_ +#define _VIA_PRIV_H_ 1 + +#ifdef XF86DRI +#include "via_drm.h" +#endif + +/* + * Alignment macro functions + */ +#define ALIGN_TO(f, alignment) (((f) + ((alignment)-1)) & ~((alignment)-1)) + +/* + * FOURCC definitions + */ + +#define FOURCC_NV12 0x3231564E +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') + +/* + * Structures for create surface + */ +typedef struct _SWDEVICE +{ + unsigned char * lpSWOverlaySurface[2]; /* Max 2 Pointers to SW Overlay Surface*/ + unsigned long dwSWPhysicalAddr[2]; /*Max 2 Physical address to SW Overlay Surface */ + unsigned long dwSWCbPhysicalAddr[2]; /* Physical address to SW Cb Overlay Surface, for YV12 format use */ + unsigned long dwSWCrPhysicalAddr[2]; /* Physical address to SW Cr Overlay Surface, for YV12 format use */ + unsigned long dwHQVAddr[3]; /* Physical address to HQV surface -- CLE_C0 */ + /*unsigned long dwHQVAddr[2];*/ /*Max 2 Physical address to SW HQV Overlay Surface*/ + unsigned long dwWidth; /*SW Source Width, not changed*/ + unsigned long dwHeight; /*SW Source Height, not changed*/ + unsigned long dwPitch; /*SW frame buffer pitch*/ + unsigned long gdwSWSrcWidth; /*SW Source Width, changed if window is out of screen*/ + unsigned long gdwSWSrcHeight; /*SW Source Height, changed if window is out of screen*/ + unsigned long gdwSWDstWidth; /*SW Destination Width*/ + unsigned long gdwSWDstHeight; /*SW Destination Height*/ + unsigned long gdwSWDstLeft; /*SW Position : Left*/ + unsigned long gdwSWDstTop; /*SW Position : Top*/ + unsigned long dwDeinterlaceMode; /*BOB / WEAVE*/ +}SWDEVICE; +typedef SWDEVICE * LPSWDEVICE; + +typedef struct _DDUPDATEOVERLAY +{ + CARD32 SrcLeft; + CARD32 SrcTop; + CARD32 SrcRight; + CARD32 SrcBottom; + + CARD32 DstLeft; + CARD32 DstTop; + CARD32 DstRight; + CARD32 DstBottom; + + unsigned long dwFlags; /* flags */ + unsigned long dwColorSpaceLowValue; +} DDUPDATEOVERLAY; +typedef DDUPDATEOVERLAY * LPDDUPDATEOVERLAY; + +/* Definition for dwFlags */ +#define DDOVER_KEYDEST 1 +#define DDOVER_INTERLEAVED 2 +#define DDOVER_BOB 4 + +#define FOURCC_HQVSW 0x34565148 /*HQV4*/ + +typedef struct +{ + CARD32 dwWidth; + CARD32 dwHeight; + CARD32 dwOffset; + CARD32 dwUVoffset; + CARD32 dwFlipTime; + CARD32 dwFlipTag; + CARD32 dwStartAddr; + CARD32 dwV1OriWidth; + CARD32 dwV1OriHeight; + CARD32 dwV1OriPitch; + CARD32 dwV1SrcWidth; + CARD32 dwV1SrcHeight; + CARD32 dwV1SrcLeft; + CARD32 dwV1SrcRight; + CARD32 dwV1SrcTop; + CARD32 dwV1SrcBot; + CARD32 dwSPWidth; + CARD32 dwSPHeight; + CARD32 dwSPLeft; + CARD32 dwSPRight; + CARD32 dwSPTop; + CARD32 dwSPBot; + CARD32 dwSPOffset; + CARD32 dwSPstartAddr; + CARD32 dwDisplayPictStruct; + CARD32 dwDisplayBuffIndex; /* Display buffer Index. 0 to ( dwBufferNumber -1) */ + CARD32 dwFetchAlignment; + CARD32 dwSPPitch; + unsigned long dwHQVAddr[3]; /* CLE_C0 */ + /*unsigned long dwHQVAddr[2];*/ + CARD32 dwMPEGDeinterlaceMode; /* default value : VIA_DEINTERLACE_WEAVE */ + CARD32 dwMPEGProgressiveMode; /* default value : VIA_PROGRESSIVE */ + CARD32 dwHQVheapInfo; /* video memory heap of the HQV buffer */ + CARD32 dwVideoControl; /* video control flag */ + CARD32 dwminifyH; /* Horizontal minify factor */ + CARD32 dwminifyV; /* Vertical minify factor */ + CARD32 dwMpegDecoded; +} OVERLAYRECORD; + +#define MEM_BLOCKS 4 + +typedef struct { + unsigned long base; /* Offset into fb */ + int pool; /* Pool we drew from */ +#ifdef XF86DRI + int drm_fd; /* Fd in DRM mode */ + drm_via_mem_t drm; /* DRM management object */ +#endif + int slot; /* Pool 3 slot */ + void *pVia; /* VIA driver pointer */ + FBLinearPtr linear; /* X linear pool info ptr */ +} VIAMem; + +typedef VIAMem *VIAMemPtr; + + + +typedef struct { + unsigned long gdwVideoFlagSW; + unsigned long gdwVideoFlagMPEG; + unsigned long gdwAlphaEnabled; /* For Alpha blending use*/ + + VIAMem SWOVMem; + VIAMem HQVMem; + VIAMem SWfbMem; + + CARD32 SrcFourCC; + DDUPDATEOVERLAY UpdateOverlayBackup; /* For HQVcontrol func use + // To save MPEG updateoverlay info.*/ + +/* device struct */ + SWDEVICE SWDevice; + OVERLAYRECORD overlayRecordV1; + OVERLAYRECORD overlayRecordV3; + + BoxRec AvailFBArea; + FBLinearPtr SWOVlinear; + + Bool MPEG_ON; + Bool SWVideo_ON; + +/*To solve the bandwidth issue */ + unsigned long gdwUseExtendedFIFO; + +/* For panning mode use */ + int panning_old_x; + int panning_old_y; + int panning_x; + int panning_y; +} swovRec, *swovPtr; + +#endif /* _VIA_PRIV_H_ */ diff --git a/unichrome/via_regs.h b/unichrome/via_regs.h new file mode 100644 index 000000000000..dd049ea2f1ac --- /dev/null +++ b/unichrome/via_regs.h @@ -0,0 +1,177 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/************************************************************************* + * + * File: via_regs.c + * Content: The defines of Via registers + * + ************************************************************************/ + +#ifndef _VIA_REGS_H_ +#define _VIA_REGS_H_ 1 + +#include "via_driver.h" + +#define BIOS_BSIZE 1024 +#define BIOS_BASE 0xc0000 + + +#define VIA_MMIO_REGSIZE 0x9000 +#define VIA_MMIO_REGBASE 0x0 +#define VIA_MMIO_VGABASE 0x8000 +#define VIA_MMIO_BLTBASE 0x200000 +#define VIA_MMIO_BLTSIZE 0x10000 + + +/* defines for VIA 2D registers */ +#define VIA_REG_GECMD 0x000 +#define VIA_REG_GEMODE 0x004 +#define VIA_REG_GESTATUS 0x004 /* as same as VIA_REG_GEMODE */ +#define VIA_REG_SRCPOS 0x008 +#define VIA_REG_DSTPOS 0x00C +#define VIA_REG_LINE_K1K2 0x008 +#define VIA_REG_LINE_XY 0x00C +#define VIA_REG_DIMENSION 0x010 /* width and height */ +#define VIA_REG_PATADDR 0x014 +#define VIA_REG_FGCOLOR 0x018 +#define VIA_REG_DSTCOLORKEY 0x018 /* as same as VIA_REG_FG */ +#define VIA_REG_BGCOLOR 0x01C +#define VIA_REG_SRCCOLORKEY 0x01C /* as same as VIA_REG_BG */ +#define VIA_REG_CLIPTL 0x020 /* top and left of clipping */ +#define VIA_REG_CLIPBR 0x024 /* bottom and right of clipping */ +#define VIA_REG_OFFSET 0x028 +#define VIA_REG_LINE_ERROR 0x028 +#define VIA_REG_KEYCONTROL 0x02C /* color key control */ +#define VIA_REG_SRCBASE 0x030 +#define VIA_REG_DSTBASE 0x034 +#define VIA_REG_PITCH 0x038 /* pitch of src and dst */ +#define VIA_REG_MONOPAT0 0x03C +#define VIA_REG_MONOPAT1 0x040 +#define VIA_REG_COLORPAT 0x100 /* from 0x100 to 0x1ff */ + + + +/* defines for VIA video registers */ +#define VIA_REG_INTERRUPT 0x200 +#define VIA_REG_CRTCSTART 0x214 + + +/* defines for VIA HW cursor registers */ +#define VIA_REG_CURSOR_MODE 0x2D0 +#define VIA_REG_CURSOR_POS 0x2D4 +#define VIA_REG_CURSOR_ORG 0x2D8 +#define VIA_REG_CURSOR_BG 0x2DC +#define VIA_REG_CURSOR_FG 0x2E0 + + +/* defines for VIA 3D registers */ +#define VIA_REG_STATUS 0x400 +#define VIA_REG_TRANSET 0x43C +#define VIA_REG_TRANSPACE 0x440 + +/* VIA_REG_STATUS(0x400): Engine Status */ +#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */ +#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */ +#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */ + + +/* VIA_REG_GECMD(0x00): 2D Engine Command */ +#define VIA_GEC_NOOP 0x00000000 +#define VIA_GEC_BLT 0x00000001 +#define VIA_GEC_LINE 0x00000005 + +#define VIA_GEC_SRC_XY 0x00000000 +#define VIA_GEC_SRC_LINEAR 0x00000010 +#define VIA_GEC_DST_XY 0x00000000 +#define VIA_GEC_DST_LINRAT 0x00000020 + +#define VIA_GEC_SRC_FB 0x00000000 +#define VIA_GEC_SRC_SYS 0x00000040 +#define VIA_GEC_DST_FB 0x00000000 +#define VIA_GEC_DST_SYS 0x00000080 + +#define VIA_GEC_SRC_MONO 0x00000100 /* source is mono */ +#define VIA_GEC_PAT_MONO 0x00000200 /* pattern is mono */ + +#define VIA_GEC_MSRC_OPAQUE 0x00000000 /* mono src is opaque */ +#define VIA_GEC_MSRC_TRANS 0x00000400 /* mono src is transparent */ + +#define VIA_GEC_PAT_FB 0x00000000 /* pattern is in frame buffer */ +#define VIA_GEC_PAT_REG 0x00000800 /* pattern is from reg setting */ + +#define VIA_GEC_CLIP_DISABLE 0x00000000 +#define VIA_GEC_CLIP_ENABLE 0x00001000 + +#define VIA_GEC_FIXCOLOR_PAT 0x00002000 + +#define VIA_GEC_INCX 0x00000000 +#define VIA_GEC_DECY 0x00004000 +#define VIA_GEC_INCY 0x00000000 +#define VIA_GEC_DECX 0x00008000 + +#define VIA_GEC_MPAT_OPAQUE 0x00000000 /* mono pattern is opaque */ +#define VIA_GEC_MPAT_TRANS 0x00010000 /* mono pattern is transparent */ + +#define VIA_GEC_MONO_UNPACK 0x00000000 +#define VIA_GEC_MONO_PACK 0x00020000 +#define VIA_GEC_MONO_DWORD 0x00000000 +#define VIA_GEC_MONO_WORD 0x00040000 +#define VIA_GEC_MONO_BYTE 0x00080000 + +#define VIA_GEC_LASTPIXEL_ON 0x00000000 +#define VIA_GEC_LASTPIXEL_OFF 0x00100000 +#define VIA_GEC_X_MAJOR 0x00000000 +#define VIA_GEC_Y_MAJOR 0x00200000 +#define VIA_GEC_QUICK_START 0x00800000 + + +/* VIA_REG_GEMODE(0x04): GE mode */ +#define VIA_GEM_8bpp 0x00000000 +#define VIA_GEM_16bpp 0x00000100 +#define VIA_GEM_32bpp 0x00000300 + +#define VIA_GEM_640 0x00000000 /* 640*480 */ +#define VIA_GEM_800 0x00000400 /* 800*600 */ +#define VIA_GEM_1024 0x00000800 /* 1024*768 */ +#define VIA_GEM_1280 0x00000C00 /* 1280*1024 */ +#define VIA_GEM_1600 0x00001000 /* 1600*1200 */ +#define VIA_GEM_2048 0x00001400 /* 2048*1536 */ + +/* VIA_REG_PITCH(0x38): Pitch Setting */ +#define VIA_PITCH_ENABLE 0x80000000 + + +/* CN400 HQV offset */ +#define REG_HQV1_INDEX 0x00001000 + + +#define MAXLOOP 0xffffff + +#define VIASETREG(addr, data) *(volatile unsigned int *)(pVia->MapBase + (addr)) = (data) +#define VIAGETREG(addr) *(volatile unsigned int *)(pVia->MapBase + (addr)) + + +#endif /* _VIA_REGS_H_ */ diff --git a/unichrome/via_shadow.c b/unichrome/via_shadow.c new file mode 100644 index 000000000000..e1a4e181de30 --- /dev/null +++ b/unichrome/via_shadow.c @@ -0,0 +1,308 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "via_driver.h" +#include "shadowfb.h" +#include "servermd.h" + + +static void +VIARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + VIAPtr pVia = VIAPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while (num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pVia->ShadowPtr + (pbox->y1 * pVia->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pVia->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while (height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pVia->ShadowPitch; + } + + pbox++; + } +} + + +static void +VIAPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + VIAPtr pVia = VIAPTR(pScrn); + int newX, newY; + + if (pVia->rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } + else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + + } + + (*pVia->PointerMoved)(index, newX, newY); +} + + +static void +VIARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + VIAPtr pVia = VIAPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pVia->rotate * pVia->ShadowPitch; + + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if (pVia->rotate == 1) { + dstPtr = pVia->FBBase + (pbox->x1 * dstPitch) + + pScrn->virtualX - y2; + srcPtr = pVia->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } + else { + dstPtr = pVia->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pVia->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while (width--) { + src = srcPtr; + dst = (CARD32*) dstPtr; + count = height; + + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + + srcPtr += pVia->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +static void +VIARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + VIAPtr pVia = VIAPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pVia->rotate * pVia->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if (pVia->rotate == 1) { + dstPtr = (CARD16*)pVia->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pVia->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } + else { + dstPtr = (CARD16*)pVia->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pVia->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while (width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + + srcPtr += pVia->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + +#ifdef UNUSED +/* this one could be faster */ +void +VIARefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + VIAPtr pVia = VIAPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pVia->rotate * pVia->ShadowPitch; + + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + + if (pVia->rotate == 1) { + dstPtr = pVia->FBBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pVia->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } + else { + dstPtr = pVia->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pVia->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + + while (width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch * 2] << 16) | + (src[(srcPitch * 2) + 1] << 24); + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | + (src[(srcPitch * 3) + 1] << 16) | + (src[(srcPitch * 3) + 2] << 24); + dst += 3; + src += srcPitch * 4; + } + + srcPtr += pVia->rotate * 3; + dstPtr += dstPitch; + } + + pbox++; + } +} +#endif /* UNUSED */ + +static void +VIARefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + VIAPtr pVia = VIAPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pVia->rotate * pVia->ShadowPitch >> 2; + + while (num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if (pVia->rotate == 1) { + dstPtr = (CARD32*)pVia->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32*)pVia->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } + else { + dstPtr = (CARD32*)pVia->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32*)pVia->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = dstPtr; + count = height; + + while(count--) { + *(dst++) = *src; + src += srcPitch; + } + + srcPtr += pVia->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + +/* + * + */ +void +ViaShadowFBInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) +{ + VIAPtr pVia = VIAPTR(pScrn); + RefreshAreaFuncPtr refreshArea = VIARefreshArea; + + if (pVia->rotate) { + if (!pVia->PointerMoved) { + pVia->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = VIAPointerMoved; + } + + switch(pScrn->bitsPerPixel) { + case 8: + refreshArea = VIARefreshArea8; + break; + case 16: + refreshArea = VIARefreshArea16; + break; + case 32: + refreshArea = VIARefreshArea32; + break; + } + } + + ShadowFBInit(pScreen, refreshArea); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB initialised.\n"); +} + diff --git a/unichrome/via_swov.c b/unichrome/via_swov.c new file mode 100644 index 000000000000..809c81fc56a5 --- /dev/null +++ b/unichrome/via_swov.c @@ -0,0 +1,2142 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86fbman.h" + +#include "via.h" +#include "xf86drm.h" + +#include "via_driver.h" +#include "via_priv.h" +#include "via_swov.h" +#include "via_drm.h" +#include "via_vgahw.h" +#include "via_id.h" + +#include <math.h> + +/* + * Warning: this file contains revision checks which are CLE266 specific. + * There seems to be no checking present for KM400 or more recent devices. + * + * TODO: + * - pVia->Chipset checking of course. + * - move content of pVia->HWDiff into pVia->swov + * - merge with CLEXF40040 + */ + +#define XV_DEBUG 1 /* write log msg to /var/log/XFree86.0.log */ + +#ifdef XV_DEBUG +# define DBG_DD(x) (x) +#else +# define DBG_DD(x) +#endif + +/* + * Old via_regrec code. + * + * + */ +#define VIDREG_BUFFER_SIZE 100 /* Number of entries in the VidRegBuffer. */ +#define IN_VIDEO_DISPLAY (*((unsigned long volatile *)(pVia->VidMapBase+V_FLAGS))&VBI_STATUS) +#if 0 + +#define IN_HQV_FIRE (*((unsigned long volatile *)(pVia->VidMapBase+HQV_CONTROL))&HQV_IDLE) +#ifdef UNUSED + +#define IN_VIDEO_FIRE (*((unsigned long volatile *)(pVia->VidMapBase+V_COMPOSE_MODE))&V1_COMMAND_FIRE) +#define IN_HQV_FLIP (*((unsigned long volatile *)(pVia->VidMapBase+HQV_CONTROL))&HQV_FLIP_STATUS) +#define IN_DISPLAY (VIDInD(V_FLAGS) & 0x200) +#define IN_VBLANK (!IN_DISPLAY) + +static void +viaWaitHQVIdle(VIAPtr pVia) +{ + while (!IN_HQV_FIRE); +} +#endif /* UNUSED */ + +#endif + +static void +viaWaitVideoCommandFire(VIAPtr pVia) +{ + /*while (IN_VIDEO_FIRE);*/ + CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE); + /*pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE);*/ + while ((*pdwState & V1_COMMAND_FIRE)||(*pdwState & V3_COMMAND_FIRE)); +} + +static void +viaWaitHQVFlip(VIAPtr pVia) +{ + unsigned long proReg=0; + CARD32 volatile *pdwState; + + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + pdwState = (CARD32 volatile *) (pVia->VidMapBase+(HQV_CONTROL|proReg)); + while (!(*pdwState & HQV_FLIP_STATUS) ); +/* + while (!((*pdwState & 0xc0)== 0xc0) ); + while (!((*pdwState & 0xc0)!= 0xc0) ); +*/ +} + +static void +viaWaitHQVFlipClear(VIAPtr pVia, unsigned long dwData) +{ + CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+(HQV_CONTROL)); + *pdwState =dwData; + + while ((*pdwState & HQV_FLIP_STATUS) ) + { + VIDOutD(HQV_CONTROL, *pdwState|HQV_FLIP_STATUS); + } +} + +static void +viaWaitVBI(VIAPtr pVia) +{ + while (IN_VIDEO_DISPLAY); +} + +static void +viaWaitHQVDone(VIAPtr pVia) +{ + CARD32 volatile *pdwState; + unsigned long proReg=0; + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + + pdwState = (CARD32 volatile *) (pVia->VidMapBase+(HQV_CONTROL|proReg)); + /*pdwState = (CARD32 volatile *) (GEAddr+HQV_CONTROL);*/ + + /*if (*pdwState & HQV_ENABLE)*/ + if (pVia->swov.MPEG_ON) + { + while ((*pdwState & HQV_SW_FLIP) ); + } +} +/* + * Send all data in VidRegBuffer to the hardware. + */ +static void +FlushVidRegBuffer(VIAPtr pVia) +{ + unsigned int i; + + viaWaitVideoCommandFire(pVia); + + for (i = 0; i < pVia->VidRegCursor; i += 2) + { + VIDOutD(pVia->VidRegBuffer[i], pVia->VidRegBuffer[i+1]); + DBG_DD(ErrorF("FlushVideoRegs: [%i] %08lx %08lx\n", + i>>1, pVia->VidRegBuffer[i]+0x200, pVia->VidRegBuffer[i+1])); + } + + /* BUG: (?) VIA never resets the cursor. + * My fix is commented out for now, in case they had a reason for that. /A + */ + /* pVia->VidRegCursor = 0; */ +} + +/* + * Initialize and clear VidRegBuffer. + */ +static void +ResetVidRegBuffer(VIAPtr pVia) +{ + /* BUG: (Memory leak) This allocation may need have a corresponding free somewhere... /A */ + if (!pVia->VidRegBuffer) + pVia->VidRegBuffer = xnfcalloc(VIDREG_BUFFER_SIZE, sizeof(CARD32) * 2); + pVia->VidRegCursor = 0; +} + +/* + * Save a video register and data in VidRegBuffer. + */ +static void +SaveVideoRegister(VIAPtr pVia, CARD32 index, CARD32 data) +{ + pVia->VidRegBuffer[pVia->VidRegCursor++] = index; + pVia->VidRegBuffer[pVia->VidRegCursor++] = data; + + if (pVia->VidRegCursor > VIDREG_BUFFER_SIZE) { + DBG_DD(ErrorF("SaveVideoRegister: Out of video register space")); + } +} + + +/* + * HW Difference Flag + * Moved here from via_hwdiff.c + * + * These are the entries of HWDiff used in our code (currently): + * CLE266Ax CLE266Cx KM400 K8M800 PM800 + * ThreeHQVBuffer FALSE TRUE TRUE TRUE TRUE + * HQVFetchByteUnit FALSE TRUE TRUE TRUE TRUE + * SupportTwoColorKey FALSE TRUE FALSE FALSE TRUE + * HQVInitPatch TRUE FALSE FALSE FALSE FALSE + * HQVDisablePatch FALSE TRUE TRUE TRUE FALSE + * + * This is now up to date with CLEXF40040. All unused entries were removed. + * The functions depending on this struct are untouched. + * + */ +void +VIAVidHWDiffInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIAHWDiff *HWDiff = &pVia->HWDiff; + + switch(pVia->Chipset) + { + case VIA_CLE266: + if (CLE266_REV_IS_AX(pVia->ChipRev)) { + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_FALSE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_FALSE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_TRUE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; + } else { + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + } + break; + case VIA_KM400: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + break; +#ifdef HAVE_K8M800 + case VIA_K8M800: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + break; +#endif /* HAVE_K8M800 */ +#ifdef HAVE_PM800 + case VIA_PM800: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; + break; +#endif /* HAVE_PM800 */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIAVidHWDiffInit: Unhandled ChipSet.\n"); + } +} +/* + * Old via_overlay code. + * + */ +typedef struct _YCBCRREC { + CARD32 dwY ; + CARD32 dwCB; + CARD32 dwCR; +} YCBCRREC; + +/* Verify that using V1 bit definitions on V3 + * is not broken in OverlayGetV1V3Format() + */ + +#if V1_COLORSPACE_SIGN != V3_COLORSPACE_SIGN +#error "V1_COLORSPACE_SIGN != V3_COLORSPACE_SIGN" +#endif +#if V1_YUV422 != V3_YUV422 +#error "V1_YUV422 != V3_YUV422" +#endif +#if V1_SWAP_HW_HQV != V3_SWAP_HW_HQV +#error "V1_SWAP_HW_HQV != V3_SWAP_HW_HQV" +#endif +#if V1_RGB15 != V3_RGB15 +#error "V1_RGB15 != V3_RGB15" +#endif +#if V1_RGB16 != V3_RGB16 +#error "V1_RGB16 != V3_RGB16" +#endif +#if V1_RGB32 != V3_RGB32 +#error "V1_RGB32 != V3_RGB32" +#endif + +static BOOL +viaOverlayGetV1V3Format(VIAPtr pVia, int vport, /* 1 or 3, as in V1 or V3 */ + unsigned long videoFlag, + unsigned long * pVidCtl, unsigned long * pHQVCtl) +{ + BOOL is_ok = TRUE; + + *pVidCtl |= V1_COLORSPACE_SIGN; + switch (pVia->swov.SrcFourCC) { + case FOURCC_YV12: + case FOURCC_XVMC: + if (videoFlag & VIDEO_HQV_INUSE) { + *pVidCtl |= V1_YUV422 | V1_SWAP_HW_HQV; + *pHQVCtl |= HQV_SRC_SW | HQV_YUV420 | HQV_ENABLE | HQV_SW_FLIP; + } else { + if (vport == 1) + *pVidCtl |= V1_YCbCr420; + else { + DBG_DD(ErrorF("viaOverlayGetV1V3Format: V3 does not support planar YUV.\n")); + is_ok = FALSE; + } + } + break; + + case FOURCC_YUY2: + if (videoFlag & VIDEO_HQV_INUSE) { + *pVidCtl |= V1_YUV422 | V1_SWAP_HW_HQV; + *pHQVCtl |= HQV_SRC_SW | HQV_YUV422 | HQV_ENABLE | HQV_SW_FLIP; + } else + *pVidCtl |= V1_YUV422; + break; + + default: + DBG_DD(ErrorF("viaOverlayGetV1V3Format: Invalid FOURCC format (0x%lx).\n", + pVia->swov.SrcFourCC)); + is_ok = FALSE; + + *pVidCtl |= V1_YUV422; + break; + } + return is_ok; +} + +static unsigned long +viaOverlayGetSrcStartAddress(VIAPtr pVia, unsigned long videoFlag, + LPDDUPDATEOVERLAY pUpdate, unsigned long srcPitch, + unsigned long * pHQVoffset) +{ + unsigned long srcWidth = (unsigned long)(pUpdate->SrcRight - pUpdate->SrcLeft); + unsigned long dstWidth = (unsigned long)(pUpdate->DstRight - pUpdate->DstLeft); + unsigned long srcHeight = (unsigned long)(pUpdate->SrcBottom - pUpdate->SrcTop); + unsigned long dstHeight = (unsigned long)(pUpdate->DstBottom - pUpdate->DstTop); + + unsigned long offset = 0; + unsigned long srcTopOffset = 0; + unsigned long srcLeftOffset = 0; + + if ((pUpdate->SrcLeft != 0) || (pUpdate->SrcTop != 0)) { + switch (pVia->swov.SrcFourCC) { + case FOURCC_YUY2: + case FOURCC_UYVY: + + if (videoFlag & VIDEO_HQV_INUSE) { + offset = (((pUpdate->SrcTop & ~3) * srcPitch) + ((pUpdate->SrcLeft << 1) & ~31)); + + if (srcHeight > dstHeight) + srcTopOffset = ((pUpdate->SrcTop & ~3) * dstHeight / srcHeight) * srcPitch; + else + srcTopOffset = (pUpdate->SrcTop & ~3) * srcPitch; + + if (srcWidth > dstWidth) + srcLeftOffset = ((pUpdate->SrcLeft << 1) & ~31) * dstWidth / srcWidth; + else + srcLeftOffset = (pUpdate->SrcLeft << 1) & ~31; + *pHQVoffset = srcTopOffset + srcLeftOffset; + } else + offset = ((pUpdate->SrcTop * srcPitch) + ((pUpdate->SrcLeft << 1) & ~15)); + break; + + case FOURCC_YV12: + case FOURCC_XVMC: + + if (videoFlag & VIDEO_HQV_INUSE) + offset = (((pUpdate->SrcTop & ~3) * (srcPitch << 1)) + ((pUpdate->SrcLeft << 1) & ~31)); + else { + offset = ((((pUpdate->SrcTop & ~3) * srcPitch) + pUpdate->SrcLeft) & ~31); + if (pUpdate->SrcTop > 0) + pVia->swov.overlayRecordV1.dwUVoffset = (((((pUpdate->SrcTop & ~3)>>1) * srcPitch) + pUpdate->SrcLeft) & ~31) >> 1; + else + pVia->swov.overlayRecordV1.dwUVoffset = offset >> 1; + } + break; + + default: + DBG_DD(ErrorF("viaGetSrcStartAddress: Invalid FOURCC format (0x%lx).\n", + pVia->swov.SrcFourCC)); + break; + } + } + else { + pVia->swov.overlayRecordV1.dwUVoffset = offset = 0; + } + + return offset; +} + +static YCBCRREC +viaOverlayGetYCbCrStartAddress(unsigned long videoFlag, unsigned long startAddr, + unsigned long offset, unsigned long UVoffset, + unsigned long srcPitch, unsigned long srcHeight) +{ + YCBCRREC YCbCr; + + if (videoFlag & VIDEO_HQV_INUSE) { + YCbCr.dwY = startAddr; + YCbCr.dwCB = startAddr + srcPitch * srcHeight; + YCbCr.dwCR = startAddr + srcPitch * srcHeight + + srcPitch * (srcHeight >> 2); + } + else { + YCbCr.dwY = startAddr + offset; + YCbCr.dwCB = startAddr + srcPitch * srcHeight + UVoffset; + YCbCr.dwCR = startAddr + srcPitch * srcHeight + UVoffset + + srcPitch * (srcHeight >> 2); + } + return YCbCr; +} + +static YCBCRREC +viaOverlayGetYCbCrStartAddressProA(unsigned long videoFlag, unsigned long startAddr, + unsigned long offset, unsigned long UVoffset, + unsigned long srcPitch, unsigned long srcHeight) +{ + YCBCRREC YCbCr; + + if (videoFlag & VIDEO_HQV_INUSE) { + YCbCr.dwY = startAddr; + YCbCr.dwCB = startAddr + srcPitch * srcHeight; + YCbCr.dwCR = startAddr + srcPitch * srcHeight; + } + else { + YCbCr.dwY = startAddr + offset; + YCbCr.dwCB = startAddr + srcPitch * srcHeight + UVoffset; + YCbCr.dwCR = startAddr + srcPitch * srcHeight + UVoffset; + } + return YCbCr; +} + +static unsigned long +viaOverlayHQVCalcZoomWidth(VIAPtr pVia, unsigned long videoFlag, + unsigned long srcWidth, unsigned long dstWidth, + unsigned long * pZoomCtl, unsigned long * pMiniCtl, + unsigned long * pHQVfilterCtl, unsigned long * pHQVminiCtl, + unsigned long * pHQVzoomflag) +{ + unsigned long tmp, sw1, d, falign, mdiv; + Bool zoom_ok = TRUE; + + CARD32 HQVfilter[5] = { + HQV_H_FILTER_DEFAULT, HQV_H_TAP4_121, HQV_H_TAP4_121, + HQV_H_TAP8_12221, HQV_H_TAP8_12221 + }; + /* CARD HQVmini[5] = { 0, 0xc00, 0xa00, 0x900, 0x8800 }; */ + + falign = 0; + mdiv = 1; + + if (srcWidth == dstWidth) { /* No zoom */ + *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT; + } + else if (srcWidth < dstWidth) { /* Zoom in */ + + tmp = srcWidth * 0x800 / dstWidth; + *pZoomCtl = ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; + *pMiniCtl |= V1_X_INTERPOLY; + zoom_ok = !(tmp > 0x7ff); + + *pHQVzoomflag = 1; + *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT; + + } else { /* srcWidth > dstWidth - Zoom out */ + + /*HQV rounding patch + //tmp = dstWidth*0x0800 / srcWidth;*/ + tmp = dstWidth * 0x800 * 0x400 / srcWidth; + tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); + + *pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN; + + /* Scale down the picture by a factor mdiv = (1 << d) = {2, 4, 8 or 16} */ + + sw1 = srcWidth; + for (d = 1; d < 5; d++) { + sw1 >>= 1; + if (sw1 <= dstWidth) break; + } + if (d == 5) { /* Too small. */ + d = 4; + zoom_ok = FALSE; + } + mdiv = 1 << d; /* <= {2,4,8,16} */ + falign = ((mdiv<<1)-1) & 0xf; /* <= {3,7,15,15} */ + *pMiniCtl |= V1_X_INTERPOLY; + *pMiniCtl |= ((d<<1)-1) << 24; /* <= {1,3,5,7} << 24 */ + + *pHQVfilterCtl |= HQVfilter[d]; + /* *pHQVminiCtl = HQVmini[d]; */ + *pHQVminiCtl |= HQV_HDEBLOCK_FILTER; + + /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ + + if (sw1 < dstWidth) { + /* CLE bug + *pZoomCtl = sw1 * 0x0800 / dstWidth;*/ + *pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth; + *pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; + } + } + + if (videoFlag & VIDEO_1_INUSE) { + pVia->swov.overlayRecordV1.dwFetchAlignment = falign; + pVia->swov.overlayRecordV1.dwminifyH = mdiv; + } + else { + pVia->swov.overlayRecordV3.dwFetchAlignment = falign; + pVia->swov.overlayRecordV3.dwminifyH = mdiv; + } + + return zoom_ok; +} + +static unsigned long +viaOverlayHQVCalcZoomHeight(VIAPtr pVia, unsigned long srcHeight, + unsigned long dstHeight, unsigned long * pZoomCtl, + unsigned long * pMiniCtl, unsigned long * pHQVfilterCtl, + unsigned long * pHQVminiCtl, unsigned long * pHQVzoomflag) +{ + unsigned long tmp, sh1, d; + Bool zoom_ok = TRUE; + + CARD32 HQVfilter[5] = { + HQV_V_TAP4_121, HQV_V_TAP4_121, HQV_V_TAP4_121, + HQV_V_TAP8_12221, HQV_V_TAP8_12221 + }; + /* CARD32 HQVmini[5] = { 0, 0x0c000000, 0x0a000000, 0x09000000, 0x08800000 }; */ + + /*if (pVia->pBIOSInfo->scaleY) + { + dstHeight = dstHeight + 1; + }*/ + + if (srcHeight == dstHeight) { /* No zoom */ + *pHQVfilterCtl |= HQV_V_TAP4_121; + } + else if (srcHeight < dstHeight) { /* Zoom in */ + + tmp = srcHeight * 0x0400 / dstHeight; + *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); + *pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY); + + *pHQVzoomflag = 1; + *pHQVfilterCtl |= HQV_V_TAP4_121; + } + else { /* srcHeight > dstHeight - Zoom out */ + + /*HQV rounding patch + //tmp = dstHeight*0x0800 / srcHeight;*/ + tmp = dstHeight * 0x0800 * 0x400 / srcHeight; + tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); + *pHQVminiCtl |= ((tmp& 0x7ff) << 16) | HQV_V_MINIFY_ENABLE | HQV_V_MINIFY_DOWN; + + /* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */ + + sh1 = srcHeight; + for (d = 1; d < 5; d++) { + sh1 >>= 1; + if (sh1 <= dstHeight) break; + } + if (d == 5) { /* Too small. */ + d = 4; + zoom_ok = FALSE; + } + + *pMiniCtl |= ((d<<1)-1) << 16; /* <= {1,3,5,7} << 16 */ + + *pHQVfilterCtl |= HQVfilter[d]; + /* *pHQVminiCtl |= HQVmini[d]; */ + *pHQVminiCtl |= HQV_VDEBLOCK_FILTER; + + /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ + + if (sh1 < dstHeight) { + tmp = sh1 * 0x0400 / dstHeight; + *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); + *pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; + } + } + + return zoom_ok; +} + +static unsigned long +viaOverlayGetFetch(VIAPtr pVia, unsigned long videoFlag, + unsigned long srcWidth, unsigned long dstWidth, + unsigned long oriSrcWidth, unsigned long * pHQVsrcFetch) +{ + unsigned long fetch = 0; + int n = 2; /* 2^n bytes per pixel. */ + + switch (pVia->swov.SrcFourCC) { + case FOURCC_YV12: + case FOURCC_XVMC: + n = 0; /* 2^n = 1 byte per pixel (Y channel in planar YUV) */ + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + n = 1; /* 2^n = 2 bytes per pixel (packed YUV) */ + break; + default: + DBG_DD(ErrorF("viaOverlayGetFetch: Invalid FOURCC format (0x%lx).\n", + pVia->swov.SrcFourCC)); + break; + } + + if (videoFlag & VIDEO_HQV_INUSE) { + *pHQVsrcFetch = oriSrcWidth << n; + if (n == 0) { + /* Assume n == 0 <=> Planar YUV. + * The V1/V3 pixelformat is always packed YUV when we use HQV, + * so we switch from 8-bit to 16-bit pixels here. + */ + n = 1; + } + if (dstWidth >= srcWidth) + fetch = (ALIGN_TO(srcWidth << n, 16) >> 4) + 1; + else + fetch = (ALIGN_TO(dstWidth << n, 16) >> 4) + 1; + } else { + if (n == 0) + fetch = (ALIGN_TO(srcWidth, 32) >> 4); + else + fetch = (ALIGN_TO(srcWidth << n, 16) >> 4) + 1; + } + + /* Fix planar mode problem. */ + if (fetch < 4) fetch = 4; + + return fetch; +} + +/* + * This function uses quadratic mapping to adjust the midpoint of the scaling. + */ +static float rangeEqualize(float inLow,float inHigh,float outLow,float outHigh,float outMid, + float inValue) +{ + float + inRange = inHigh - inLow, + outRange = outHigh - outLow, + normIn = ((inValue - inLow) / inRange)*2.-1., + delta = outMid - outRange*0.5 - outLow; + return (inValue - inLow) * outRange / inRange + outLow + (1. - normIn*normIn)*delta; +} + +static unsigned vPackFloat(float val, float hiLimit, float loLimit, float mult, int shift, + Bool doSign) +{ + unsigned packed,mask,sign; + val = (val > hiLimit) ? hiLimit : val; + val = (val < loLimit) ? loLimit : val; + sign = (val < 0) ? 1:0; + val = (sign) ? -val : val; + packed = ((unsigned)(val*mult + 1.)) >> 1; + mask = (1 << shift) - 1; + return (((packed >= mask) ? mask : packed) | ((doSign) ? (sign << shift) : 0)); + +} + + +typedef float colorCoeff[5]; +static colorCoeff colorCTable[] = {{1.1875,1.625,0.875,0.375,2.0}, + {1.164,1.596,0.54,0.45,2.2}}; + +/* + * This function is a partial rewrite of the overlay.c file of the original VIA drivers, + * which was extremely nasty and difficult to follow. Coefficient for new chipset models should + * be added in the table above and, if needed, implemented in the model switch below. + */ + +static void +viaCalculateVideoColor(VIAPtr pVia, int hue, int saturation, int brightness, + int contrast,Bool reset,CARD32 *col1,CARD32 *col2) +{ + float fA,fB1,fC1,fD,fB2,fC2,fB3,fC3; + float fPI,fContrast,fSaturation,fHue,fBrightness; + const float *mCoeff; + unsigned long dwA,dwB1,dwC1,dwD,dwB2,dwC2,dwB3,dwC3,dwS; + unsigned long dwD_Int,dwD_Dec; + int intD; + int model; + fPI = (float)(M_PI/180.); + + if ( reset ) { + saturation = 10000; + brightness = 5000; + contrast = 10000; + } + + switch ( pVia->ChipId ) + { + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + case PCI_CHIP_VT3259: + model = 0; + break; + case PCI_CHIP_CLE3122: + model = (CLE266_REV_IS_CX(pVia->ChipRev) ? 0 : 1); + break; + default: + ErrorF("Unknown Chip ID\n"); + model = 0; + } + + switch( model ) + { + case 0: + fBrightness = rangeEqualize(0.,10000.,-128.,128.,-16.,(float) brightness); + fContrast = rangeEqualize(0.,20000.,0.,1.6645,1.0,(float) contrast); + fSaturation = rangeEqualize(0.,20000,0.,2.,1.,(float) saturation); + break; + default: + fBrightness = rangeEqualize(0.,10000.,-128.,128.,-12.,(float) brightness); + fContrast = rangeEqualize(0.,20000.,0.,1.6645,1.1,(float) contrast); + fSaturation = rangeEqualize(0.,20000,0.,2.,1.15,(float) saturation); + break; + } + fHue = (float)hue; + + mCoeff = colorCTable[model]; + + fA = (float)(mCoeff[0]*fContrast); + fB1 = (float)(-mCoeff[1]*fContrast*fSaturation*sin(fHue*fPI)); + fC1 = (float)(mCoeff[1]*fContrast*fSaturation*cos(fHue*fPI)); + fD = (float)(mCoeff[0]*(fBrightness)); + fB2 = (float)((mCoeff[2]*sin(fHue*fPI)- + mCoeff[3]*cos(fHue*fPI))*fContrast*fSaturation); + fC2 = (float)(-(mCoeff[2]*cos(fHue*fPI)+ + mCoeff[3]*sin(fHue*fPI))*fContrast*fSaturation); + fB3 = (float)(mCoeff[4]*fContrast*fSaturation*cos(fHue*fPI)); + fC3 = (float)(mCoeff[4]*fContrast*fSaturation*sin(fHue*fPI)); + + switch(model) + { + case 0: + dwA = vPackFloat(fA,1.9375,0.,32.,5,0); + dwB1 = vPackFloat(fB1,2.125,-2.125,16.,5,1); + dwC1 = vPackFloat(fC1,2.125,-2.125,16.,5,1); + + if (fD>=0) { + intD=(int)fD; + if (intD>127) + intD = 127; + dwD_Int = ((unsigned long)intD)&0xff; + dwD = ((unsigned long)(fD*16+1))>>1; + dwD_Dec= dwD&0x7; + } else { + intD=(int)fD; + if (intD< -128) + intD = -128; + intD = intD+256; + dwD_Int = ((unsigned long)intD)&0xff; + fD = -fD; + dwD = ((unsigned long)(fD*16+1))>>1; + dwD_Dec= dwD&0x7; + } + + dwB2 = vPackFloat(fB2,1.875,-1.875,16,4,1); + dwC2 = vPackFloat(fC2,1.875,-1.875,16,4,1); + dwB3 = vPackFloat(fB3,3.875,-3.875,16,5,1); + dwC3 = vPackFloat(fC3,3.875,-3.875,16,5,1); + *col1 = (dwA<<24)|(dwB1<<16)|(dwC1<<8)|dwD_Int; + *col2 = (dwD_Dec<<29|dwB2<<24)|(dwC2<<16)|(dwB3<<8)|(dwC3); + break; + + default: + dwA = vPackFloat(fA,1.9375,-0.,32,5,0); + dwB1 = vPackFloat(fB1,0.75,-0.75,8.,2,1); + dwC1 = vPackFloat(fC1,2.875,1.,16.,5,0); + + if (fD>=127) + fD=127; + + if (fD<=-128) + fD=-128; + + if (fD>=0) { + dwS = 0; + } + else { + dwS = 1; + fD = fD+128; + } + + dwD = ((unsigned long)(fD*2+1))>>1; + if (dwD>=0x7f) { + dwD = 0x7f|(dwS<<7); + } else { + dwD = (dwD&0x7f)|(dwS<<7); + } + + dwB2 = vPackFloat(fB2,0.,-0.875,16.,3,0); + dwC2 = vPackFloat(fC2,0.,-1.875,16.,4,0); + dwB3 = vPackFloat(fB3,3.75,0.,8.,4,0); + dwC3 = vPackFloat(fC3,1.25,-1.25,8.,3,1); + *col1 = (dwA<<24)|(dwB1<<18)|(dwC1<<9)|dwD; + *col2 = (dwB2<<25)|(dwC2<<17)|(dwB3<<10)|(dwC3<<2); + break; + } +} + +/* + * + * + */ +void viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness, int contrast, + Bool reset) +{ + CARD32 col1,col2; + + viaCalculateVideoColor(pVia,hue,saturation,brightness, contrast,reset,&col1,&col2); + switch ( pVia->ChipId ) { + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + VIDOutD(V3_ColorSpaceReg_1, col1); + VIDOutD(V3_ColorSpaceReg_2, col2); + DBG_DD(ErrorF("000002C4 %08lx\n",col1)); + DBG_DD(ErrorF("000002C8 %08lx\n",col2)); + break; + case PCI_CHIP_CLE3122: + case PCI_CHIP_VT3259: + VIDOutD(V1_ColorSpaceReg_2, col2); + VIDOutD(V1_ColorSpaceReg_1, col1); + VIDOutD(V3_ColorSpaceReg_2, col2); + VIDOutD(V3_ColorSpaceReg_1, col1); + + DBG_DD(ErrorF("00000288 %08lx\n",col2)); + DBG_DD(ErrorF("00000284 %08lx\n",col1)); + break; + default: +/*IVOR*/ + DBG_DD(ErrorF("000002C4 %08lx\n",col1)); + DBG_DD(ErrorF("000002C8 %08lx\n",col2)); + + break; + } +} + +static unsigned long ViaInitVideoStatusFlag(VIAPtr pVia) +{ + switch ( pVia->ChipId ) { + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + case PCI_CHIP_VT3259: + return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_3_INUSE; + case PCI_CHIP_CLE3122: + return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE; + default: + DBG_DD(ErrorF("Unknown DeviceID\n")); + break; + } + return 0UL; +} + +static unsigned long ViaSetVidCtl(VIAPtr pVia, unsigned int videoFlag) +{ + if (videoFlag & VIDEO_1_INUSE) { + /*=* Modify for C1 FIFO *=*/ + /* WARNING: not checking Chipset! */ + if (CLE266_REV_IS_CX(pVia->ChipRev)) + return V1_ENABLE | V1_EXPIRE_NUM_F; + else { + /* Overlay source format for V1 */ + if (pVia->swov.gdwUseExtendedFIFO) + return V1_ENABLE | V1_EXPIRE_NUM_A | V1_FIFO_EXTENDED; + else + return V1_ENABLE | V1_EXPIRE_NUM; + } + } + else { + switch (pVia->ChipId) + { + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + return V3_ENABLE | V3_EXPIRE_NUM_3205; + + case PCI_CHIP_CLE3122: + if (CLE266_REV_IS_CX(pVia->ChipRev)) + return V3_ENABLE | V3_EXPIRE_NUM_F; + else + return V3_ENABLE | V3_EXPIRE_NUM; + break; + + case PCI_CHIP_VT3259: + return V3_ENABLE | V3_EXPIRE_NUM_3205; + break; + + default: + DBG_DD(ErrorF("Unknown DeviceID\n")); + break; + } + } + return 0; +}/*End of DeviceID*/ + +/* + * Fill the buffer with 0x8000 (YUV2 black) + */ +static void +ViaYUVFillBlack(VIAPtr pVia, int offset, int num) +{ + CARD16 *ptr = (CARD16 *)(pVia->FBBase + offset); + + while(num-- > 0) +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + *ptr++ = 0x0080; +#else + *ptr++ = 0x8000; +#endif +} + +/* + * Add an HQV surface to an existing FOURCC surface. + * numbuf: number of buffers, 1, 2 or 3 + * fourcc: FOURCC code of the current (already existing) surface + */ +static long AddHQVSurface(ScrnInfoPtr pScrn, unsigned int numbuf, CARD32 fourcc) +{ + unsigned int i, width, height, pitch, fbsize, addr; + unsigned long retCode; + BOOL isplanar; + + VIAPtr pVia = VIAPTR(pScrn); + CARD32 AddrReg[3] = {HQV_DST_STARTADDR0, HQV_DST_STARTADDR1, HQV_DST_STARTADDR2}; + + unsigned long proReg=0; + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + isplanar = ((fourcc == FOURCC_YV12) || (fourcc == FOURCC_XVMC)); + + width = pVia->swov.SWDevice.gdwSWSrcWidth; + height = pVia->swov.SWDevice.gdwSWSrcHeight; + pitch = pVia->swov.SWDevice.dwPitch; + fbsize = pitch * height * (isplanar ? 2 : 1); + + VIAFreeLinear(&pVia->swov.HQVMem); + retCode = VIAAllocLinear(&pVia->swov.HQVMem, pScrn, fbsize * numbuf); + if(retCode != Success) return retCode; + addr = pVia->swov.HQVMem.base; + + ViaYUVFillBlack(pVia, addr, fbsize); + + for (i = 0; i < numbuf; i++) { + pVia->swov.overlayRecordV1.dwHQVAddr[i] = addr; + VIDOutD(AddrReg[i]|proReg, addr); + addr += fbsize; + } + + return Success; +} + +/* + * Create a FOURCC surface (Supported: YUY2, YV12 or VIA) + * doalloc: set true to actually allocate memory for the framebuffers + */ +static long +CreateSurface(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, + CARD16 Height, BOOL doalloc) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned long pitch, fbsize, addr; + unsigned long retCode; + BOOL isplanar; + + pVia->swov.SrcFourCC = FourCC; + pVia->swov.gdwVideoFlagSW = ViaInitVideoStatusFlag(pVia); + + isplanar = ((FourCC == FOURCC_YV12) || (FourCC == FOURCC_XVMC)); + + pitch = ALIGN_TO(Width, 32) * (isplanar ? 1 : 2); + fbsize = pitch * Height * (isplanar ? 1.5 : 1.0); + + VIAFreeLinear(&pVia->swov.SWfbMem); + + if (doalloc) { + retCode = VIAAllocLinear(&pVia->swov.SWfbMem, pScrn, fbsize * 2); + if(retCode != Success) + return retCode; + addr = pVia->swov.SWfbMem.base; + + ViaYUVFillBlack(pVia, addr, fbsize); + + pVia->swov.SWDevice.dwSWPhysicalAddr[0] = addr; + pVia->swov.SWDevice.dwSWPhysicalAddr[1] = addr + fbsize; + pVia->swov.SWDevice.lpSWOverlaySurface[0] = pVia->FBBase + addr; + pVia->swov.SWDevice.lpSWOverlaySurface[1] = + pVia->swov.SWDevice.lpSWOverlaySurface[0] + fbsize; + + if (isplanar) { + pVia->swov.SWDevice.dwSWCrPhysicalAddr[0] = + pVia->swov.SWDevice.dwSWPhysicalAddr[0] + (pitch*Height); + pVia->swov.SWDevice.dwSWCrPhysicalAddr[1] = + pVia->swov.SWDevice.dwSWPhysicalAddr[1] + (pitch*Height); + pVia->swov.SWDevice.dwSWCbPhysicalAddr[0] = + pVia->swov.SWDevice.dwSWCrPhysicalAddr[0] + ((pitch>>1)*(Height>>1)); + pVia->swov.SWDevice.dwSWCbPhysicalAddr[1] = + pVia->swov.SWDevice.dwSWCrPhysicalAddr[1] + ((pitch>>1)*(Height>>1)); + } + } + + pVia->swov.SWDevice.gdwSWSrcWidth = Width; + pVia->swov.SWDevice.gdwSWSrcHeight = Height; + pVia->swov.SWDevice.dwPitch = pitch; + + pVia->swov.overlayRecordV1.dwV1OriWidth = Width; + pVia->swov.overlayRecordV1.dwV1OriHeight = Height; + pVia->swov.overlayRecordV1.dwV1OriPitch = pitch; + + return Success; +} + +/* + * + */ +int +ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, CARD32 FourCC, + CARD16 Width, CARD16 Height) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned long retCode = Success; + int numbuf = pVia->HWDiff.dwThreeHQVBuffer ? 3 : 2; + + DBG_DD(ErrorF("ViaSwovSurfaceCreate: FourCC =0x%08lx\n", FourCC)); + + if (pVia->VideoStatus & VIDEO_SWOV_SURFACE_CREATED) + return Success; + + switch (FourCC) { + case FOURCC_YUY2: + retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE); + if (retCode != Success) + break; + if ((pVia->swov.gdwVideoFlagSW & SW_USE_HQV)) + retCode = AddHQVSurface(pScrn, numbuf, FOURCC_YUY2); + break; + + case FOURCC_HQVSW: + retCode = AddHQVSurface(pScrn, numbuf, FOURCC_YUY2); + break; + + case FOURCC_YV12: + retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE); + if (retCode == Success) + retCode = AddHQVSurface(pScrn, numbuf, FOURCC_YV12); + break; + + case FOURCC_XVMC: + retCode = CreateSurface(pScrn, FourCC, Width, Height, FALSE); + if (retCode == Success) + retCode = AddHQVSurface(pScrn, numbuf, FOURCC_XVMC); + break; + + default: + break; + } + + if (retCode == Success) { + pVia->swov.SWDevice.lpSWOverlaySurface[0] = pVia->FBBase + pVia->swov.SWDevice.dwSWPhysicalAddr[0]; + pVia->swov.SWDevice.lpSWOverlaySurface[1] = pVia->FBBase + pVia->swov.SWDevice.dwSWPhysicalAddr[1]; + + DBG_DD(ErrorF(" lpSWOverlaySurface[0]: %p\n", pVia->swov.SWDevice.lpSWOverlaySurface[0])); + DBG_DD(ErrorF(" lpSWOverlaySurface[1]: %p\n", pVia->swov.SWDevice.lpSWOverlaySurface[1])); + + pVia->VideoStatus |= VIDEO_SWOV_SURFACE_CREATED | VIDEO_SWOV_ON; + } + return retCode; +} + +/* + * Destroy Surface + */ +void +ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv) +{ + VIAPtr pVia = VIAPTR(pScrn); + DBG_DD(ErrorF("ViaSwovSurfaceDestroy: FourCC =0x%08lx\n", + pPriv->FourCC)); + + if (pVia->VideoStatus & VIDEO_SWOV_SURFACE_CREATED) { + DBG_DD(ErrorF("ViaSwovSurfaceDestroy: VideoStatus =0x%08lx\n", + pVia->VideoStatus)); + + switch (pPriv->FourCC) { + case FOURCC_YUY2: + pVia->swov.SrcFourCC = 0; + + VIAFreeLinear(&pVia->swov.SWfbMem); + if ((pVia->swov.gdwVideoFlagSW & SW_USE_HQV)) + VIAFreeLinear(&pVia->swov.HQVMem); + pVia->swov.gdwVideoFlagSW = 0; + break; + + case FOURCC_HQVSW: + VIAFreeLinear(&pVia->swov.HQVMem); + pVia->swov.gdwVideoFlagSW = 0; + break; + + case FOURCC_YV12: + case FOURCC_XVMC: + pVia->swov.SrcFourCC = 0; + + VIAFreeLinear(&pVia->swov.SWfbMem); + VIAFreeLinear(&pVia->swov.HQVMem); + pVia->swov.gdwVideoFlagSW = 0; + break; + } + + pVia->VideoStatus &= ~VIDEO_SWOV_SURFACE_CREATED; + + } else + DBG_DD(ErrorF("ViaSwovSurfaceDestroy: No SW Overlay Surface Destroyed," + " VideoStatus =0x%08lx\n", pVia->VideoStatus)); +} + +static void SetFIFO_V1(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 threshold) +{ + SaveVideoRegister(pVia, V_FIFO_CONTROL, ((depth-1) & 0x7f) | + ((prethreshold & 0x7f) << 24) | ((threshold & 0x7f) << 8)); +} + +static void SetFIFO_V3(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 threshold) +{ + SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL, + (VIDInD(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK) | + ((depth - 1) & 0xff) | ((threshold & 0xff) << 8)); + SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL, + (VIDInD(ALPHA_V3_PREFIFO_CONTROL) & ~V3_FIFO_MASK) | + (prethreshold & 0x7f)); +} + +static void SetFIFO_64or32(VIAPtr pVia) +{ + /*=* Modify for C1 FIFO *=*/ + /* WARNING: not checking Chipset! */ + if (CLE266_REV_IS_CX(pVia->ChipRev)) + SetFIFO_V1(pVia, 64, 56, 56); + else + SetFIFO_V1(pVia, 32, 29, 16); +} + +static void SetFIFO_64or16(VIAPtr pVia) +{ + /*=* Modify for C1 FIFO *=*/ + /* WARNING: not checking Chipset! */ + if (CLE266_REV_IS_CX(pVia->ChipRev)) + SetFIFO_V1(pVia, 64, 56, 56); + else + SetFIFO_V1(pVia, 16, 12, 8); +} + +static void SetFIFO_64or48or32(VIAPtr pVia) +{ + /*=* Modify for C1 FIFO *=*/ + /* WARNING: not checking Chipset! */ + if (CLE266_REV_IS_CX(pVia->ChipRev)) + SetFIFO_V1(pVia, 64, 56, 56); + else { + if (pVia->swov.gdwUseExtendedFIFO) + SetFIFO_V1(pVia, 48, 40, 40); + else + SetFIFO_V1(pVia, 32, 29, 16); + } +} + +static void SetFIFO_V3_64or32or32(VIAPtr pVia) +{ + switch (pVia->ChipId) + { + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 32, 29, 29); + break; + + case PCI_CHIP_CLE3122: + if (CLE266_REV_IS_CX(pVia->ChipRev)) + SetFIFO_V3(pVia, 64, 56, 56); + else + SetFIFO_V3(pVia, 32, 16, 16); + break; + + default: + break; + } +} + +static void SetFIFO_V3_64or32or16(VIAPtr pVia) +{ + switch (pVia->ChipId) + { + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 32, 29, 29); + break; + + case PCI_CHIP_CLE3122: + if (CLE266_REV_IS_CX(pVia->ChipRev)) + SetFIFO_V3(pVia, 64, 56, 56); + else + SetFIFO_V3(pVia, 16, 16, 8); + break; + + default: + break; + } +} + +static void +SetupFIFOs(VIAPtr pVia, unsigned long videoFlag, unsigned long miniCtl, + unsigned long srcWidth) +{ + if (miniCtl & V1_Y_INTERPOLY) + { + if (pVia->swov.SrcFourCC == FOURCC_YV12 || + pVia->swov.SrcFourCC == FOURCC_XVMC) + { + if (videoFlag & VIDEO_HQV_INUSE) + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or32(pVia); + else + SetFIFO_V3_64or32or16(pVia); + } + else + { + /* Minified video will be skewed without this workaround. */ + if (srcWidth <= 80) /* Fetch count <= 5 */ + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_V1(pVia, 16, 0, 0); + else + SetFIFO_V3(pVia, 16, 16, 0); + } + else + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or16(pVia); + else + SetFIFO_V3_64or32or16(pVia); + } + } + } + else + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or48or32(pVia); + else + { + /* Fix V3 bug. */ + if (srcWidth <= 8) + SetFIFO_V3(pVia, 1, 0, 0); + else + SetFIFO_V3_64or32or32(pVia); + } + } + } + else + { + if (pVia->swov.SrcFourCC == FOURCC_YV12 || + pVia->swov.SrcFourCC == FOURCC_XVMC) + { + if (videoFlag & VIDEO_HQV_INUSE) + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or32(pVia); + else + SetFIFO_V3_64or32or16(pVia); + } + else + { + /* Minified video will be skewed without this workaround. */ + if (srcWidth <= 80) /* Fetch count <= 5 */ + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_V1(pVia, 16, 0, 0); + else + SetFIFO_V3(pVia, 16, 16, 0); + } + else + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or16(pVia); + else + SetFIFO_V3_64or32or16(pVia); + } + } + } + else + { + if (videoFlag & VIDEO_1_INUSE) + SetFIFO_64or48or32(pVia); + else + { + /* Fix V3 bug. */ + if (srcWidth <= 8) + SetFIFO_V3(pVia, 1, 0, 0); + else + SetFIFO_V3_64or32or32(pVia); + } + } + } +} + +static CARD32 SetColorKey(VIAPtr pVia, unsigned long videoFlag, + CARD32 keyLow, CARD32 keyHigh, CARD32 compose) +{ + keyLow &= 0x00FFFFFF; + + keyLow|=0x40000000; + + /*SaveVideoRegister(pVia, V_COLOR_KEY, keyLow);*/ + + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V_COLOR_KEY, keyLow); + } + else { + /* IVOR if (pVia->HWDiff.dwSupportTwoColorKey )*/ /*CLE_C0*/ + SaveVideoRegister(pVia, V3_COLOR_KEY, keyLow); + } + + /*compose = (compose & ~0x0f) | SELECT_VIDEO_IF_COLOR_KEY;*/ + /*CLE_C0*/ + compose = (compose & ~0x0f) | SELECT_VIDEO_IF_COLOR_KEY | SELECT_VIDEO3_IF_COLOR_KEY; + /*compose = (compose & ~0x0f) ;*/ + + return compose; +} + + +static CARD32 SetChromaKey(VIAPtr pVia, unsigned long videoFlag, + CARD32 chromaLow, CARD32 chromaHigh, + CARD32 miniCtl, CARD32 compose) +{ + chromaLow &= CHROMA_KEY_LOW; + chromaHigh &= CHROMA_KEY_HIGH; + + chromaLow |= (VIDInD(V_CHROMAKEY_LOW) & ~CHROMA_KEY_LOW); + chromaHigh |= (VIDInD(V_CHROMAKEY_HIGH)& ~CHROMA_KEY_HIGH); + + chromaLow |= 0x40000000; + + SaveVideoRegister(pVia, V_CHROMAKEY_HIGH, chromaHigh); + if (videoFlag & VIDEO_1_INUSE) + { + SaveVideoRegister(pVia, V_CHROMAKEY_LOW, chromaLow&(~V_CHROMAKEY_V3)); + /*Temporarily solve the H/W Interpolation error when using Chroma Key*/ + SaveVideoRegister(pVia, V1_MINI_CONTROL, miniCtl & 0xFFFFFFF8); + } + else + { + SaveVideoRegister(pVia, V_CHROMAKEY_LOW, chromaLow | V_CHROMAKEY_V3); + SaveVideoRegister(pVia, V3_MINI_CONTROL, miniCtl & 0xFFFFFFF8); + } + + /*Modified by Scottie[2001.12.5] for select video if (color key & chroma key)*/ + if (compose == SELECT_VIDEO_IF_COLOR_KEY) + compose = SELECT_VIDEO_IF_COLOR_KEY | SELECT_VIDEO_IF_CHROMA_KEY; + else + compose = (compose & ~0x0f) | SELECT_VIDEO_IF_CHROMA_KEY; + + return compose; +} + +static void SetVideoStart(VIAPtr pVia, unsigned long videoFlag, + unsigned int numbufs, CARD32 a1, CARD32 a2, CARD32 a3) +{ + CARD32 V1Addr[3] = {V1_STARTADDR_0, V1_STARTADDR_1, V1_STARTADDR_2}; + CARD32 V3Addr[3] = {V3_STARTADDR_0, V3_STARTADDR_1, V3_STARTADDR_2}; + CARD32* VideoAddr = (videoFlag & VIDEO_1_INUSE) ? V1Addr : V3Addr; + + SaveVideoRegister(pVia, VideoAddr[0], a1); + if (numbufs > 1) SaveVideoRegister(pVia, VideoAddr[1], a2); + if (numbufs > 2) SaveVideoRegister(pVia, VideoAddr[2], a3); +} + +static void SetHQVFetch(VIAPtr pVia, CARD32 srcFetch, unsigned long srcHeight) +{ +unsigned long proReg=0; + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + if (!pVia->HWDiff.dwHQVFetchByteUnit) { /* CLE_C0 */ + srcFetch >>= 3; /* fetch unit is 8-byte */ + } + SaveVideoRegister(pVia, proReg|HQV_SRC_FETCH_LINE, ((srcFetch - 1) << 16) | (srcHeight - 1)); +} + +static void SetFetch(VIAPtr pVia, unsigned long videoFlag, CARD32 fetch) +{ + fetch <<= 20; + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V12_QWORD_PER_LINE, fetch); + } + else { + fetch |= VIDInD(V3_ALPHA_QWORD_PER_LINE) & ~V3_FETCH_COUNT; + SaveVideoRegister(pVia, V3_ALPHA_QWORD_PER_LINE, fetch); + } +} + +static void SetDisplayCount(VIAPtr pVia, unsigned long videoFlag, + unsigned long srcWidth, unsigned long srcHeight) +{ + unsigned long DisplayCount; + + /* Removed VIA's large pixelformat switch/case. + * All formats (YV12, UYVY, YUY2, VIA, RGB16 and RGB32) + * seem to use the same count. /A + */ + + if (videoFlag & VIDEO_HQV_INUSE) + DisplayCount = srcWidth - 1; + else + DisplayCount = srcWidth - pVia->swov.overlayRecordV1.dwminifyH; + + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_SOURCE_HEIGHT, (srcHeight << 16) | DisplayCount); + else + SaveVideoRegister(pVia, V3_SOURCE_WIDTH, DisplayCount); +} + +static void SetMiniAndZoom(VIAPtr pVia, unsigned long videoFlag, + CARD32 miniCtl, CARD32 zoomCtl) +{ + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V1_MINI_CONTROL, miniCtl); + SaveVideoRegister(pVia, V1_ZOOM_CONTROL, zoomCtl); + } + else { + SaveVideoRegister(pVia, V3_MINI_CONTROL, miniCtl); + SaveVideoRegister(pVia, V3_ZOOM_CONTROL, zoomCtl); + } +} + +static void SetVideoControl(VIAPtr pVia, unsigned long videoFlag, CARD32 vidCtl) +{ + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_CONTROL, vidCtl); + else + SaveVideoRegister(pVia, V3_CONTROL, vidCtl); +} + +static void FireVideoCommand(VIAPtr pVia, unsigned long videoFlag, CARD32 compose) +{ + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V_COMPOSE_MODE, compose | V1_COMMAND_FIRE); + else + SaveVideoRegister(pVia, V_COMPOSE_MODE, compose | V3_COMMAND_FIRE); +} + +static void +SetVideoWindow(ScrnInfoPtr pScrn, unsigned long videoFlag, LPDDUPDATEOVERLAY pUpdate) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + CARD32 left = pUpdate->DstLeft; + CARD32 top = pUpdate->DstTop; + CARD32 right = pUpdate->DstRight - 1; + CARD32 bottom = pUpdate->DstBottom - 1; + + DBG_DD(ErrorF("SetVideoWindow: X (%ld,%ld) Y (%ld,%ld)\n", + left, right, top, bottom)); + + /* modify for HW DVI limitation, + * When we enable the CRT and DVI both, then change resolution. + * If the resolution small than the panel physical size, + * the video display in Y direction will be cut. + * So, we need to adjust the Y top and bottom position. + */ + if (videoFlag & VIDEO_1_INUSE) { + if (pBIOSInfo->SetDVI && pBIOSInfo->scaleY) { + top = pUpdate->DstTop * pBIOSInfo->panelY / pScrn->currentMode->VDisplay; + bottom = pUpdate->DstBottom * pBIOSInfo->panelY / pScrn->currentMode->VDisplay; + } + } + + if (top < 0) + top = 0; + else if (top > 2047) + top = 2047; + + if (bottom < 0) + bottom = 0; + else if (bottom > 2047) + bottom = 2047; + + if (left < 0) + left = 0; + else if (left > 2047) + left = 2047; + + if (right < 0) + right = 0; + else if (right > 2047) + right = 2047; + + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V1_WIN_END_Y, (right << 16) | bottom); + SaveVideoRegister(pVia, V1_WIN_START_Y, (left << 16) | top); + } else { + SaveVideoRegister(pVia, V3_WIN_END_Y, (right << 16) | bottom); + SaveVideoRegister(pVia, V3_WIN_START_Y, (left << 16) | top); + } +} + +/* IVOR - Guess what. this needs checking */ + +/**************************************************************************** + * + * Upd_Video() + * + ***************************************************************************/ +static Bool +Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag, + unsigned long startAddr, LPDDUPDATEOVERLAY pUpdate, + unsigned long srcPitch, + unsigned long oriSrcWidth, unsigned long oriSrcHeight, + unsigned long deinterlaceMode, + unsigned long haveColorKey, unsigned long haveChromaKey, + unsigned long colorKeyLow, unsigned long colorKeyHigh, + unsigned long chromaKeyLow, unsigned long chromaKeyHigh) +{ + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAHWDiff *hwDiff = &pVia->HWDiff; + + int i; + unsigned long vidCtl = 0, compose; + unsigned long srcWidth, srcHeight, dstWidth, dstHeight; + unsigned long zoomCtl = 0, miniCtl = 0; + unsigned long hqvCtl = 0; + unsigned long hqvFilterCtl = 0, hqvMiniCtl = 0; + unsigned long haveHQVzoomH = 0, haveHQVzoomV = 0; + unsigned long hqvSrcWidth = 0, hqvDstWidth = 0; + unsigned long hqvSrcFetch = 0, hqvOffset = 0; + unsigned long dwOffset = 0,fetch = 0,tmp = 0; + +unsigned long proReg=0; + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(videoFlag & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + compose = (VIDInD(V_COMPOSE_MODE) & + ~(SELECT_VIDEO_IF_COLOR_KEY | V1_COMMAND_FIRE | V3_COMMAND_FIRE)) | V_COMMAND_LOAD_VBI; + + DBG_DD(ErrorF("// Upd_Video:\n")); + DBG_DD(ErrorF("Modified rSrc X (%ld,%ld) Y (%ld,%ld)\n", + pUpdate->SrcLeft, pUpdate->SrcRight, + pUpdate->SrcTop, pUpdate->SrcBottom)); + DBG_DD(ErrorF("Modified rDest X (%ld,%ld) Y (%ld,%ld)\n", + pUpdate->DstLeft, pUpdate->DstRight, + pUpdate->DstTop, pUpdate->DstBottom)); + + pVia->swov.overlayRecordV1.dwWidth = dstWidth = pUpdate->DstRight - pUpdate->DstLeft; + pVia->swov.overlayRecordV1.dwHeight = dstHeight = pUpdate->DstBottom - pUpdate->DstTop; + srcWidth = (unsigned long) pUpdate->SrcRight - pUpdate->SrcLeft; + srcHeight = (unsigned long) pUpdate->SrcBottom - pUpdate->SrcTop; + DBG_DD(ErrorF("===srcWidth= %ld \n", srcWidth)); + DBG_DD(ErrorF("===srcHeight= %ld \n", srcHeight)); + + vidCtl = ViaSetVidCtl(pVia, videoFlag); + viaOverlayGetV1V3Format(pVia, (videoFlag & VIDEO_1_INUSE) ? 1 : 3, + videoFlag, &vidCtl, &hqvCtl); + +#if 0 + if (hwDiff->dwThreeHQVBuffer) { /* CLE_C0: HQV supports triple-buffering */ + hqvCtl &= ~HQV_SW_FLIP; + hqvCtl |= HQV_TRIPLE_BUFF | HQV_FLIP_STATUS; + } +#endif + + /* Starting address of source and Source offset*/ + dwOffset = viaOverlayGetSrcStartAddress(pVia, videoFlag, pUpdate, srcPitch, &hqvOffset); + DBG_DD(ErrorF("===dwOffset= 0x%lx \n", dwOffset)); + DBG_DD(ErrorF("===hqvOffset= 0x%lx \n", hqvOffset)); + + pVia->swov.overlayRecordV1.dwOffset = dwOffset; + + if (pVia->swov.SrcFourCC == FOURCC_YV12 || + pVia->swov.SrcFourCC == FOURCC_XVMC) { + YCBCRREC YCbCr; + if (videoFlag & VIDEO_HQV_INUSE) { + SetVideoStart(pVia, videoFlag, hwDiff->dwThreeHQVBuffer ? 3 : 2, + pVia->swov.overlayRecordV1.dwHQVAddr[0]+dwOffset, + pVia->swov.overlayRecordV1.dwHQVAddr[1]+dwOffset, + pVia->swov.overlayRecordV1.dwHQVAddr[2]+dwOffset); + + if (pVia->swov.SrcFourCC != FOURCC_XVMC) { + if (pVia->ChipId == PCI_CHIP_VT3259) + { + DBG_DD(ErrorF("viaOverlayGetYCbCrStartAddressProA\n")); + YCbCr = viaOverlayGetYCbCrStartAddressProA(videoFlag, startAddr, + pVia->swov.overlayRecordV1.dwOffset, + pVia->swov.overlayRecordV1.dwUVoffset, + srcPitch,oriSrcHeight); + } + else + { + DBG_DD(ErrorF("viaOverlayGetYCbCrStartAddress\n")); + YCbCr = viaOverlayGetYCbCrStartAddress(videoFlag, startAddr, + pVia->swov.overlayRecordV1.dwOffset, + pVia->swov.overlayRecordV1.dwUVoffset, + srcPitch,oriSrcHeight); + } + + if (pVia->ChipId == PCI_CHIP_VT3259) + SaveVideoRegister(pVia, proReg|0x1cc, dwOffset); + SaveVideoRegister(pVia, proReg|HQV_SRC_STARTADDR_Y, YCbCr.dwY); + SaveVideoRegister(pVia, proReg|HQV_SRC_STARTADDR_U, YCbCr.dwCR); + + if (pVia->ChipId != PCI_CHIP_VT3259) + SaveVideoRegister(pVia, proReg|HQV_SRC_STARTADDR_V, YCbCr.dwCB); + } + } else { + DBG_DD(ErrorF("viaOverlayGetYCbCrStartAddress2\n")); + YCbCr = viaOverlayGetYCbCrStartAddress(videoFlag, startAddr, + pVia->swov.overlayRecordV1.dwOffset, + pVia->swov.overlayRecordV1.dwUVoffset, + srcPitch, oriSrcHeight); + + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V1_STARTADDR_0, YCbCr.dwY); + SaveVideoRegister(pVia, V1_STARTADDR_CB0, YCbCr.dwCR); + SaveVideoRegister(pVia, V1_STARTADDR_CR0, YCbCr.dwCB); + } else + DBG_DD(ErrorF("Upd_Video() : We do not support YV12 with V3!\n")); + } + } else { + if (videoFlag & VIDEO_HQV_INUSE) { + hqvSrcWidth = (unsigned long) pUpdate->SrcRight - pUpdate->SrcLeft; + hqvDstWidth = (unsigned long) pUpdate->DstRight - pUpdate->DstLeft; + + if (hqvSrcWidth > hqvDstWidth) + dwOffset = dwOffset * hqvDstWidth / hqvSrcWidth; + + SetVideoStart(pVia, videoFlag, hwDiff->dwThreeHQVBuffer ? 3 : 2, + pVia->swov.overlayRecordV1.dwHQVAddr[0] + hqvOffset, + pVia->swov.overlayRecordV1.dwHQVAddr[1] + hqvOffset, + pVia->swov.overlayRecordV1.dwHQVAddr[2] + hqvOffset); + + if (pVia->ChipId == PCI_CHIP_VT3259) + SaveVideoRegister(pVia, proReg|0x1cc, dwOffset); + + SaveVideoRegister(pVia, proReg|HQV_SRC_STARTADDR_Y, startAddr); + } else { + startAddr += dwOffset; + SetVideoStart(pVia, videoFlag, 1, startAddr, 0, 0); + } + } + + fetch = viaOverlayGetFetch(pVia, videoFlag, + srcWidth, dstWidth, oriSrcWidth, &hqvSrcFetch); + DBG_DD(ErrorF("===fetch= 0x%lx \n", fetch)); + +#if 0 + /* For DCT450 test-BOB INTERLEAVE */ + if ((deinterlaceMode & DDOVER_INTERLEAVED) && (deinterlaceMode & DDOVER_BOB)) { + if (videoFlag & VIDEO_HQV_INUSE) + hqvCtl |= HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_DEINTERLACE; + else + vidCtl |= V1_BOB_ENABLE | V1_FRAME_BASE; + } else if (deinterlaceMode & DDOVER_BOB) { + if (videoFlag & VIDEO_HQV_INUSE) + /* The HQV source data line count should be two times of the original line count */ + hqvCtl |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE; + else + vidCtl |= V1_BOB_ENABLE; + } +#endif + + if (videoFlag & VIDEO_HQV_INUSE) { + if (!(deinterlaceMode & DDOVER_INTERLEAVED) && (deinterlaceMode & DDOVER_BOB)) + SetHQVFetch(pVia, hqvSrcFetch, oriSrcHeight << 1); + else + SetHQVFetch(pVia, hqvSrcFetch, oriSrcHeight); + + if (pVia->swov.SrcFourCC == FOURCC_YV12 || + pVia->swov.SrcFourCC == FOURCC_XVMC) { + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_STRIDE, srcPitch << 1); + else + SaveVideoRegister(pVia, V3_STRIDE, srcPitch << 1); + + SaveVideoRegister(pVia, proReg|HQV_SRC_STRIDE, ((srcPitch >> 1) << 16) | srcPitch); + SaveVideoRegister(pVia, proReg|HQV_DST_STRIDE, (srcPitch << 1)); + } else { + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_STRIDE, srcPitch); + else + SaveVideoRegister(pVia, V3_STRIDE, srcPitch); + + SaveVideoRegister(pVia, proReg|HQV_SRC_STRIDE, srcPitch); + SaveVideoRegister(pVia, proReg|HQV_DST_STRIDE, srcPitch); + } + + } else { + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_STRIDE, srcPitch | (srcPitch << 15)); + else + SaveVideoRegister(pVia, V3_STRIDE, srcPitch | (srcPitch << 15)); + } + + /* Set destination window */ + SetVideoWindow(pScrn, videoFlag, pUpdate); + + compose |= ALWAYS_SELECT_VIDEO; + + /* Setup X zoom factor*/ + + pVia->swov.overlayRecordV1.dwFetchAlignment = 0; + + if (!viaOverlayHQVCalcZoomWidth(pVia, videoFlag, srcWidth, dstWidth, &zoomCtl, &miniCtl, + &hqvFilterCtl, &hqvMiniCtl, &haveHQVzoomH)) { + /* Need to scale (minify) too much - can't handle it. */ + SetFetch(pVia, videoFlag, fetch); + FireVideoCommand(pVia, videoFlag, compose); + FlushVidRegBuffer(pVia); + return FALSE; + } + + SetFetch(pVia, videoFlag, fetch); + + /* Setup Y zoom factor */ + + /* For DCT450 test-BOB INTERLEAVE */ + if ((deinterlaceMode & DDOVER_INTERLEAVED) && (deinterlaceMode & DDOVER_BOB)) { + if (!(videoFlag & VIDEO_HQV_INUSE)) { + srcHeight /= 2; + if (videoFlag & VIDEO_1_INUSE) + vidCtl |= V1_BOB_ENABLE | V1_FRAME_BASE; + else + vidCtl |= V3_BOB_ENABLE | V3_FRAME_BASE; + } else + hqvCtl |= HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_DEINTERLACE; + } else if (deinterlaceMode & DDOVER_BOB) { + if (videoFlag & VIDEO_HQV_INUSE) { + srcHeight <<= 1; + hqvCtl |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE; + } else { + if (videoFlag & VIDEO_1_INUSE) + vidCtl |= V1_BOB_ENABLE; + else + vidCtl |= V3_BOB_ENABLE; + } + } + + SetDisplayCount(pVia, videoFlag, srcWidth, srcHeight); + + if (!viaOverlayHQVCalcZoomHeight(pVia, srcHeight, dstHeight, &zoomCtl, &miniCtl, + &hqvFilterCtl, &hqvMiniCtl ,&haveHQVzoomV)) { + /* Need to scale (minify) too much - can't handle it. */ + FireVideoCommand(pVia, videoFlag, compose); + FlushVidRegBuffer(pVia); + return FALSE; + } + + SetupFIFOs(pVia, videoFlag, miniCtl, srcWidth); + + if (videoFlag & VIDEO_HQV_INUSE) { + miniCtl=0; + + if (haveHQVzoomH || haveHQVzoomV) { + tmp = 0; + + if (haveHQVzoomH) { + miniCtl = V1_X_INTERPOLY; + tmp = zoomCtl & 0xffff0000; + } + + if (haveHQVzoomV) { + miniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; + tmp |= zoomCtl & 0x0000ffff; + hqvFilterCtl &= 0xfffdffff; + } + + /* Temporary fix for 2D bandwidth problem. 2002/08/01*/ + if (pVia->swov.gdwUseExtendedFIFO) + miniCtl &= ~V1_Y_INTERPOLY; + + SetMiniAndZoom(pVia, videoFlag, miniCtl, tmp); + } else { + if (srcHeight == dstHeight) + hqvFilterCtl &= 0xfffdffff; + + SetMiniAndZoom(pVia, videoFlag, 0, 0); + } + SaveVideoRegister(pVia, proReg|HQV_MINIFY_CONTROL, hqvMiniCtl); + SaveVideoRegister(pVia, proReg|HQV_FILTER_CONTROL, hqvFilterCtl); + } else + SetMiniAndZoom(pVia, videoFlag, miniCtl, zoomCtl); + + if (haveColorKey) + compose = SetColorKey(pVia, videoFlag, colorKeyLow, colorKeyHigh, compose); + + if (haveChromaKey) + compose = SetChromaKey(pVia, videoFlag, chromaKeyLow, chromaKeyHigh, + miniCtl, compose); + +/*wait hqvdone.*/ + viaWaitHQVDone(pVia); + +DBG_DD(ErrorF("** 6 of %ld **", pVia->VidRegCursor)); + + /* Setup video control*/ + if (videoFlag & VIDEO_HQV_INUSE) + { + if (!pVia->swov.SWVideo_ON) + { + DBG_DD(ErrorF(" First HQV\n")); + + FlushVidRegBuffer(pVia); + + DBG_DD(ErrorF(" Wait flips")); + + if (hwDiff->dwHQVInitPatch) + { + DBG_DD(ErrorF(" Initializing HQV twice ...")); + for (i = 0; i < 2; i++) { + viaWaitHQVFlipClear(pVia, + ((hqvCtl & ~HQV_SW_FLIP) | HQV_FLIP_STATUS) & ~HQV_ENABLE); + VIDOutD(proReg|HQV_CONTROL, hqvCtl); + viaWaitHQVFlip(pVia); + } + DBG_DD(ErrorF(" done.\n")); + } + else + { /* CLE_C0 */ + CARD32 volatile *HQVCtrl = + (CARD32 volatile *) (pVia->VidMapBase + (proReg|HQV_CONTROL)); + +#if 1 /* check HQV is idle */ + DBG_DD(ErrorF("HQV control wf - %08lx\n", *HQVCtrl)); + while (!(*HQVCtrl & HQV_IDLE)) { + DBG_DD(ErrorF("HQV control busy - %08lx\n", *HQVCtrl)); + usleep(1); + } +#endif + + VIDOutD(proReg|HQV_CONTROL, hqvCtl | HQV_FLIP_STATUS); + VIDOutD(proReg|HQV_CONTROL, hqvCtl | HQV_SW_FLIP); + + DBG_DD(ErrorF("HQV control wf5 - %08lx\n", *HQVCtrl)); + DBG_DD(ErrorF(" Wait flips5")); + +/* for (i = 0; (i < 50) && !(*HQVCtrl & HQV_FLIP_STATUS); i++) { + DBG_DD(ErrorF(" HQV wait %d %08x\n",i, *HQVCtrl)); + *HQVCtrl |= HQV_SW_FLIP | HQV_FLIP_STATUS; + usleep(1); + }*/ + + viaWaitHQVFlip(pVia); + + DBG_DD(ErrorF(" Wait flips6")); + } + + + + if (videoFlag & VIDEO_1_INUSE) + { + VIDOutD(V1_CONTROL, vidCtl); + VIDOutD(V_COMPOSE_MODE, compose | V1_COMMAND_FIRE); + if (pVia->swov.gdwUseExtendedFIFO) + { + /*Set Display FIFO*/ + DBG_DD(ErrorF(" Wait flips7")); + viaWaitVBI(pVia); + DBG_DD(ErrorF(" Wait flips 8")); + hwp->writeSeq(hwp, 0x17, 0x2F); + ViaSeqMask(hwp, 0x16, 0x14, 0x1F); + hwp->writeSeq(hwp, 0x18, 0x56); + DBG_DD(ErrorF(" Wait flips 9")); + } + } + else + { + DBG_DD(ErrorF(" Wait flips 10 ctl: %08lx, comp %08lx\n", vidCtl,compose)); + VIDOutD(V3_CONTROL, vidCtl); + VIDOutD(V_COMPOSE_MODE, compose | V3_COMMAND_FIRE); + } + + DBG_DD(ErrorF(" Done flips")); + } + else + { + DBG_DD(ErrorF(" Normal called\n")); + SaveVideoRegister(pVia, proReg|HQV_CONTROL, hqvCtl | HQV_FLIP_STATUS); + + SetVideoControl(pVia, videoFlag, vidCtl); + FireVideoCommand(pVia, videoFlag, compose); + /*viaWaitHQVDone(pVia);*/ + + FlushVidRegBuffer(pVia); + } + } + else + { + SetVideoControl(pVia, videoFlag, vidCtl); + FireVideoCommand(pVia, videoFlag, compose); +/* viaWaitHQVDone(pVia);*/ + FlushVidRegBuffer(pVia); + } + pVia->swov.SWVideo_ON = TRUE; + + DBG_DD(ErrorF(" Done Upd_Video")); + + return TRUE; + +} /* Upd_Video */ + +/* + * VIAVidUpdateOverlay + * Parameters: src rectangle, dst rectangle, colorkey... + * Return Value: unsigned long of state + * note: Update the overlay image param. + */ +Bool +VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) +{ + VIAPtr pVia = VIAPTR(pScrn); + OVERLAYRECORD* ovlV1 = &pVia->swov.overlayRecordV1; + + unsigned long flags = pUpdate->dwFlags; + unsigned long videoFlag = 0; + unsigned long startAddr = 0; + unsigned long deinterlaceMode=0; + + unsigned long haveColorKey = 0, haveChromaKey = 0; + unsigned long colorKeyLow = 0, colorKeyHigh = 0; + unsigned long chromaKeyLow = 0, chromaKeyHigh = 0; + + + unsigned long scrnWidth, scrnHeight; + int dstTop, dstBottom, dstLeft, dstRight; + int panDX,panDY; /* Panning delta */ + + unsigned long proReg=0; + + panDX = pVia->swov.panning_x - pVia->swov.panning_old_x; + panDY = pVia->swov.panning_y - pVia->swov.panning_old_y; + + /* Adjust to fix panning mode bug */ + + pUpdate->DstLeft -= panDX; + pUpdate->DstTop -= panDY; + pUpdate->DstRight -= panDX; + pUpdate->DstBottom -= panDY; + + DBG_DD(ErrorF("Raw rSrc X (%ld,%ld) Y (%ld,%ld)\n", + pUpdate->SrcLeft, pUpdate->SrcRight, + pUpdate->SrcTop, pUpdate->SrcBottom)); + DBG_DD(ErrorF("Raw rDest X (%ld,%ld) Y (%ld,%ld)\n", + pUpdate->DstLeft, pUpdate->DstRight, + pUpdate->DstTop, pUpdate->DstBottom)); + + if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || + (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_XVMC)) + { + videoFlag = pVia->swov.gdwVideoFlagSW; + } + + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(videoFlag & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + + flags |= DDOVER_INTERLEAVED; + + /* Disable destination color keying if the alpha window is in use. */ + if (pVia->swov.gdwAlphaEnabled) + flags &= ~DDOVER_KEYDEST; + + ResetVidRegBuffer(pVia); + + /*for SW decode HW overlay use*/ + startAddr = VIDInD(proReg|HQV_SRC_STARTADDR_Y); + + if (flags & DDOVER_KEYDEST) { + haveColorKey = 1; + colorKeyLow = pUpdate->dwColorSpaceLowValue; + } + + if (flags & DDOVER_INTERLEAVED) + deinterlaceMode |= DDOVER_INTERLEAVED; + + if (flags & DDOVER_BOB) + deinterlaceMode |= DDOVER_BOB; + + if ((pVia->ChipId == PCI_CHIP_CLE3122) && (pScrn->currentMode->HDisplay > 1024)) { + DBG_DD(ErrorF("UseExtendedFIFO\n")); + pVia->swov.gdwUseExtendedFIFO = 1; + } else + pVia->swov.gdwUseExtendedFIFO = 0; + + /* Figure out actual rSrc rectangle */ + + dstLeft = pUpdate->DstLeft; + dstTop = pUpdate->DstTop; + dstRight = pUpdate->DstRight; + dstBottom = pUpdate->DstBottom; + + scrnWidth = pScrn->currentMode->HDisplay; + scrnHeight = pScrn->currentMode->VDisplay; + + if (dstLeft < 0) { + pUpdate->SrcLeft = (((-dstLeft) * ovlV1->dwV1OriWidth) + + ((dstRight - dstLeft) >> 1)) / (dstRight - dstLeft); + } + if (dstRight > scrnWidth) { + pUpdate->SrcRight = (((scrnWidth - dstLeft) * ovlV1->dwV1OriWidth) + + ((dstRight - dstLeft) >> 1)) / (dstRight - dstLeft); + } + if (dstTop < 0) { + pUpdate->SrcTop = (((-dstTop) * ovlV1->dwV1OriHeight) + + ((dstBottom - dstTop) >> 1)) / (dstBottom - dstTop); + } + if (dstBottom > scrnHeight) { + pUpdate->SrcBottom = (((scrnHeight - dstTop) * ovlV1->dwV1OriHeight) + + ((dstBottom - dstTop) >> 1)) / (dstBottom - dstTop); + } + + /* Save modified src & original dest rectangle param. */ + + if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || + (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_XVMC)) { + pVia->swov.SWDevice.gdwSWDstLeft = pUpdate->DstLeft + panDX; + pVia->swov.SWDevice.gdwSWDstTop = pUpdate->DstTop + panDY; + pVia->swov.SWDevice.gdwSWDstWidth = pUpdate->DstRight - pUpdate->DstLeft; + pVia->swov.SWDevice.gdwSWDstHeight = pUpdate->DstBottom - pUpdate->DstTop; + + pVia->swov.SWDevice.gdwSWSrcWidth = + ovlV1->dwV1SrcWidth = pUpdate->SrcRight - pUpdate->SrcLeft; + pVia->swov.SWDevice.gdwSWSrcHeight = + ovlV1->dwV1SrcHeight = pUpdate->SrcBottom - pUpdate->SrcTop; + } + + ovlV1->dwV1SrcLeft = pUpdate->SrcLeft; + ovlV1->dwV1SrcRight = pUpdate->SrcRight; + ovlV1->dwV1SrcTop = pUpdate->SrcTop; + ovlV1->dwV1SrcBot = pUpdate->SrcBottom; + + /* Figure out actual rDest rectangle */ + + pUpdate->DstLeft = (dstLeft < 0) ? 0 : dstLeft; + pUpdate->DstTop = (dstTop < 0) ? 0 : dstTop; + if (pUpdate->DstTop >= scrnHeight) pUpdate->DstTop = scrnHeight-1; + pUpdate->DstRight = (dstRight > scrnWidth) ? scrnWidth : dstRight; + pUpdate->DstBottom = (dstBottom > scrnHeight) ? scrnHeight : dstBottom; + + /* Update the overlay */ + + if (!Upd_Video(pScrn, videoFlag, startAddr, pUpdate, + pVia->swov.SWDevice.dwPitch, ovlV1->dwV1OriWidth, + ovlV1->dwV1OriHeight, deinterlaceMode, haveColorKey, haveChromaKey, + colorKeyLow, colorKeyHigh, chromaKeyLow, chromaKeyHigh)) + return FALSE; + + pVia->swov.SWVideo_ON = FALSE; + + pVia->swov.panning_old_x = pVia->swov.panning_x; + pVia->swov.panning_old_y = pVia->swov.panning_y; + + return TRUE; + +} /*VIAVidUpdateOverlay*/ + +/* + * + */ +void +ViaOverlayHide(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD32 videoFlag = 0; + unsigned long proReg = 0; + + if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || + (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_XVMC)) + videoFlag = pVia->swov.gdwVideoFlagSW; + + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(videoFlag & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + + ResetVidRegBuffer(pVia); + + if (pVia->HWDiff.dwHQVDisablePatch) + ViaSeqMask(hwp, 0x2E, 0x00, 0x10); + + SaveVideoRegister(pVia, V_FIFO_CONTROL, V1_FIFO_PRETHRESHOLD12 | + V1_FIFO_THRESHOLD8 | V1_FIFO_DEPTH16); + SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL, ALPHA_FIFO_THRESHOLD4 + | ALPHA_FIFO_DEPTH8 | V3_FIFO_THRESHOLD24 | V3_FIFO_DEPTH32); + + if (videoFlag & VIDEO_HQV_INUSE) + SaveVideoRegister(pVia, proReg|HQV_CONTROL, VIDInD(proReg|HQV_CONTROL) & ~HQV_ENABLE); + + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_CONTROL, VIDInD(V1_CONTROL) & ~V1_ENABLE); + else + SaveVideoRegister(pVia, V3_CONTROL, VIDInD(V3_CONTROL) & ~V3_ENABLE); + + FireVideoCommand(pVia, videoFlag, VIDInD(V_COMPOSE_MODE)); + FlushVidRegBuffer(pVia); + + if (pVia->HWDiff.dwHQVDisablePatch) + ViaSeqMask(hwp, 0x2E, 0x10, 0x10); + + pVia->swov.SWVideo_ON = FALSE; + + if (pVia->swov.gdwUseExtendedFIFO) + ViaSetPrimaryFIFO(pScrn, pScrn->currentMode); + + pVia->VideoStatus &= ~VIDEO_SWOV_ON; +} diff --git a/unichrome/via_swov.h b/unichrome/via_swov.h new file mode 100644 index 000000000000..ac84d6d512d6 --- /dev/null +++ b/unichrome/via_swov.h @@ -0,0 +1,83 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_SWOV_H_ +#define _VIA_SWOV_H_ 1 + +/* #define XV_DEBUG 1 */ /* write log msg to /var/log/XFree86.0.log */ + +#ifdef XV_DEBUG +# define DBG_DD(x) (x) +#else +# define DBG_DD(x) +#endif + +#include "via_priv.h" +#include "via_xvpriv.h" + +/* Definition for VideoStatus */ +#define VIDEO_NULL 0x00000000 +#define VIDEO_SWOV_SURFACE_CREATED 0x00000001 +#define VIDEO_SWOV_ON 0x00000002 + +/*For Video HW Difference */ +#define VID_HWDIFF_TRUE 0x00000001 +#define VID_HWDIFF_FALSE 0x00000000 + +/* + * Video HW Difference Structure + */ +typedef struct __VIAHWDiff +{ + unsigned long dwThreeHQVBuffer; /* Use Three HQV Buffers*/ + /* unsigned long dwV3SrcHeightSetting;*/ /* Set Video Source Width and Height*/ + /* unsigned long dwSupportExtendFIFO;*/ /* Support Extand FIFO*/ + unsigned long dwHQVFetchByteUnit; /* HQV Fetch Count unit is byte*/ + unsigned long dwHQVInitPatch; /* Initialize HQV Engine 2 times*/ + /*unsigned long dwSupportV3Gamma;*/ /* Support V3 Gamma */ + /*unsigned long dwUpdFlip;*/ /* Set HQV3D0[15] to flip video*/ + unsigned long dwHQVDisablePatch; /* Change Video Engine Clock setting for HQV disable bug*/ + /*unsigned long dwSUBFlip;*/ /* Set HQV3D0[15] to flip video for sub-picture blending*/ + /*unsigned long dwNeedV3Prefetch;*/ /* V3 pre-fetch function for K8*/ + /*unsigned long dwNeedV4Prefetch;*/ /* V4 pre-fetch function for K8*/ + /*unsigned long dwUseSystemMemory;*/ /* Use system memory for DXVA compressed data buffers*/ + /*unsigned long dwExpandVerPatch;*/ /* Patch video HW bug in expand SIM mode or same display path*/ + /*unsigned long dwExpandVerHorPatch;*/ /* Patch video HW bug in expand SAMM mode or same display path*/ + /*unsigned long dwV3ExpireNumTune;*/ /* Change V3 expire number setting for V3 bandwidth issue*/ + /*unsigned long dwV3FIFOThresholdTune;*/ /* Change V3 FIFO, Threshold and Pre-threshold setting for V3 bandwidth issue*/ + /*unsigned long dwCheckHQVFIFOEmpty;*/ /* HW Flip path, need to check HQV FIFO status */ + /*unsigned long dwUseMPEGAGP;*/ /* Use MPEG AGP function*/ + /*unsigned long dwV3FIFOPatch;*/ /* For CLE V3 FIFO Bug (srcWidth <= 8)*/ + unsigned long dwSupportTwoColorKey; /* Support two color key*/ + /* unsigned long dwCxColorSpace; */ /* CLE_Cx ColorSpace*/ +} VIAHWDiff; + +void VIAVidHWDiffInit(ScrnInfoPtr pScrn); +int ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, CARD32 FourCC, CARD16 Width, CARD16 Height); +void ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv); +Bool VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate); +void ViaOverlayHide(ScrnInfoPtr pScrn); + +#endif /* _VIA_SWOV_H_ */ diff --git a/unichrome/via_vbe.c b/unichrome/via_vbe.c new file mode 100644 index 000000000000..5eaaacc7afc9 --- /dev/null +++ b/unichrome/via_vbe.c @@ -0,0 +1,338 @@ +/* + * Copyright 2004 The Unichrome Project [unichrome.sf.net] + * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * + * VBE Mode setting + * + */ + +#include "via_driver.h" +#include "vbe.h" +#include "vbeModes.h" + +#define R16(v) ((v) & 0xffff) + +/* + * Functions more or less stolen from the vesa driver. Added to support BIOS modes directly. + */ + +void +ViaVbeAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + VIAPtr pVia = VIAPTR(xf86Screens[scrnIndex]); + + VBESetDisplayStart(pVia->pVbe, x, y, TRUE); +} + + +static Bool +ViaVbeSetRefresh(ScrnInfoPtr pScrn, int maxRefresh) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + int RealOff; + pointer page = NULL; + vbeInfoPtr pVbe = pVia->pVbe; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVbeSetRefresh\n")); + page = xf86Int10AllocPages(pVbe->pInt10, 1, &RealOff); + if (!page) + return FALSE; + pVbe->pInt10->ax = 0x4F14; + pVbe->pInt10->bx = 0x0001; + pVbe->pInt10->cx = 0; + pVbe->pInt10->dx = 0; + pVbe->pInt10->di = 0; + pVbe->pInt10->num = 0x10; + + /* Set Active Device and Translate BIOS byte definition */ + if (pBIOSInfo->CrtActive) + pVbe->pInt10->cx = 0x01; + if (pBIOSInfo->PanelActive) + pVbe->pInt10->cx |= 0x02; + if (pBIOSInfo->TVActive) + pVbe->pInt10->cx |= 0x04; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Active Device: %d\n", + pVbe->pInt10->cx)); + + if (maxRefresh >= 120) { + pVbe->pInt10->di = 10; + } else if (maxRefresh >= 100) { + pVbe->pInt10->di = 9; + } else if (maxRefresh >= 85) { + pVbe->pInt10->di = 7; + } else if (maxRefresh >= 75) { + pVbe->pInt10->di = 5; + } else { + pVbe->pInt10->di = 0; + } + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Refresh Rate Index: %d\n", + pVbe->pInt10->di)); + + /* Real execution */ + xf86ExecX86int10(pVbe->pInt10); + + if (pVbe->pInt10->ax != 0x4F) + { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Via BIOS Set Device Refresh Rate fail!\n")); + if (page) + xf86Int10FreePages(pVbe->pInt10, page, 1); + return FALSE; + } + + if (page) + xf86Int10FreePages(pVbe->pInt10, page, 1); + + return TRUE; +} + +Bool +ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) +{ + VIAPtr pVia; + VbeModeInfoData *data; + int mode; + + pVia = VIAPTR(pScrn); + + pVia->OverlaySupported = FALSE; + + if (pVia->FirstInit) + memset(pVia->FBBase, 0x00, pVia->videoRambytes); + + data = (VbeModeInfoData*)pMode->Private; + + mode = data->mode | (1 << 15); + + /* enable linear addressing */ + mode |= 1 << 14; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Trying VBE Mode %dx%d (0x%x) Refresh %.2f:\n", + (int) data->data->XResolution, + (int) data->data->YResolution, + mode & ~(1 << 11), (float) data->block->RefreshRate/100.); + ViaVbeSetRefresh(pScrn, 75 /*data->block->RefreshRate/100*/); + if (VBESetVBEMode(pVia->pVbe, mode, data->block) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBESetVBEMode failed"); + if ((data->block || (data->mode & (1 << 11))) && + VBESetVBEMode(pVia->pVbe, (mode & ~(1 << 11)), NULL) == TRUE) { + /* Some cards do not like setting the clock. + */ + xf86ErrorF("...but worked OK without customized refresh and dotclock.\n"); + data->mode &= ~(1 << 11); + } + else { + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); + return (FALSE); + } + } + + if (data->data->XResolution != pScrn->displayWidth) + VBESetLogicalScanline(pVia->pVbe, pScrn->displayWidth); + + pScrn->vtSema = TRUE; + + if (!pVia->NoAccel) + VIAInitialize2DEngine(pScrn); + +#ifdef XF86DRI + VIAInitialize3DEngine(pScrn); +#endif + + ViaVbeAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return (TRUE); +} + +Bool +ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) +{ + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + + if ((MODE_QUERY < 0) || (function > MODE_RESTORE)) + return (FALSE); + + if (function == MODE_SAVE) { + pVia->SavedReg.SR1A = hwp->readSeq(hwp, 0x1A); + } + + /* Query amount of memory to save state */ + if ((function == MODE_QUERY) || + ((function == MODE_SAVE) && (pVia->vbeMode.state == NULL))) { + + /* Make sure we save at least this information in case of failure */ + (void)VBEGetVBEMode(pVia->pVbe, &(pVia->vbeMode.stateMode)); + + if (pVia->vbeMode.major > 1) { + + if (!VBESaveRestore(pVia->pVbe, function, + (pointer) &(pVia->vbeMode.state), + &(pVia->vbeMode.stateSize), + &(pVia->vbeMode.statePage))) + return FALSE; + + } + } + + /* Save/Restore Super VGA state */ + if (function != MODE_QUERY) { + Bool retval = TRUE; + + if (pVia->vbeMode.major > 1) { + if (function == MODE_RESTORE) + memcpy(pVia->vbeMode.state, pVia->vbeMode.pstate, pVia->vbeMode.stateSize); + + if ((retval = VBESaveRestore(pVia->pVbe, function, + (pointer) &(pVia->vbeMode.state), + &(pVia->vbeMode.stateSize), + &(pVia->vbeMode.statePage))) + && (function == MODE_SAVE)) { + /* don't rely on the memory not being touched */ + if (pVia->vbeMode.pstate == NULL) + pVia->vbeMode.pstate = xalloc(pVia->vbeMode.stateSize); + memcpy(pVia->vbeMode.pstate, pVia->vbeMode.state, pVia->vbeMode.stateSize); + } + } + + if (function == MODE_RESTORE) { + VBESetVBEMode(pVia->pVbe, pVia->vbeMode.stateMode, NULL); + } + + if (!retval) + return (FALSE); + + } + + return (TRUE); +} + + +Bool +ViaVbeModePreInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VbeInfoBlock *vbe; + VbeModeInfoBlock *vbeMode; + DisplayModePtr pMode; + int i; + + memset(&(pVia->vbeMode), 0, sizeof(ViaVbeModeInfo)); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Searching for matching VESA mode(s):\n"); + + if ((vbe = VBEGetVBEInfo(pVia->pVbe)) == NULL) { + return FALSE; + } + + pVia->vbeMode.major = (unsigned) (vbe->VESAVersion >> 8); + pVia->vbeMode.minor = vbe->VESAVersion & 0xff; + + pScrn->modePool = VBEGetModePool (pScrn, pVia->pVbe, vbe, V_MODETYPE_VBE); + if (pScrn->modePool == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No matching modes\n"); + return FALSE; + } + + VBESetModeNames(pScrn->modePool); + + i = VBEValidateModes(pScrn, NULL, pScrn->display->modes, + NULL, NULL, 0, 2048, 1, 0, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pScrn->videoRam, LOOKUP_BEST_REFRESH); + + + if (i <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + return (FALSE); + } + + VBESetModeParameters(pScrn, pVia->pVbe); + xf86PruneDriverModes(pScrn); + + pMode = pScrn->modes; + do { + vbeMode = ((VbeModeInfoData*)pMode->Private)->data; + pMode = pMode->next; + } while (pMode != pScrn->modes); + + return TRUE; +} + +static int ViaVbePanelPower(vbeInfoPtr pVbe, int mode) +{ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5F54; + pVbe->pInt10->bx = (mode) ? 0x00 : 0x01; + + xf86ExecX86int10(pVbe->pInt10); + + return (R16(pVbe->pInt10->ax) == 0x015f); +} + +#if 0 +/* + * FIXME: This might be useful in the future. Otherwise feel free to remove. + * if mode=1 sets the panel in a low power, low performance state. + * if mode=0 high performance. + */ + +static int ViaVbePanelLowPower(vbeInfoPtr pVbe, int mode) +{ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5F60; + pVbe->pInt10->bx = (mode) ? 0x01 : 0x00; + + xf86ExecX86int10(pVbe->pInt10); + + return (R16(pVbe->pInt10->ax) == 0x015f); +} +#endif + +void +ViaVbeDoDPMS(ScrnInfoPtr pScrn, int mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + + if (pBIOSInfo->PanelActive) + ViaVbePanelPower(pVia->pVbe, (mode == DPMSModeOn)); + + VBEDPMSSet(pVia->pVbe,mode); +} + +void +ViaVbeDPMS(ScrnInfoPtr pScrn, int mode, int flags) +{ + if (!pScrn->vtSema) + return; + + ViaVbeDoDPMS(pScrn, mode); +} diff --git a/unichrome/via_vgahw.c b/unichrome/via_vgahw.c new file mode 100644 index 000000000000..b1b79cb09b62 --- /dev/null +++ b/unichrome/via_vgahw.c @@ -0,0 +1,189 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * Wrap around xf86 vgaHW + * Provide general IO calls too as they are not part of the vgaHW implementation + * It's a bit daft to provide this short stuff in a seperate file, + * but then again, we'd only complicate matters in already complicated files. + */ +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86.h" +#include "via_driver.h" /* for HAVE_DEBUG */ +#include "via_vgahw.h" + +/* + * The current vgaHW implementation lacks generic IO + * + */ + +/* + * + */ +static +CARD8 +ViaVgahwIn(vgaHWPtr hwp, int address) +{ + if (hwp->MMIOBase) + return MMIO_IN8(hwp->MMIOBase, hwp->MMIOOffset + address); + else + return inb(hwp->PIOOffset + address); +} + +/* + * + */ +static +void +ViaVgahwOut(vgaHWPtr hwp, int address, CARD8 value) +{ + if (hwp->MMIOBase) + MMIO_OUT8(hwp->MMIOBase, hwp->MMIOOffset + address, value); + else + outb(hwp->PIOOffset + address, value); +} + +/* + * indexed. + */ +static +CARD8 +ViaVgahwRead(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress) +{ + ViaVgahwOut(hwp, indexaddress, index); + return ViaVgahwIn(hwp, valueaddress); +} + +/* + * indexed. + */ +void +ViaVgahwWrite(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress, CARD8 value) +{ + ViaVgahwOut(hwp, indexaddress, index); + ViaVgahwOut(hwp, valueaddress, value); +} + +/* + * This code makes a big change in readability, allows one to clearly + * formulate what is changed. + * + */ + +/* + * + */ +void +ViaVgahwMask(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress, CARD8 value, CARD8 mask) +{ + CARD8 tmp; + + tmp = ViaVgahwRead(hwp, indexaddress, index, valueaddress); + + tmp &= ~mask; + tmp |= (value & mask); + + ViaVgahwWrite(hwp, indexaddress, index, valueaddress, tmp); +} + +/* + * + */ +void +ViaCrtcMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask) +{ + CARD8 tmp; + + tmp = hwp->readCrtc(hwp, index); + tmp &= ~mask; + tmp |= (value & mask); + + hwp->writeCrtc(hwp, index, tmp); +} + +/* + * + */ +void +ViaSeqMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask) +{ + CARD8 tmp; + + tmp = hwp->readSeq(hwp, index); + tmp &= ~mask; + tmp |= (value & mask); + + hwp->writeSeq(hwp, index, tmp); +} + +/* + * + */ +void +ViaGrMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask) +{ + CARD8 tmp; + + tmp = hwp->readGr(hwp, index); + tmp &= ~mask; + tmp |= (value & mask); + + hwp->writeGr(hwp, index, tmp); +} + +/* + * + */ +#ifdef HAVE_DEBUG +void +ViaVgahwPrint(vgaHWPtr hwp) +{ + int i; + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Printing VGA Sequence registers:\n"); + for (i = 0x00; i < 0x80; i++) + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "SR%02X: 0x%02X\n", i, hwp->readSeq(hwp, i)); + + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Printing VGA CRTM/C registers:\n"); + for (i = 0x00; i < 0x19; i++) + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "CR%02X: 0x%02X\n", i, hwp->readCrtc(hwp, i)); + for (i = 0x33; i < 0xA3; i++) + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "CR%02X: 0x%02X\n", i, hwp->readCrtc(hwp, i)); + + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Printing VGA Graphics registers:\n"); + for (i = 0x00; i < 0x08; i++) + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "GR%02X: 0x%02X\n", i, hwp->readGr(hwp, i)); + + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Printing VGA Attribute registers:\n"); + for (i = 0x00; i < 0x14; i++) + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "AR%02X: 0x%02X\n", i, hwp->readAttr(hwp, i)); + + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Printing VGA Miscellaneous register:\n"); + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "Misc: 0x%02X\n", hwp->readMiscOut(hwp)); + + xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "End of VGA Registers.\n"); +} +#endif /* HAVE_DEBUG */ diff --git a/unichrome/via_vgahw.h b/unichrome/via_vgahw.h new file mode 100644 index 000000000000..10047bb7a2f8 --- /dev/null +++ b/unichrome/via_vgahw.h @@ -0,0 +1,51 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_VGAHW_H_ +#define _VIA_VGAHW_H_ + +#include "vgaHW.h" + +/* not used currently */ +/* +CARD8 ViaVgahwIn(vgaHWPtr hwp, int address); +void ViaVgahwOut(vgaHWPtr hwp, int address, CARD8 value); + +CARD8 ViaVgahwRead(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress); +*/ + +void ViaVgahwWrite(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress, CARD8 value); + +void ViaVgahwMask(vgaHWPtr hwp, int indexaddress, CARD8 index, + int valueaddress, CARD8 value, CARD8 mask); + +void ViaCrtcMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask); +void ViaSeqMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask); +void ViaGrMask(vgaHWPtr hwp, CARD8 index, CARD8 value, CARD8 mask); + +#ifdef HAVE_DEBUG +void ViaVgahwPrint(vgaHWPtr hwp); +#endif /* HAVE_DEBUG */ + +#endif /* _VIA_VGAHW_H_ */ diff --git a/unichrome/via_video.c b/unichrome/via_video.c new file mode 100644 index 000000000000..139dbfd52c38 --- /dev/null +++ b/unichrome/via_video.c @@ -0,0 +1,1115 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * I N C L U D E S + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" +#include "via_driver.h" +#include "via_video.h" + +#include "via.h" + +#include "xf86xv.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "via_xvpriv.h" +#include "via_swov.h" +#include "via_memcpy.h" +#include "via_id.h" +#include "fourcc.h" + +/* + * D E F I N E + */ +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 +#define PARAMSIZE 1024 +#define SLICESIZE 65536 +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) +#define VIA_MAX_XVIMAGE_X 1920 +#define VIA_MAX_XVIMAGE_Y 1200 + +#define LOW_BAND 0x0CB0 +#define MID_BAND 0x1f10 + +#define XV_IMAGE 0 +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#ifndef XvExtension +void viaInitVideo(ScreenPtr pScreen) {} +#else + +static vidCopyFunc viaFastVidCpy = NULL; + + +/* + * F U N C T I O N D E C L A R A T I O N + */ +static unsigned viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors); +static void viaStopVideo(ScrnInfoPtr, pointer, Bool); +static void viaQueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int viaQueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static int viaGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short, + short, short,int, unsigned char*, short, short, Bool, + RegionPtr, pointer); + +static Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation, xvAutoPaint; + +/* + * S T R U C T S + */ +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { XV_IMAGE , "XV_IMAGE",VIA_MAX_XVIMAGE_X,VIA_MAX_XVIMAGE_Y,{1, 1}}, +}; + +#define NUM_FORMATS_G 9 + +static XF86VideoFormatRec FormatsG[NUM_FORMATS_G] = +{ + { 8, TrueColor }, /* Dithered */ + { 8, PseudoColor }, /* Using .. */ + { 8, StaticColor }, + { 8, GrayScale }, + { 8, StaticGray }, /* .. TexelLUT */ + {16, TrueColor}, + {24, TrueColor}, + {16, DirectColor}, + {24, DirectColor} +}; + +#define NUM_ATTRIBUTES_G 6 + +static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 10000, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 20000, "XV_CONTRAST"}, + {XvSettable | XvGettable, 0, 20000,"XV_SATURATION"}, + {XvSettable | XvGettable,-180,180,"XV_HUE"}, + {XvSettable | XvGettable,0,1,"XV_AUTOPAINT_COLORKEY"} +}; + +#define NUM_IMAGES_G 3 + +static XF86ImageRec ImagesG[NUM_IMAGES_G] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + { + /* + * Below, a dummy picture type that is used in XvPutImage only to do + * an overlay update. Introduced for the XvMC client lib. + * Defined to have a zero data size. + */ + + FOURCC_XVMC, + XvYUV, + LSBFirst, + {'V','I','A',0x00, + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, + 12, + XvPlanar, + 1, + 0, 0, 0, 0 , + 8, 8, 8, + 1, 2, 2, + 1, 2, 2, + {'Y','V','U', + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + } +}; + +static char * XvAdaptorName[XV_ADAPT_NUM] = +{ + "XV_SWOV" +}; + +static XF86VideoAdaptorPtr viaAdaptPtr[XV_ADAPT_NUM]; +static XF86VideoAdaptorPtr *allAdaptors; +static unsigned numAdaptPort[XV_ADAPT_NUM] = + {1}; + +/* + * F U N C T I O N + */ + +/* + * Decide if the mode support video overlay. This depends on the bandwidth + * of the mode and the type of RAM available. + */ +static Bool DecideOverlaySupport(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + DisplayModePtr mode = pScrn->currentMode; + +/* IVOR +Fix bandwidth check** + + */ + DBG_DD(ErrorF("Fix Bandwidth check!!!\n")); + return TRUE; + + /* Small trick here. We keep the height in 16's of lines and width in 32's + to avoid numeric overflow */ + + if ( pVia->ChipId != PCI_CHIP_VT3205 && + pVia->ChipId != PCI_CHIP_VT3204 ) { + CARD32 bandwidth = (mode->HDisplay >> 4) * (mode->VDisplay >> 5) * + pScrn->bitsPerPixel * mode->VRefresh; + + switch (pVia->MemClk) { + case VIA_MEM_SDR100: /* No overlay without DDR */ + case VIA_MEM_SDR133: + return FALSE; + case VIA_MEM_DDR200: + /* Basic limit for DDR200 is about this */ + if(bandwidth > 1800000) + return FALSE; + /* But we have constraints at higher than 800x600 */ + if (mode->HDisplay > 800) { + if(pScrn->bitsPerPixel != 8) + return FALSE; + if(mode->VDisplay > 768) + return FALSE; + if(mode->VRefresh > 60) + return FALSE; + } + return TRUE; + case 0: /* FIXME: Why does my CLE266 report 0? */ + case VIA_MEM_DDR266: + if(bandwidth > 7901250) + return FALSE; + return TRUE; + } + return FALSE; + + } else { + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + unsigned width,height,refresh,dClock; + float mClock,memEfficiency,needBandWidth,totalBandWidth; + int bTV = 0; + + switch(pVia->MemClk) { + case VIA_MEM_SDR100: + mClock = 50; /*HW base on 128 bit*/ + break; + case VIA_MEM_SDR133: + mClock = 66.5 ; + break; + case VIA_MEM_DDR200: + mClock = 100; + break; + case VIA_MEM_DDR266: + mClock = 133; + break; + case VIA_MEM_DDR333: + mClock = 166; + break; + default: + /*Unknow DRAM Type*/ + DBG_DD(ErrorF("Unknow DRAM Type!\n")); + mClock = 166; + break; + } + + switch(pVia->MemClk) { + case VIA_MEM_SDR100: + case VIA_MEM_SDR133: + case VIA_MEM_DDR200: + memEfficiency = (float)SINGLE_3205_100; + break; + case VIA_MEM_DDR266: + case VIA_MEM_DDR333: + memEfficiency = (float)SINGLE_3205_133; + break; + default: + /*Unknow DRAM Type .*/ + DBG_DD(ErrorF("Unknow DRAM Type!\n")); + memEfficiency = (float)SINGLE_3205_133; + break; + } + + width = mode->HDisplay; + height = mode->VDisplay; + refresh = mode->VRefresh; + + /* + * FIXME: If VBE modes assume a high refresh (100) for now + */ + + if (pVia->pVbe) { + refresh = 100; + if (pBIOSInfo->PanelActive) + refresh = 70; + if (pBIOSInfo->TVActive) + refresh = 60; + } else { + if (pBIOSInfo->PanelActive) { + width = pBIOSInfo->panelX; + height = pBIOSInfo->panelY; + if ((width == 1400) && (height == 1050)) { + width = 1280; + height = 1024; + refresh = 60; + } + } else if (pBIOSInfo->TVActive) { + bTV = 1; + } + } + if (bTV) { + + /* + * Approximative, VERY conservative formula in some cases. + * This formula and the one below are derived analyzing the + * tables present in VIA's own drivers. They may reject the over- + * lay in some cases where VIA's driver don't. + */ + + dClock = (width * height * 60) / 580000; + + } else { + + /* + * Approximative, slightly conservative formula. See above. + */ + + dClock = (width * height * refresh) / 680000; + } + + if (dClock) { + needBandWidth = (float)(((pScrn->bitsPerPixel >> 3) + VIDEO_BPP)*dClock); + totalBandWidth = (float)(mClock*16.*memEfficiency); + + DBG_DD(ErrorF(" via_video.c : cBitsPerPel= %d : \n",pScrn->bitsPerPixel)); + DBG_DD(ErrorF(" via_video.c : Video_Bpp= %d : \n",VIDEO_BPP)); + DBG_DD(ErrorF(" via_video.c : refresh = %d : \n",refresh)); + DBG_DD(ErrorF(" via_video.c : dClock= %d : \n",dClock)); + DBG_DD(ErrorF(" via_video.c : mClk= %f : \n",mClock)); + DBG_DD(ErrorF(" via_video.c : memEfficiency= %f : \n",memEfficiency)); + DBG_DD(ErrorF(" via_video.c : needBandwidth= %f : \n",needBandWidth)); + DBG_DD(ErrorF(" via_video.c : totalBandwidth= %f : \n",totalBandWidth)); + if (needBandWidth < totalBandWidth) + return TRUE; + } + return FALSE; + } + return FALSE; +} + +static void +viaResetVideo(ScrnInfoPtr pScrn) +{ + CARD32 dwTemp; + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + + DBG_DD(ErrorF(" via_video.c : viaResetVideo: \n")); + + dwTemp = viaVidEng->video1_ctl; + viaVidEng->video1_ctl = dwTemp & 0x00200000; + + viaVidEng->video3_ctl = 0; + viaVidEng->compose = 0x80000000; + viaVidEng->compose = 0x40000000; + viaVidEng->color_key = 0x821; + viaVidEng->snd_color_key = 0x821; + +} + +void viaSaveVideo(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + + pVia->dwV1 = ((vmmtr)viaVidEng)->video1_ctl; + pVia->dwV3 = ((vmmtr)viaVidEng)->video3_ctl; + viaVidEng->video1_ctl = pVia->dwV1 & 0x00200000; + viaVidEng->video3_ctl = 0; + viaVidEng->compose = 0x80000000; + viaVidEng->compose = 0x40000000; +} + +void viaRestoreVideo(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + + viaVidEng->video1_ctl = pVia->dwV1 ; + viaVidEng->video3_ctl = pVia->dwV3 ; + viaVidEng->compose = 0x80000000; + viaVidEng->compose = 0x40000000; + +} + + + +void viaExitVideo(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + CARD32 dwTemp; + XF86VideoAdaptorPtr curAdapt; + int i; + + DBG_DD(ErrorF(" via_video.c : viaExitVideo : \n")); + + dwTemp = viaVidEng->video1_ctl; + viaVidEng->video1_ctl = dwTemp & 0x00200000; + +#ifdef XF86DRI + ViaCleanupXVMC(pScrn, viaAdaptPtr, XV_ADAPT_NUM); +#endif + + viaVidEng->video3_ctl = 0; + viaVidEng->compose = 0x80000000; + viaVidEng->compose = 0x40000000; + + /* + * Free all adaptor info allocated in viaInitVideo. + */ + + for (i=0; i<XV_ADAPT_NUM; ++i) { + curAdapt = viaAdaptPtr[i]; + if (curAdapt) { + if (curAdapt->pPortPrivates) { + if (curAdapt->pPortPrivates->ptr) { + xfree(curAdapt->pPortPrivates->ptr); + } + xfree(curAdapt->pPortPrivates); + } + xfree(curAdapt); + } + } + if (allAdaptors) + xfree(allAdaptors); +} + +void viaInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + XF86VideoAdaptorPtr *adaptors, *newAdaptors; + int num_adaptors, num_new; + + + DBG_DD(ErrorF(" via_video.c : viaInitVideo : \n")); + + allAdaptors = NULL; + newAdaptors = NULL; + num_new = 0; + + if (!viaFastVidCpy) + viaFastVidCpy = viaVidCopyInit("video", pScreen); + + if ( (pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) ) { + num_new = viaSetupAdaptors(pScreen, &newAdaptors); + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[Xv] Unsupported Chipset. X video functionality disabled.\n"); + num_adaptors=0; + } + + DBG_DD(ErrorF(" via_video.c : num_adaptors : %d\n",num_adaptors)); + if(newAdaptors) { + allAdaptors = xalloc((num_adaptors + num_new) * + sizeof(XF86VideoAdaptorPtr*)); + if(allAdaptors) { + if (num_adaptors) + memcpy(allAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); + memcpy(allAdaptors + num_adaptors, newAdaptors, + num_new * sizeof(XF86VideoAdaptorPtr)); + num_adaptors += num_new; + } + } + + if (num_adaptors) { + xf86XVScreenInit(pScreen, allAdaptors, num_adaptors); +#ifdef XF86DRI + ViaInitXVMC(pScreen); +#endif + viaSetColorSpace(pVia,0,0,0,0,TRUE); + } +} + + +static unsigned +viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + viaPortPrivRec *viaPortPriv; + DevUnion *pdevUnion; + int i,j, usedPorts, numPorts; + + DBG_DD(ErrorF(" via_video.c : viaSetupImageVideo: \n")); + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvHue = MAKE_ATOM("XV_HUE"); + xvSaturation = MAKE_ATOM("XV_SATURATION"); + xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + + *adaptors = NULL; + usedPorts = 0; + + + for ( i = 0; i < XV_ADAPT_NUM; i ++ ) { + if(!(viaAdaptPtr[i] = xf86XVAllocateVideoAdaptorRec(pScrn))) + return 0; + numPorts = numAdaptPort[i]; + + viaPortPriv = (viaPortPrivPtr)xnfcalloc(numPorts, sizeof(viaPortPrivRec) ); + pdevUnion = (DevUnion *)xnfcalloc(numPorts, sizeof(DevUnion)); + + if(i == XV_ADAPT_SWOV) /* Overlay engine */ + { + viaAdaptPtr[i]->type = XvInputMask | XvWindowMask | XvImageMask | + XvVideoMask | XvStillMask; + viaAdaptPtr[i]->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + } + else + { + viaAdaptPtr[i]->type = XvInputMask | XvWindowMask | XvVideoMask; + viaAdaptPtr[i]->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + } + viaAdaptPtr[i]->name = XvAdaptorName[i]; + viaAdaptPtr[i]->nEncodings = 1; + viaAdaptPtr[i]->pEncodings = DummyEncoding; + viaAdaptPtr[i]->nFormats = sizeof(FormatsG) / sizeof(FormatsG[0]); + viaAdaptPtr[i]->pFormats = FormatsG; + + /* The adapter can handle 1 port simultaneously */ + viaAdaptPtr[i]->nPorts = numPorts; + viaAdaptPtr[i]->pPortPrivates = pdevUnion; + viaAdaptPtr[i]->pPortPrivates->ptr = (pointer) viaPortPriv; + viaAdaptPtr[i]->nAttributes = NUM_ATTRIBUTES_G; + viaAdaptPtr[i]->pAttributes = AttributesG; + + viaAdaptPtr[i]->nImages = NUM_IMAGES_G; + viaAdaptPtr[i]->pImages = ImagesG; + viaAdaptPtr[i]->PutVideo = NULL; + viaAdaptPtr[i]->StopVideo = viaStopVideo; + viaAdaptPtr[i]->QueryBestSize = viaQueryBestSize; + viaAdaptPtr[i]->GetPortAttribute = viaGetPortAttribute; + viaAdaptPtr[i]->SetPortAttribute = viaSetPortAttribute; + viaAdaptPtr[i]->PutImage = viaPutImage; + viaAdaptPtr[i]->QueryImageAttributes = viaQueryImageAttributes; + + for (j=0; j<numPorts; ++j) { + viaPortPriv[j].colorKey = 0x0821; + viaPortPriv[j].autoPaint = TRUE; + viaPortPriv[j].brightness = 5000.; + viaPortPriv[j].saturation = 10000; + viaPortPriv[j].contrast = 10000; + viaPortPriv[j].hue = 0; + viaPortPriv[j].xv_portnum = j + usedPorts; +#ifdef X_USE_REGION_NULL + REGION_NULL(pScreen, &viaPortPriv[j].clip); +#else + REGION_INIT(pScreen, &viaPortPriv[j].clip, NullBox, 1); +#endif + } + usedPorts += j; +#ifdef XF86DRI + viaXvMCInitXv(pScrn, viaAdaptPtr[i]); +#endif + } /* End of for */ + viaResetVideo(pScrn); + *adaptors = viaAdaptPtr; + return XV_ADAPT_NUM; +} + + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static void +viaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) +{ + VIAPtr pVia = VIAPTR(pScrn); + viaPortPrivPtr pPriv = (viaPortPrivPtr)data; + + DBG_DD(ErrorF(" via_video.c : viaStopVideo: exit=%d\n", exit)); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + if (exit) { + ViaOverlayHide(pScrn); + ViaSwovSurfaceDestroy(pScrn, pPriv); + pVia->dwFrameNum = 0; + pPriv->old_drw_x= 0; + pPriv->old_drw_y= 0; + pPriv->old_drw_w= 0; + pPriv->old_drw_h= 0; + } +} + +static int +viaSetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data + ){ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + viaPortPrivPtr pPriv = (viaPortPrivPtr)data; + int attr, avalue; + + DBG_DD(ErrorF(" via_video.c : viaSetPortAttribute : \n")); + + + /* Color Key */ + if(attribute == xvColorKey) { + DBG_DD(ErrorF(" V4L Disable xvColorKey = %08lx\n",value)); + + pPriv->colorKey = value; + /* All assume color depth is 16 */ + value &= 0x00FFFFFF; + viaVidEng->color_key = value; + viaVidEng->snd_color_key = value; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + DBG_DD(ErrorF(" V4L Disable done xvColorKey = %08lx\n",value)); + + } else if (attribute == xvAutoPaint) { + pPriv->autoPaint = value; + DBG_DD(ErrorF(" xvAutoPaint = %08lx\n",value)); + /* Color Control */ + } else if (attribute == xvBrightness || + attribute == xvContrast || + attribute == xvSaturation || + attribute == xvHue) { + if (attribute == xvBrightness) + { + DBG_DD(ErrorF(" xvBrightness = %08ld\n",value)); + pPriv->brightness = value; + } + if (attribute == xvContrast) + { + DBG_DD(ErrorF(" xvContrast = %08ld\n",value)); + pPriv->contrast = value; + } + if (attribute == xvSaturation) + { + DBG_DD(ErrorF(" xvSaturation = %08ld\n",value)); + pPriv->saturation = value; + } + if (attribute == xvHue) + { + DBG_DD(ErrorF(" xvHue = %08ld\n",value)); + pPriv->hue = value; + } + viaSetColorSpace(pVia, pPriv->hue, pPriv->saturation, + pPriv->brightness, pPriv->contrast, FALSE); + }else{ + DBG_DD(ErrorF(" via_video.c : viaSetPortAttribute : is not supported the attribute")); + return BadMatch; + } + + /* attr,avalue hardware processing goes here */ + (void)attr; + (void)avalue; + + return Success; +} + +static int +viaGetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +){ + viaPortPrivPtr pPriv = (viaPortPrivPtr)data; + + DBG_DD(ErrorF(" via_video.c : viaGetPortAttribute : port %d %ld\n", + pPriv->xv_portnum, attribute)); + + *value = 0; + if (attribute == xvColorKey ) { + *value =(INT32) pPriv->colorKey; + DBG_DD(ErrorF(" via_video.c : ColorKey 0x%lx\n",pPriv->colorKey)); + } else if (attribute == xvAutoPaint ) { + *value = (INT32) pPriv->autoPaint; + DBG_DD(ErrorF(" AutoPaint = %08ld\n", *value)); + /* Color Control */ + } else if (attribute == xvBrightness || + attribute == xvContrast || + attribute == xvSaturation || + attribute == xvHue) { + if (attribute == xvBrightness) + { + *value = pPriv->brightness; + DBG_DD(ErrorF(" xvBrightness = %08ld\n", *value)); + } + if (attribute == xvContrast) + { + *value = pPriv->contrast; + DBG_DD(ErrorF(" xvContrast = %08ld\n", *value)); + } + if (attribute == xvSaturation) + { + *value = pPriv->saturation; + DBG_DD(ErrorF(" xvSaturation = %08ld\n", *value)); + } + if (attribute == xvHue) + { + *value = pPriv->hue; + DBG_DD(ErrorF(" xvHue = %08ld\n", *value)); + } + + }else { + /*return BadMatch*/ ; + } + return Success; +} + +static void +viaQueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + DBG_DD(ErrorF(" via_video.c : viaQueryBestSize :\n")); + *p_w = drw_w; + *p_h = drw_h; + + if(*p_w > 2048 ) + *p_w = 2048; +} + +/* + * To do SW Flip + */ +static void Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc, unsigned long DisplayBufferIndex) +{ + unsigned long proReg=0; + if ((pVia->ChipId == PCI_CHIP_VT3259) && + !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) + proReg = REG_HQV1_INDEX; + + switch(fourcc) + { + case FOURCC_UYVY: + case FOURCC_YUY2: + while ((VIDInD(HQV_CONTROL|proReg) & HQV_SW_FLIP) ); + VIDOutD(HQV_SRC_STARTADDR_Y|proReg, pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + VIDOutD(HQV_CONTROL|proReg,( VIDInD(HQV_CONTROL)&~HQV_FLIP_ODD) |HQV_SW_FLIP|HQV_FLIP_STATUS); + break; + + case FOURCC_YV12: + default: + while ((VIDInD(HQV_CONTROL|proReg) & HQV_SW_FLIP) ); + if (proReg == REG_HQV1_INDEX) + { + VIDOutD(HQV_SRC_STARTADDR_Y|proReg, pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + VIDOutD(HQV_SRC_STARTADDR_U|proReg, pVia->swov.SWDevice.dwSWCrPhysicalAddr[DisplayBufferIndex]); + } + else + { + VIDOutD(HQV_SRC_STARTADDR_Y, pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + VIDOutD(HQV_SRC_STARTADDR_U, pVia->swov.SWDevice.dwSWCbPhysicalAddr[DisplayBufferIndex]); + VIDOutD(HQV_SRC_STARTADDR_V, pVia->swov.SWDevice.dwSWCrPhysicalAddr[DisplayBufferIndex]); + } + VIDOutD(HQV_CONTROL|proReg,( VIDInD(HQV_CONTROL|proReg)&~HQV_FLIP_ODD) |HQV_SW_FLIP|HQV_FLIP_STATUS); + break; + } +} + +/* + * Slow and dirty. NV12 blit. + */ +static void nv12cp(unsigned char *dst, + const unsigned char *src, + int dstPitch, + int w, + int h, int yuv422) +{ + int count; + int x; + unsigned char* src2; + +#ifdef XV_DEBUG + ErrorF("src %08x, dst %08x, pitch %d, w %d, h %d", src, dst, dstPitch,w,h); +#endif + + /* copy Y component to video memory */ + count = h; + while(count--) + { + xf86memcpy(dst, src, w); + src += w; + dst += dstPitch; + } + + /* UV component is 1/2 of Y */ + w >>= 1; + + /* copy V(Cr),U(Cb) components to video memory */ + count = h/2; + + src2 = src + w*count; + while(count--) + { + for (x=0; x<w; x++) + { + dst[x*2+1] = src[x]; + dst[x*2] = src2[x]; + } + + dst+= dstPitch; + src += w; + src2 += w; + } +} + +static int +viaPutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data + ){ + VIAPtr pVia = VIAPTR(pScrn); + viaPortPrivPtr pPriv = (viaPortPrivPtr)data; + unsigned long retCode; + +# ifdef XV_DEBUG + ErrorF(" via_video.c : viaPutImage : called\n"); + ErrorF(" via_video.c : FourCC=0x%x width=%d height=%d sync=%d\n",id,width,height,sync); + ErrorF(" via_video.c : src_x=%d src_y=%d src_w=%d src_h=%d colorkey=0x%lx\n",src_x, src_y, src_w, src_h, pPriv->colorKey); + ErrorF(" via_video.c : drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",drw_x,drw_y,drw_w,drw_h); +# endif + + switch ( pPriv->xv_portnum ) + { + case XV_ADAPT_SWOV: + { + DDUPDATEOVERLAY UpdateOverlay_Video; + LPDDUPDATEOVERLAY lpUpdateOverlay = &UpdateOverlay_Video; + + int dstPitch; + unsigned long dwUseExtendedFIFO=0; + + DBG_DD(ErrorF(" via_video.c : : S/W Overlay! \n")); + /* Allocate video memory(CreateSurface), + * add codes to judge if need to re-create surface + */ + if ( (pPriv->old_src_w != src_w) || (pPriv->old_src_h != src_h) ) + ViaSwovSurfaceDestroy(pScrn, pPriv); + + if (Success != ( retCode = ViaSwovSurfaceCreate(pScrn, pPriv, id, width, height) )) + { + DBG_DD(ErrorF(" : Fail to Create SW Video Surface\n")); + return retCode; + } + + + /* Copy image data from system memory to video memory + * TODO: use DRM's DMA feature to accelerate data copy + */ + if (FOURCC_XVMC != id) { + dstPitch = pVia->swov.SWDevice.dwPitch; + switch(id) { + case FOURCC_NV12: + case FOURCC_YV12: + if (pVia->ChipId == PCI_CHIP_VT3259) + { + DBG_DD(ErrorF("Pro blit\n")); + nv12cp(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,0); + } + else + (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,0); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,1); + break; + } + } + + /* If there is bandwidth issue, block the H/W overlay */ + + if (!pVia->OverlaySupported && + !(pVia->OverlaySupported = DecideOverlaySupport(pScrn))) { + DBG_DD(ErrorF(" via_video.c : Xv Overlay rejected due to insufficient " + "memory bandwidth.\n")); + return BadAlloc; + } + + /* + * fill video overlay parameter + */ + lpUpdateOverlay->SrcLeft = src_x; + lpUpdateOverlay->SrcTop = src_y; + lpUpdateOverlay->SrcRight = src_x + src_w; + lpUpdateOverlay->SrcBottom = src_y + src_h; + + lpUpdateOverlay->DstLeft = drw_x; + lpUpdateOverlay->DstTop = drw_y; + lpUpdateOverlay->DstRight = drw_x + drw_w; + lpUpdateOverlay->DstBottom = drw_y + drw_h; + + lpUpdateOverlay->dwFlags = DDOVER_KEYDEST; + + if (pScrn->bitsPerPixel == 8) + lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff; + else + lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; + + /* If use extend FIFO mode */ + if (pScrn->currentMode->HDisplay > 1024) + { + dwUseExtendedFIFO = 1; + } + + if (FOURCC_XVMC != id) { + + /* + * XvMC flipping is done in the client lib. + */ + + DBG_DD(ErrorF(" : Flip\n")); + Flip(pVia, pPriv, id, pVia->dwFrameNum&1); + } + + pVia->dwFrameNum ++; + + /* If the dest rec. & extendFIFO doesn't change, don't do UpdateOverlay + unless the surface clipping has changed */ + if ( (pPriv->old_drw_x == drw_x) && (pPriv->old_drw_y == drw_y) + && (pPriv->old_drw_w == drw_w) && (pPriv->old_drw_h == drw_h) + && (pPriv->old_src_x == src_x) && (pPriv->old_src_y == src_y) + && (pPriv->old_src_w == src_w) && (pPriv->old_src_h == src_h) + && (pVia->old_dwUseExtendedFIFO == dwUseExtendedFIFO) + && (pVia->VideoStatus & VIDEO_SWOV_ON) && + RegionsEqual(&pPriv->clip, clipBoxes)) + { + return Success; + } + + pPriv->old_src_x = src_x; + pPriv->old_src_y = src_y; + pPriv->old_src_w = src_w; + pPriv->old_src_h = src_h; + + pPriv->old_drw_x = drw_x; + pPriv->old_drw_y = drw_y; + pPriv->old_drw_w = drw_w; + pPriv->old_drw_h = drw_h; + pVia->old_dwUseExtendedFIFO = dwUseExtendedFIFO; + pVia->VideoStatus |= VIDEO_SWOV_ON; + + /* BitBlt: Draw the colorkey rectangle */ + if(!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + if (pPriv->autoPaint) + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + + /* + * Update video overlay + */ + if (!VIAVidUpdateOverlay(pScrn, lpUpdateOverlay)) { + DBG_DD(ErrorF(" via_video.c : call v4l updateoverlay fail. \n")); + } else { + DBG_DD(ErrorF(" via_video.c : PutImage done OK\n")); + return Success; + } + break; + } + default: + DBG_DD(ErrorF(" via_video.c : XVPort not supported\n")); + break; + } + DBG_DD(ErrorF(" via_video.c : PutImage done OK\n")); + return Success; +} + + +static int +viaQueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + int size, tmp; + + DBG_DD(ErrorF(" via_video.c : viaQueryImageAttributes : FourCC=0x%x, ", id)); + + if ( (!w) || (!h) ) + return 0; + + if(*w > VIA_MAX_XVIMAGE_X) *w = VIA_MAX_XVIMAGE_X; + if(*h > VIA_MAX_XVIMAGE_Y) *h = VIA_MAX_XVIMAGE_Y; + + *w = (*w + 1) & ~1; + if(offsets) + offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: /*Planar format : YV12 -4:2:0*/ + *h = (*h + 1) & ~1; + size = *w; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = (*w >> 1); + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_XVMC: + *h = (*h + 1) & ~1; +#ifdef XF86DRI + size = viaXvMCPutImageSize(pScrn); +#else + size = 0; +#endif + if (pitches) pitches[0] = size; + break; + case FOURCC_AI44: + case FOURCC_IA44: + size = *w * *h; + if (pitches) pitches[0] = *w; + if (offsets) offsets[0] = 0; + break; + case FOURCC_UYVY: /*Packed format : UYVY -4:2:2*/ + case FOURCC_YUY2: /*Packed format : YUY2 -4:2:2*/ + default: + size = *w << 1; + if(pitches) + pitches[0] = size; + size *= *h; + break; + } + + if ( pitches ) + DBG_DD(ErrorF(" pitches[0]=%d, pitches[1]=%d, pitches[2]=%d, ", pitches[0], pitches[1], pitches[2])); + if ( offsets ) + DBG_DD(ErrorF(" offsets[0]=%d, offsets[1]=%d, offsets[2]=%d, ", offsets[0], offsets[1], offsets[2])); + DBG_DD(ErrorF(" width=%d, height=%d \n", *w, *h)); + + return size; +} + + +/* + * + */ +void +VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y) +{ + VIAPtr pVia = VIAPTR(pScrn); + + pVia->swov.panning_x = x; + pVia->swov.panning_y = y; + + /* Check if HW mpeg engine active */ + if (pVia->VideoStatus & VIDEO_SWOV_ON) { /* SW video case */ + DDUPDATEOVERLAY UpdateOverlay; + + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Call SW MPEG UpdateOverlay at panning mode.\n"); + + UpdateOverlay.dwFlags = DDOVER_KEYDEST; + UpdateOverlay.dwColorSpaceLowValue = VIAGETREG(0x220); + UpdateOverlay.SrcLeft = 0; + UpdateOverlay.SrcTop = 0; + UpdateOverlay.SrcRight = 720; + UpdateOverlay.SrcBottom = 480; + + UpdateOverlay.DstLeft = (int) pVia->swov.SWDevice.gdwSWDstLeft; + UpdateOverlay.DstTop = (int) pVia->swov.SWDevice.gdwSWDstTop; + UpdateOverlay.DstRight = UpdateOverlay.DstLeft + pVia->swov.SWDevice.gdwSWDstWidth; + UpdateOverlay.DstBottom = UpdateOverlay.DstTop + pVia->swov.SWDevice.gdwSWDstHeight; + + VIAVidUpdateOverlay(pScrn, &UpdateOverlay); + } + +} + +#endif /* !XvExtension */ diff --git a/unichrome/via_video.h b/unichrome/via_video.h new file mode 100644 index 000000000000..dbd6dd02a4cf --- /dev/null +++ b/unichrome/via_video.h @@ -0,0 +1,112 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_VIDEO_H_ +#define _VIA_VIDEO_H_ 1 + +/* + * I N C L U D E S + */ + +/*#define XV_DEBUG 1*/ /* write log msg to /var/log/XFree86.0.log */ +#define COLOR_KEY 1 /* set color key value from driver layer*/ + +#define HW_3123 + +/* Definition for VideoStatus */ +#define VIDEO_NULL 0x00000000 +#define VIDEO_SWOV_SURFACE_CREATED 0x00000001 +#define VIDEO_SWOV_ON 0x00000002 + +#define SINGLE_3205_100 0.41 +#define SINGLE_3205_133 0.70 + +#define VIDEO_BPP 2 + +typedef struct{ + CARD32 interruptflag; /* 200 */ + CARD32 ramtab; /* 204 */ + CARD32 alphawin_hvstart; /* 208 */ + CARD32 alphawin_size; /* 20c */ + CARD32 alphawin_ctl; /* 210 */ + CARD32 crt_startaddr; /* 214 */ + CARD32 crt_startaddr_2; /* 218 */ + CARD32 alphafb_stride ; /* 21c */ + CARD32 color_key; /* 220 */ + CARD32 alphafb_addr; /* 224 */ + CARD32 chroma_low; /* 228 */ + CARD32 chroma_up; /* 22c */ + CARD32 video1_ctl; /* 230 */ + CARD32 video1_fetch; /* 234 */ + CARD32 video1y_addr1; /* 238 */ + CARD32 video1_stride; /* 23c */ + CARD32 video1_hvstart; /* 240 */ + CARD32 video1_size; /* 244 */ + CARD32 video1y_addr2; /* 248 */ + CARD32 video1_zoom; /* 24c */ + CARD32 video1_mictl; /* 250 */ + CARD32 video1y_addr0; /* 254 */ + CARD32 video1_fifo; /* 258 */ + CARD32 video1y_addr3; /* 25c */ + CARD32 hi_control; /* 260 */ + CARD32 snd_color_key; /* 264 */ + CARD32 v3alpha_prefifo; /* 268 */ + CARD32 v1_source_w_h; /* 26c */ + CARD32 hi_transparent_color; /* 270 */ + CARD32 v_display_temp; /* 274 :No use */ + CARD32 v3alpha_fifo; /* 278 */ + CARD32 v3_source_width; /* 27c */ + CARD32 dummy1; /* 280 */ + CARD32 video1_CSC1; /* 284 */ + CARD32 video1_CSC2; /* 288 */ + CARD32 video1u_addr0; /* 28c */ + CARD32 video1_opqctl; /* 290 */ + CARD32 video3_opqctl; /* 294 */ + CARD32 compose; /* 298 */ + CARD32 dummy2; /* 29c */ + CARD32 video3_ctl; /* 2a0 */ + CARD32 video3_addr0; /* 2a4 */ + CARD32 video3_addr1; /* 2a8 */ + CARD32 video3_stribe; /* 2ac */ + CARD32 video3_hvstart; /* 2b0 */ + CARD32 video3_size; /* 2b4 */ + CARD32 v3alpha_fetch; /* 2b8 */ + CARD32 video3_zoom; /* 2bc */ + CARD32 video3_mictl; /* 2c0 */ + CARD32 video3_CSC1; /* 2c4 */ + CARD32 video3_CSC2; /* 2c8 */ + CARD32 v3_display_temp; /* 2cc */ + CARD32 reserved[5]; /* 2d0 */ + CARD32 video1u_addr1; /* 2e4 */ + CARD32 video1u_addr2; /* 2e8 */ + CARD32 video1u_addr3; /* 2ec */ + CARD32 video1v_addr0; /* 2f0 */ + CARD32 video1v_addr1; /* 2f4 */ + CARD32 video1v_addr2; /* 2f8 */ + CARD32 video1v_addr3; /* 2fc */ +} video_via_regs; + +#define vmmtr volatile video_via_regs * + +#endif /* _VIA_VIDEO_H_ */ diff --git a/unichrome/via_vt162x.c b/unichrome/via_vt162x.c new file mode 100644 index 000000000000..8f21e2322a61 --- /dev/null +++ b/unichrome/via_vt162x.c @@ -0,0 +1,684 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_vt162x.h" +#include "via_id.h" + +/* + * + */ +static void +VT162xPrintRegs(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 i, buf; + + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Printing registers for %s\n", + pBIOSInfo->TVI2CDev->DevName); + + for (i = 0; i < 0x68; i++) { + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &buf); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV%02X: 0x%02X\n", i, buf); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of TV registers.\n"); +} + +/* + * + */ +I2CDevPtr +ViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + I2CDevPtr pDev = xf86CreateI2CDevRec(); + CARD8 buf; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVT162xDetect\n")); + + pDev->DevName = "VT162x"; + pDev->SlaveAddr = Address; + pDev->pI2CBus = pBus; + + if (!xf86I2CDevInit(pDev)) { + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + if (!xf86I2CReadByte(pDev, 0x1B, &buf)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n", + pBus->BusName, Address); + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + switch (buf) { + case 0x02: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected VIA Technologies VT1621 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_VT1621; + pDev->DevName = "VT1621"; + break; + case 0x03: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected VIA Technologies VT1622 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_VT1622; + pDev->DevName = "VT1622"; + break; + case 0x10: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected VIA Technologies VT1622A/VT1623 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_VT1623; + pDev->DevName = "VT1623"; + break; + case 0x50: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected VIA Technologies VT1625 TV Encoder\n"); +#if 0 + pBIOSInfo->TVEncoder = VIA_VT1625; + pDev->DevName = "VT1625"; +#else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1625 is not supported yet.\n"); + xf86DestroyI2CDevRec(pDev, TRUE); + pDev = NULL; +#endif + break; + default: + pBIOSInfo->TVEncoder = VIA_NONETV; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unknown TV Encoder found at %s %X.\n", pBus->BusName, Address); + xf86DestroyI2CDevRec(pDev,TRUE); + pDev = NULL; + break; + } + + return pDev; +} + +/* + * + */ +static void +VT162xSave(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 buf = 0x00; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xSave\n")); + + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, &buf,1, pBIOSInfo->TVRegs, 0x68); +} + +/* + * + */ +static void +VT162xRestore(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xRestore\n")); + + for (i = 0; i < 0x68; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); +} + +/* + * the same for VT1621 as for VT1622/VT1622A/VT1623, result is different though + * still needs testing on vt1621 of course. + */ +static CARD8 +VT162xDACSenseI2C(I2CDevPtr pDev) +{ + CARD8 save, sense; + + xf86I2CReadByte(pDev, 0x0E, &save); + xf86I2CWriteByte(pDev, 0x0E, 0x00); + xf86I2CWriteByte(pDev, 0x0E, 0x80); + xf86I2CWriteByte(pDev, 0x0E, 0x00); + xf86I2CReadByte(pDev, 0x0F, &sense); + xf86I2CWriteByte(pDev, 0x0E, save); + + return (sense & 0x0F); +} + +/* + * VT1621 only knows composite and s-video + */ +static Bool +VT1621DACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621DACSense\n")); + + sense = VT162xDACSenseI2C(pBIOSInfo->TVI2CDev); + switch (sense) { + case 0x00: + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1621: S-Video & Composite connected.\n"); + return TRUE; + case 0x01: + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1621: Composite connected.\n"); + return TRUE; + case 0x02: + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1621: S-Video connected.\n"); + return TRUE; + case 0x03: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1621: Nothing connected.\n"); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1621: Unknown cable combination: 0x0%2X.\n", + sense); + return FALSE; + } +} + + +/* + * VT1622, VT1622A and VT1623 know composite, s-video, RGB and YCBCR + */ +static Bool +VT1622DACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622DACSense\n")); + + sense = VT162xDACSenseI2C(pBIOSInfo->TVI2CDev); + switch (sense) { + case 0x00: /* DAC A,B,C,D */ + pBIOSInfo->TVOutput = TVOUTPUT_RGB; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: RGB connected.\n"); + return TRUE; + case 0x01: /* DAC A,B,C */ + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: S-Video & Composite connected.\n"); + return TRUE; + case 0x07: /* DAC A */ + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: Composite connected.\n"); + return TRUE; + case 0x08: /* DAC B,C,D */ + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: YcBcR connected.\n"); + return TRUE; + case 0x09: /* DAC B,C */ + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: S-Video connected.\n"); + return TRUE; + case 0x0F: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT162x: Nothing connected.\n"); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT162x: Unknown cable combination: 0x0%2X.\n", + sense); + return FALSE; + } +} + +/* + * + */ +static CARD8 +VT1621ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeIndex\n")); + + for (i = 0; VT1621Table[i].Width; i++) { + if ((VT1621Table[i].Width == mode->CrtcHDisplay) && + (VT1621Table[i].Height == mode->CrtcVDisplay) && + (VT1621Table[i].Standard == pBIOSInfo->TVType) && + !(strcmp(VT1621Table[i].name, mode->name))) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1622ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +/* + * + */ +static ModeStatus +VT1621ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeValid\n")); + + if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || + ((mode->Private != (void *) &VT162xModePrivateNTSC) && + (mode->Private != (void *) &VT162xModePrivatePAL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not a mode defined by the TV Encoder.\n"); + return MODE_BAD; + } + + if ((pBIOSInfo->TVType == TVTYPE_NTSC) && + (mode->Private != (void *) &VT162xModePrivateNTSC)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is NTSC. This is a PAL mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && + (mode->Private != (void *) &VT162xModePrivatePAL)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n"); + return MODE_BAD; + } + + if (VT1621ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + return MODE_BAD; +} + +/* + * + */ +static CARD8 +VT1622ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + struct VT162XTableRec *Table; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeIndex\n")); + + if (pBIOSInfo->TVEncoder == VIA_VT1622) + Table = VT1622Table; + else + Table = VT1623Table; + + for (i = 0; Table[i].Width; i++) { + if ((Table[i].Width == mode->CrtcHDisplay) && + (Table[i].Height == mode->CrtcVDisplay) && + (Table[i].Standard == pBIOSInfo->TVType) && + !strcmp(Table[i].name, mode->name)) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1622ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +/* + * + */ +static ModeStatus +VT1622ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeValid\n")); + + if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || + ((mode->Private != (void *) &VT162xModePrivateNTSC) && + (mode->Private != (void *) &VT162xModePrivatePAL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not a mode defined by the TV Encoder.\n"); + return MODE_BAD; + } + + if ((pBIOSInfo->TVType == TVTYPE_NTSC) && + (mode->Private != (void *) &VT162xModePrivateNTSC)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is NTSC. This is a PAL mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && + (mode->Private != (void *) &VT162xModePrivatePAL)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n"); + return MODE_BAD; + } + + if (VT1622ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + return MODE_BAD; +} + +/* + * + */ +static void +VT162xSetSubCarrier(I2CDevPtr pDev, CARD32 SubCarrier) +{ + xf86I2CWriteByte(pDev, 0x16, SubCarrier & 0xFF); + xf86I2CWriteByte(pDev, 0x17, (SubCarrier >> 8) & 0xFF); + xf86I2CWriteByte(pDev, 0x18, (SubCarrier >> 16) & 0xFF); + xf86I2CWriteByte(pDev, 0x19, (SubCarrier >> 24) & 0xFF); +} + +/* + * + */ +static void +VT1621ModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + struct VT1621TableRec Table = VT1621Table[VT1621ModeIndex(pScrn, mode)]; + CARD8 i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeI2C\n")); + + for (i = 0; i < 0x16; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); + + VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.SubCarrier); + + /* skip reserved (1A) and version id (1B). */ + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1C, Table.TV[0x1C]); + + /* skip software reset (1D) */ + + for (i = 0x1E; i < 0x24; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); + + /* write some zeroes? */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x24, 0x00); + for (i = 0; i < 0x08; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A + i, 0x00); + + if (pBIOSInfo->TVOutput == TVOUTPUT_COMPOSITE) + for (i = 0; i < 0x10; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x52 + i, Table.TVC[i]); + else + for (i = 0; i < 0x10; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x52 + i, Table.TVS[i]); + + /* Turn on all Composite and S-Video output */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); + + if (pBIOSInfo->TVDotCrawl) { + if (Table.DotCrawlSubCarrier) { + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x11, &i); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x11, i | 0x08); + + VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.DotCrawlSubCarrier); + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "This mode does not currently " + "support DotCrawl suppression.\n"); + } +} + +/* + * + */ +static void +VT1621ModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + struct VT1621TableRec Table = VT1621Table[VT1621ModeIndex(pScrn, mode)]; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeCrtc\n")); + + if (pVia->IsSecondary) { + hwp->writeCrtc(hwp, 0x6A, 0x80); + hwp->writeCrtc(hwp, 0x6B, 0x20); + hwp->writeCrtc(hwp, 0x6C, 0x80); + + /* Disable LCD Scaling */ + if (!pVia->SAMM || pVia->FirstInit) + hwp->writeCrtc(hwp, 0x79, 0x00); + + } else { + hwp->writeCrtc(hwp, 0x6A, 0x00); + hwp->writeCrtc(hwp, 0x6B, 0x80); + hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C); + } + pBIOSInfo->ClockExternal = TRUE; + ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); +} + +/* + * also suited for VT1622A, VT1623 + */ +static void +VT1622ModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + struct VT162XTableRec Table; + CARD8 save, i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeI2C\n")); + + if (pBIOSInfo->TVEncoder == VIA_VT1622) + Table = VT1622Table[VT1622ModeIndex(pScrn, mode)]; + else /* VT1622A/VT1623 */ + Table = VT1623Table[VT1622ModeIndex(pScrn, mode)]; + + /* TV Reset */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x00); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x80); + + for (i = 0; i < 0x16; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV1[i]); + + VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.SubCarrier); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1A, Table.TV1[0x1A]); + + /* skip version id */ + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1C, Table.TV1[0x1C]); + + /* skip software reset */ + + for (i = 0x1E; i < 0x30; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV1[i]); + + for (i = 0; i < 0x1B; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A + i, Table.TV2[i]); + + /* Turn on all Composite and S-Video output */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); + + if (pBIOSInfo->TVDotCrawl) { + if (Table.DotCrawlSubCarrier) { + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x11, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x11, save | 0x08); + + VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.DotCrawlSubCarrier); + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "This mode does not currently " + "support DotCrawl suppression.\n"); + } + + if (pBIOSInfo->TVOutput == TVOUTPUT_RGB) { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x2A); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x65, Table.RGB[0]); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x66, Table.RGB[1]); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x67, Table.RGB[2]); + if (Table.RGB[3]) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x27, Table.RGB[3]); + if (Table.RGB[4]) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x2B, Table.RGB[4]); + if (Table.RGB[5]) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x2C, Table.RGB[5]); + } else if (pBIOSInfo->TVOutput == TVOUTPUT_YCBCR) { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x03); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x65, Table.YCbCr[0]); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x66, Table.YCbCr[1]); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x67, Table.YCbCr[2]); + } + + /* Configure flicker filter */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &save); + save &= 0xFC; + if (pBIOSInfo->TVDeflicker == 1) + save |= 0x01; + else if (pBIOSInfo->TVDeflicker == 2) + save |= 0x02; + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, save); +} + +/* + * Also suited for VT1622A, VT1623 + */ +static void +VT1622ModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + struct VT162XTableRec Table; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeCrtc\n")); + + if (pBIOSInfo->TVEncoder == VIA_VT1622) + Table = VT1622Table[VT1622ModeIndex(pScrn, mode)]; + else /* VT1622A/VT1623 */ + Table = VT1623Table[VT1622ModeIndex(pScrn, mode)]; + + hwp->writeCrtc(hwp, 0x6A, 0x00); + hwp->writeCrtc(hwp, 0x6B, 0x00); + hwp->writeCrtc(hwp, 0x6C, 0x00); + + if (pVia->IsSecondary) { + hwp->writeCrtc(hwp, 0x6C, Table.SecondaryCR6C); + + ViaCrtcMask(hwp, 0x6A, 0x80, 0x80); + ViaCrtcMask(hwp, 0x6C, 0x80, 0x80); + + /* CLE266Ax use 2x XCLK */ + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) { + ViaCrtcMask(hwp, 0x6B, 0x20, 0x20); + + /* Fix TV clock Polarity for CLE266A2 */ + if (pVia->ChipRev == 0x02) + ViaCrtcMask(hwp, 0x6C, 0x1C, 0x1C); + } + + /* Disable LCD Scaling */ + if (!pVia->SAMM || pVia->FirstInit) + hwp->writeCrtc(hwp, 0x79, 0x00); + + } else { + if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) { + ViaCrtcMask(hwp, 0x6B, 0x80, 0x80); + + /* Fix TV clock Polarity for CLE266A2 */ + if (pVia->ChipRev == 0x02) + hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C); + } + } + pBIOSInfo->ClockExternal = TRUE; + ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); + ViaSeqMask(hwp, 0x1E, 0xC0, 0xC0); /* Enable DI0/DVP0 */ +} + +/* + * + */ +static void +VT1621Power(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621Power\n")); + + if (On) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); + else + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x03); +} + +/* + * + */ +static void +VT1622Power(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622Power\n")); + + if (On) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); + else + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x0F); +} + +/* + * + */ +void +ViaVT162xInit(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVT162xInit\n")); + + switch (pBIOSInfo->TVEncoder) { + case VIA_VT1621: + pBIOSInfo->TVSave = VT162xSave; + pBIOSInfo->TVRestore = VT162xRestore; + pBIOSInfo->TVDACSense = VT1621DACSense; + pBIOSInfo->TVModeValid = VT1621ModeValid; + pBIOSInfo->TVModeI2C = VT1621ModeI2C; + pBIOSInfo->TVModeCrtc = VT1621ModeCrtc; + pBIOSInfo->TVPower = VT1621Power; + pBIOSInfo->TVModes = VT1621Modes; + pBIOSInfo->TVPrintRegs = VT162xPrintRegs; + break; + case VIA_VT1622: + pBIOSInfo->TVSave = VT162xSave; + pBIOSInfo->TVRestore = VT162xRestore; + pBIOSInfo->TVDACSense = VT1622DACSense; + pBIOSInfo->TVModeValid = VT1622ModeValid; + pBIOSInfo->TVModeI2C = VT1622ModeI2C; + pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; + pBIOSInfo->TVPower = VT1622Power; + pBIOSInfo->TVModes = VT1622Modes; + pBIOSInfo->TVPrintRegs = VT162xPrintRegs; + break; + case VIA_VT1623: + pBIOSInfo->TVSave = VT162xSave; + pBIOSInfo->TVRestore = VT162xRestore; + pBIOSInfo->TVDACSense = VT1622DACSense; + pBIOSInfo->TVModeValid = VT1622ModeValid; + pBIOSInfo->TVModeI2C = VT1622ModeI2C; + pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; + pBIOSInfo->TVPower = VT1622Power; + pBIOSInfo->TVModes = VT1623Modes; + pBIOSInfo->TVPrintRegs = VT162xPrintRegs; + break; + default: + break; + } +} diff --git a/unichrome/via_vt162x.h b/unichrome/via_vt162x.h new file mode 100644 index 000000000000..0f1c2cc5c600 --- /dev/null +++ b/unichrome/via_vt162x.h @@ -0,0 +1,667 @@ +/* + * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_VT162X_H_ +#define _VIA_VT162X_H_ 1 + +struct VT162xModePrivate { + char id[12]; /* "VT162x" */ + CARD8 Standard; +}; + +static struct VT162xModePrivate VT162xModePrivateNTSC = { + { 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, + TVTYPE_NTSC, +}; + +static struct VT162xModePrivate VT162xModePrivatePAL = { + { 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, + TVTYPE_PAL, +}; + + +#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT +#define MODESUFFIXNTSC 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivateNTSC,0,0.0,0.0 +#define MODESUFFIXPAL 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivatePAL,0,0.0,0.0 + +/* + * + * VT1621 modetables + * + */ +/* for dotclock i just took HTotal*VTotal*50 -- is not actually used - just to satisfy modevalidation */ +static DisplayModeRec VT1621Modes[] = { + { MODEPREFIX("640x480"), 23520, 640, 656, 752, 784, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480"), 26250, 640, 664, 792, 840, 0, 480, 529, 539, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), 36000, 800, 824, 904, 960, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("640x480Over"), 20580, 640, 656, 752, 784, 0, 480, 494, 507, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480Over"), 24000, 640, 672, 888, 960, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), 36400, 800, 840, 960, 1040, 0, 600, 602, 604, 700, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), 29500, 800, 824, 896, 944, 0, 600, 599, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + +struct VT1621TableRec { + char * name; + CARD16 Width; + CARD16 Height; + int Standard; + CARD8 PrimaryCR6C; + CARD8 TV[0x25]; + CARD8 TVC[0x18]; + CARD8 TVS[0x18]; + CARD32 SubCarrier; + CARD32 DotCrawlSubCarrier; +}; + +static struct VT1621TableRec +VT1621Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, 0, + { 0x64, 0x03, 0x22, 0x33, 0x43, 0, 0x10, 0x7D, 0xAC, 0x05, 0x99, 0x17, 0x93, 0xA5, 0x03, 0xBA, + 0, 0, 0x0A, 0xCD, 0x80, 0x28, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x6D }, + { 0x48, 0x01, 0x02, 0, 0xFC, 0xF9, 0xFF, 0x10, 0x23, 0x2C, 0x09, 0x08, 0x0A, 0x0C, 0x0D, 0x0D }, + { 0x48, 0x02, 0x02, 0xFD, 0x06, 0xF8, 0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, 0x11, 0x6E }, + 0x207FFFBE, 0x207FF6BE, + }, + { "640x480", 640, 480, TVTYPE_PAL, 0x04, + { 0x64, 0x01, 0x02, 0x33, 0x40, 0, 0x10, 0xAD, 0xD3, 0x37, 0xA3, 0, 0x94, 0xFF, 0x03, 0xBA, + 0, 0, 0x07, 0x26, 0x2C, 0x20, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x76 }, + { 0x48, 0, 0, 0xFE, 0xFC, 0xFD, 0x05, 0x12, 0x1F, 0x25, 0x0B, 0x08, 0x0A, 0x0C, 0x0D, 0x0D }, + { 0x48, 0xFE, 0x03, 0xFB, 0x06, 0xF8, 0x0A, 0xF5, 0x0C, 0x73, 0x06, 0xF8, 0x0B, 0xF2, 0x10, 0x6F }, + 0x25D56350, 0, + }, + { "800x600", 800, 600, TVTYPE_NTSC, 0x1E, + { 0x84, 0x03, 0x2A, 0x33, 0x43, 0, 0x10, 0xDD, 0xB9, 0x15, 0x99, 0x17, 0x93, 0xA5, 0x03, 0xBA, + 0, 0, 0x0A, 0xED, 0x98, 0x1C, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x6D }, + { 0x48, 0, 0xFF, 0xFD, 0xFC, 0xFF, 0x07, 0x13, 0x1E, 0x22, 0x0D, 0x08, 0x09, 0x0A, 0x0B, 0x0C }, + { 0x48, 0x02, 0x02, 0xFD, 0x06, 0xF8, 0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, 0x11, 0x6E }, + 0x1B5E5096, 0x1B5E5796, + }, + { "800x600", 800, 600, TVTYPE_PAL, 0x04, + { 0x84, 0x03, 0x1A, 0x33, 0x40, 0, 0x10, 0x85, 0xF1, 0x4B, 0xA3, 0, 0x94, 0xFF, 0x03, 0xBA, + 0, 0, 0x07, 0x25, 0x2C, 0x1C, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x76 }, + { 0x48, 0xFF, 0xFE, 0xFD, 0xFE, 0x02, 0x0A, 0x13, 0x1A, 0x1D, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x0B }, + { 0x48, 0xFB, 0x04, 0xFB, 0x07, 0xF8, 0x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2, 0x10, 0x6F }, + 0x1F872818, 0, + }, + { "640x480Over", 640, 480, TVTYPE_NTSC, 0, + { 0x64, 0x03, 0x02, 0x33, 0x43, 0, 0x10, 0x7D, 0x72, 0x05, 0x99, 0x17, 0x93, 0xA5, 0x03, 0xBA, + 0, 0, 0x0D, 0x45, 0x38, 0x34, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x6D }, + { 0x48, 0, 0x01, 0x02, 0xFF, 0xF9, 0xFA, 0x0C, 0x26, 0x32, 0x07, 0x08, 0x0A, 0x0D, 0x0E, 0x0F }, + { 0x48, 0x02, 0x02, 0xFD, 0x06, 0xF8, 0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, 0x11, 0x6E }, + 0x252491F1, 0x252499F1, + }, + { "640x480Over", 640, 480, TVTYPE_PAL, 0, + { 0x64, 0x01, 0x12, 0x33, 0x40, 0, 0x10, 0x1D, 0x68, 0x26, 0xA3, 0, 0x94, 0xFF, 0x03, 0xBA, + 0, 0, 0x0F, 0x67, 0x58, 0x3C, 0, 0, 0, 0, 0, 0, 0x0A, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x76 }, + { 0x48, 0, 0x01, 0x01, 0xFE, 0xFA, 0xFD, 0x0E, 0x24, 0x2E, 0x07, 0x07, 0x0A, 0x0D, 0x0F, 0x0F }, + { 0x48, 0xFD, 0x03, 0xFB, 0x07, 0xF8, 0x0A, 0xF5, 0x0B, 0x74, 0x06, 0xF8, 0x0B, 0xF2, 0x10, 0x6F }, + 0x2F4ABC24, 0, + }, + { "800x600Over", 800, 600, TVTYPE_NTSC, 0, + { 0x84, 0x03, 0x0A, 0x33, 0x43, 0, 0x10, 0xC5, 0xAD, 0x10, 0x99, 0x17, 0x93, 0xA5, 0x03, 0xBA, + 0, 0, 0x04, 0x07, 0x20, 0x0C, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x6D }, + { 0x48, 0, 0xFF, 0xFD, 0xFC, 0xFE, 0x06, 0x13, 0x1E, 0x23, 0x0D, 0x08, 0x0A, 0x0B, 0x0C, 0x0C }, + { 0x48, 0x02, 0x02, 0xFD, 0x06, 0xF8, 0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, 0x11, 0x6E }, + 0x1C000008, 0x1C000808, + }, + { "800x600Over", 800, 600, TVTYPE_PAL, 0, + { 0x84, 0x03, 0x02, 0x33, 0x40, 0, 0x10, 0x75, 0x7B, 0x34, 0xA3, 0, 0x94, 0xFF, 0x03, 0xBA, + 0, 0, 0x08, 0xFD, 0xEF, 0x20, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0, + 0x75, 0x0C, 0x04, 0x76 }, + { 0x48, 0xFF, 0xFE, 0xFD, 0xFE, 0x02, 0x0A, 0x13, 0x1A, 0x1D, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x0B }, + { 0x48, 0xFB, 0x04, 0xFB, 0x07, 0xF8, 0x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2, 0x10, 0x6F }, + 0x26798C0C, 0, + }, + { NULL, 0, 0, 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + 0, 0, + } +}; + +/* + * + * VT1622 modetables + * + */ +static DisplayModeRec VT1622Modes[] = { + { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("848x480"), 34860, 848, 872, 1032, 1200, 0, 480, 495, 509, 581, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("848x480"), 36000, 848, 872, 1032, 1200, 0, 480, 498, 509, 600, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480"), 25200, 720, 728, 776, 840, 0, 480, 511, 515, 600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576"), 28500, 720, 728, 744, 760, 0, 576, 635, 643, 750, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 487, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("848x480Over"), 27720, 848, 856, 928, 1008, 0, 480, 490, 493, 550, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("848x480Over"), 33000, 848, 872, 1032, 1200, 0, 480, 490, 493, 550, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480Over"), 21000, 720, 728, 760, 800, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576Over"), 30000, 720, 728, 864, 1000, 0, 576, 576, 579, 600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x576Noscale"), 28000, 720, 728, 864, 896, 0, 576, 576, 579, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + +struct VT162XTableRec { + char * name; + CARD16 Width; + CARD16 Height; + int Standard; + CARD8 PrimaryCR6C; + CARD8 SecondaryCR6C; + CARD8 TV1[0x30]; + CARD8 TV2[0x1B]; + CARD8 RGB[6]; + CARD8 YCbCr[3]; + CARD32 SubCarrier; + CARD32 DotCrawlSubCarrier; +}; + +static struct VT162XTableRec +VT1622Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x02, 0x03, 0, 0x10, 0x7E, 0x9D, 0x0D, 0x60, 0x17, 0x52, 0x45, 0x0F, 0, + 0, 0, 0xD0, 0x33, 0xBF, 0x3A, 0, 0, 0, 0, 0xE9, 0, 0, 0, 0, 0x05, + 0x12, 0x0C, 0x04, 0x74, 0, 0x5A, 0x2F, 0x97, 0x50, 0, 0, 0xAA, 0x2B, 0x7A, 0xD8, 0 }, + { 0xDC, 0x50, 0x04, 0, 0, 0x40, 0x0F, 0x81, 0x23, 0x57, 0x02, 0x0F, 0x29, 0x73, 0x23, 0x86, + 0xC4, 0xEA, 0xDF, 0x05, 0x92, 0xA1, 0x04, 0, 0, 0x7F, 0x03 }, + { 0xAF, 0xAA, 0xAA, 0x91, 0x9C, 0x27 }, + { 0x50, 0x4B, 0x4D }, + 0x252491F1, 0x252487BE, + }, + { "640x480", 640, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x82, 0, 0, 0x10, 0x3E, 0xA4, 0x37, 0x67, 0, 0x49, 0x49, 0x0F, 0, + 0, 0, 0xEC, 0x2A, 0xB8, 0x29, 0, 0, 0, 0, 0xED, 0, 0x0A, 0, 0, 0x04, + 0x12, 0x0C, 0x04, 0x7B, 0, 0x64, 0x30, 0x93, 0x49, 0x5F, 0x15, 0xA5, 0x23, 0x7A, 0xCC, 0 }, + { 0xF9, 0x50, 0x04, 0, 0, 0x45, 0xE7, 0x81, 0x23, 0x57, 0x02, 0x1F, 0x31, 0x75, 0x23, 0x8A, + 0xC8, 0xF0, 0xFF, 0x05, 0xD7, 0x8E, 0x03, 0x7F, 0xCF, 0xBF, 0x03 }, + { 0x8A, 0x86, 0x86, 0x8D, 0x96, 0x20 }, + { 0x42, 0x49, 0x49 }, + 0x2D66772D, 0, + }, + { "800x600", 800, 600, TVTYPE_NTSC, 0x1E, 0, + { 0x84, 0, 0, 0x24, 0x03, 0, 0x10, 0xDE, 0xD4, 0x0E, 0x59, 0x17, 0x46, 0x40, 0x0F, 0, + 0, 0, 0xEA, 0x0D, 0x98, 0x1C, 0, 0, 0, 0, 0x3D, 0, 0x01, 0, 0, 0x85, + 0x0D, 0x0A, 0x04, 0x74, 0, 0x5A, 0x41, 0x96, 0x6B, 0, 0, 0xAA, 0x2B, 0xA6, 0x1E, 0x10 }, + { 0xE4, 0x69, 0x04, 0, 0, 0x3F, 0x27, 0x21, 0x34, 0xED, 0x02, 0x27, 0xF5, 0x9D, 0x24, 0xB7, + 0x0D, 0x40, 0, 0x58, 0xB6, 0x3B, 0x05, 0, 0x01, 0xEF, 0x05 }, + { 0x93, 0x90, 0x90, 0x91, 0x9C, 0 }, + { 0x43, 0x4A, 0x49 }, + 0x1B5E5096, 0x1B5E4912, + }, + { "800x600", 800, 600, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0xA4, 0, 0, 0x19, 0x66, 0xBF, 0x12, 0x60, 0, 0x56, 0x45, 0x0F, 0, + 0, 0, 0xEC, 0x15, 0xFD, 0x28, 0, 0, 0, 0, 0x16, 0, 0x01, 0, 0, 0x85, + 0x10, 0x0C, 0x04, 0x7B, 0, 0x64, 0x37, 0x93, 0x54, 0x5F, 0x15, 0xA5, 0x23, 0x8F, 0xF4, 0 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x44, 0x97, 0x21, 0x33, 0xED, 0x02, 0x97, 0x87, 0x87, 0x23, 0x9F, + 0xE7, 0x16, 0xE7, 0x16, 0xCC, 0xF3, 0x04, 0, 0x01, 0x4F, 0x04 }, + { 0xB8, 0xB4, 0xB4, 0, 0, 0 }, + { 0x58, 0x5E, 0x5E }, + 0x277A7DE4, 0, + }, + { "1024x768", 1024, 768, TVTYPE_NTSC, 0x12, 0x1C, + { 0x84, 0, 0, 0x44, 0x03, 0, 0x10, 0x80, 0x15, 0x0A, 0x58, 0x17, 0x5B, 0x40, 0x0F, 0, + 0, 0, 0xE9, 0x1E, 0x9D, 0x19, 0, 0, 0, 0, 0x9C, 0, 0x05, 0, 0, 0x85, + 0x0A, 0x05, 0x04, 0x74, 0, 0x5A, 0x56, 0x96, 0x8B, 0, 0, 0xAA, 0x2B, 0xDA, 0x79, 0x10 }, + { 0xDA, 0x50, 0x04, 0, 0, 0x3F, 0x87, 0xFF, 0x34, 0xB0, 0x03, 0x6F, 0xDB, 0xCD, 0x35, 0xF1, + 0x5E, 0xA5, 0x7E, 0x5A, 0x33, 0x26, 0x07, 0, 0x01, 0x27, 0x08 }, + { 0xC2, 0xBE, 0xBE, 0x91, 0x9C, 0 }, + { 0x58, 0x4B, 0x4A }, + 0x14EB66D6, 0x14EB6118, + }, + { "1024x768", 1024, 768, TVTYPE_PAL, 0x1E, 0, + { 0x84, 0, 0, 0xC0, 0, 0, 0x10, 0xA0, 0x2A, 0x38, 0x70, 0, 0x4E, 0x50, 0x0F, 0, + 0, 0, 0xE4, 0x23, 0xD1, 0x0C, 0, 0, 0, 0, 0x96, 0, 0x07, 0, 0, 0x85, + 0x0C, 0x0C, 0x04, 0x7B, 0, 0x64, 0x53, 0x90, 0x7B, 0x5B, 0x15, 0xA0, 0x22, 0xD1, 0x71, 0x10 }, + { 0xDD, 0x60, 0x04, 0, 0, 0x45, 0xAF, 0xFF, 0x34, 0xB5, 0x03, 0x57, 0xA8, 0xC8, 0x35, 0xEC, + 0x4C, 0xCC, 0x67, 0x5A, 0x14, 0x5C, 0x06, 0, 0x01, 0x1F, 0x07 }, + { 0xA9, 0xA6, 0xA6, 0x90, 0x99, 0 }, + { 0x51, 0x49, 0x49 }, + 0x1A8CC372, 0, + }, + { "848x480", 848, 480, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x24, 0x03, 0, 0x10, 0x46, 0xCC, 0x0E, 0x56, 0x17, 0x43, 0x3E, 0x0F, 0, + 0, 0, 0xE8, 0x29, 0x67, 0x19, 0, 0, 0, 0, 0x29, 0, 0x0B, 0, 0, 0x85, + 0x0E, 0x08, 0x04, 0x74, 0, 0x5A, 0x3D, 0x96, 0x64, 0, 0, 0xAA, 0x2B, 0x9C, 0x17, 0x10 }, + { 0xDC, 0x50, 0, 0, 0, 0x40, 0xAF, 0x51, 0x34, 0x44, 0x02, 0xE3, 0xC1, 0x93, 0x23, 0xAD, + 0xFD, 0x2B, 0x7C, 0x17, 0x6D, 0xCA, 0x04, 0, 0x01, 0x2F, 0x05 }, + { 0x94, 0x90, 0x91, 0x91, 0x9C, 0 }, + { 0x44, 0x45, 0x45 }, + 0x1D3CA863, 0x1D3CA05B, + }, + { "848x480", 848, 480, TVTYPE_PAL, 0x08, 0, + { 0x04, 0, 0, 0xC2, 0, 0, 0x10, 0x47, 0xE4, 0x09, 0x64, 0, 0x4F, 0x48, 0x0F, 0, + 0, 0, 0xE7, 0x05, 0x2C, 0x1C, 0, 0, 0, 0, 0x5E, 0, 0x09, 0, 0, 0x84, + 0x0A, 0x0C, 0x04, 0x7B, 0, 0x64, 0x46, 0x93, 0x68, 0x5F, 0x15, 0xA5, 0x23, 0xB4, 0x2A, 0x10 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x43, 0xAF, 0x51, 0x34, 0x57, 0x02, 0x7F, 0x4F, 0xA9, 0x34, 0xD1, + 0x2B, 0x5D, 0xAA, 0x58, 0xD7, 0x01, 0x03, 0, 0x01, 0x7F, 0x04 }, + { 0xA4, 0xA0, 0xA1, 0, 0, 0 }, + { 0x50, 0x49, 0x49 }, + 0x1F872818, 0, + }, + { "720x480", 720, 480, TVTYPE_NTSC, 0x04, 0, + { 0x04, 0, 0, 0x26, 0x03, 0, 0x10, 0x6D, 0xC3, 0x08, 0x56, 0x17, 0x43, 0x3E, 0x0F, 0, + 0, 0, 0x0D, 0x07, 0x60, 0x34, 0, 0, 0, 0, 0x1E, 0, 0x03, 0, 0, 0x85, + 0x0F, 0x08, 0x04, 0x74, 0, 0x5A, 0x39, 0x95, 0x5E, 0, 0, 0xAA, 0x2B, 0x92, 0xFF, 0 }, + { 0xE4, 0x69, 0x04, 0, 0, 0x40, 0x47, 0xD1, 0x23, 0x57, 0x02, 0xBF, 0xAF, 0x8D, 0x23, 0xA4, + 0xF3, 0x20, 0x36, 0x17, 0x92, 0x33, 0x04, 0, 0, 0xBF, 0x03 }, + { 0x94, 0x90, 0x90, 0x91, 0x9C, 0 }, + { 0x42, 0x49, 0x48 }, + 0x1E555518, 0x1E554CC3, + }, + { "720x576", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0xA2, 0, 0, 0x10, 0x1E, 0xAC, 0x38, 0x67, 0, 0x57, 0x49, 0x0F, 0, + 0, 0, 0xF0, 0x0F, 0xD1, 0x38, 0, 0, 0, 0, 0xF2, 0, 0x02, 0, 0, 0x84, + 0x13, 0x0C, 0x04, 0x7B, 0x48, 0x64, 0x30, 0x93, 0x49, 0x5F, 0x15, 0xA5, 0x23, 0x8B, 0xBD, 0 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x45, 0xF7, 0xD1, 0x22, 0xED, 0x02, 0x1D, 0x29, 0x75, 0x23, 0x88, + 0xC6, 0xF0, 0xFA, 0x0F, 0xCC, 0x30, 0x14, 0, 0, 0x8F, 0x03 }, + { 0xB5, 0xB1, 0xB1, 0, 0, 0 }, + { 0x59, 0x4D, 0x4A }, + 0x2D839832, 0, + }, + { "640x480Over", 640, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x02, 0x03, 0, 0x10, 0x48, 0x72, 0x0A, 0x60, 0x17, 0x52, 0x45, 0x0F, 0, + 0, 0, 0xED, 0x23, 0x80, 0x35, 0, 0, 0, 0, 0xE9, 0, 0x02, 0, 0, 0x05, + 0x12, 0x0C, 0x04, 0x75, 0, 0x5A, 0x2F, 0x97, 0x50, 0, 0, 0xAA, 0x2B, 0x7A, 0xD8, 0 }, + { 0xC4, 0x50, 0x04, 0, 0, 0x41, 0xCF, 0x7F, 0x22, 0x2F, 0x02, 0xFF, 0x7F, 0x71, 0x22, 0x83, + 0xC0, 0xE5, 0xC0, 0x05, 0x44, 0, 0x04, 0, 0, 0xFF, 0x02 }, + { 0xAD, 0xA9, 0xA9, 0, 0, 0 }, + { 0x4F, 0x49, 0x49 }, + 0x25EAAA5E, 0x25EA9FF4, + }, + { "640x480Over", 640, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x82, 0, 0, 0x10, 0xB0, 0x39, 0x39, 0x67, 0, 0x48, 0x4A, 0x0F, 0, + 0, 0, 0x2C, 0x05, 0x2C, 0x30, 0, 0, 0, 0, 0xC8, 0, 0x02, 0, 0, 0x05, + 0x15, 0x0C, 0x04, 0x7B, 0, 0x64, 0x28, 0x93, 0x3E, 0x5F, 0x15, 0xA5, 0x23, 0x65, 0xCC, 0 }, + { 0xF9, 0x50, 0x04, 0, 0, 0x45, 0x47, 0x7F, 0x23, 0xF3, 0x01, 0x9F, 0x7F, 0x62, 0x22, 0x72, + 0xA7, 0xCB, 0x05, 0x05, 0x33, 0, 0x03, 0, 0, 0x9F, 0x02 }, + { 0x8A, 0x86, 0x86, 0x90, 0x99, 0 }, + { 0x42, 0x49, 0x49 }, + 0x360C44BC, 0, + }, + { "800x600Over", 800, 600, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x24, 0x03, 0, 0x10, 0xEF, 0xB0, 0x0A, 0x5A, 0x17, 0x46, 0x40, 0x0F, 0, + 0, 0, 0xE8, 0x32, 0xC3, 0x19, 0, 0, 0, 0, 0x33, 0, 0x01, 0, 0, 0x85, + 0x0D, 0x0A, 0x04, 0x75, 0, 0x5A, 0x41, 0x96, 0x68, 0, 0, 0xAA, 0x2B, 0x9E, 0x1E, 0x10 }, + { 0xE4, 0x69, 0x04, 0, 0, 0x40, 0x37, 0x21, 0x34, 0x98, 0x02, 0x01, 0x21, 0x97, 0x34, 0xB1, + 0xFF, 0x34, 0xB6, 0x17, 0x11, 0, 0x05, 0, 0x01, 0x57, 0x05 }, + { 0x93, 0x90, 0x90, 0, 0, 0 }, + { 0x42, 0x45, 0x45 }, + 0x1C61CEE0, 0x1C61C714, + }, + { "800x600Over", 800, 600, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0xA0, 0, 0, 0x19, 0xA6, 0x9F, 0x38, 0x60, 0, 0x57, 0x45, 0x0F, 0, + 0, 0, 0xC8, 0x12, 0x8F, 0x1C, 0, 0, 0, 0, 0x0E, 0, 0x03, 0, 0, 0x85, + 0x10, 0x0C, 0x04, 0x7B, 0, 0x64, 0x37, 0x93, 0x54, 0x5F, 0x15, 0xA5, 0x23, 0x8B, 0xF4, 0 }, + { 0xE9, 0x50, 0x04, 0, 0, 0x44, 0xE7, 0x1F, 0x33, 0x89, 0x02, 0x8D, 0xBC, 0x85, 0x23, 0x9C, + 0xE4, 0x13, 0xD4, 0x16, 0x28, 0x90, 0x04, 0, 0x01, 0x0F, 0x04 }, + { 0xB8, 0xB4, 0xB4, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x48 }, + 0x27E98D57, 0, + }, + { "1024x768Over", 1024, 768, TVTYPE_NTSC, 0x16, 0x1C, + { 0x84, 0, 0, 0x44, 0x03, 0, 0x10, 0xA0, 0xAA, 0x05, 0x57, 0x17, 0x5C, 0x3F, 0x0F, 0, + 0, 0, 0xE8, 0x33, 0x1A, 0x16, 0, 0, 0, 0, 0x66, 0, 0x01, 0, 0, 0x85, + 0x0A, 0x05, 0x04, 0x74, 0, 0x5A, 0x4B, 0x96, 0x79, 0, 0, 0xAA, 0x2B, 0xB9, 0x4B, 0x10 }, + { 0xE4, 0x50, 0x04, 0, 0, 0x40, 0xAF, 0xFF, 0x34, 0x47, 0x03, 0xAF, 0xFF, 0xB1, 0x34, 0xD1, + 0x30, 0x68, 0x0B, 0x59, 0x66, 0, 0x06, 0, 0x01, 0x7F, 0x07 }, + { 0xC2, 0xBE, 0xBE, 0, 0, 0 }, + { 0x57, 0x45, 0x45 }, + 0x1844440E, 0x18443D63, + }, + { "1024x768Over", 1024, 768, TVTYPE_PAL, 0x1E, 0, + { 0x84, 0, 0, 0xC0, 0, 0, 0x10, 0xA8, 0xC5, 0x36, 0x5D, 0, 0x4E, 0x43, 0x0F, 0, + 0, 0, 0xC9, 0x0A, 0x79, 0x1C, 0, 0, 0, 0, 0x6E, 0, 0x03, 0, 0, 0x85, + 0x0C, 0x0C, 0x04, 0x7B, 0, 0x64, 0x4B, 0x93, 0x6F, 0x5F, 0x15, 0xA5, 0x23, 0xBE, 0x5A, 0x10 }, + { 0xDD, 0x60, 0x04, 0, 0, 0x43, 0xAF, 0xFF, 0x34, 0x38, 0x03, 0xCF, 0xDF, 0xB4, 0x34, 0xD6, + 0x35, 0x75, 0x47, 0x59, 0x47, 0x20, 0x05, 0, 0x01, 0x2F, 0x06 }, + { 0xA9, 0xA6, 0xA6, 0x90, 0x99, 0 }, + { 0x51, 0x49, 0x49 }, + 0x1D7B0E38, 0, + }, + { "848x480Over", 848, 480, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x44, 0x03, 0, 0x10, 0x96, 0xA7, 0x08, 0x5B, 0x17, 0x46, 0x40, 0x0F, 0, + 0, 0, 0xE8, 0x3C, 0x2D, 0x22, 0, 0, 0, 0, 0x3D, 0, 0x01, 0, 0, 0x85, + 0x0D, 0x08, 0x04, 0x75, 0, 0x5A, 0x41, 0x96, 0x69, 0, 0, 0xAA, 0x2B, 0xA2, 0x24, 0x10 }, + { 0xDC, 0x50, 0, 0, 0, 0x40, 0xEF, 0x51, 0x33, 0x25, 0x02, 0x1F, 0x4D, 0x9C, 0x34, 0xB5, + 0x0C, 0x3D, 0xF1, 0x57, 0x30, 0x01, 0x04, 0, 0x01, 0x1F, 0x04 }, + { 0xC0, 0xBC, 0xBC, 0, 0, 0 }, + { 0x58, 0x45, 0x45 }, + 0x1B9364A1, 0x1B933067, + }, + { "848x480Over", 848, 480, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0xC0, 0, 0, 0x10, 0x47, 0xA8, 0x39, 0x64, 0, 0x4E, 0x46, 0x0F, 0, + 0, 0, 0xEA, 0x15, 0xF2, 0x28, 0, 0, 0, 0, 0x39, 0, 0x0B, 0, 0, 0x84, + 0x0F, 0x0C, 0x04, 0x7B, 0, 0x64, 0x40, 0x93, 0x5F, 0x5F, 0x15, 0xA5, 0x23, 0xA3, 0x2A, 0x10 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x43, 0xAF, 0x4F, 0x34, 0x25, 0x02, 0x1F, 0x4F, 0x9B, 0x34, 0xB7, + 0x0A, 0x3F, 0xF0, 0x57, 0x85, 0, 0x03, 0, 0x01, 0x1F, 0x04 }, + { 0xA4, 0xA1, 0xA1, 0x90, 0x99, 0 }, + { 0x4E, 0x49, 0x49 }, + 0x2264E5EC, 0, + }, + { "720x480Over", 720, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x02, 0x03, 0, 0x10, 0x18, 0x28, 0x09, 0x5B, 0x17, 0x46, 0x41, 0x0F, 0, + 0, 0, 0xEE, 0x0D, 0xA0, 0x38, 0, 0, 0, 0, 0xEE, 0, 0x02, 0, 0, 0x85, + 0x11, 0x08, 0x04, 0x75, 0, 0x5A, 0x31, 0x95, 0x51, 0, 0, 0xAA, 0x2B, 0x7A, 0xDB, 0 }, + { 0xE4, 0x69, 0x04, 0, 0, 0x40, 0x1F, 0xCF, 0x23, 0x0C, 0x02, 0x1F, 0xCF, 0x76, 0x23, 0x88, + 0xC9, 0xEF, 0xFF, 0x05, 0, 0, 0, 0, 0, 0x1F, 0x03 }, + { 0xAB, 0xA7, 0xA7, 0, 0, 0 }, + { 0x4D, 0x49, 0x49 }, + 0x2466661D, 0x24665C1E, + }, + { "720x576Over", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0xA6, 0, 0, 0x10, 0x10, 0x7D, 0x32, 0x60, 0, 0x57, 0x46, 0x0F, 0, + 0, 0, 0xEC, 0x15, 0xDC, 0x28, 0, 0, 0, 0, 0xEE, 0, 0x0A, 0, 0, 0x84, + 0x13, 0x0C, 0x04, 0x7B, 0x48, 0x64, 0x30, 0x93, 0x49, 0x5F, 0x15, 0xA5, 0x23, 0x77, 0xFF, 0 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x45, 0xE7, 0xCF, 0x23, 0x57, 0x02, 0x1F, 0x80, 0x75, 0x23, 0x89, + 0xC7, 0xF1, 0xFF, 0x05, 0xD7, 0x80, 0x03, 0, 0, 0xBF, 0x03 }, + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x49 }, + 0x2D66772D, 0, + }, + { "720x576Noscale", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0xA4, 0, 0, 0x10, 0x75, 0xA5, 0x3A, 0x5A, 0, 0x49, 0x46, 0, 0x89, + 0, 0, 0xE9, 0x19, 0xDC, 0x24, 0, 0, 0, 0, 0xEE, 0, 0x0A, 0, 0, 0x04, + 0x13, 0x0C, 0x04, 0x7B, 0x48, 0x64, 0x30, 0x93, 0x49, 0x5F, 0x15, 0xA5, 0x23, 0x77, 0xFF, 0 }, + { 0xE7, 0x45, 0x04, 0, 0, 0x45, 0x7F, 0xD0, 0x23, 0x70, 0x02, 0x7F, 0xD0, 0x93, 0x23, 0x89, + 0xC7, 0xF1, 0xBD, 0x06, 0, 0, 0, 0, 0, 0x7F, 0x03 }, + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, /* added later - untested */ + { 0x58, 0x48, 0x49 }, /* added later - untested */ + 0x288933E3, 0, + }, + { NULL, 0, 0, 0, 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0 }, + 0, 0, + } +}; + +/* + * + * VT1622A/VT1623 modetables + * + */ +static DisplayModeRec VT1623Modes[] = { + { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("848x480"), 34860, 848, 872, 1032, 1200, 0, 480, 495, 509, 581, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("848x480"), 36000, 848, 872, 1032, 1200, 0, 480, 498, 509, 600, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480"), 25200, 720, 728, 776, 840, 0, 480, 511, 515, 600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576"), 28500, 720, 728, 744, 760, 0, 576, 635, 643, 750, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 490, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("848x480Over"), 27720, 848, 856, 928, 1008, 0, 480, 490, 493, 550, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("848x480Over"), 33000, 848, 872, 1032, 1200, 0, 480, 490, 493, 550, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480Over"), 21000, 720, 728, 760, 800, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x576Over"), 27000, 720, 768, 800, 864, 0, 576, 577, 579, 625, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + +static struct VT162XTableRec +VT1623Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x06, 0x03, 0, 0x20, 0x28, 0x9A, 0x0C, 0x55, 0, 0x52, 0x3B, 0x0F, 0, + 0, 0, 0xF8, 0x3E, 0x81, 0x56, 0, 0, 0, 0, 0xEA, 0, 0, 0, 0, 0x11, + 0x15, 0x0C, 0x5F, 0x75, 0x08, 0x56, 0x2F, 0x90, 0x50, 0, 0, 0xA3, 0x29, 0x5B, 0xBF, 0 }, + { 0, 0, 0, 0, 0, 0x3B, 0x0F, 0x7F, 0x23, 0x57, 0x02, 0x0F, 0x26, 0x73, 0x63, 0x86, + 0xC4, 0xEA, 0xDF, 0x05, 0x92, 0xA1, 0x84, 0, 0, 0x7F, 0x03 }, + { 0x6A, 0x62, 0x65, 0x91, 0x9C, 0x27 }, + { 0x50, 0x4B, 0x4D }, + 0x252491F1, 0x252487BE, + }, + { "640x480", 640, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x06, 0, 0, 0x20, 0xBF, 0x9F, 0x37, 0x5D, 0, 0x4F, 0x42, 0x0F, 0, + 0, 0, 0xAC, 0x15, 0x6E, 0x28, 0, 0, 0, 0, 0xED, 0, 0x02, 0, 0, 0x99, + 0x17, 0x0C, 0x31, 0x7A, 0x04, 0x62, 0x30, 0x8E, 0x4A, 0x5B, 0x15, 0xA0, 0x22, 0x5C, 0xCC, 0 }, + { 0, 0, 0, 0, 0, 0x43, 0xE7, 0x7F, 0x23, 0x57, 0x02, 0x1F, 0x2F, 0x75, 0x63, 0x8A, + 0xC8, 0xF0, 0xFF, 0x05, 0xD7, 0x8E, 0x83, 0x7F, 0xCF, 0xBF, 0x03 }, + { 0x6A, 0x62, 0x65, 0x8D, 0x96, 0x20 }, + { 0x42, 0x49, 0x49 }, + 0x2D66772D, 0, + }, + { "800x600", 800, 600, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0x58, 0xD4, 0x09, 0x52, 0, 0x51, 0x3B, 0x0F, 0, + 0, 0, 0x6A, 0x0D, 0x4C, 0x1C, 0, 0, 0, 0, 0x3E, 0, 0x01, 0, 0, 0x44, + 0x10, 0x0A, 0x9C, 0x75, 0x04, 0x56, 0x41, 0x90, 0x6B, 0, 0, 0xA3, 0x29, 0x86, 0x10, 0x10 }, + { 0, 0, 0, 0, 0, 0x3A, 0x27, 0x1F, 0x34, 0xED, 0x02, 0x27, 0xF5, 0x9D, 0x64, 0xB7, + 0x0D, 0x40, 0, 0x58, 0xB6, 0x3B, 0x85, 0, 0x01, 0xEF, 0x05 }, + { 0x6A, 0x62, 0x65, 0x91, 0x9C, 0 }, + { 0x43, 0x4A, 0x49 }, + 0x1B5E5096, 0x1B5E4912, + }, + { "800x600", 800, 600, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0x04, 0, 0, 0x20, 0x27, 0xB8, 0x0D, 0x5C, 0, 0x4E, 0x40, 0x0F, 0, + 0, 0, 0xEC, 0x2A, 0xFD, 0x28, 0, 0, 0, 0, 0x11, 0, 0x01, 0, 0, 0xAA, + 0x13, 0x0C, 0x9F, 0x79, 0x0C, 0x62, 0x37, 0x8E, 0x54, 0x5B, 0x15, 0xA0, 0x22, 0x70, 0xF4, 0 }, + { 0, 0, 0, 0, 0, 0x41, 0x97, 0x1F, 0x33, 0xED, 0x02, 0x97, 0x87, 0x87, 0x63, 0x9F, + 0xE7, 0x16, 0xE7, 0x16, 0xCC, 0xF3, 0x84, 0, 0x01, 0x4F, 0x04 }, + { 0x6A, 0x62, 0x65, 0, 0, 0}, + { 0x58, 0x5E, 0x5E }, + 0x277A7DE4, 0, + }, + { "1024x768", 1024, 768, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0x47, 0x12, 0x08, 0x50, 0, 0x50, 0x3A, 0x0F, 0, + 0, 0, 0xEF, 0x37, 0x77, 0x2A, 0, 0, 0, 0, 0xA1, 0, 0x05, 0, 0, 0x77, + 0x0D, 0x05, 0xEF, 0x73, 0x0C, 0x56, 0x56, 0x90, 0x8B, 0, 0, 0xA3, 0x29, 0xB9, 0x6A, 0x10 }, + { 0, 0, 0, 0, 0, 0x39, 0x87, 0xFF, 0x34, 0xB0, 0x03, 0x6F, 0xDC, 0xCD, 0x35, 0xF1, + 0x5E, 0xA5, 0x7E, 0x5A, 0x33, 0x26, 0x87, 0, 0x01, 0x27, 0x08 }, + { 0x6A, 0x62, 0x65, 0x91, 0x9C, 0 }, + { 0x58, 0x4B, 0x4A }, + 0x14EB66D6, 0x14EB6118, + }, + { "1024x768", 1024, 768, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0x04, 0, 0, 0x20, 0x57, 0x25, 0x35, 0x5A, 0, 0x4D, 0x40, 0x0F, 0, + 0, 0, 0xE8, 0x23, 0xD1, 0x18, 0, 0, 0, 0, 0x96, 0, 0x07, 0, 0, 0xFF, + 0x0F, 0x0C, 0x87, 0x79, 0, 0x62, 0x53, 0x8E, 0x7B, 0x5B, 0x15, 0xA0, 0x22, 0xB6, 0x5A, 0x10 }, + { 0, 0, 0, 0, 0, 0x40, 0xAF, 0xFF, 0x34, 0xB5, 0x03, 0x57, 0xA8, 0xC8, 0x35, 0xEC, + 0x4C, 0xCC, 0x67, 0x5A, 0x14, 0x5C, 0x06, 0, 0x01, 0x1F, 0x07 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x50, 0x69, 0x69 }, + 0x1A8CC372, 0, + }, + { "848x480", 848, 480, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0xA7, 0xC1, 0x07, 0x50, 0, 0x50, 0x39, 0x0F, 0, + 0, 0, 0xF0, 0x29, 0x67, 0x31, 0, 0, 0, 0, 0x2A, 0, 0x03, 0, 0, 0x33, + 0x11, 0x08, 0x47, 0x73, 0x0C, 0x56, 0x3C, 0x90, 0x65, 0, 0, 0xA3, 0x29, 0x7C, 0, 0x10 }, + { 0, 0, 0, 0, 0, 0x39, 0xAF, 0x4F, 0x34, 0x44, 0x02, 0xE3, 0xC2, 0x93, 0x63, 0xAD, + 0xFD, 0x2B, 0x7C, 0x17, 0x6D, 0xCA, 0x84, 0, 0x01, 0x2F, 0x05 }, + { 0x6A, 0x62, 0x65, 0x91, 0x9C, 0 }, + { 0x44, 0x45, 0x45 }, + 0x1D3CA863, 0x1D3CA05B, + }, + { "848x480", 848, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x06, 0, 0, 0x20, 0xA7, 0xE6, 0x06, 0x5C, 0, 0x4E, 0x41, 0x0F, 0, + 0, 0, 0xE6, 0x23, 0x84, 0x18, 0, 0, 0, 0, 0x56, 0, 0x01, 0, 0, 0xCC, + 0x0F, 0x0C, 0x60, 0x79, 0, 0x62, 0x46, 0x8E, 0x68, 0x5B, 0x15, 0xA0, 0x22, 0x94, 0x2A, 0x10 }, + { 0, 0, 0, 0, 0, 0x40, 0xAF, 0x4F, 0x34, 0x57, 0x02, 0x7F, 0x31, 0xA9, 0x74, 0xD1, + 0x2B, 0x5D, 0xAA, 0x58, 0xD7, 0x26, 0x83, 0, 0x01, 0x7F, 0x04 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x50, 0x49, 0x49 }, + 0x1F872818, 0, + }, + { "720x480", 720, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x06, 0x03, 0, 0x20, 0x3F, 0xB6, 0x07, 0x52, 0, 0x51, 0x3A, 0x0F, 0, + 0, 0, 0xED, 0x31, 0x50, 0x35, 0, 0, 0, 0, 0x1E, 0, 0x03, 0, 0, 0x33, + 0x12, 0x08, 0x57, 0x75, 0, 0x56, 0x3A, 0x90, 0x61, 0, 0, 0xA3, 0x29, 0x76, 0xF1, 0 }, + { 0, 0, 0, 0, 0, 0x3A, 0x47, 0xCF, 0x23, 0x57, 0x02, 0xBF, 0xAD, 0x8D, 0x63, 0xA4, + 0xF3, 0x20, 0x36, 0x17, 0x92, 0x33, 0x84, 0, 0, 0xBF, 0x03 }, + { 0x6A, 0x62, 0x65, 0x91, 0x9C, 0 }, + { 0x42, 0x49, 0x48 }, + 0x1E555518, 0x1E554CC3, + }, + { "720x576", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x06, 0, 0, 0x20, 0x0F, 0xAF, 0x35, 0x5D, 0, 0x4F, 0x41, 0x0F, 0, + 0, 0, 0xF8, 0x3C, 0x73, 0x56, 0, 0, 0, 0, 0xED, 0, 0x02, 0, 0, 0x99, + 0x18, 0x0C, 0x76, 0x7A, 0x44, 0x62, 0x30, 0x8E, 0x49, 0x5B, 0x15, 0xA0, 0x22, 0x5C, 0xBD, 0 }, + { 0, 0, 0, 0, 0, 0x43, 0xF7, 0xCF, 0x22, 0xED, 0x02, 0x1D, 0x29, 0x75, 0x63, 0x88, + 0xC6, 0xF0, 0xFA, 0x0F, 0xCC, 0x30, 0x94, 0, 0, 0x8F, 0x03 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x59, 0x4D, 0x4A }, + 0x2D839832, 0, + }, + { "640x480Over", 640, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0x06, 0x03, 0, 0x20, 0x10, 0x76, 0x0A, 0x56, 0x05, 0x50, 0x3B, 0x0F, 0, + 0, 0, 0xED, 0x23, 0xC0, 0x34, 0, 0, 0, 0, 0xE5, 0, 0x02, 0, 0, 0x11, + 0x17, 0x0C, 0x46, 0x73, 0x0C, 0x56, 0x2E, 0x90, 0x4E, 0, 0, 0xA3, 0x29, 0x59, 0xBA, 0 }, + { 0, 0, 0, 0, 0, 0x3A, 0xCF, 0x7F, 0x22, 0x2F, 0x02, 0xFF, 0x59, 0x71, 0x62, 0x83, + 0xC0, 0xE5, 0xC0, 0x05, 0x44, 0x44, 0x84, 0, 0, 0xFF, 0x02 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x4F, 0x49, 0x49 }, + 0x25EAAA5E, 0x25EA9FF4, + }, + { "640x480Over", 640, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0x06, 0, 0, 0x20, 0x23, 0x4E, 0x2A, 0x61, 0, 0x4D, 0x47, 0x0F, 0, + 0, 0, 0x4A, 0x0F, 0x37, 0x28, 0, 0, 0, 0, 0xC7, 0, 0x02, 0, 0, 0x88, + 0x1B, 0x0C, 0xFF, 0x79, 0, 0x62, 0x28, 0x8E, 0x3E, 0x5B, 0x15, 0xA0, 0x22, 0x49, 0xCC, 0 }, + { 0, 0, 0, 0, 0, 0x44, 0x47, 0x7F, 0x23, 0xF3, 0x01, 0x9F, 0x3F, 0x62, 0x62, 0x72, + 0xA7, 0xCB, 0x05, 0x05, 0x33, 0x70, 0x83, 0, 0, 0x9F, 0x02 }, + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + { 0x42, 0x49, 0x49 }, + 0x360C44BC, 0, + }, + { "800x600Over", 800, 600, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0x5F, 0xA4, 0x08, 0x51, 0, 0x50, 0x39, 0x0F, 0, + 0, 0, 0xE8, 0x33, 0xE6, 0x18, 0, 0, 0, 0, 0x32, 0, 0x03, 0, 0, 0x33, + 0x11, 0x0A, 0x9B, 0x73, 0x08, 0x56, 0x3F, 0x90, 0x68, 0, 0, 0xA3, 0x29, 0x82, 0x02, 0x10 }, + { 0, 0, 0, 0, 0, 0x39, 0x37, 0x21, 0x34, 0x98, 0x02, 0x01, 0x21, 0x97, 0x74, 0xB1, + 0xFF, 0x34, 0xB6, 0x17, 0x11, 0, 0x85, 0, 0x01, 0x57, 0x05 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x42, 0x45, 0x45 }, + 0x1C61CEE0, 0x1C61C714, + }, + { "800x600Over", 800, 600, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0x04, 0, 0, 0x20, 0x47, 0x90, 0x3B, 0x5A, 0, 0x4D, 0x3F, 0x0F, 0, + 0, 0, 0xE8, 0x24, 0x8F, 0x1C, 0, 0, 0, 0, 0x0E, 0, 0x03, 0, 0, 0xAA, + 0x14, 0x0C, 0x2F, 0x79, 0, 0x62, 0x37, 0x8E, 0x54, 0x5B, 0x15, 0xA0, 0x22, 0x6E, 0xF4, 0 }, + { 0, 0, 0, 0, 0, 0x41, 0xE7, 0x1F, 0x33, 0x89, 0x02, 0x8D, 0xCD, 0x85, 0x63, 0x9C, + 0xE4, 0x13, 0xD4, 0x16, 0x28, 0x60, 0x84, 0, 0x01, 0x0F, 0x04 }, + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x48 }, + 0x27E98D57, 0, + }, + { "1024x768Over", 1024, 768, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0x52, 0xAE, 0x09, 0x50, 0, 0x50, 0x39, 0x0F, 0, + 0, 0, 0xE8, 0x33, 0x0D, 0x15, 0, 0, 0, 0, 0x66, 0, 0x03, 0, 0, 0x55, + 0x0F, 0x05, 0xF1, 0x73, 0x08, 0x56, 0x4A, 0x90, 0x79, 0, 0, 0xA3, 0x29, 0x9B, 0x33, 0x10 }, + { 0, 0, 0, 0, 0, 0x39, 0xAF, 0xFF, 0x34, 0x47, 0x03, 0xAF, 0xC3, 0xB1, 0x34, 0xD1, + 0x30, 0x68, 0x0B, 0x59, 0x66, 0x40, 0x86, 0, 0x01, 0x7F, 0x07 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x57, 0x45, 0x45 }, + 0x1844440E, 0x18443D63, + }, + { "1024x768Over", 1024, 768, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0x04, 0, 0, 0x20, 0x56, 0xC0, 0x32, 0x5A, 0, 0x4D, 0x40, 0x0F, 0, + 0, 0, 0xC9, 0x14, 0x79, 0x1C, 0, 0, 0, 0, 0x6D, 0, 0x03, 0, 0, 0xDD, + 0x0F, 0x0C, 0xCA, 0x79, 0x08, 0x62, 0x4B, 0x8E, 0x6F, 0x5B, 0x15, 0xA0, 0x22, 0xA1, 0x5A, 0x10 }, + { 0, 0, 0, 0, 0, 0x40, 0xAF, 0xFF, 0x34, 0x38, 0x03, 0xCF, 0xDF, 0xB4, 0x34, 0xD6, + 0x35, 0x75, 0x47, 0x59, 0x47, 0x20, 0x05, 0, 0x01, 0x2F, 0x06 }, + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + { 0x51, 0x49, 0x49 }, + 0x1D7B0E38, 0, + }, + { "848x480Over", 848, 480, TVTYPE_NTSC, 0, 0, + { 0x84, 0, 0, 0x04, 0x03, 0, 0x20, 0x4E, 0x9E, 0x07, 0x51, 0, 0x50, 0x3A, 0x0F, 0, + 0, 0, 0xED, 0x23, 0x08, 0x35, 0, 0, 0, 0, 0x3C, 0, 0x03, 0, 0, 0x44, + 0x11, 0x0A, 0xF0, 0x73, 0x04, 0x56, 0x41, 0x90, 0x6A, 0, 0, 0xA3, 0x29, 0x87, 0x0A, 0x10 }, + { 0, 0, 0, 0, 0, 0x39, 0xEF, 0x51, 0x33, 0x25, 0x02, 0x1F, 0x47, 0x9C, 0x74, 0xB5, + 0x0C, 0x3D, 0xF1, 0x57, 0x30, 0x0C, 0x84, 0, 0x01, 0x1F, 0x04 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x58, 0x45, 0x45 }, + 0x1B9364A1, 0x1B933067, + }, + { "848x480Over", 848, 480, TVTYPE_PAL, 0, 0, + { 0x84, 0, 0, 0x04, 0, 0, 0x20, 0xA5, 0xA1, 0x38, 0x5E, 0, 0x4D, 0x41, 0x0F, 0, + 0, 0, 0xC7, 0x1E, 0x79, 0x1C, 0, 0, 0, 0, 0x39, 0, 0x03, 0, 0, 0xBB, + 0x12, 0x0C, 0x5A, 0x79, 0x0C, 0x62, 0x40, 0x8E, 0x5F, 0x5B, 0x15, 0xA0, 0x22, 0x88, 0x2A, 0x10 }, + { 0, 0, 0, 0, 0, 0x3A, 0xAF, 0x4F, 0x34, 0x25, 0x02, 0x1F, 0x4F, 0x9B, 0x74, 0xB7, + 0x0A, 0x3F, 0xF0, 0x58, 0x85, 0, 0x83, 0, 0x01, 0x1F, 0x04 }, + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + { 0x4E, 0x49, 0x49 }, + 0x2264E5EC, 0, + }, + { "720x480Over", 720, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0, 0x03, 0, 0x20, 0x28, 0x52, 0x08, 0x50, 0, 0x4E, 0x2F, 0x0F, 0, + 0, 0, 0x2D, 0x07, 0x28, 0x34, 0, 0, 0, 0, 0xEE, 0, 0x02, 0, 0, 0x11, + 0x16, 0x08, 0xDF, 0x76, 0x04, 0x56, 0x31, 0x90, 0x51, 0, 0, 0xA3, 0x29, 0x5D, 0xC3, 0 }, + { 0, 0, 0, 0, 0x08, 0x3A, 0x1F, 0xCF, 0x23, 0x0C, 0x02, 0x1F, 0xCE, 0x76, 0x23, 0x88, + 0xC9, 0xEF, 0xFF, 0x05, 0, 0, 0, 0, 0, 0x1F, 0x03 }, + { 0x6A, 0x62, 0x65, 0, 0, 0 }, + { 0x4D, 0x49, 0x49 }, + 0x2466661D, 0x24665C1E, + }, + { "720x576Over", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0, 0, 0, 0, 0, 0x20, 0x3F, 0x89, 0x35, 0x50, 0, 0x43, 0x2E, 0x0F, 0, + 0, 0, 0xE8, 0x23, 0x84, 0x20, 0, 0, 0, 0, 0xFF, 0, 0x02, 0, 0, 0x99, + 0x17, 0x0C, 0x6F, 0x79, 0x48, 0x62, 0x34, 0x8E, 0x4F, 0x5B, 0x15, 0xA0, 0x22, 0x67, 0xFF, 0 }, + { 0, 0, 0, 0, 0, 0x3A, 0x5F, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xBF, 0x7E, 0x23, 0x94, + 0xD0, 0x27, 0x8F, 0x16, 0, 0, 0x04, 0, 0, 0x5F, 0x03 }, + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x49 }, + 0x2A098ACB, 0, + }, + { NULL, 0, 0, 0, 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0 }, + 0, 0, + } +}; + +#endif /* _VIA_VT162X_H_ */ diff --git a/unichrome/via_xvmc.c b/unichrome/via_xvmc.c new file mode 100644 index 000000000000..711309783ac3 --- /dev/null +++ b/unichrome/via_xvmc.c @@ -0,0 +1,1034 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension X server driver. + * + * Copyright (c) 2004 The Unichrome Project. All rights reserved. + * Copyright (c) 2000 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#ifdef XF86DRI + +#include "via.h" +#include "via_dri.h" +#include "via_driver.h" +#include "via_id.h" + +#include "xf86xv.h" +#include "fourcc.h" + +#if defined(X_NEED_XVPRIV_H) || defined (_XF86_FOURCC_H_) +#include "xf86xvpriv.h" +#endif + +#include "xf86xvmc.h" +#include "Xv.h" +#include "XvMC.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "via_xvmc.h" +#include "dristruct.h" +#include "dri.h" +#include "via_xvpriv.h" +#include "via_video.h" + +#define MAKE_ATOM(a) MakeAtom(a, strlen(a), TRUE) + + +/* + * List Attributes for the XvMC extension to handle: + * As long as the attribute is supported by the Xv adaptor, it needs only to + * be added here to be supported also by XvMC. + * Currently, only colorkey seems to be supported by Xv for Putimage. + */ + +static char *attrXvMC[VIA_NUM_XVMC_ATTRIBUTES] = + {"XV_COLORKEY", + "XV_AUTOPAINT_COLORKEY", + "XV_BRIGHTNESS", + "XV_CONTRAST", + "XV_SATURATION", + "XV_HUE"}; +static Atom attrAtoms[VIA_NUM_XVMC_ATTRIBUTES]; + +/* + * Xv Port private structure for XvMC. + */ + +typedef struct{ + unsigned ctxDisplaying; + int xvmc_port; + ViaXvMCAttrHolder xvAttr; + int newAttribute; + + SetPortAttributeFuncPtr SetPortAttribute; + GetPortAttributeFuncPtr GetPortAttribute; + PutImageFuncPtr PutImage; +}ViaXvMCXVPriv; + + +/* + * Proposed XvMC via driver extension: + */ + +#define XVMC_VLD 0x0020000 + +/* + * Function declarations. + */ + + +static int ViaXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, + int *num_priv, long **priv ); +static void ViaXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext); +static int ViaXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, long **priv ); +static void ViaXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf); +static int ViaXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf, + int *num_priv, long **priv ); +static void ViaXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp); +static int viaXvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value,pointer data); +static int viaXvMCInterceptPutImage(ScrnInfoPtr, short, short, short, short, short, + short, short, short,int, unsigned char*, short, + short, Bool, RegionPtr, pointer); +static int viaXvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 *value,pointer data); +/* + * Init and clean up the screen private parts of XvMC. + */ + +static void initViaXvMC(ViaXvMCPtr vXvMC) +{ + unsigned i; + + for (i=0; i < VIA_XVMC_MAX_CONTEXTS; ++i) { + vXvMC->contexts[i] = 0; + vXvMC->cPrivs[i] = 0; + } + + for (i=0; i < VIA_XVMC_MAX_SURFACES; ++i) { + vXvMC->surfaces[i] = 0; + vXvMC->sPrivs[i] = 0; + } + +} + +static void +cleanupViaXvMC(ViaXvMCPtr vXvMC, XF86VideoAdaptorPtr *XvAdaptors, + int XvAdaptorCount) +{ + unsigned i; + + for (i=0; i < VIA_XVMC_MAX_CONTEXTS; ++i) { + vXvMC->contexts[i] = 0; + if (vXvMC->cPrivs[i]) { + xfree(vXvMC->cPrivs[i]); + vXvMC->cPrivs[i] = 0; + } + } + + for (i=0; i < VIA_XVMC_MAX_SURFACES; ++i) { + vXvMC->surfaces[i] = 0; + if (vXvMC->sPrivs[i]) { + xfree(vXvMC->sPrivs[i]); + vXvMC->sPrivs[i] = 0; + } + } +} + +static unsigned stride(int w) +{ + return (w + 31) & ~31; +} + +static unsigned long size_yuv420(int w, int h) +{ + unsigned yPitch = stride(w); + return h* (yPitch + (yPitch >> 1)); +} + +static unsigned long size_xx44(int w, int h) +{ + return h * stride(w); +} + + +static int yv12_subpicture_index_list[2] = +{ + FOURCC_IA44, + FOURCC_AI44 +}; + +static XF86MCImageIDList yv12_subpicture_list = +{ + 2, + yv12_subpicture_index_list +}; + +static XF86MCSurfaceInfoRec Via_YV12_mpg2_surface = +{ + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 2048, + 2048, + 2048, + 2048, + XVMC_MPEG_2 | XVMC_VLD, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoRec Via_YV12_mocomp_mpg12_surface = +{ + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 1024, + 1024, + 1024, + 1024, + XVMC_MPEG_1 | XVMC_MPEG_2 | XVMC_MOCOMP, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoRec Via_YV12_idct_mpg12_surface = +{ + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 1024, + 1024, + 1024, + 1024, + XVMC_MPEG_1 | XVMC_MPEG_2 | XVMC_IDCT, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoRec Via_YV12_mpg1_surface = +{ + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 2048, + 2048, + 2048, + 2048, + XVMC_MPEG_1 | XVMC_VLD, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoPtr ppSI[2] = +{ + (XF86MCSurfaceInfoPtr)&Via_YV12_mpg2_surface, + (XF86MCSurfaceInfoPtr)&Via_YV12_mpg1_surface +}; + +static XF86MCSurfaceInfoPtr ppSI_mocomp[2] = +{ + (XF86MCSurfaceInfoPtr)&Via_YV12_mocomp_mpg12_surface, + (XF86MCSurfaceInfoPtr)&Via_YV12_idct_mpg12_surface +}; + + +/* List of subpicture types that we support */ +static XF86ImageRec ia44_subpicture = XVIMAGE_IA44; +static XF86ImageRec ai44_subpicture = XVIMAGE_AI44; + +static XF86ImagePtr Via_subpicture_list[2] = +{ + (XF86ImagePtr)&ia44_subpicture, + (XF86ImagePtr)&ai44_subpicture +}; + +/* + * Fill in the device dependent adaptor record. + * This is named "VIA Video Overlay" because this code falls under the + * XV extenstion, the name must match or it won't be used. + * + * Surface and Subpicture - see above + * Function pointers to functions below + */ + +static XF86MCAdaptorRec pAdapt = +{ + "XV_SWOV", /* name */ + 2, /* num_surfaces */ + ppSI, /* surfaces */ + 2, /* num_subpictures */ + Via_subpicture_list, /* subpictures */ + (xf86XvMCCreateContextProcPtr)ViaXvMCCreateContext, + (xf86XvMCDestroyContextProcPtr)ViaXvMCDestroyContext, + (xf86XvMCCreateSurfaceProcPtr)ViaXvMCCreateSurface, + (xf86XvMCDestroySurfaceProcPtr)ViaXvMCDestroySurface, + (xf86XvMCCreateSubpictureProcPtr)ViaXvMCCreateSubpicture, + (xf86XvMCDestroySubpictureProcPtr)ViaXvMCDestroySubpicture +}; + +static XF86MCAdaptorRec pAdapt_mocomp = +{ + "XV_SWOV", /* name */ + 2, /* num_surfaces */ + ppSI_mocomp, /* surfaces */ + 2, /* num_subpictures */ + Via_subpicture_list, /* subpictures */ + (xf86XvMCCreateContextProcPtr)ViaXvMCCreateContext, + (xf86XvMCDestroyContextProcPtr)ViaXvMCDestroyContext, + (xf86XvMCCreateSurfaceProcPtr)ViaXvMCCreateSurface, + (xf86XvMCDestroySurfaceProcPtr)ViaXvMCDestroySurface, + (xf86XvMCCreateSubpictureProcPtr)ViaXvMCCreateSubpicture, + (xf86XvMCDestroySubpictureProcPtr)ViaXvMCDestroySubpicture +}; + +static XF86MCAdaptorPtr ppAdapt[1] = {(XF86MCAdaptorPtr)&pAdapt}; +static XF86MCAdaptorPtr ppAdapt_mocomp[1] = {(XF86MCAdaptorPtr)&pAdapt_mocomp}; + +static void mpegDisable(VIAPtr pVia,CARD32 val) + +{ + MPGOutD(0x0c, MPGInD(0x0c) & (val ^ 0xffffffff)); +} + + +void +ViaInitXVMC(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + volatile ViaXvMCSAreaPriv *saPriv; + char *bID; + drmVersionPtr drmVer; + + pVia->XvMCEnabled = 0; + + if (!(pVia->Chipset == VIA_CLE266) && !(pVia->Chipset == VIA_K8M800) && + !(pVia->Chipset == VIA_PM800)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Not supported on this chipset.\n"); + return; + } + + if (!pVia->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Cannot use XvMC without DRI!\n"); + return; + } + + if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Could not get drm version. Disabling XvMC\n"); + return; + } + if (((drmVer->version_major <= 2) && (drmVer->version_minor < 4))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Kernel drm is not compatible with XvMC.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Kernel drm version: %d.%d.%d " + "and need at least version 2.4.0.\n", + drmVer->version_major,drmVer->version_minor, + drmVer->version_patchlevel); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Please update. Disabling XvMC.\n"); + drmFreeVersion(drmVer); + return; + } + if ((drmVer->version_major >= 3)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] XvMC X driver may not be compatible " + "with kernel drm.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Continuing, but strange things may happen.\n"); + } + drmFreeVersion(drmVer); + + if (!DRIOpenConnection(pScreen,&vXvMC->sAreaBase,&bID)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] DRIOpenConnection failed. Disabling XvMC.\n"); + return; + } + DRICloseConnection(pScreen); + + vXvMC->mmioBase = pVia->registerHandle; + + if (drmAddMap(pVia->drmFD, + (drm_handle_t)pVia->FrameBufferBase, + pVia->videoRambytes, DRM_FRAME_BUFFER, + 0 , &(vXvMC->fbBase)) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] drmAddMap(FB) failed. Disabling XvMC.\n"); + return; + } + + initViaXvMC(vXvMC); + + if (! xf86XvMCScreenInit(pScreen, 1, + (pVia->Chipset == VIA_KM400) ? + ppAdapt_mocomp : ppAdapt)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] XvMCScreenInit failed. Disabling XvMC.\n"); + drmRmMap(pVia->drmFD,vXvMC->fbBase); + return; + } + +#if (XvMCVersion > 1) || (XvMCRevision > 0) + { + DRIInfoPtr pDRIInfo = pVia->pDRIInfo; + xf86XvMCRegisterDRInfo(pScreen, "viaXvMC",pDRIInfo->busIdString, + VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL); + } +#endif + + vXvMC->activePorts = 0; + saPriv=(ViaXvMCSAreaPriv *) DRIGetSAREAPrivate(pScreen); + saPriv->XvMCCtxNoGrabbed = ~0; + + XVMCLOCKPTR(saPriv,UNICHROME_LOCK_DECODER1)->lock = 0; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Initialized XvMC extension.\n"); + pVia->XvMCEnabled = 1; +} + +void ViaCleanupXVMC(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr *XvAdaptors, + int XvAdaptorCount) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + int i,j; + + if (pVia->XvMCEnabled) { + mpegDisable(pVia,0); + drmRmMap(pVia->drmFD,vXvMC->mmioBase); + drmRmMap(pVia->drmFD,vXvMC->fbBase); + cleanupViaXvMC(vXvMC, XvAdaptors, XvAdaptorCount); + } + for (i=0; i<XvAdaptorCount; ++i) { + for (j=0; j<XvAdaptors[i]->nPorts; ++j) { + viaPortPrivPtr pPriv = XvAdaptors[i]->pPortPrivates[j].ptr; + if (pPriv->xvmc_priv) + xfree(pPriv->xvmc_priv); + } + } + pVia->XvMCEnabled = 0; +} + +static int +ViaXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, + int *num_priv, long **priv ) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + DRIInfoPtr pDRIInfo = pVia->pDRIInfo; + VIADRIPtr pViaDRI = pDRIInfo->devPrivate; + ViaXvMCCreateContextRec *contextRec; + unsigned ctxNo; + ViaXvMCContextPriv *cPriv; + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) pContext->port_priv; + viaPortPrivPtr pPriv = (viaPortPrivPtr) portPriv->DevPriv.ptr; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + volatile ViaXvMCSAreaPriv *sAPriv; + int authenticated; + + sAPriv = (ViaXvMCSAreaPriv*) DRIGetSAREAPrivate(pScrn->pScreen); + + if (-1 == vx->xvmc_port) { + vx->xvmc_port = (vXvMC->activePorts++); + sAPriv->XvMCSubPicOn[vx->xvmc_port] = 0; + sAPriv->XvMCDisplaying[vx->xvmc_port] = 0; + } + + if(vXvMC->nContexts >= VIA_XVMC_MAX_CONTEXTS) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateContext: Out of contexts.\n"); + return BadAlloc; + } + + *priv = xcalloc(1,sizeof(ViaXvMCCreateContextRec)); + contextRec = (ViaXvMCCreateContextRec *)*priv; + + if(!*priv) { + *num_priv = 0; + return BadAlloc; + } + + *num_priv = sizeof(ViaXvMCCreateContextRec) >> 2; + + for (ctxNo = 0; ctxNo < VIA_XVMC_MAX_CONTEXTS; ++ctxNo) { + if (0 == vXvMC->contexts[ctxNo] ) break; + } + + cPriv = (ViaXvMCContextPriv *) xcalloc(1,sizeof(ViaXvMCContextPriv)); + + if(!cPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateContext: Unable to allocate memory!\n"); + xfree(*priv); + *num_priv = 0; + return BadAlloc; + } + + if(drmCreateContext(pVia->drmFD, &(contextRec->drmcontext) ) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateContext: Unable to create DRMContext!\n"); + xfree(*priv); + xfree(cPriv); + return BadAlloc; + } + drmSetContextFlags(pVia->drmFD, contextRec->drmcontext, + DRM_CONTEXT_2DONLY); + cPriv->drmCtx = contextRec->drmcontext; + + authenticated = (drmAuthMagic(pVia->drmFD, pContext->flags) == 0); + + /* + * Export framebuffer and mmio to non-root clients. + */ + + contextRec->ctxNo = ctxNo; + contextRec->xvmc_port = vx->xvmc_port; + contextRec->fbOffset = vXvMC->fbBase; + contextRec->fbSize = pVia->videoRambytes; + contextRec->mmioOffset = vXvMC->mmioBase; + contextRec->mmioSize = VIA_MMIO_REGSIZE; + contextRec->sAreaOffset = vXvMC->sAreaBase; + contextRec->sAreaSize = pDRIInfo->SAREASize; + contextRec->sAreaPrivOffset = sizeof(XF86DRISAREARec); + contextRec->major = VIAXVMC_MAJOR; + contextRec->minor = VIAXVMC_MINOR; + contextRec->pl = VIAXVMC_PL; + strncpy (contextRec->busIdString,pDRIInfo->busIdString, 20); + contextRec->initAttrs = vx->xvAttr; + contextRec->useAGP = pViaDRI->ringBufActive && + ((pVia->Chipset == VIA_CLE266) || + (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_PM800)); + contextRec->authenticated = authenticated; + contextRec->chipId = pVia->ChipId; + vXvMC->nContexts++; + vXvMC->contexts[ctxNo] = pContext->context_id; + vXvMC->cPrivs[ctxNo] = cPriv; + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Chipid: %08x.", contextRec->chipId); + + return Success; +} + + +static int +ViaXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, long **priv ) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + unsigned srfNo,numBuffers,i; + ViaXvMCSurfacePriv *sPriv; + XvMCContextPtr ctx; + unsigned bufSize,yBufSize; + + if (VIA_XVMC_MAX_SURFACES == vXvMC->nSurfaces) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSurface: Too many surfaces !\n"); + return BadAlloc; + } + + sPriv = (ViaXvMCSurfacePriv *) xcalloc(1,sizeof(ViaXvMCSurfacePriv)); + + if(!sPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSurface: Unable to allocate memory!\n"); + *num_priv = 0; + return BadAlloc; + } + + numBuffers = 1; + + /* + * Some chips require more than one buffer per surface (and a special + * flipping procedure; See Ivor Hewitt's ddmpeg.c version 1.6). The client + * lib will detect the number of buffers allocated and determine the + * flipping method from that. + */ +#if 0 /* Not enabled yet. */ + switch(pVia->ChipSet) { + case VIA_CLE266: + switch(pVia->ChipRev) { + case 0x10: /* CLE266 C0 only? or all C? */ + numBuffers = 2; + break; + default: + break; + } + break; + default: + break; + } +#endif + *num_priv = numBuffers + 2; + + *priv = (long *)xcalloc(*num_priv,sizeof(long)); + + if(!*priv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSurface: Unable to allocate memory!\n"); + *num_priv = 0; + xfree(sPriv); + return BadAlloc; + } + + for (srfNo = 0; srfNo < VIA_XVMC_MAX_SURFACES; ++srfNo) { + if (0 == vXvMC->sPrivs[srfNo] ) break; + } + + (*priv)[0] = srfNo; + + ctx = pSurf->context; + bufSize = size_yuv420(ctx->width, ctx->height); + sPriv->memory_ref.pool = 0; + if (VIAAllocLinear(&(sPriv->memory_ref), pScrn, numBuffers * bufSize + 32)) { + xfree(*priv); + xfree(sPriv); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSurface: " + "Unable to allocate frambuffer memory!\n"); + return BadAlloc; + } + + (*priv)[1] = numBuffers; + (*priv)[2] = sPriv->offsets[0] = ALIGN_TO(sPriv->memory_ref.base, 32); + for (i = 1; i < numBuffers; ++i) { + (*priv)[i+2] = sPriv->offsets[i] = sPriv->offsets[i-1] + bufSize; + } + + yBufSize = stride(ctx->width)*ctx->height; + for (i = 0; i < numBuffers; ++i) { + memset((CARD8 *)(pVia->FBBase) + sPriv->offsets[i], 0, yBufSize); + memset((CARD8 *)(pVia->FBBase) + sPriv->offsets[i] + yBufSize, 0x80, + yBufSize >> 1); + } + + vXvMC->sPrivs[srfNo] = sPriv; + vXvMC->surfaces[srfNo] = pSurf->surface_id; + vXvMC->nSurfaces++; + return Success; +} + +static int +ViaXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, + int *num_priv, long **priv ) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + unsigned srfNo; + ViaXvMCSurfacePriv *sPriv; + XvMCContextPtr ctx; + unsigned bufSize; + + if (VIA_XVMC_MAX_SURFACES == vXvMC->nSurfaces) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSubpicture: Too many surfaces !\n"); + return BadAlloc; + } + + sPriv = (ViaXvMCSurfacePriv *) xcalloc(1,sizeof(ViaXvMCSurfacePriv)); + + if(!sPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSubpicture: Unable to allocate memory!\n"); + *num_priv = 0; + return BadAlloc; + } + + *priv = (long *)xcalloc(3,sizeof(long)); + + if(!*priv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSubpicture: Unable to allocate memory!\n"); + *num_priv = 0; + xfree(sPriv); + return BadAlloc; + } + + *num_priv = 2; + + for (srfNo = 0; srfNo < VIA_XVMC_MAX_SURFACES; ++srfNo) { + if (0 == vXvMC->sPrivs[srfNo] ) break; + } + + (*priv)[0] = srfNo; + + ctx = pSubp->context; + bufSize = size_xx44(ctx->width,ctx->height); + sPriv->memory_ref.pool = 0; + if (VIAAllocLinear(&(sPriv->memory_ref), pScrn, + 1 * bufSize + 32)) { + xfree(*priv); + xfree(sPriv); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSubpicture: Unable to allocate " + "framebuffer memory!\n"); + return BadAlloc; + } + (*priv)[1] = sPriv->offsets[0] = ALIGN_TO(sPriv->memory_ref.base, 32); + + vXvMC->sPrivs[srfNo] = sPriv; + vXvMC->surfaces[srfNo] = pSubp->subpicture_id; + vXvMC->nSurfaces++; + + return Success; +} + +static void ViaXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + int i; + volatile ViaXvMCSAreaPriv *sAPriv; + drm_context_t context; + viaPortPrivPtr pPriv; + XvPortRecPrivatePtr portPriv; + ViaXvMCXVPriv *vx; + + for(i=0; i < VIA_XVMC_MAX_CONTEXTS; i++) { + if(vXvMC->contexts[i] == pContext->context_id) { + + context = vXvMC->cPrivs[i]->drmCtx; + sAPriv=(ViaXvMCSAreaPriv *) DRIGetSAREAPrivate(pScrn->pScreen); + portPriv = (XvPortRecPrivatePtr) pContext->port_priv; + pPriv = (viaPortPrivPtr) portPriv->DevPriv.ptr; + vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + + if ((i | VIA_XVMC_VALID) == vx->ctxDisplaying) { + vx->ctxDisplaying = 0; + } + + drmDestroyContext(pVia->drmFD,vXvMC->cPrivs[i]->drmCtx); + xfree(vXvMC->cPrivs[i]); + vXvMC->cPrivs[i] = 0; + vXvMC->nContexts--; + vXvMC->contexts[i] = 0; + return; + } + } + return; +} + +static void ViaXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + int i; + volatile ViaXvMCSAreaPriv *sAPriv; + XvMCContextPtr pContext = pSurf->context; + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) pContext->port_priv; + viaPortPrivPtr pPriv = (viaPortPrivPtr) portPriv->DevPriv.ptr; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + for(i=0; i < VIA_XVMC_MAX_SURFACES; i++) { + if(vXvMC->surfaces[i] == pSurf->surface_id) { + + sAPriv=(ViaXvMCSAreaPriv*) DRIGetSAREAPrivate(pScrn->pScreen); + { + DRM_CAS_RESULT(__ret); + DRM_CAS(&(sAPriv->XvMCDisplaying[vx->xvmc_port]), + i|VIA_XVMC_VALID,0,__ret); + if (!__ret) + ViaOverlayHide(pScrn); + } + + VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref)); + xfree(vXvMC->sPrivs[i]); + vXvMC->nSurfaces--; + vXvMC->sPrivs[i] = 0; + vXvMC->surfaces[i] = 0; + return; + } + } + return; +} + + +static void ViaXvMCDestroySubpicture (ScrnInfoPtr pScrn, + XvMCSubpicturePtr pSubp) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCPtr vXvMC = &(pVia->xvmc); + int i; + volatile ViaXvMCSAreaPriv *sAPriv; + XvMCContextPtr pContext = pSubp->context; + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) pContext->port_priv; + viaPortPrivPtr pPriv = (viaPortPrivPtr) portPriv->DevPriv.ptr; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + for(i=0; i < VIA_XVMC_MAX_SURFACES; i++) { + if(vXvMC->surfaces[i] == pSubp->subpicture_id) { + + sAPriv=(ViaXvMCSAreaPriv*) DRIGetSAREAPrivate(pScrn->pScreen); + + { + DRM_CAS_RESULT(__ret); + + DRM_CAS(&(sAPriv->XvMCSubPicOn[vx->xvmc_port]), + i|VIA_XVMC_VALID,0,__ret); + if (!__ret) { + + /* + * Turn subpicture off. + */ + + while (VIDInD(V_COMPOSE_MODE) & + (V1_COMMAND_FIRE | V3_COMMAND_FIRE)); + VIDOutD(SUBP_CONTROL_STRIDE, VIDInD(SUBP_CONTROL_STRIDE) & + ~SUBP_HQV_ENABLE); + + } + } + VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref)); + xfree(vXvMC->sPrivs[i]); + vXvMC->nSurfaces--; + vXvMC->sPrivs[i] = 0; + vXvMC->surfaces[i] = 0; + + return; + } + } + return; +} + +/* + * Tell XvMC clients that Xv is currently displaying. + * return 1 if another client was displaying before. + */ + +static int viaXvMCSetDisplayLock(ScrnInfoPtr pScrn, ViaXvMCXVPriv *vx) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaXvMCSAreaPriv *sAPriv =(ViaXvMCSAreaPriv*) + DRIGetSAREAPrivate(pScrn->pScreen); + + if (vx->xvmc_port > 0) { + if ((VIA_XVMC_MAX_SURFACES | VIA_XVMC_VALID) != + sAPriv->XvMCDisplaying[vx->xvmc_port]) { + sAPriv->XvMCDisplaying[vx->xvmc_port] = + (VIA_XVMC_MAX_SURFACES | VIA_XVMC_VALID); + } + + if (sAPriv->XvMCSubPicOn[vx->xvmc_port] & VIA_XVMC_VALID) { + sAPriv->XvMCSubPicOn[vx->xvmc_port] = 0; + + while (VIDInD(V_COMPOSE_MODE) & + (V1_COMMAND_FIRE | V3_COMMAND_FIRE)); + VIDOutD(SUBP_CONTROL_STRIDE, VIDInD(SUBP_CONTROL_STRIDE) & + ~SUBP_HQV_ENABLE); + + } + } + + return 0; +} + + +int viaXvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt) +{ + viaPortPrivPtr pPriv; + ViaXvMCXVPriv *vx; + unsigned i,j; + + for (j=0; j < XvAdapt->nPorts; ++j) { + pPriv= (viaPortPrivPtr) XvAdapt->pPortPrivates[j].ptr; + + if (NULL == (pPriv->xvmc_priv = xcalloc(1,sizeof(ViaXvMCXVPriv)))) { + return BadAlloc; + } + + for (i=0; i < VIA_NUM_XVMC_ATTRIBUTES; ++i) { + attrAtoms[i] = MAKE_ATOM(attrXvMC[i]); + } + + vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + vx->ctxDisplaying = 0; + vx->xvAttr.numAttr = VIA_NUM_XVMC_ATTRIBUTES; + vx->xvmc_port = -1; + vx->newAttribute = 1; + + /* set up wrappers */ + vx->GetPortAttribute = XvAdapt->GetPortAttribute; + vx->SetPortAttribute = XvAdapt->SetPortAttribute; + vx->PutImage = XvAdapt->PutImage; + + XvAdapt->GetPortAttribute = viaXvMCInterceptXvGetAttribute; + XvAdapt->SetPortAttribute = viaXvMCInterceptXvAttribute; + XvAdapt->PutImage = viaXvMCInterceptPutImage; + + for (i = 0; i < VIA_NUM_XVMC_ATTRIBUTES; ++i) { + vx->xvAttr.attributes[i].attribute = attrAtoms[i]; + vx->xvAttr.attributes[i].value = 0; + vx->GetPortAttribute( pScrn, attrAtoms[i] , + &(vx->xvAttr.attributes[i].value), pPriv); + } + } + return Success; +} + +static int +viaXvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value,pointer data) +{ + unsigned i; + viaPortPrivPtr pPriv = (viaPortPrivPtr) data; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + if (VIAPTR(pScrn)->XvMCEnabled) { + for (i=0; i< vx->xvAttr.numAttr; ++i) { + if (vx->xvAttr.attributes[i].attribute == attribute) { + vx->xvAttr.attributes[i].value = value; + if (vx->ctxDisplaying != + (VIA_XVMC_MAX_CONTEXTS | VIA_XVMC_VALID)) { + vx->newAttribute = 1; + return 0; + } + } + } + } + return vx->SetPortAttribute(pScrn, attribute, value, data); +} + +static int +viaXvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 *value,pointer data) +{ + unsigned i; + viaPortPrivPtr pPriv = (viaPortPrivPtr) data; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + if (VIAPTR(pScrn)->XvMCEnabled) { + for (i=0; i< vx->xvAttr.numAttr; ++i) { + if (vx->xvAttr.attributes[i].attribute == attribute) { + *value = vx->xvAttr.attributes[i].value; + return Success; + } + } + } + + return vx->GetPortAttribute( pScrn, attribute, value, data); +} + + +static int viaXvMCDisplayAttributes(ScrnInfoPtr pScrn, + const ViaXvMCAttrHolder *ah, viaPortPrivPtr pPriv) +{ + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + unsigned i; + int ret; + + for (i=0; i< ah->numAttr; ++i) { + ret = vx->SetPortAttribute(pScrn, ah->attributes[i].attribute, + ah->attributes[i].value, pPriv); + if (ret) return ret; + } + return Success; +} + + +static int +viaXvMCInterceptPutImage( ScrnInfoPtr pScrn,short src_x, short src_y, + short drw_x, short drw_y, short src_w, + short src_h,short drw_w, short drw_h, + int id, unsigned char* buf, short width, + short height, Bool sync, RegionPtr clipBoxes, + pointer data) +{ + viaPortPrivPtr pPriv = (viaPortPrivPtr) data; + ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv; + + if (VIAPTR(pScrn)->XvMCEnabled) { + if (FOURCC_XVMC == id) { + volatile ViaXvMCSAreaPriv *sAPriv; + ViaXvMCCommandBuffer *vXvMCData = (ViaXvMCCommandBuffer *) buf; + sAPriv=(ViaXvMCSAreaPriv*) DRIGetSAREAPrivate(pScrn->pScreen); + + switch(vXvMCData->command) { + case VIA_XVMC_COMMAND_ATTRIBUTES: + if ((vXvMCData->ctxNo | VIA_XVMC_VALID) != vx->ctxDisplaying) + return 1; + viaXvMCDisplayAttributes( pScrn, &vXvMCData->attrib, pPriv); + return 0; + case VIA_XVMC_COMMAND_FDISPLAY: + if (sAPriv->XvMCDisplaying[vx->xvmc_port] != vXvMCData->srfNo) return 1; + viaXvMCDisplayAttributes( pScrn, &vXvMCData->attrib, pPriv); + vx->ctxDisplaying = vXvMCData->ctxNo; + break; + case VIA_XVMC_COMMAND_DISPLAY: + if ((vXvMCData->ctxNo | VIA_XVMC_VALID) != vx->ctxDisplaying) { + viaXvMCDisplayAttributes( pScrn, &vXvMCData->attrib, pPriv); + } + if (sAPriv->XvMCDisplaying[vx->xvmc_port] != vXvMCData->srfNo) return 1; + vx->ctxDisplaying = vXvMCData->ctxNo; + break; + case VIA_XVMC_COMMAND_UNDISPLAY: + { + DRM_CAS_RESULT(__ret); + DRM_CAS(&(sAPriv->XvMCDisplaying[vx->xvmc_port]), + vXvMCData->srfNo, 0,__ret); + if (!__ret) + ViaOverlayHide(pScrn); + } + return Success; + default: + break; + } + } else { + if ((VIA_XVMC_MAX_CONTEXTS | VIA_XVMC_VALID) != vx->ctxDisplaying) { + viaXvMCDisplayAttributes( pScrn, &vx->xvAttr, pPriv); + vx->ctxDisplaying = VIA_XVMC_MAX_CONTEXTS | VIA_XVMC_VALID; + } else if (vx->newAttribute) { + vx->newAttribute = 0; + viaXvMCDisplayAttributes( pScrn, &vx->xvAttr, pPriv); + } + viaXvMCSetDisplayLock( pScrn, vx ); + } + } + return vx->PutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, + drw_w, drw_h, id, buf, width, height, sync, + clipBoxes, data); +} + +unsigned long viaXvMCPutImageSize(ScrnInfoPtr pScrn) +{ + if (VIAPTR(pScrn)->XvMCEnabled) + return sizeof(ViaXvMCCommandBuffer); + return 0; +} + +#endif diff --git a/unichrome/via_xvmc.h b/unichrome/via_xvmc.h new file mode 100644 index 000000000000..6a475dcc731e --- /dev/null +++ b/unichrome/via_xvmc.h @@ -0,0 +1,102 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension X server driver. + * + * Copyright (c) 2004 The Unichrome project. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _VIA_XVMC_H +#define _VIA_XVMC_H 1 + +#include "via_drm.h" + +/* + * This file contains the common definitions between the XvMC lib and the + * X server side. It is referenced also by the XvMC lib. Make sure any + * structure change is reflected also in a change in minor version number!! + */ + + +#define VIAXVMC_MAJOR 0 +#define VIAXVMC_MINOR 9 +#define VIAXVMC_PL 0 +#define VIA_NUM_XVMC_ATTRIBUTES 6 +#define VIA_XVMC_VALID 0x80000000 + +/* + * Commands that client submits through XvPutImage: + */ + +#define VIA_XVMC_COMMAND_FDISPLAY 0 +#define VIA_XVMC_COMMAND_DISPLAY 1 +#define VIA_XVMC_COMMAND_UNDISPLAY 2 +#define VIA_XVMC_COMMAND_ATTRIBUTES 3 + +typedef drm_via_sarea_t ViaXvMCSAreaPriv; + +typedef struct{ + Atom attribute; + INT32 value; +}ViaAttrPair; + +typedef struct { + unsigned numAttr; + ViaAttrPair attributes[VIA_NUM_XVMC_ATTRIBUTES]; +}ViaXvMCAttrHolder; + +/* + * Passed from client to X server during overlay updates. + */ + +typedef struct{ + unsigned command; + unsigned ctxNo; + unsigned srfNo; + unsigned subPicNo; + ViaXvMCAttrHolder attrib; + unsigned pad; +}ViaXvMCCommandBuffer; + +/* + * Passed from X server to client at context creation. + */ + +typedef struct { + unsigned int major,minor,pl; + unsigned ctxNo; + unsigned xvmc_port; + drm_context_t drmcontext; + unsigned int fbOffset; + unsigned int fbSize; + unsigned int mmioOffset; + unsigned int mmioSize; + unsigned int sAreaOffset; + unsigned int sAreaSize; + unsigned int sAreaPrivOffset; + char busIdString[20]; + ViaXvMCAttrHolder initAttrs; + int useAGP; + int authenticated; + unsigned chipId; + unsigned pad; +} ViaXvMCCreateContextRec; + +#endif diff --git a/unichrome/via_xvpriv.h b/unichrome/via_xvpriv.h new file mode 100644 index 000000000000..b692e9156304 --- /dev/null +++ b/unichrome/via_xvpriv.h @@ -0,0 +1,69 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIA_XVPRIV_H_ +#define _VIA_XVPRIV_H_ 1 + +#include "xf86xv.h" + + +enum{ XV_ADAPT_SWOV=0, + XV_ADAPT_NUM}; + +#define VIA_MAX_XV_PORTS 1 + +typedef struct { + unsigned char xv_adaptor; + unsigned char xv_portnum; + int adaptor; + int brightness; + int saturation; + int contrast; + int hue; + RegionRec clip; + CARD32 colorKey; + Bool autoPaint; + + CARD32 FourCC; /* from old SurfaceDesc -- passed down from viaPutImageG */ + + /* store old video source & dst data */ + short old_src_x; + short old_src_y; + short old_src_w; + short old_src_h; + + short old_drw_x; + short old_drw_y; + short old_drw_w; + short old_drw_h; + + void *xvmc_priv; + +} viaPortPrivRec, *viaPortPrivPtr; + +extern viaPortPrivPtr viaPortPriv[]; +extern unsigned viaNumXvPorts; + + +#endif /* _VIA_XVPRIV_H_ */ |