diff options
author | Xavier Bachelot <xavier@bachelot.org> | 2008-01-02 19:57:29 +0000 |
---|---|---|
committer | Xavier Bachelot <xavier@bachelot.org> | 2008-01-02 19:57:29 +0000 |
commit | cfd824ea3fc8d710510e3d2446342707566667ec (patch) | |
tree | 950626b7aa8a0653ae1ed63588a880cad3386665 | |
parent | ac43a38d48f8fcdb58a10f843b51abd29acc1132 (diff) |
Second release candidate for 0.3.0release_0_2_901
66 files changed, 36820 insertions, 0 deletions
diff --git a/trunk/COPYING b/trunk/COPYING new file mode 100644 index 000000000000..9adc03c239a6 --- /dev/null +++ b/trunk/COPYING @@ -0,0 +1,17 @@ +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 COPYRIGHT HOLDER(S) OR AUTHOR(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. diff --git a/trunk/ChangeLog b/trunk/ChangeLog new file mode 100644 index 000000000000..401e8084d8ee --- /dev/null +++ b/trunk/ChangeLog @@ -0,0 +1,2002 @@ +2007-10-29 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * src/via_driver.c: (VIAPreInit): + + Redoing the second change of June 10: Printing VideoRAM again + only when it's actually been probed; plus further tiny code + cleanups: comments, line wraps, whitespace. + +2007-10-29 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * src/via_driver.c: (VIAPreInit): + + Redoing the first change of June 10: Putting the chipset and + revision print statements together at the beginning; moving + the reading of the VideoRAM option to after X has parsed the + config file; plus a few small layout tweaks. + +2007-10-05 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_swov.c: (Upd_Video): + + Enable colorkey on secondary. + +2007-10-03 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_driver.c: (VIAPreInit): + + Fix memory detection for P4M900 and CX700. + +2007-09-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * src/via_bios.h: + * src/via_driver.c: (VIAWriteMode), (VIAAdjustFrame), + (VIASwitchMode): + * src/via_mode.c: (ViaModeSecondaryVGAFetchCount), + (ViaModeSecondaryVGAOffset), (ViaModeSecondaryVGA): + * src/via_swov.c: (Upd_Video): + * src/via_vbe.c: (ViaVbeSetPanelMode), (ViaVbeSetMode): + + Fix offset when using vbe modes on secondary. + +2007-09-11 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * src/via.h: + * src/via_accel.c: (viaInitExa): + * src/via_bandwidth.c: (ViaSetPrimaryFIFO): + * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIASave), (VIARestore), (VIALoadPalette): + * src/via_driver.h: + * src/via_id.c: + * src/via_mode.c: (ViaOutputsDetect): + * src/via_priv.h: + * src/via_swov.c: (Upd_Video): + * src/via_vbe.c: (ViaVbeInitInt10), (ViaVbeGetRefreshRateIndex), + (ViaVbeGetActiveDevices), (ViaVbeSetActiveDevices), + (ViaVbeSetPanelExpansion), (ViaVbeSetRefresh), (ViaVbeSetMode), + (ViaVbeSaveRestore), (ViaVbeModePreInit): + * src/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + Sync with experimental_branch. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_id.c: + + Added Gigabyte GA-VM900M ID, reported by Alexandre Penasso Teixeira. + +2007-09-07 Gabiel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * unichrome/via.h: + * unichrome/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIASave), (VIARestore), (VIALoadPalette): + * unichrome/via_driver.h: + * unichrome/via_mode.c: (ViaOutputsDetect): + * unichrome/via_swov.c: (Upd_Video): + * unichrome/via_vbe.c: (ViaVbeInitInt10), + (ViaVbeGetRefreshRateIndex), (ViaVbeGetActiveDevices), + (ViaVbeSetActiveDevices), (ViaVbeSetPanelExpansion), + (ViaVbeSetRefresh), (ViaVbeSetMode), (ViaVbeSaveRestore), + (ViaVbeModePreInit): + * unichrome/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + Merged vn896_branch from revision 361 to 391. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.c: (ViaOutputsDetect): + * unichrome/via_vbe.c: (ViaVbeSetActiveDevices): + + Disabled TV detection for P4M900. + +2007-09-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.h: + * unichrome/via_vbe.c: (ViaVbeInitInt10), + (ViaVbeGetRefreshRateIndex), (ViaVbeGetActiveDevices), + (ViaVbeSetActiveDevices), (ViaVbeSetPanelExpansion), + (ViaVbeSetRefresh), (ViaVbeSetMode), (ViaVbeModePreInit): + + VBE code cleanup. + +2007-09-02 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIASetupDefaultOptions), (VIASave), + (VIARestore): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + Disabled XvDMA for P4M900. + Modified VBE functions calling order. + +2007-08-18 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_driver.c: (VIASetupDefaultOptions): + * unichrome/via_priv.h: + * unichrome/via_swov.c: (Upd_Video): + + Xvideo code cleanup; added maximum resolution with + interpolation for all chipsets. + +2007-08-03 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * src/via_bios.h: + * src/via_mode.h: + * src/via_video.c: (DecideOverlaySupport): + + Add basic support for DDR667. + +2007-07-31 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * src/via_xvmc.c: (ViaInitXVMC): + + Fixed the xvmc name we register. Was still looking for + the old via xvmc library names. + +2007-07-04 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * configure.ac: + * src/via_driver.c: (VIAPreInit): + * src/via_driver.h: + + Bump driver version to 0.2.900. + Do not log detected chipset 2 times. + Remove duplicate changelog entry. + +2007-06-20 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO) + + FIFO settings for CX700. + +2007-06-14 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * configure.ac: + * libxvmc/viaLowLevel.h: + * src/via.h: + * src/via_accel.c: (viaFlushPCI), (viaInitPCIe), (viaEnableAgpVQ), + (viaEnablePCIeVQ), (viaDisableVQ), (viaInitialize2DEngine), + (viaAccelSync), (viaInitXAA), (viaInitExa), (viaInitAccel): + * src/via_bandwidth.c: (ViaSetPrimaryFIFO), (ViaSetSecondaryFIFO): + * src/via_dri.c: (VIADRIRingBufferInit): + * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), + (VIALeaveVT), (VIASave), (VIAScreenInit), (VIACloseScreen): + * src/via_driver.h: + * src/via_id.c: (ViaDoubleCheckCLE266Revision), (ViaCheckCardId): + * src/via_id.h: + * src/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * src/via_mode.h: + * src/via_regs.h: + * src/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVDone), + (VIAVidHWDiffInit), (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (AddHQVSurface), + (SetFIFO_V3), (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), + (SetColorKey), (SetChromaKey), (SetHQVFetch), (Upd_Video), + (VIAVidUpdateOverlay), (ViaOverlayHide): + * src/via_swov.h: + * src/via_vbe.c: (ViaVbeSetMode): + * src/via_video.c: (DecideOverlaySupport), (viaInitVideo), (Flip), + (viaDmaBlitImage), (viaPutImage): + * src/via_video.h: + * src/via_xvmc.c: (ViaInitXVMC): + + Pulled in Changes from the experimental_branch including + - Partial support for VIA_K8M890, VIA_P4M900, VIA_CX700, + VIA_P4M890 + - Added the VideoEngine option to help clean up code + - Ability to enable debugging with the configure script + +2007-06-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_swov.c: (viaCalculateVideoColor), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3), (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), + (Upd_Video): + * unichrome/via_vbe.c: (ViaVbeSetMode): + * unichrome/via_video.c: (DecideOverlaySupport): + + Renamed VT3157 to VT3324. + Added check for null data block in vbe. + Remove version check for older version of Xorg. + +2007-06-12 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + + Added missing includes. + +2007-06-10 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIAPreInit): + + Print VideoRAM again only when it's actually been probed. + Further tiny code cleanups: comments, line wraps, whitespace. + +2007-06-10 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via.man: + * unichrome/via_driver.c: (VIAPreInit): + + Move reading of the VideoRAM option to after X has parsed the + config file. Also put the chipset and revision print statements + together and at the beginning. Plus several small layout tweaks. + +2007-06-07 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * Makefile.am: + * configure.ac: + * libxvmc/Makefile.am: + * man/Makefile.am: + * src/Makefile.am: + * src/via_driver.c: + * src/via_driver.h: + + Renaming driver to openchrome_drv.so and XvMC library to + libchromeXvMC.so. + +2007-06-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Removed the chipset option definitions that aren't in + trunk yet. + +2007-06-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + * unichrome/via_driver.h: + * unichrome/via.man: + + Added per-chipset option defaults. This should allow the + driver to work out of the box with almost all hardware and + xorg.conf configurations. + +2007-05-23 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via.h: + + Remove version check for older version of Xorg. This is + really not necessary anymore, and was causing some breakage + with xorg-server's new version numbering. + +2007-05-18 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * libxvmc/Makefile.am: + * libxvmc/viaXvMC.c: (XvMCCreateContext): + + Backport 2 fixes from Xorg tree. + http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-via.git;a=commit;h=362e03a38682bfcf366242c53444fa36b6052794 + http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-via.git;a=commit;h=3cd7dac2b5a1c4bfb66bd1b67904d72dc08cbd0e + +2007-05-15 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_driver.c: (VIASetupDefaultOptions): + * unichrome/via_driver.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (Flip), (viaDmaBlitImage), (viaPutImage): + + Xv code cleanup. + +2007-05-10 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + * unichrome/via_driver.h: + * unichrome/via.man: + + Added per chipset option defaults. This should allow the + driver to install and work out of the box with almost all + hardware and xorg.conf configurations. + +2007-05-07 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * libxvmc/viaLowLevel.h: + * unichrome/via_accel.c: (viaFlushPCI), (viaDisableVQ), + (viaAccelSync): + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (Flip), + (viaDmaBlitImage), (viaPutImage): + + Fix Xv for P4M890. + +2007-04-30 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_swov.c: (Upd_Video): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Disable interpolation when the source width is greater than 800, + otherwise the picture wraps around the screen (bug #109). + Fix a typo in ViaInitXVMC (bug #111). + +2007-04-14 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: (ViaDoubleCheckCLE266Revision), + (ViaCheckCardId): + + VN -> VM, message tweaks, and trailing white space fixes. + +2007-03-28 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO): + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (Upd_Video): + * unichrome/via_video.c: (Flip), (viaDmaBlitImage), (viaPutImage): + + Fix Xv for CX700. + +2007-03-20 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (SetFIFO_V3), (SetFIFO_V3_64or32or32): + * unichrome/via_video.c: (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for P4M890. + +2007-03-09 Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> + + * unichrome/via_accel.c: (viaFlushPCI), (viaAccelSync), + (viaInitXAA): + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_driver.c: (VIAPreInit), (VIALeaveVT), + (VIACloseScreen): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (SetFIFO_V3_64or32or32), + (SetFIFO_V3_64or32or16), (SetColorKey), (SetChromaKey), + (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo), + (Flip), (viaDmaBlitImage), (viaPutImage): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for P4M900. + +2007-03-08 Xavier Bachelot <xavier-at-bachelot-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_driver.c: + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (SetFIFO_V3), (SetFIFO_V3_64or32or32): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Initial support for CX700. + +2007-03-04 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via.man: + + Textual tweaks and options ordered alphabetically. + +2007-02-16 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_accel.c: (viaSetClippingRectangle), + (viaAccelSolidHelper), (viaAccelCopyHelper), + (viaSubsequentMono8x8PatternFillRect), + (viaSubsequentColor8x8PatternFillRect), + (viaSubsequentSolidTwoPointLine), (viaSubsequentSolidHorVertLine): + + Limit x value to sixteen bits. Fixes a rendering glitch reported + by Marg Huijgen <mark-dot-sf-dot-net-at-huijgen-dot-tk>; solution + found by Thomas. + +2007-02-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaFlushDRIEnabled), + (viaSubsequentSolidTwoPointLine): + + Fix line-clipping bug reported by Manuel Bilderbeek + <manuel-dot-bilderbeek-at-oce-dot-com>. + +2007-02-06 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: + + Try CR39 when CR34 says zero during memory detection on + the CLE266. Idea from Luc Verhaegen, patch by Mark Huijgen + <mark-dot-sf-dot-net-at-huijgen-dot-tk>. + +2007-01-20 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * ChangeLog + + Switch encoding of ChangeLog file to Unicode. + Whitespace and format adjustments. + +2007-01-20 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIALoadRgbLut), (VIALoadPalette), + (VIAScreenInit): + + Add ability to change gamma setting. Original patch by + Gonzalo A. de la Vega <gadelavega-at-gmail-dot-com>, + adapted from Luc Verhaegen's implementation. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaExaTexUploadToScreen): + + Work around an obscure hardware limitation when texturing from + AGP. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIASetAgpMode): + + Fix AGP mode setting. + +2006-12-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + Use non-power-of-two textures for EXA whenever possible. + +2006-12-18 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_xvmc.c: + + Thomas needs a good drm test which means we need XvMC. I + have re-enabled it for testing. + +2006-12-15 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via.h: + * unichrome/via_swov.c: + + This is my cleanup commit of the excellent patch that + Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com> provided, + which finishes the XVideo work on the VT3336 chipset. Nice + work Gabriel. + +2006-12-13 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + + Don't use HQV Offset for HQV_CONTROL. + +2006-12-11 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + * unichrome/via_swov.c: + + Looks like the VT3336 has the same offset as the VT3259 + for the hardware overlay. + +2006-12-10 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_memcpy.c: + * unichrome/via_swov.c: + + Removed the previous changes; I am not ready to rewrite + the assembly code for x86_64. + The ColorSpace registers were being set up incorrectly + for VT3336. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_memcpy.c: + + The ifdef's in memcpy.c only support i386 arch; should + also support i86_64. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_xvmc.c: + + K8M890 does not support XvMC like the other chipsets; + disable it for now. + +2006-12-09 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.h: + * unichrome/via_swov.h: + * unichrome/via_swov.c: + + Made K8M890 XV FIFO settings match K8M800. + Enabled XV_DEBUG. + +2006-12-07 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_mode.h: + + Updated the BandwidthTable for K8M890 chipset. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Initialize the AGP ring buffer before command submission. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Blank and clear screen when entering VT. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAEnterVT): + + Blank and clear screen when entering VT. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload), + (viaExaDownloadFromScreen), (viaInitExa): + + Indent via_accel.c. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload): + + Fix download from screen which was reusing kernel argument + data that was altered by the kernel. + +2006-12-07 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload), + (viaExaDownloadFromScreen): + + Reimplement download from screen to something more easily + debuggable. + +2006-12-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Fixed some of the boolean option changes that are + inverses such as DisableIRQ. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: (viaExaFBSave), (viaOffScreenLinear): + + Cause a "FatalError" if EXA is used with an un-patched Xserver, + and an illegal save locked memory action is requested. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAInitialize3DEngine): + + Proper register names in VIAInitialize3DEngine. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIALeaveVT), (VIAWriteMode), + (VIACloseScreen): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + Now that we initialize the 3D engine every time we write + mode, make sure this is done before setting up VQ and AGP + so that those settings persist. The GPU will be unstable + otherwise. + Also fix some code comments. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIALeaveVT): + + Force 3D context upload after a VT switch. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (viaDRIFBMemcpy), (viaDRIOffscreenSave): + + Fix up previous commit for > 16MB sizes. + +2006-12-06 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (viaDRIOffscreenSave), + (viaDRIOffscreenRestore): + * unichrome/via_driver.c: (VIAEnterVT), (VIALeaveVT): + * unichrome/via_driver.h: + + Back up DRI offscreen memory before leaving VT and restore it + when entering VT. It may be overwritten in between. + Use PCI DMA blit for this if available. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAWriteMode), (VIAInitialize3DEngine): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + With EXA + 3D we need to reinitialize the 3D engine after + a mode switch (possibly the soft reset + 2D engine + initialization). Otherwise the GPU will hang. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + + Fix the dma2d option setting. + +2006-12-05 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO): + + Use a more aggressive fifo setting for CLE266 Cx. + Boosts performance. + Please report problems with this. + +2006-12-05 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_video.c: + * unichrome/via_swov.c: + + Added missing hardware overlay support for VT3336. + +2006-12-04 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_driver.c: + + Added patch to fix the K8M890 hang on VT switch; submitted + by Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com>. + +2006-12-01 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_bios.h: + * unichrome/via_dri.c: (VIADRIScreenInit): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + + Remove unused options. + First pass cleaning up option handling. + Make most boolean options work as expected; + (that is, accepting both a "true" and a "false" argument). + +2006-11-30 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_mode.c: + * unichrome/via_accel.c: + + Added patch to fix some of the K8M890 logic; submitted by + Gabriel Mansi <gabriel-dot-mansi-at-gmail-dot-com>. + +2006-11-28 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_bandwidth.c: + * unichrome/via_accel.c: + + Patched via_bandwidth.c for dumb mistake I made. Thanks, Gabriel + Mansi, for the second set of eyes. Move HWCursor memory allocation + even further in the driver initialization. + +2006-11-25 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_id.c: + * unichrome/via_accel.c: + + Added additional IDs for the K8M890 cards. + Changed memory allocation order for the HW cursor and 2D engine. + +2006-10-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: + * unichrome/via_regs.h: + + Via managed to mix up the 2D / 3D engine busy status bits. + Funny we never noticed this before. + +2006-10-24 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_xvmc.c: (ViaXvMCCreateContext): + + Remove VT3314 (CN700, VM800 etc.) mpeg2 AGP DMA support. + +2006-10-11 Xavier Bachelot <xb_ml-at-kelkoo-dot-net> + + reviewed by: Ivor + + * unichrome/via_bios.h: + * unichrome/via_id.c: + * unichrome/via_mode.h: + * unichrome/via_video.c: (DecideOverlaySupport): + + DDR533 memory support and small cleanup. + Fujitsu/Siemens Amilo L7320 pci id (reported by DeNayGo). + +2006-10-03 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_video.c: (viaPutImage): + + Removed some stray debug messages. + +2006-10-02 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIASave), (VIARestore): + + Moved a line to after declarations for picky gcc-2.96, + tweaked comments and debugging lines. + +2006-09-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: + + Don't include drm headers in non-dri build. + +2006-09-25 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/Makefile.am: + + Mention the overall revision number in the log, not just + the driver code revision. + +2006-09-24 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaLowLevel.c: (initXvMCLowLevel): + * libxvmc/viaLowLevelPro.c: (initXvMCLowLevel): + * libxvmc/viaXvMC.c: (XvMCSetAttribute): + + Fix a mutex unlocking issue (Luc Verhaegen). + Have the lowlevel drivers check for the correct chipid. + +2006-09-24 Michal Ludvig <michal-at-logix-dot-cz> + + * man/Makefile.am: + + Fix man-page symlink for out-of-tree build (trac ticket #50). + +2006-09-22 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * unichrome/via_drmclient.h: + + Include stdint.h instead of re-typedefining CARD32. + +2006-09-22 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * src/via_id.h + * src/via_video.c + * src/via_mode.c + * src/via_mode.h + * src/via_driver.c + * src/via_swov.c + * src/via_bandwidth.c + * src/via_accel.c + * src/via_vbe.c + * src/via_xvmc.c + * src/via_id.c + + Initial code for support of VT3336 cards. + +2006-09-17 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.c: (VIASave): + + Put in a few extra debugging lines. + +2006-09-05 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_swov.c: + + Comment and whitespace tweaks. + +2006-09-05 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: + + Add an ID (trac ticket #67), note identical numbers, remove + a duplicate, remove obsolete unknown, remove trailing tab. + +2006-08-27 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_id.c: + + Textual tweaks. + +2006-08-27 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_dri.c: (VIADRIAgpInit): + + Rearrange declarations to fix compilation problem with gcc-2.96, + reported by Nikolai V. Ivanyushin <nvi-at-sven-dot-ru>. + +2006-08-22 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_accel.c: + + Whitespace adjustment; getting back close to Xorg. + Comment tweaks and #endif clarifications. + +2006-08-19 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire), + (SetVideoWindow): + + Comment tweaks. + +2006-08-18 Benno Schulenberg <bensberg-at-justemail-dot-net> + + * unichrome/via_driver.h: + + Move definition of AGP_SIZE out of #ifdef VIA_HAVE_EXA block, + to make the driver compile again for Xorg-6.8.2. + +2006-08-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + * unichrome/via_video.c: (viaPaintColorkey): + + Re-enable Ivor's Dotclock computation. + Enable accelerated redirected colorkey painting for Xv. + +2006-07-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: (VIAPreInit): + + ...And get default AGP size correct as well. + +2006-07-28 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaIsAGP): + * unichrome/via_dri.c: (VIADRIAgpInit): + + Fix false AGP detection and make sure we have the correct AGP + size. + +2006-07-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_accel.c: (viaExaUploadToScratch), + (viaExaCheckComposite), (viaIsAGP), (viaInitExa), (viaInitAccel): + * unichrome/via_ch7xxx.c: (ViaCH7xxxInit): + * unichrome/via_dri.c: (VIADRIAgpInit): + * unichrome/via_driver.c: (VIAPreInit), (VIAEnterVT), (VIALeaveVT), + (VIAScreenInit), (VIACloseScreen): + * unichrome/via_driver.h: + + Changes donated by "PConRails, LLC" and "Tungsten Graphics, Inc.": + EXA and memory management optimizations, Manpage update. + New options: + ExaScratchSize + MaxDRIMem + AGPMem + VBESaveRestore + +2006-07-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.h: + * unichrome/via_accel.c: + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + * unichrome/via_swov.c: (ViaOverlayHide): + * unichrome/via_video.c: (DecideOverlaySupport), + (viaVideoFillPixmap), (viaPaintColorkey), (viaReputImage), + (viaPutImage): + + Changes donated by "PConRails, LLC" and "Tungsten Graphics, Inc.": + Video optimizations: + Paint colorkey correctly under composite manager. + Make sure the driver compiles with Xorg git. + Don't reset the primary display FIFO after XV. It's never touched + by the Xv code, and slows things down in VBE mode. + + +2006-07-11 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaXvMC.c: + * unichrome/via_dri.c: + + Change DRM major compatibility from 3.x.x to 2.x.x. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: (finish_header_agp), + (computeHQVScaleAndFilter): + * libxvmc/viaXvMC.c: (yOffs), (vOffs), (uOffs), (defaultQMatrices), + (releaseDecoder), (grabDecoder), (setupAttribDesc), + (releaseAttribDesc), (releaseContextResources), + (XvMCCreateContext), (XvMCDestroyContext), (XvMCCreateSurface), + (XvMCDestroySurface), (XvMCPutSlice2), (XvMCPutSlice), + (updateXVOverlay), (XvMCPutSurface), (debugControl), + (XvMCBeginSurface), (XvMCSyncSurface), (XvMCLoadQMatrix), + (XvMCRenderSurface), (XvMCCreateBlocks), (XvMCDestroyBlocks), + (XvMCCreateMacroBlocks), (XvMCDestroyMacroBlocks), + (XvMCCreateSubpicture), (XvMCSetSubpicturePalette), (findOverlap), + (XvMCClearSubpicture), (XvMCCompositeSubpicture), + (XvMCBlendSubpicture), (XvMCBlendSubpicture2), + (XvMCSyncSubpicture), (XvMCFlushSubpicture), + (XvMCDestroySubpicture), (XvMCGetSubpictureStatus), + (XvMCFlushSurface), (XvMCGetSurfaceStatus), (XvMCQueryAttributes), + (XvMCSetAttribute), (XvMCGetAttribute), (XvMCHideSurface): + * libxvmc/xf86dri.c: + + Remove the "config.h" includes from libxvmc, as they break it. + I wonder how the openChrome libXvMC has been working? + + Indent viaXvMC.c. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/viaXvMC.c: (XvMCCreateContext): + * unichrome/via_dri.c: (VIADRIRingBufferInit), (VIADRIScreenInit): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + Update DRM version checking. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire): + + Increase video command fire timeout. + +2006-07-10 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_memory.c: (viaOffScreenLinear): + + Fix dri close screen segfault caused by previous commit. + +2006-06-15 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIADRIFBInit): + * unichrome/via_driver.h: + * unichrome/via_memory.c: (viaOffScreenLinear), (VIAAllocLinear): + + Fix severe dri memory allocation bug. (Reported by Trevor Kramer) + +2006-05-11 Ivor Hewitt <ivor-at-ivor-dot-org> + + * configure.ac: + * unichrome/via.h: + * unichrome/via_accel.c: + * unichrome/via_cursor.c: + * unichrome/via_dri.c: + * unichrome/via_driver.h: + * unichrome/via_memcpy.c: + * unichrome/via_memory.c: + * unichrome/via_mode.c: + * unichrome/via_shadow.c: + * unichrome/via_swov.c: + * unichrome/via_vbe.c: + * unichrome/via_vgahw.c: + * unichrome/via_video.c: + * unichrome/via_xvmc.c: + + - Xorg xv ABI compatibility patch. (Marcin Kurek) + +2006-04-14 Ivor Hewitt <ivor-at-ivor-dot-org> + + * libxvmc/Imakefile: + + - Unbreak makefile. + +2006-03-19 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/Makefile.am: + * unichrome/Makefile.am: + + - Backport Makefile changes form xorg. + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: + + - Update the built-against macro to recognize Xorg if present. + (Reported by Eric Anholt) + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * configure.ac: + + - Update compatibility check for XvMC. + +2006-03-17 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaInitExa): + * unichrome/via_driver.c: (VIAPreInit): + + - Support EXA 2.0. + +2006-03-13 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaSetupForSolidLine), + (viaSubsequentSolidTwoPointLine), (viaSetupForDashedLine): + * unichrome/via_driver.h: + + - Possible fix for XAA bug rendering solid lines as dashed. + (Reported by Lewin Edwards) + +2006-03-08 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + + * libxvmc/Imakefile: + * unichrome/via_swov.c: + * unichrome/via_swov.h: + * unichrome/via_video.c: (viaInitVideo), (viaExitVideo), + * unichrome/via_video.h: + * unichrome/via_xvmc.c: (initViaXvMC), (cleanupViaXvMC), (stride), + * unichrome/via_xvmc.h: + * unichrome/via_xvpriv.h: + + - Run indent on above files after syncing them with Xorg. + +2006-02-23 Xavier Bachelot <xb_ml AT kelkoo DOT net> + + * configure.ac: + + - Fix man pages suffix. + - Bump driver version number to be equal to xorg. + +2006-02-21 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_bios.h: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.h: + * unichrome/via_priv.h: + * unichrome/via_swov.c: (viaOverlayGetV1V3Format), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (CreateSurface), (ViaSwovSurfaceCreate), (ViaSwovSurfaceDestroy), + (VIAVidUpdateOverlay), (ViaOverlayHide): + * unichrome/via_video.c: (viaInitVideo), (Flip), (viaDmaBlitImage), + (viaPutImage), (viaQueryImageAttributes): + + - Lets have RV32 too. + - Add 12x8 panel. + +2006-02-10 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via.h: + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_dri.c: (VIADRIRingBufferInit): + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_swov.c: (VIAVidHWDiffInit), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (SetFIFO_V3), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (SetHQVFetch), (Upd_Video): + * unichrome/via_video.c: (DecideOverlaySupport), (viaInitVideo), + (viaDmaBlitImage): + * unichrome/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + + - Get some code exercised for VM800, let's see where it crumbles. + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Fix VBE refresh setting. + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaInitExa): + * unichrome/via_driver.c: (VIAPreInit): + + - Merge EXA branch revisions 152:155 + +2006-01-29 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: + * unichrome/via_video.c: (viaXvError), (viaReputImage), + (viaSetupAdaptors), (viaDmaBlitImage), (viaPutImage): + * unichrome/via_xvpriv.h: + + - Removed time.h and sys/time.h includes from via_swov.c + (Reported by George E Sollish). + - More verbose Xv error reporting. + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_3d.c: + * unichrome/via_accel.c: (viaAccelPlaneMaskHelper), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaFinishInitAccel): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + + - Merge EXA branch revisions 138:152 + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_mode.c: (ViaModePrimary): + + - Import Luc's fix for sometimes-blanking CRTs on CLE266. + (Luc Verhaegen) + +2006-01-27 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaWaitVideoCommandFire): + + - The previous commit causes problems with older X versions. + Avoid using gettimeofday(). Reported by Paul Bender. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (viaTimeDiff), (viaWaitVideoCommandFire): + + - Make the Xv viaWaitVideoCommandFire loop time out. Better than server hang? + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via.man: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_driver.h: + * unichrome/via_video.c: (viaInitVideo): + + - Added a "NoXVDMA" option to disable PCI DMA for Xv image transfers. + May turn out useful to vlc users. + - Updated man page. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_driver.c: + + - Added vgaHWGetIndex to vgaHW symbol list. + (Reported by Ole Sandum) + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_swov.c: (ViaOverlayHide): + + - Fix HQV offset bug. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * libxvmc/driDrawable.c: (drawStamp), (getDRIDrawableInfoLocked), + (driDestroyHashContents): + * libxvmc/driDrawable.h: + * libxvmc/viaLowLevel.c: (hwlLock), (hwlUnlock), (timeDiff), + (viaDMATimeStampLowLevel), (viaDMAWaitTimeStamp), + (viaDMAInitTimeStamp), (viaDMACleanupTimeStamp), + (viaMpegGetStatus), (viaMpegIsBusy), (syncDMA), (syncVideo), + (syncAccel), (syncMpeg), (pciFlush), (agpFlush), + (flushXvMCLowLevel), (flushPCIXvMCLowLevel), (pciCommand), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (initXvMCLowLevel), (closeXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initHQVShadow), + (setHQVHWDeinterlacing), (setHQVDeblocking), (setHQVStartAddress), + (setHQVColorSpaceConversion), (setHQVFetchLine), (setHQVScale), + (setHQVSingleDestination), (setHQVDeinterlacing), + (setHQVTripleBuffer), (finish_header_agp), (hwlLock), (hwlUnlock), + (timeDiff), (viaDMATimeStampLowLevel), (viaDMAWaitTimeStamp), + (viaDMAInitTimeStamp), (viaDMACleanupTimeStamp), + (viaMpegGetStatus), (viaMpegIsBusy), (syncDMA), (syncVideo), + (syncAccel), (syncMpeg), (pciFlush), (agpFlush), + (uploadHQVDeinterlace), (uploadHQVShadow), (flushXvMCLowLevel), + (flushPCIXvMCLowLevel), (viaMpegSetSurfaceStride), + (viaVideoSetSWFLipLocked), (viaVideoSWFlipLocked), (viaMpegSetFB), + (viaMpegBeginPicture), (viaMpegReset), (viaMpegWriteSlice), + (viaVideoSubPictureOffLocked), (viaVideoSubPictureLocked), + (viaBlit), (syncXvMCLowLevel), (updateLowLevelBuf), + (cleanupLowLevelBuf), (releaseXvMCLowLevel), (initXvMCLowLevel), + (setLowLevelLocking), (closeXvMCLowLevel), (computeDownScaling), + (computeHQVScaleAndFilter), (setupBackBuffer): + * libxvmc/viaXvMCPriv.h: + * libxvmc/vldXvMC.h: + * libxvmc/xf86dri.c: (uniDRIDestroyContext), + (uniDRICreateDrawable), (uniDRIDestroyDrawable), + (uniDRIGetDrawableInfo): + * libxvmc/xf86dri.h: + * libxvmc/xf86dristr.h: + + - Run indent on libXvMC. Sync XvMC with Xorg 7.0. + +2006-01-26 Thomas Hellström <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (VIADRIKernelInit), (VIADRIMapInit): + * unichrome/via_driver.h: + + - Add a framebuffer map for DRI. Don't just assume that the + framebuffer map handle is the physical address. + +2006-01-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaExaDownloadFromScreen), + (viaExaTexUploadToScreen), (viaExaUploadToScreen), + (viaExaCheckComposite): + * unichrome/via_driver.h: + + - Exa branch revision 132:138 merge. + +2006-01-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (CreateSurface): + * unichrome/via_video.c: (viaInitVideo), (Flip), (viaDmaBlitImage): + + - Fix planar Xv Flipping and surface allocation size. + (Reported by Tim, MagicITX) + - Fix Xv dmablit strides and bump drm version for dmablit to 2.9.0, since + there is a direction bug in earlier versions. + +2006-01-09 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaXvMC.c: (releaseContextResources): + * unichrome/via_swov.c: (CreateSurface), (ViaSwovSurfaceDestroy): + + - Mark already destroyed XvMC contexts as bad, in case clients + try to destroy them twice. + - Don't try to destroy YV12 buffers when exiting XvMC video. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaPixelARGB8888): + + - Merge exa_branch 130:132. Rendering errors. + - Changelog typo. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_3d.c: (viaSet3DFlags), (viaSet3DCompositeOperator): + * unichrome/via_accel.c: (viaIsAGP): + + - Merge exa_branch 127:130. Rendering errors. + +2006-01-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Makefile.am: + + - Modular build fix. (Boris Dusek) + +2006-01-07 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaDumpDMA), (viaFlushPCI), + (viaFlushDRIEnabled), (viaSetupCBuffer), (viaAccelClippingHelper), + (viaAccelSolidHelper), (viaAccelPlaneMaskHelper), + (viaAccelTransparentHelper), (viaAccelCopyHelper), + (viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy), + (viaSetupForSolidFill), (viaSubsequentSolidFillRect), + (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaAccelMarkSync), (viaExaPrepareSolid), (viaExaSolid), + (viaExaPrepareCopy), (viaExaCopy), (viaExaCompositePictDesc), + (viaExaPrintComposite), (viaBitExpandHelper), (viaPixelARGB8888), + (viaExpandablePixel), (viaCheckUpload), (viaOrder), + (viaExaDownloadFromScreen), (viaExaTexUploadToScreen), + (viaExaUploadToScreen), (viaExaUploadToScratch), + (viaExaCheckComposite), (viaIsAGP), (viaIsOffscreen), + (viaExaPrepareComposite), (viaExaComposite), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaFinishInitAccel), + (viaAccelBlitRect), (viaAccelFillRect), (viaAccelSyncMarker): + * unichrome/via_dga.c: + * unichrome/via_dmabuffer.h: + * unichrome/via_dri.c: (VIADRIFBInit): + * unichrome/via_driver.c: (VIALeaveVT), (VIAScreenInit), + (VIAWriteMode), (VIACloseScreen): + * unichrome/via_driver.h: + + - Merge in exa_branch from revision 104 to 127. Exa Composite acceleration. + See the branch Changelog for a detailed description of changes. + +2006-01-06 Thomas Hellström + + * unichrome/via_accel.c: (viaExaDownloadFromScreen), + (viaExaUploadToScreen): + * unichrome/via_video.c: (viaDmaBlitImage): + + - Update Xv blit to new blit-combining feature of DRM. + (Idea from Luc Verhaegen/Unichrome). + - Prepare for ugly via_drm.h dmablit IOCTL arg change and via_drm.h + versioning. + +2005-12-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaDmaBlitImage): + + - Fix Xv YUY2/RVXX dmaBlit stride. + +2005-12-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Makefile.am: + + - Modular built two identical XvMC libs. The pro lib was not a pro lib. + Fix this. (Tim Dodge) + +2005-12-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaInitAccel): + + - Make sure the accel marker system is properly initialized. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_memory.c: (VIAAllocLinear): + + - Protect the accelerated initial sceen clearing with a DRI lock. + - Submit the correct context for drm memory allocation. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_ch7xxx.c: (CH7xxxModeI2C): + * unichrome/via_dri.c: (VIADRIAgpInit): + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_id.c: + + - Moved the memset from previous commit to after dri is initialized, so + that AGP command submission will work. + - Silenced some warnings. + +2005-12-08 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAScreenInit): + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Moved memset to blank screen from ModeSetting to ScreenInit, in + an attempt to avoid long standing hangs on K8M800. Also use + the 2D engine for this if acceleration is enabled. + +2005-12-07 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * Makefile.in: + + - Removed Makefile.in since it is generated by the build process. + +2005-12-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> + + * Makefile.am: + * Makefile.in: + + - Added Makefile.am and Makefile.in to allow running make + in the root directory. + +2005-12-06 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * acinclude.m4: + * autogen.sh: + * configure.ac: + * libxvmc/Makefile.am: + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: + * libxvmc/viaLowLevelPro.c: + * libxvmc/viaXvMC.c: + * libxvmc/viaXvMCPriv.h: + * libxvmc/xf86dri.c: + * man/Makefile.am: + * unichrome/Makefile.am: + * unichrome/via_accel.c: + * unichrome/via_bandwidth.c: + * unichrome/via_ch7xxx.c: + * unichrome/via_cursor.c: + * unichrome/via_dga.c: + * unichrome/via_dri.c: + * unichrome/via_driver.c: + * unichrome/via_i2c.c: + * unichrome/via_id.c: + * unichrome/via_memcpy.c: + * unichrome/via_memory.c: + * unichrome/via_mode.c: + * unichrome/via_shadow.c: + * unichrome/via_vbe.c: + * unichrome/via_vgahw.c: + * unichrome/via_vt162x.c: + * unichrome/via_xvmc.c: + + - Adjust for modular build. + +2005-12-04 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_vt162x.c: (VT1622ModeCrtc): + + - Fix trac item #13. + This will probably also make TV-out work on some K8M/N800 laptops, + and will probaly fix TV-out after a resume. + +2005-12-02 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Imakefile: + * libxvmc/xf86dri.c: + + - 64 bit fixes on libviaXvMC* + +2005-12-02 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaAccelPlaneMaskHelper), + (viaAccelTransparentHelper), (viaSetupForScreenToScreenCopy), + (viaSetupForSolidFill), (viaSetupForMono8x8PatternFill), + (viaSetupForColor8x8PatternFill), + (viaSetupForCPUToScreenColorExpandFill), (viaSetupForImageWrite), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSetupForDashedLine), (viaAccelMarkSync), (viaExaPrepareSolid), + (viaExaPrepareCopy), (viaInitAccel), (viaDGABlitRect), + (viaDGAFillRect): + * unichrome/via_driver.c: + * unichrome/via_driver.h: + + - Merge exa_branch revisions 91:104: + Add support for EXA planemasks. + Tell loader about some missing EXA functions (Reported by Adam Jackson). + Fix broken XAA dashed lines. + +2005-12-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/Imakefile: + * unichrome/Imakefile: + * unichrome/via_driver.c: + + - Remove drmCommandWriteRead from drm loader symbols again. + Ivor had already added it :) + - Fix a typo in unichrome/Imakefile that broke build on x86_64. + - Add $(PICFLAGS) to libxvmc Makefile to make it build on x86_64. + +2005-12-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: + * unichrome/via_memory.c: (VIAFreeLinear): + + - Add drmCommandWriteRead to drm loader symbols. + - Make the drm freemem call drmCommandWrite. + +2005-11-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaInitAccel): + * unichrome/via_memory.c: (VIAAllocLinear): + + - Merge exa_branch revisions 86:91 + +2005-11-29 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + + - Yet another drm.h include fixup. For 6.8 and earlier? + +2005-11-28 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Just another id. (Tobias Blom) + +2005-11-28 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + + - Include the correct drm.h file. This is important for 64 bit builds. + +2005-11-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaFlushDRIEnabled), (viaSetupCBuffer): + + - Merged EXA branch changes between revisions 84 and 86. + +2005-11-23 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (viaFlushPCI), (viaFlushDRIEnabled), + (viaSetupCBuffer), (viaTearDownCBuffer), (viaEnableVQ), + (viaDisableVQ), (viaAccelSetMode), (viaInitialize2DEngine), + (viaAccelSync), (viaSetClippingRectangle), + (viaAccelClippingHelper), (viaAccelSolidHelper), + (viaAccelTransparentHelper), (viaAccelCopyHelper), + (viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy), + (viaSetupForSolidFill), (viaSubsequentSolidFillRect), + (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaSubsequentDashedTwoPointLine), (viaInitXAA), + (viaAccelMarkSync), (viaAccelWaitMarker), (viaExaPrepareSolid), + (viaExaSolid), (viaExaPrepareCopy), (viaExaCopy), + (viaExaDownloadFromScreen), (viaExaUploadToScreen), (viaInitExa), + (viaInitAccel), (viaExitAccel), (viaDGABlitRect), (viaDGAFillRect): + + - Merged EXA branch changes between revisions 74 and 84. Mainly + indentations and minor bugfixes. + +2005-11-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (ViaSwovSurfaceCreate), + (ViaSwovSurfaceDestroy): + * unichrome/via_video.c: (viaSetupAdaptors): + * unichrome/via_xvpriv.h: + + - Fix Xv surface destruction and re-allocation. + (Reported by Cedric Berger). + +2005-11-15 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaTearDownCBuffer), + (viaAccelSolidHelper), (viaAccelCopyHelper), + (viaExaDownloadFromScreen), (viaExaUploadToScreen): + * unichrome/via_driver.c: (VIAScreenInit): + + - Merged changes in exa_branch revisions 67 to 74. For a detailed + ChangeLog, see that branch. + +2005-11-09 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/Imakefile: + * unichrome/via_accel.c: (viaFlushPCI), (viaFlushDRIEnabled), + (viaSetupCBuffer), (viaTearDownCBuffer), (viaInitAgp), + (viaEnableVQ), (viaDisableVQ), (viaAccelSetMode), + (viaInitialize2DEngine), (viaAccelSync), (viaSetClippingRectangle), + (viaDisableClipping), (viaAccelClippingHelper), + (viaAccelSolidHelper), (viaAccelTransparentHelper), + (viaAccelCopyHelper), (viaSetupForScreenToScreenCopy), + (viaSubsequentScreenToScreenCopy), (viaSetupForSolidFill), + (viaSubsequentSolidFillRect), (viaSetupForMono8x8PatternFill), + (viaSubsequentMono8x8PatternFillRect), + (viaSetupForColor8x8PatternFill), + (viaSubsequentColor8x8PatternFillRect), + (viaSetupForCPUToScreenColorExpandFill), + (viaSubsequentScanlineCPUToScreenColorExpandFill), + (viaSetupForImageWrite), (viaSubsequentImageWriteRect), + (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine), + (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine), + (viaSubsequentDashedTwoPointLine), (viaInitXAA), + (viaAccelMarkSync), (viaAccelWaitMarker), (viaExaPrepareSolid), + (viaExaSolid), (viaExaDoneSolidCopy), (viaExaPrepareCopy), + (viaExaCopy), (viaExaDownloadFromScreen), (viaExaUploadToScreen), + (viaInitExa), (viaInitAccel), (viaExitAccel), (viaDGABlitRect), + (viaDGAFillRect), (viaDGAWaitMarker): + * unichrome/via_cursor.c: (VIALoadCursorImage): + * unichrome/via_dga.c: + * unichrome/via_dri.c: (VIADRIFBInit), (VIADRIScreenInit), + (VIADRICloseScreen), (VIADRIFinishScreenInit): + * unichrome/via_driver.c: (VIASetup), (VIAPreInit), (VIALeaveVT), + (VIAScreenInit), (VIAWriteMode), (VIACloseScreen), (VIASwitchMode): + * unichrome/via_driver.h: + * unichrome/via_memcpy.c: (viaVidCopyInit): + * unichrome/via_memory.c: (VIAFreeLinear), (offScreenLinear), + (VIAAllocLinear), (VIAInitLinear): + * unichrome/via_priv.h: + * unichrome/via_vbe.c: (ViaVbeSetMode): + + - Merge exa_branch from revision 52 to 67. For a detailed Changelog, + check that branch. + +2005-11-09 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_mode.c: (ViaModeDotClockTranslate): + + - Fix pro-mode and remove pro warning. (Paul Bender) + +2005-11-08 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIASwitchMode): + + - Don't kickVblank with no DRI enabled. (Joris van Rantwijk) + +2005-11-02 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_mode.c: (ViaGetMemoryBandwidth): + * unichrome/via_mode.h: + + - Give VM800 some bandwidth. + +2005-11-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevel.c: (viaDMAInitTimeStamp): + * libxvmc/viaLowLevelPro.c: (viaDMAInitTimeStamp), + (updateLowLevelBuf): + * unichrome/via_drmclient.h: + + - Fix compilation errors caused by the drm / dri update. + (reported by Tarun Kripalani) + +2005-10-31 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + * unichrome/via_cursor.c: (VIAHWCursorInit): + + - Second attempt at fixing the hw cursor issue. + There were actually two errors involved. + +2005-10-31 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_xvpriv.h: + + - Fix stray include left over by previous commit. + +2005-10-31 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Mitac 8889 device id. (Daniel Schindler) + +2005-10-30 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + + - Revert the hardware cursor fix since it for some strange reason + makes hw cursors white. Need to figure out why. + +2005-10-30 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaInitVideo), (viaSetupAdaptors), + (nv12cp), (viaDmaBlitImage), (viaPutImage), (nv12Blit): + * unichrome/via_xvpriv.h: + + - Enable DMA Xv image transfers also for PM8X0 / CN400. + YV12 to NV12 conversion is still software but now takes place + in system memory instead of during transfer to framebuffer memory. + CPU usage is much improved on PM8X0. Less so on CN400. + Hardware YV12 to NV12 conversion using the blitter was implemented + and tested but was very slow, probably due to the fact that blitting + only took place one column at a time. Since sync on the 2D engine + currently requires a busy-wait, the approach was not only slow, but + also CPU-consuming. + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaExitVideo), (viaSaveVideo), + (viaRestoreVideo), (VIAVidAdjustFrame): + + - Fix server crash when compiled without -DXvExtension. + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIADRIRingBufferInit), (VIADRIScreenInit), + (VIADRIFinishScreenInit), (VIADRIMapInit): + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_drm.h: + * unichrome/via_memory.c: (VIAFreeLinear), (VIAAllocLinear): + * unichrome/via_video.c: (viaInitVideo): + * unichrome/via_xvmc.c: (ViaInitXVMC): + + - Sync dri handling with Xorg. This should hopefully make it run + with Mesa 6.4 again. (Luc Verhaegen, Eric Anholt, me) + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaPutImage): + + - Make via_video.c compile without -DXF86DRI. Was broken with the + dmablit commit. (Reported by Luc Verhaegen) + +2005-10-27 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_accel.c: (VIAInitAccel): + + - Fix HW cursor memory allocation. + +2005-10-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_bandwidth.c: (ViaSetPrimaryFIFO), + (ViaSetSecondaryFIFO): + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_swov.c: (VIAVidHWDiffInit): + + - Remaining device id's lying about. + - Remove PM800 conditionals. + +2005-10-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_id.h: + * unichrome/via_mode.h: + + - Device id additions. AsRock P4VM800 reported by Mariano Benedettini + +2005-09-25 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via.h: + * unichrome/via_dri.c: (VIADRIRingBufferInit), + (VIADRIFinishScreenInit): + * unichrome/via_dri.h: + * unichrome/via_driver.h: + * unichrome/via_drm.h: + * unichrome/via_priv.h: + * unichrome/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVFlipClear), + (viaWaitHQVDone), (viaOverlayGetV1V3Format), + (viaOverlayGetSrcStartAddress), (viaOverlayGetFetch), + (viaSetColorSpace), (ViaSetVidCtl), (AddHQVSurface), + (ViaSwovSurfaceCreate), (ViaSwovSurfaceDestroy), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (SetHQVFetch), (Upd_Video), (VIAVidUpdateOverlay), + (ViaOverlayHide): + * unichrome/via_video.c: (DecideOverlaySupport), (viaResetVideo), + (viaSaveVideo), (viaExitVideo), (viaInitVideo), (viaReputImage), + (viaSetupAdaptors), (viaStopVideo), (Flip), (nv12cp), + (viaDmaBlitImage), (viaPutImage), (viaQueryImageAttributes): + * unichrome/via_xvmc.c: (ViaInitXVMC): + * unichrome/via_xvpriv.h: + + Big Xv update. + - Bring Xv in sync with Xorg, which includes RV15 and RV16 support. + - Add support for PCI DMA Xv image transfer. This requires DRM >= 2.7.0, + and does not yet work on Unichrome Pro group A, since YV12->NV12 + hardware conversion is not yet implemented. + +2005-08-13 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_swov.c: (ViaSwovSurfaceDestroy): + + - Destroy video surfaces on video exit / stop. + +2005-08-13 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAAdjustFrame) + + - Fix Xv panning also for VBEModes. + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAEnterVT): + + - Fix segfault on EnterVT when DRI is not enabled. + (Joris van Rantwijk) + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_priv.h: + * unichrome/via_swov.c: (VIAVidUpdateOverlay): + * unichrome/via_video.c: (RegionsEqual), (viaReputImage), + (viaSetupAdaptors), (VIAVidAdjustFrame): + + - Fix Xv panning. Speed up overlay updates on window moves. + +2005-08-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_video.c: (viaExitVideo): + + - Fix stopvideo for all ports and adaptors. + +2005-08-10 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/Imakefile: + * unichrome/via_bios.h: + * unichrome/via_ch7xxx.c: (CH7xxxPrintRegs), (ViaCH7xxxDetect), + (CH7xxxSave), (CH7xxxRestore), (CH7xxxDACSenseI2C), + (CH7xxxDACSense), (CH7011ModeIndex), (CH7019ModeIndex), + (CH7xxxModeValid), (CH7xxxModeI2C), (CH7xxxModeCrtc), + (CH7xxxTVPower), (CH7019LCDPower), (ViaCH7xxxInit): + * unichrome/via_ch7xxx.h: + * unichrome/via_driver.c: (VIAPreInit): + * unichrome/via_id.c: + * unichrome/via_mode.c: (ViaTVDetect), (ViaTVInit): + * unichrome/via_vt162x.c: (ViaVT162xDetect), (VT1625DACSenseI2C), + (VT1625DACSense), (VT1621ModeIndex), (VT1622ModeIndex), + (VT1625ModeValid), (VT1622ModeI2C), (VT1622ModeCrtc), + (VT1625Power), (ViaVT162xInit): + * unichrome/via_vt162x.h: + + - Initial steps to incorporating CH7xxx and VT1625 support; + merging patches from David George, Philip Prindeville, Terry Lewis. + +2005-07-30 Ivor Hewitt <ivor-at-ivor-dot-org> + + * libxvmc/Imakefile: + * unichrome/via_mode.c: (ViaGetMemoryBandwidth), + (ViaModePrimaryVGA), (ViaModePrimary): + * unichrome/via_swov.c: + + - Merge fixes from xorg for typos in mode setting and sync set + +2005-07-18 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Additional card-id. Reported by Philip Prindeville. + +2005-07-04 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_driver.c: (VIAPreInit), (VIAScreenInit): + * unichrome/via_id.c: + + - Avoid calling DPMS to blank screen during init with VBEModes. + - Add another card ID. + +2005-06-29 Ivor Hewitt <ivor-at-ivor-dot-org> + + * unichrome/via_id.c: + + - Additional card-ids. Patch from Xavier Bachelot + +2005-06-26 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevelPro.c: (finish_header_agp), (syncDMA), + (syncVideo), (pciFlush), (agpFlush), (uploadHQVDeinterlace), + (uploadHQVShadow), (flushXvMCLowLevel), (flushPCIXvMCLowLevel), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (releaseXvMCLowLevel), (initXvMCLowLevel), (closeXvMCLowLevel): + + - Clean up the VIDEO_DMA ifdef mess before xorg inclusion. + - Make VIDEO_DMA wait for DMA quiescent before flipping, pending proper + HQV locking. + - Disable VIDEO_DMA to improve latency pending proper HQV locking. + +2005-06-17 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_mode.c: (ViaSetPrimaryDotclock), + (ViaSetSecondaryDotclock), (ViaComputeProDotClock), + (ViaModeDotClockTranslate): + + - Free dotclock on Unichrome Pro. Pls report problems with + unstable clocks. + - Minor 64-bit fixes. + +2005-06-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_xvmc.c: (ViaXvMCCreateContext), + (ViaXvMCCreateSurface), (ViaXvMCCreateSubpicture): + * unichrome/via_xvmc.h: + + - XvMC 64 bit fixes. XvMC now runs on K8M800 64-bit Linux. + +2005-06-12 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_bios.h: + * unichrome/via_i2c.c: + * unichrome/via_mode.c: (ViaTVRestore): + * unichrome/via_vt162x.c: (VT162xPrintRegs), (ViaVT162xDetect), + (VT162xSave), (VT162xRestore), (ViaVT162xInit): + + - Fix up the vt1623 encoder: Correct device ID, number of registers + and most of all reading from the i2cbus it is sitting on. + +2005-06-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIADRIScreenInit): + + - Update via_dri.c to compile with new libdri. + +2005-06-01 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_vt162x.h: + + - Fix TV-out on Unichrome Pro. To make it work CRT+TV needs to be + enabled in BIOS. Still it will hang the machine or possibly only + the display chip on X server exit. + - Import the 720x576Noscale mode for vt1622A/vt1623 from the Unichrome + driver (Terry Barnaby) + +2005-05-25 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/viaLowLevelPro.c: (setHQVDeinterlacing): + * libxvmc/viaXvMC.c: + * unichrome/via_driver.c: + * unichrome/via_mode.c: (ViaModePrimary): + * unichrome/via_mode.h: + * unichrome/via_vt162x.c: (ViaVT162xDetect): + + - Updated incorrect field order in libViaXvMCPro. + - Fixed warnings about unresolved int10 symbols in the Unichrome driver. + - Updated Unichrome Pro dotclocks - also for TV. + - Made the driver recognize the vt1623 TV encoder on the EPIA SP13000. + - Removed unnecessary define in viaXvMC.c. + +2005-05-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/driDrawable.c: (getDRIDrawableInfoLocked): + * libxvmc/viaXvMC.c: (releaseContextResources), + (XvMCCreateContext): + * libxvmc/xf86dri.c: (uniDRIDestroyContext), + (uniDRICreateDrawable), (uniDRIDestroyDrawable), + (uniDRIGetDrawableInfo): + * libxvmc/xf86dri.h: + + - Changed DRI client function names since they clash with + via_dri.so, causing strange problems in, for example, xine. + +2005-05-16 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * unichrome/via_dri.c: (VIASetAgpMode), (VIADRIAgpInit): + + - Added better AGP mode control to the DDX. + +2005-05-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * prepare-ChangeLogSVN.pl: + + - Added the above file for generation of ChangeLog Entries. + +2005-05-11 Thomas Hellström <unichrome-at-shipmail-dot-org> + + * libxvmc/driDrawable.c: + * libxvmc/viaLowLevel.c: (hwlLock), (hwlUnlock), + (setAGPSyncLowLevel), (viaDMATimeStampLowLevel), + (flushXvMCLowLevel), (flushPCIXvMCLowLevel), + (viaMpegSetSurfaceStride), (viaVideoSetSWFLipLocked), + (viaVideoSWFlipLocked), (viaMpegSetFB), (viaMpegBeginPicture), + (viaMpegReset), (viaMpegWriteSlice), (viaVideoSubPictureOffLocked), + (viaVideoSubPictureLocked), (viaBlit), (syncXvMCLowLevel), + (initXvMCLowLevel), (setLowLevelLocking), (closeXvMCLowLevel): + * libxvmc/viaLowLevel.h: + * libxvmc/viaLowLevelPro.c: (initHQVShadow), + (setHQVHWDeinterlacing), (setHQVDeblocking), (setHQVStartAddress), + (setHQVColorSpaceConversion), (setHQVFetchLine), (setHQVScale), + (setHQVSingleDestination), (setHQVDeinterlacing), + (setHQVTripleBuffer), (hwlLock), (hwlUnlock), (setAGPSyncLowLevel), + (viaDMATimeStampLowLevel), (viaDMAInitTimeStamp), + (uploadHQVDeinterlace), (uploadHQVShadow), (flushXvMCLowLevel), + (flushPCIXvMCLowLevel), (viaMpegSetSurfaceStride), + (viaVideoSetSWFLipLocked), (viaVideoSWFlipLocked), (viaMpegSetFB), + (viaMpegBeginPicture), (viaMpegReset), (viaMpegWriteSlice), + (viaVideoSubPictureOffLocked), (viaVideoSubPictureLocked), + (viaBlit), (syncXvMCLowLevel), (updateLowLevelBuf), + (cleanupLowLevelBuf), (initXvMCLowLevel), (setLowLevelLocking), + (closeXvMCLowLevel), (computeDownScaling), + (computeHQVScaleAndFilter), (setupBackBuffer): + * libxvmc/viaXvMC.c: (grabDecoder), (releaseContextResources), + (XvMCCreateContext), (XvMCCreateSurface), (XvMCPutSlice2), + (XvMCPutSlice), (XvMCPutSurface), (XvMCBeginSurface), + (XvMCSyncSurface), (XvMCLoadQMatrix), (XvMCCreateSubpicture), + (XvMCSetSubpicturePalette), (XvMCClearSubpicture), + (XvMCCompositeSubpicture), (XvMCBlendSubpicture2), + (XvMCSyncSubpicture), (XvMCDestroySubpicture), (XvMCFlushSurface), + (XvMCGetSurfaceStatus), (XvMCQueryAttributes), (XvMCSetAttribute), + (XvMCGetAttribute), (XvMCHideSurface): + * libxvmc/viaXvMCPriv.h: + * unichrome/via_swov.c: (ViaSwovSurfaceCreate): + * unichrome/via_video.c: (viaSetupAdaptors): + * unichrome/via_xvpriv.h: + + - Added ChangeLog to the repository. + - Made the DDX update the overlay if a change in surface format occured + while it's dimensions are still the same. + - Made the XvMCLowLevel struct opaque (void *) and not defined in the + header file. This allows for different definitions for different hardware + - Added a HQV shadow which holds the HQV context for the Unichrome Pro. + The purpose is twofold: + 1. If someone else touched the HQV since we last used it, we can upload the + whole context. + 2. We do not need to read from the HQV, which is bad because we have to + halt the DMA engine to do that. + - Added and activated mpeg deblocking for Unichrome Pro. + - Added a number of HQV utility functions for the upcoming video engine free + output. These are not activated yet. (Unichrome Pro.) + - Added HW deinterlacing functions. Deactivated, since I cannot see any visible + difference. (Unichrome Pro.) diff --git a/trunk/Makefile.am b/trunk/Makefile.am new file mode 100644 index 000000000000..50af7d527d41 --- /dev/null +++ b/trunk/Makefile.am @@ -0,0 +1,24 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on 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 +# ADAM JACKSON 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. + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src man libxvmc + +EXTRA_DIST = release_notes-0.3.0 COPYING diff --git a/trunk/acinclude.m4 b/trunk/acinclude.m4 new file mode 100644 index 000000000000..127eed99d8be --- /dev/null +++ b/trunk/acinclude.m4 @@ -0,0 +1,91 @@ +dnl Copyright 2005 Red Hat, Inc +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation. +dnl +dnl The above copyright notice and this permission notice shall be included +dnl in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of the copyright holders shall +dnl not be used in advertising or otherwise to promote the sale, use or +dnl other dealings in this Software without prior written authorization +dnl from the copyright holders. +dnl + +# XORG_DRIVER_CHECK_EXT() +# -------------------------- +# Checks for the $1 define in xorg-server.h (from the sdk). If it +# is defined, then add $1 to $REQUIRED_MODULES. + +AC_DEFUN([XORG_DRIVER_CHECK_EXT],[ + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I`pkg-config --variable=sdkdir xorg-server`" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include "xorg-server.h" +#if !defined $1 +#error $1 not defined +#endif + ]])], + [_EXT_CHECK=yes], + [_EXT_CHECK=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_CHECKING([if $1 is defined]) + AC_MSG_RESULT([$_EXT_CHECK]) + if test "$_EXT_CHECK" != no; then + REQUIRED_MODULES="$REQUIRED_MODULES $2" + fi +]) +dnl Copyright 2005 Red Hat, Inc +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation. +dnl +dnl The above copyright notice and this permission notice shall be included +dnl in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of the copyright holders shall +dnl not be used in advertising or otherwise to promote the sale, use or +dnl other dealings in this Software without prior written authorization +dnl from the copyright holders. +dnl + +# XORG_RELEASE_VERSION +# -------------------- +# Adds --with/without-release-string and changes the PACKAGE and +# PACKAGE_TARNAME to use "$PACKAGE{_TARNAME}-$RELEASE_VERSION". If +# no option is given, PACKAGE and PACKAGE_TARNAME are unchanged. + +AC_DEFUN([XORG_RELEASE_VERSION],[ + AC_ARG_WITH(release-version, + AC_HELP_STRING([--with-release-version=STRING], + [Use release version string in package name]), + [RELEASE_VERSION="$withval"], + [RELEASE_VERSION=""]) + if test "x$RELEASE_VERSION" != "x"; then + PACKAGE="$PACKAGE-$RELEASE_VERSION" + PACKAGE_TARNAME="$PACKAGE_TARNAME-$RELEASE_VERSION" + AC_MSG_NOTICE([Building with package name set to $PACKAGE]) + fi +]) diff --git a/trunk/autogen.sh b/trunk/autogen.sh new file mode 100755 index 000000000000..904cd6746c87 --- /dev/null +++ b/trunk/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/trunk/configure.ac b/trunk/configure.ac new file mode 100644 index 000000000000..ab31cbdcd8ad --- /dev/null +++ b/trunk/configure.ac @@ -0,0 +1,192 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on 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 +# ADAM JACKSON 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. +# +# Process this file with autoconf to produce a configure script + +AC_PREREQ(2.57) +AC_INIT([xf86-video-openchrome], + 0.2.901, + [https://www.openchrome.org/trac/report], + xf86-video-openchrome) + +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER([config.h]) +AC_CONFIG_AUX_DIR(.) + +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_CC + +AH_TOP([#include "xorg-server.h"]) + +AC_ARG_WITH(xorg-module-dir, + AC_HELP_STRING([--with-xorg-module-dir=DIR], + [Default xorg module directory [[default=$libdir/xorg/modules]]]), + [moduledir="$withval"], + [moduledir="$libdir/xorg/modules"]) + +AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri], + [Disable DRI support [[default=auto]]]), + [DRI="$enableval"], + [DRI=auto]) + +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], + [Enable debugging support [[default=no]]]), + [DEBUG="$enableval"], + [DEBUG=no]) + +AC_ARG_ENABLE(xv-debug, AC_HELP_STRING([--enable-xv-debug], + [Enable XVideo debugging support [[default=no]]]), + [XV_DEBUG="$enableval"], + [XV_DEBUG=no]) + +# Checks for extensions +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) +XORG_DRIVER_CHECK_EXT(RENDER, renderproto) +XORG_DRIVER_CHECK_EXT(XV, videoproto) +XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto x11) +XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto libdrm $REQUIRED_MODULES]) +sdkdir=$(pkg-config --variable=sdkdir xorg-server) + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC + +if test "$DRI" != no; then + AC_CHECK_FILE([${sdkdir}/dri.h], + [have_dri_h="yes"], [have_dri_h="no"]) + AC_CHECK_FILE([${sdkdir}/sarea.h], + [have_sarea_h="yes"], [have_sarea_h="no"]) + AC_CHECK_FILE([${sdkdir}/dristruct.h], + [have_dristruct_h="yes"], [have_dristruct_h="no"]) +fi + +AC_MSG_CHECKING([whether to include DRI support]) +if test x$DRI = xauto; then + if test "$have_dri_h" = yes -a \ + "$have_sarea_h" = yes -a \ + "$have_dristruct_h" = yes; then + DRI="yes" + else + DRI="no" + fi +fi +AC_MSG_RESULT([$DRI]) + +AM_CONDITIONAL(DRI, test x$DRI = xyes) +if test "$DRI" = yes; then + PKG_CHECK_MODULES(DRI, [libdrm xf86driproto]) + AC_DEFINE(XF86DRI,1,[Enable DRI driver support]) + AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support]) + case "$host_cpu" in + i*86) + XVMC=yes ;; + amd64*|x86_64*) + XVMC=yes ;; + *) + XVMC=no ;; + esac +else + XVMC="no" +fi + +if test "x$XVMC" = xyes; then + AC_CHECK_HEADERS(pthread.h sys/ioctl.h sys/time.h time.h,,[XVMC="no"; break],) +fi + +AC_MSG_CHECKING([whether to build XvMC driver support]) +AC_MSG_RESULT([$XVMC]) + +AM_CONDITIONAL(XVMC, test x$XVMC = xyes) + +AC_CHECK_FILE([${sdkdir}/xf86Module.h], + [have_xf86Module_h="yes"], [have_xf86Module_h="no"]) + +# Check the ABI_VIDEODRV_VERSION +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" + +if test "x$have_xf86Module_h" = xyes; then +AC_MSG_CHECKING([whether to use old Xv ABI]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ +#include "xf86Module.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 1 +#error Old Xv ABI +#endif + ]])], + [OLD_XVABI=no], + [OLD_XVABI=yes]) +else + OLD_XVABI=yes + echo -n "xf86Module.h not found, " +fi + +CPPFLAGS="$SAVE_CPPFLAGS" + +if test "x$OLD_XVABI" = xyes; then + echo "yes." +else + echo "no." + AC_DEFINE(USE_NEW_XVABI, 1, [Use new Xv ABI (7.1RC1+)]) +fi + +AM_CONDITIONAL(DEBUG, test x$DEBUG = xyes) +if test "$DEBUG" = yes; then + AC_DEFINE(HAVE_DEBUG,1,[Enable debug support]) +fi + +AM_CONDITIONAL(XV_DEBUG, test x$XV_DEBUG = xyes) +if test "$XV_DEBUG" = yes; then + AC_DEFINE(XV_DEBUG,1,[Enable XVideo debug support]) +fi + +AC_SUBST([DRI_CFLAGS]) +AC_SUBST([XORG_CFLAGS]) +AC_SUBST([moduledir]) + +DRIVER_NAME=openchrome +AC_SUBST([DRIVER_NAME]) + +AC_DEFINE(X_USE_LINEARFB,1,[Compatibility define for older Xen]) +AC_DEFINE(X_USE_REGION_NULL,1,[Compatibility define for older Xen]) +AC_DEFINE(X_HAVE_XAAGETROP,1,[Compatibility define for older Xen]) +AC_DEFINE(X_NEED_I2CSTART,1,[Compatibility define for older Xen]) +AC_DEFINE(VIA_HAVE_EXA,1,[Build support for Exa]) + +DRIVER_MAN_SUFFIX="4" +AC_SUBST([DRIVER_MAN_SUFFIX]) + +XORG_RELEASE_VERSION + +AC_OUTPUT([ + Makefile + libxvmc/Makefile + man/Makefile + src/Makefile +]) diff --git a/trunk/libxvmc/Imakefile b/trunk/libxvmc/Imakefile new file mode 100644 index 000000000000..663204ae1523 --- /dev/null +++ b/trunk/libxvmc/Imakefile @@ -0,0 +1,59 @@ +#define DoNormalLib NormalLibXvMC +#define DoSharedLib SharedLibXvMC +#define DoDebugLib DebugLibXvMC +#define DoProfileLib ProfileLibXvMC +/*#define LibName viaXvMC*/ +#define SoRev SOXVMCREV +#define LibHeaders NO + +#include <Threads.tmpl> + +/* Anyone know how to determine this properly? + * Comment out the following to build in the x tree + */ +#define OUTOFTREE + +#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) $(PICFLAGS) -DTRUE=1 -DFALSE=0 + INCLUDES = -I$(XINCLUDESRC) -I$(INCLUDESRC) -I$(XLIBSRC) -I$(EXTINCSRC) \ + -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(DRMSRCDIR)/shared-core \ + -I$(DRMSRCDIR)/shared \ + -I$(XF86OSSRC)/linux/drm/kernel -I$(VIADRIVERSRC) + SRCS = viaXvMC.c viaLowLevel.c viaLowLevelPro.c xf86dri.c driDrawable.c + OBJS = viaXvMC.o viaLowLevel.o xf86drm.o xf86drmHash.o \ + xf86drmRandom.o xf86drmSL.o xf86dri.o driDrawable.o + OBJSPRO = viaXvMC.o viaLowLevelPro.o xf86drm.o xf86drmHash.o \ + xf86drmRandom.o xf86drmSL.o xf86dri.o driDrawable.o + LINTLIBS = $(LINTXLIB) + +#include <Library.tmpl> + +SharedLibraryTarget(viaXvMC,$(SoRev),$(OBJS) $(EXTRASHAREDOBJS),.,.) +SharedLibraryTarget(viaXvMCPro,$(SoRev),$(OBJSPRO) $(EXTRASHAREDOBJS),.,.) +InstallSharedLibrary(viaXvMC,$(SoRev),$(SHLIBDIR)) +InstallSharedLibrary(viaXvMCPro,$(SoRev),$(SHLIBDIR)) + +#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/trunk/libxvmc/Makefile.am b/trunk/libxvmc/Makefile.am new file mode 100644 index 000000000000..e171c2c9ab2d --- /dev/null +++ b/trunk/libxvmc/Makefile.am @@ -0,0 +1,46 @@ +if XVMC +lib_LTLIBRARIES=libchromeXvMC.la libchromeXvMCPro.la + +libchromeXvMC_la_SOURCES = \ + viaLowLevel.c \ + driDrawable.c \ + viaXvMC.c \ + xf86dri.c \ + viaLowLevel.h \ + driDrawable.h \ + viaXvMCPriv.h \ + xf86dri.h \ + xf86dristr.h \ + vldXvMC.h +libchromeXvMCPro_la_SOURCES = \ + viaLowLevelPro.c \ + driDrawable.c \ + viaXvMC.c \ + xf86dri.c \ + viaLowLevel.h \ + driDrawable.h \ + viaXvMCPriv.h \ + xf86dri.h \ + xf86dristr.h \ + vldXvMC.h + +libchromeXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0 +libchromeXvMC_la_LDFLAGS = -version-number 1:0:0 +libchromeXvMC_la_LIBADD = @DRI_LIBS@ + +libchromeXvMCPro_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0 +libchromeXvMCPro_la_LDFLAGS = -version-number 1:0:0 +libchromeXvMCPro_la_LIBADD = @DRI_LIBS@ +else +EXTRA_DIST = \ + driDrawable.c \ + driDrawable.h \ + viaLowLevelPro.c \ + viaLowLevel.c \ + viaLowLevel.h \ + viaXvMC.c \ + viaXvMCPriv.h \ + xf86dri.c \ + xf86dri.h \ + xf86dristr.h +endif diff --git a/trunk/libxvmc/driDrawable.c b/trunk/libxvmc/driDrawable.c new file mode 100644 index 000000000000..1072efe07d85 --- /dev/null +++ b/trunk/libxvmc/driDrawable.c @@ -0,0 +1,173 @@ +/***************************************************************************** + * driDrawable.c: Lean Version of DRI utilities. + * + * Copyright (c) 2005 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, 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 <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "xf86drm.h" +#include "drm.h" +#include "xf86dri.h" +#include "drm_sarea.h" +#include "driDrawable.h" + +static unsigned +drawStamp(volatile drm_sarea_t * pSarea, int index) +{ + return pSarea->drawableTable[index].stamp; +} + +int +getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen, + Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext, + drmAddress sarea, Bool updateInfo, drawableInfo ** info, + unsigned long infoSize) +{ + drawableInfo *drawInfo; + void *res; + drm_drawable_t drmDraw = 0; + volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea; + drm_clip_rect_t *clipFront, *clipBack; + + int ret; + + if (drmHashLookup(drawHash, (unsigned long)draw, &res)) { + + /* + * The drawable is unknown to us. Create it and put it in the + * hash table. + */ + + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) { + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + return 1; + } + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + + drawInfo = (drawableInfo *) malloc(infoSize); + if (!drawInfo) + return 1; + + drawInfo->drmDraw = drmDraw; + drawInfo->stamp = 0; + drawInfo->clipFront = 0; + drawInfo->clipBack = 0; + + drmHashInsert(drawHash, (unsigned long)draw, drawInfo); + + } else { + drawInfo = res; + } + + drawInfo->touched = FALSE; + while (!drawInfo->clipFront + || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { + + /* + * The drawable has been touched since we last got info about it. + * obtain new info from the X server. + */ + + drawInfo->touched = TRUE; + + if (updateInfo || !drawInfo->clipFront) { + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + + ret = uniDRIGetDrawableInfo(display, screen, draw, + &drawInfo->index, &drawInfo->stamp, &drawInfo->x, + &drawInfo->y, &drawInfo->w, &drawInfo->h, + &drawInfo->numClipFront, &clipFront, + &drawInfo->backX, &drawInfo->backY, + &drawInfo->numClipBack, &clipBack); + + DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext); + + /* + * Error. Probably the drawable is destroyed. Return error and old values. + */ + + if (!ret) { + free(drawInfo); + drawInfo = NULL; + drmHashDelete(drawHash, (unsigned long)draw); + + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + uniDRIDestroyDrawable(display, screen, draw); + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + + return 1; + } + + if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { + + /* + * The info is already outdated. Sigh. Have another go. + */ + + XFree(clipFront); + XFree(clipBack); + continue; + } + + if (drawInfo->clipFront) + XFree(drawInfo->clipFront); + drawInfo->clipFront = clipFront; + if (drawInfo->clipBack) + XFree(drawInfo->clipBack); + drawInfo->clipBack = clipBack; + } else { + if (!drawInfo->clipFront) + drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL; + drawInfo->stamp = drawStamp(pSarea, drawInfo->index); + } + } + *info = drawInfo; + return 0; +} + +void +driDestroyHashContents(void *drawHash) +{ + unsigned long key; + void *content; + drawableInfo *drawInfo; + + if (drmHashFirst(drawHash, &key, &content) < 1) + return; + drawInfo = (drawableInfo *) content; + if (drawInfo->clipBack) + XFree(drawInfo->clipBack); + if (drawInfo->clipFront) + XFree(drawInfo->clipFront); + free(drawInfo); + while (drmHashNext(drawHash, &key, &content) == 1) { + drawInfo = (drawableInfo *) content; + if (drawInfo->clipBack) + XFree(drawInfo->clipBack); + if (drawInfo->clipFront) + XFree(drawInfo->clipFront); + free(drawInfo); + } + + return; +} diff --git a/trunk/libxvmc/driDrawable.h b/trunk/libxvmc/driDrawable.h new file mode 100644 index 000000000000..a758c7c711db --- /dev/null +++ b/trunk/libxvmc/driDrawable.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * driDrawable.h: Lean Version of DRI utilities. + * + * Copyright (c) 2005 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, 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 _DRIDRAWABLE_H +#define _DRIDRAWABLE_H + +typedef struct _drawableInfo +{ + drm_drawable_t drmDraw; + unsigned stamp; + unsigned index; + drm_clip_rect_t *clipFront; + drm_clip_rect_t *clipBack; + int x; + int y; + int w; + int h; + int backX; + int backY; + int numClipFront; + int numClipBack; + Bool touched; +} drawableInfo; + +/* + * Get updated info about the drawable "draw". The drawableInfo record returned is malloced + * and administrated internally. Never free it unless you know exactly what you are doing. + * The drm hash table "drawHash" needs to be initialized externally. + */ + +extern int +getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen, + Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext, + drmAddress sarea, Bool updateInfo, drawableInfo ** info, + unsigned long infoSize); + +/* + * Free all resources created by the above function. Typically done on exit. + */ + +extern void driDestroyHashContents(void *drawHash); + +#endif diff --git a/trunk/libxvmc/viaLowLevel.c b/trunk/libxvmc/viaLowLevel.c new file mode 100644 index 000000000000..2d90f8088813 --- /dev/null +++ b/trunk/libxvmc/viaLowLevel.c @@ -0,0 +1,1055 @@ +/***************************************************************************** + * 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. + */ + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include <time.h> +#include <sys/time.h> +#include <stdio.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 fbStride; + unsigned fbDepth; + unsigned width; + unsigned height; + 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; + +/* + * 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_STARTADDR_Y 0x1D4 +#define HQV_SRC_STARTADDR_U 0x1D8 +#define HQV_SRC_STARTADDR_V 0x1DC +#define HQV_MINIFY_DEBLOCK 0x1E8 + +#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 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 0x00000002 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000001 /* 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 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) \ + (xl)->agp_buffer[(xl)->agp_pos++] = (val) +#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 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); + +/* + * We want to have two concurrent types of thread taking the hardware + * lock simulataneously. One is the video out thread that needs immediate + * access to flip an image. The other is everything else which may have + * the lock for quite some time. This is only so the video out thread can + * sneak in and display an image while other resources are busy. + */ + +void +hwlLock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_LOCK(xl); +} + +void +hwlUnlock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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(void *xlp, int val, CARD32 timeStamp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->agpSync = val; + xl->agpSyncTimeStamp = timeStamp; +} + +CARD32 +viaDMATimeStampLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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 && (timeStamp > xl->lastReadTimeStamp)) { + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + + while (timeStamp > (xl->lastReadTimeStamp = *xl->tsP)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_DMAWAITTIMEOUT) { + if ((timeStamp > (xl->lastReadTimeStamp = *xl->tsP))) { + 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 = VIA_MEM_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); + } +} + +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; + + sleep.tv_nsec = 1; + sleep.tv_sec = 0; + here.tz_minuteswest = 0; + here.tz_dsttime = 0; + gettimeofday(&then, &here); + while (VIDIN(xl, HQV_CONTROL) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP)) { + gettimeofday(&now, &here); + if (timeDiff(&now, &then) > VIA_SYNCWAITTIMEOUT) { + if (VIDIN(xl, HQV_CONTROL) & (HQV_SW_FLIP | HQV_SUBPIC_FLIP)) { + xl->errors |= LL_VIDEO_TIMEDOUT; + break; + } + } + if (doSleep) + nanosleep(&sleep, &rem); + } +} + +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; + + 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, 0); + 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; + + 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; + } 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, 0); + 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(void *xlp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pci_pos) + pciFlush(xl); + if (xl->agp_pos) + agpFlush(xl); + errors = xl->errors; + xl->errors = 0; + return errors; +} + +void +flushPCIXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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; + xl->pci_buffer[xl->pci_pos++] = value; +} + +void +viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx) +{ + CARD32 y_stride = ctx->yStride; + CARD32 uv_stride = y_stride >> 1; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + BEGIN_RING_AGP(xl, 2); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc50), + (y_stride >> 3) | ((uv_stride >> 3) << 16)); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + +void +viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + pciCommand(xl, HQV_SRC_STARTADDR_Y | 0x200, yOffs, LL_MODE_VIDEO); + pciCommand(xl, HQV_SRC_STARTADDR_U | 0x200, uOffs, 0); + pciCommand(xl, HQV_SRC_STARTADDR_V | 0x200, vOffs, 0); +} + +void +viaVideoSWFlipLocked(void *xlp, unsigned flags, int progressiveSequence) +{ + CARD32 andWd, orWd; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + andWd = 0; + orWd = 0; + + 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_SW_FLIP | HQV_FLIP_ODD | 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_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_SW_FLIP | HQV_FLIP_STATUS | HQV_SUBPIC_FLIP; + } + if (progressiveSequence) { + andWd &= ~HQV_FIELD_UV; + orWd &= ~HQV_FIELD_UV; + } + + pciCommand(xl, HQV_CONTROL | 0x200, (VIDIN(xl, + HQV_CONTROL) & andWd) | orWd, 0); +} + +void +viaMpegSetFB(void *xlp, unsigned i, + unsigned yOffs, unsigned uOffs, unsigned vOffs) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + i *= 12; + BEGIN_RING_AGP(xl, 6); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc20 + i), yOffs >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc24 + i), uOffs >> 3); + OUT_RING_QW_AGP(xl, H1_ADDR(0xc28 + i), vOffs >> 3); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); +} + +void +viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control) +{ + + unsigned j, mb_width, mb_height; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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_RING_AGP(xl, 144); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, H1_ADDR(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, H1_ADDR(0xc5c), 0); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(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, H1_ADDR(0xc5c), 1); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(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, H1_ADDR(0xc5c), 2); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(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, H1_ADDR(0xc5c), 3); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(xl, H1_ADDR(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, H1_ADDR(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, H1_ADDR(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, H1_ADDR(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(void *xlp) +{ + int i, j; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + BEGIN_RING_AGP(xl, 100); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + for (i = 0; i < 14; i++) + OUT_RING_QW_AGP(xl, H1_ADDR(0xc08), 0); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc98), 0x400000); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xc0c), 0x43 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl, H1_ADDR(j), 0); + } + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc0c), 0xc3 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(xl, H1_ADDR(j), 0); + +} + +void +viaMpegWriteSlice(void *xlp, CARD8 * slice, int nBytes, CARD32 sCode) +{ + int i, n, r; + CARD32 *buf; + int count; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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_RING_AGP(xl, 4); + WAITFLAGS(xl, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(xl, H1_ADDR(0xc9c), nBytes); + + if (sCode) + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), sCode); + + i = 0; + count = 0; + + do { + count += (LL_AGP_CMDBUF_SIZE - 20) >> 1; + count = (count > n) ? n : count; + BEGIN_RING_AGP(xl, (count - i) << 1); + + for (; i < count; i++) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), *buf++); + } + } while (i < n); + + BEGIN_RING_AGP(xl, 6); + + if (r) { + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), *buf & ((1 << (r << 3)) - 1)); + } + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), 0); + OUT_RING_QW_AGP(xl, H1_ADDR(0xca0), 0); + +} + +void +viaVideoSubPictureOffLocked(void *xlp) +{ + + CARD32 stride; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + stride = VIDIN(xl, SUBP_CONTROL_STRIDE); + + pciCommand(xl, SUBP_CONTROL_STRIDE | 0x200, stride & ~SUBP_HQV_ENABLE, + LL_MODE_VIDEO); +} + +void +viaVideoSubPictureLocked(void *xlp, ViaXvMCSubPicture * pViaSubPic) +{ + + unsigned i; + CARD32 cWord; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + for (i = 0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + pciCommand(xl, RAM_TABLE_CONTROL | 0x200, pViaSubPic->palette[i], + LL_MODE_VIDEO); + } + + pciCommand(xl, SUBP_STARTADDR | 0x200, pViaSubPic->offset, 0); + cWord = (pViaSubPic->stride & SUBP_STRIDE_MASK) | SUBP_HQV_ENABLE; + cWord |= (pViaSubPic->ia44) ? SUBP_IA44 : SUBP_AI44; + pciCommand(xl, SUBP_CONTROL_STRIDE | 0x200, cWord, 0); +} + +void +viaBlit(void *xlp, 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; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (!w || !h) + return; + + 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(void *xlp, unsigned int mode, unsigned int doSleep, + CARD32 timeStamp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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; +} + +extern void * +initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId) +{ + int ret; + XvMCLowLevel *xl; + + if (chipId == PCI_CHIP_VT3259 || chipId == PCI_CHIP_VT3364) { + fprintf(stderr, "You are using an XvMC driver for the wrong chip.\n"); + fprintf(stderr, "Chipid is 0x%04x.\n", chipId); + return NULL; + } + + xl = (XvMCLowLevel *) malloc(sizeof(XvMCLowLevel)); + + if (!xl) + return NULL; + + 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; + ret = viaDMAInitTimeStamp(xl); + if (ret) { + free(xl); + return NULL; + } + return xl; +} + +void +setLowLevelLocking(void *xlp, int performLocking) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->performLocking = performLocking; +} + +void +closeXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + viaDMACleanupTimeStamp(xl); + free(xl); +} diff --git a/trunk/libxvmc/viaLowLevel.h b/trunk/libxvmc/viaLowLevel.h new file mode 100644 index 000000000000..59171d790338 --- /dev/null +++ b/trunk/libxvmc/viaLowLevel.h @@ -0,0 +1,141 @@ +/***************************************************************************** + * 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*2) +#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" +#include "viaXvMCPriv.h" + +#define setRegion(xx,yy,ww,hh,region) \ + do { \ + (region).x = (xx); \ + (region).y = (yy); \ + (region).w = (ww); \ + (region).h = (hh); \ + } while(0) + +#define regionEqual(r1, r2) \ + ((r1).x == (r2).x && \ + (r1).y == (r2).y && \ + (r1).w == (r2).w && \ + (r1).h == (r2).h) + +extern void + *initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId); + +extern void setLowLevelLocking(void *xlp, int perFormLocking); +extern void closeXvMCLowLevel(void *xlp); +extern void flushPCIXvMCLowLevel(void *xlp); +extern CARD32 viaDMATimeStampLowLevel(void *xlp); +extern void setAGPSyncLowLevel(void *xlp, int val, CARD32 timeStamp); + +/* + * These two functions also return and clear the current error status. + */ + +extern unsigned flushXvMCLowLevel(void *xlp); +extern unsigned syncXvMCLowLevel(void *xlp, unsigned int mode, + unsigned int doSleep, CARD32 timeStamp); + +extern void hwlUnlock(void *xlp, int videoLock); +extern void hwlLock(void *xlp, int videoLock); + +extern void viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride); + +extern void viaMpegReset(void *xlp); +extern void viaMpegWriteSlice(void *xlp, CARD8 * slice, + int nBytes, CARD32 sCode); +extern void viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx); +extern void viaMpegSetFB(void *xlp, unsigned i, unsigned yOffs, + unsigned uOffs, unsigned vOffs); +extern void viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control); + +/* + * Low-level Video functions in viaLowLevel.c + */ + +extern void viaBlit(void *xlp, 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(void *xlp, unsigned flags, + int progressiveSequence); + +extern void viaVideoSubPictureLocked(void *xlp, + ViaXvMCSubPicture * pViaSubPic); +extern void viaVideoSubPictureOffLocked(void *xlp); + +#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 */ +#define PCI_CHIP_VT3327 0x3343 /* P4M890 */ +#define PCI_CHIP_VT3364 0x3371 /* P4M900 */ + +#endif diff --git a/trunk/libxvmc/viaLowLevelPro.c b/trunk/libxvmc/viaLowLevelPro.c new file mode 100644 index 000000000000..8c97e28062d3 --- /dev/null +++ b/trunk/libxvmc/viaLowLevelPro.c @@ -0,0 +1,1650 @@ +/***************************************************************************** + * 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. (Initial decoder interface functions). + * Thomas Hellstrom 2004, 2005 (Blitting functions, AGP and locking, Unichrome Pro Video AGP). + * Ivor Hewitt 2005 (Unichrome Pro modifications and merging). + */ + +/* IH + * I've left the proReg or-ing in case we need/want to implement the V1/V3 + * register toggle too, which also moves the register locations. + * The CN400 has dual mpeg decoders, not sure at the moment whether these + * are also operated through independent registers also. + */ + +#undef VIDEO_DMA +#define HQV_USE_IRQ +#define UNICHROME_PRO + +#include "viaXvMCPriv.h" +#include "viaLowLevel.h" +#include "driDrawable.h" +#include <time.h> +#include <sys/time.h> +#include <stdio.h> + +typedef enum +{ ll_init, ll_agpBuf, ll_pciBuf, ll_timeStamp, ll_llBuf } +LLState; + +typedef struct +{ + drm_via_mem_t mem; + unsigned offset; + unsigned stride; + unsigned height; +} LowLevelBuffer; + +struct _XvMCLowLevel; + +typedef struct _ViaCommandBuffer +{ + CARD32 *buf; + CARD32 waitFlags; + unsigned pos; + unsigned bufSize; + int mode; + int header_start; + int rindex; + void (*flushFunc) (struct _ViaCommandBuffer * cb, + struct _XvMCLowLevel * xl); +} ViaCommandBuffer; + +typedef struct _XvMCLowLevel +{ + ViaCommandBuffer agpBuf, pciBuf, *videoBuf; + int use_agp; + int fd; + drm_context_t *drmcontext; + drmLockPtr hwLock; + drmAddress mmioAddress; + drmAddress fbAddress; + unsigned fbStride; + unsigned fbDepth; + unsigned width; + unsigned height; + int performLocking; + unsigned errors; + drm_via_mem_t tsMem; + CARD32 tsOffset; + volatile CARD32 *tsP; + CARD32 curTimeStamp; + CARD32 lastReadTimeStamp; + int agpSync; + CARD32 agpSyncTimeStamp; + unsigned chipId; + + /* + * Data for video-engine less display + */ + + XvMCRegion sRegion; + XvMCRegion dRegion; + LowLevelBuffer scale; + LowLevelBuffer back; + Bool downScaling; + CARD32 downScaleW; + CARD32 downScaleH; + CARD32 upScaleW; + CARD32 upScaleH; + unsigned fetch; + unsigned line; + LLState state; +} XvMCLowLevel; + +/* + * 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 HQV_SCALE_ENABLE 0x00000800 +#define HQV_SCALE_DOWN 0x00001000 + +#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 0x00000002 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000001 /* 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 + +typedef struct +{ + CARD32 data; + Bool set; +} HQVRegister; + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(cb, flags) \ + (cb)->waitFlags |= (flags) +#define BEGIN_RING_AGP(cb, xl, size) \ + do { \ + if ((cb)->pos > ((cb)->bufSize-(size))) { \ + cb->flushFunc(cb, xl); \ + } \ + } while(0) +#define OUT_RING_AGP(cb, val) do{ \ + (cb)->buf[(cb)->pos++] = (val); \ + } while(0); + +#define OUT_RING_QW_AGP(cb, val1, val2) \ + do { \ + (cb)->buf[(cb)->pos++] = (val1); \ + (cb)->buf[(cb)->pos++] = (val2); \ + } while (0) + +#define BEGIN_HEADER5_AGP(cb, xl, index) \ + do { \ + BEGIN_RING_AGP(cb, xl, 8); \ + (cb)->mode = VIA_AGP_HEADER5; \ + (cb)->rindex = (index); \ + (cb)->header_start = (cb)->pos; \ + (cb)->pos += 4; \ + } while (0) + +#define BEGIN_HEADER6_AGP(cb, xl) \ + do { \ + BEGIN_RING_AGP(cb, xl, 8); \ + (cb)->mode = VIA_AGP_HEADER6; \ + (cb)->header_start = (cb)->pos; \ + (cb)->pos += 4; \ + } while (0) + +#define BEGIN_HEADER5_DATA(cb, xl, size, index) \ + do { \ + if ((cb)->pos > ((cb)->bufSize - ((size) + 16))) { \ + cb->flushFunc(cb, xl); \ + BEGIN_HEADER5_AGP(cb, xl, index); \ + } else if ((cb)->mode && (((cb)->mode != VIA_AGP_HEADER5) || \ + ((cb)->rindex != index))) { \ + finish_header_agp(cb); \ + BEGIN_HEADER5_AGP((cb), xl, (index)); \ + } else if (cb->mode != VIA_AGP_HEADER5) { \ + BEGIN_HEADER5_AGP((cb), xl, (index)); \ + } \ + }while(0) + +#define BEGIN_HEADER6_DATA(cb, xl, size) \ + do{ \ + if ((cb)->pos > (cb->bufSize-(((size) << 1) + 16))) { \ + cb->flushFunc(cb, xl); \ + BEGIN_HEADER6_AGP(cb, xl); \ + } else if ((cb)->mode && ((cb)->mode != VIA_AGP_HEADER6)) { \ + finish_header_agp(cb); \ + BEGIN_HEADER6_AGP(cb, xl); \ + } \ + else if ((cb->mode != VIA_AGP_HEADER6)) { \ + BEGIN_HEADER6_AGP(cb, (xl)); \ + } \ + }while(0) + +#define HQV_SHADOW_BASE 0x3CC +#define HQV_SHADOW_SIZE 13 + +#define SETHQVSHADOW(shadow, offset, value) \ + do { \ + HQVRegister *r = (shadow) + (((offset) - HQV_SHADOW_BASE) >> 2); \ + r->data = (value); \ + r->set = TRUE; \ + } while(0) + +#define GETHQVSHADOW(shadow, offset) ((shadow)[(offset - HQV_SHADOW_BASE) >> 2].data) + +#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); + +static HQVRegister hqvShadow[HQV_SHADOW_SIZE]; + +static void +initHQVShadow(HQVRegister * r) +{ + int i; + + for (i = 0; i < HQV_SHADOW_SIZE; ++i) { + r->data = 0; + r++->set = FALSE; + } +} + +#if 0 +static void +setHQVHWDeinterlacing(HQVRegister * shadow, Bool on, Bool motionDetect, + CARD32 stride, CARD32 height) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3E4); + + if (!on) { + tmp &= ~((1 << 0) | (1 << 12) | (1 << 27) | (1 << 31)); + SETHQVSHADOW(shadow, 0x3E4, tmp); + return; + } + + tmp = (1 << 31) | + (4 << 28) | + (1 << 27) | + (3 << 25) | (1 << 18) | (2 << 14) | (8 << 8) | (8 << 1) | (1 << 0); + + if (motionDetect) + tmp |= (1 << 12); + + SETHQVSHADOW(shadow, 0x3E4, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3DC); + tmp |= (stride * height * 1536) / 1024 & 0x7ff; + + SETHQVSHADOW(shadow, 0x3DC, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D0); + tmp |= (1 << 23); + + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +#endif + +static void +setHQVDeblocking(HQVRegister * shadow, Bool on, Bool lowPass) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3DC); + + if (!on) { + tmp &= ~(1 << 27); + SETHQVSHADOW(shadow, 0x3DC, tmp); + return; + } + + tmp |= (8 << 16) | (1 << 27); + if (lowPass) + tmp |= (1 << 26); + SETHQVSHADOW(shadow, 0x3DC, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D4); + tmp |= (6 << 27); + SETHQVSHADOW(shadow, 0x3D4, tmp); + + tmp = GETHQVSHADOW(shadow, 0x3D8); + tmp |= (19 << 27); + SETHQVSHADOW(shadow, 0x3D8, tmp); +} + +static void +setHQVStartAddress(HQVRegister * shadow, unsigned yOffs, unsigned uOffs, + unsigned stride, unsigned format) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D4); + + tmp |= yOffs & 0x03FFFFF0; + SETHQVSHADOW(shadow, 0x3D4, tmp); + tmp = GETHQVSHADOW(shadow, 0x3D8); + tmp |= uOffs & 0x03FFFFF0; + SETHQVSHADOW(shadow, 0x3D8, tmp); + tmp = GETHQVSHADOW(shadow, 0x3F8); + tmp |= (stride & 0x1FF8); + SETHQVSHADOW(shadow, 0x3F8, tmp); + tmp = GETHQVSHADOW(shadow, 0x3D0); + + if (format == 0) { + /* + * NV12 + */ + tmp |= (0x0C << 28); + } else if (format == 1) { + /* + * RGB16 + */ + tmp |= (0x02 << 28); + } else if (format == 2) { + /* + * RGB32 + */ + ; + } + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +#if 0 + +static void +setHQVColorSpaceConversion(HQVRegister * shadow, unsigned depth, Bool on) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3DC); + + if (!on) { + tmp &= ~(1 << 28); + SETHQVSHADOW(shadow, 0x3DC, tmp); + return; + } + + if (depth == 32) + tmp |= (1 << 29); + tmp |= (1 << 28); + tmp &= ~(1 << 15); + SETHQVSHADOW(shadow, 0x3DC, tmp); +} + +static void +setHQVFetchLine(HQVRegister * shadow, unsigned fetch, unsigned lines) +{ + SETHQVSHADOW(shadow, 0x3E0, + ((lines - 1) & 0x7FF) | (((fetch - 1) & 0x1FFF) << 16)); +} + +static void +setHQVScale(HQVRegister * shadow, unsigned horizontal, unsigned vertical) +{ + SETHQVSHADOW(shadow, 0x3E8, + (horizontal & 0xFFFF) | ((vertical & 0xFFFF) << 16)); +} + +static void +setHQVSingleDestination(HQVRegister * shadow, unsigned offset, + unsigned stride) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + tmp |= (1 << 6); + + SETHQVSHADOW(shadow, 0x3D0, tmp); + SETHQVSHADOW(shadow, 0x3EC, offset & 0x03FFFFF8); + SETHQVSHADOW(shadow, 0x3F4, stride & 0x1FF8); +} +#endif + +static void +setHQVDeinterlacing(HQVRegister * shadow, CARD32 frameType) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + if ((frameType & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + tmp |= HQV_FIELD_UV | + HQV_DEINTERLACE | HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD; + } else if ((frameType & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + tmp |= HQV_FIELD_UV | + HQV_DEINTERLACE | + HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_FLIP_ODD; + } + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +static void +setHQVTripleBuffer(HQVRegister * shadow, Bool on) +{ + CARD32 tmp = GETHQVSHADOW(shadow, 0x3D0); + + if (on) + tmp |= (1 << 26); + else + tmp &= ~(1 << 26); + SETHQVSHADOW(shadow, 0x3D0, tmp); +} + +static void +finish_header_agp(ViaCommandBuffer * cb) +{ + int numDWords, i; + + CARD32 *hb; + + if (!cb->mode) + return; + numDWords = cb->pos - cb->header_start - 4; + hb = cb->buf + cb->header_start; + switch (cb->mode) { + case VIA_AGP_HEADER5: + hb[0] = VIA_AGP_HEADER5 | cb->rindex; + 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(cb, 0x00000000); + } + cb->mode = 0; +} + +void +hwlLock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + LL_HW_LOCK(xl); +} + +void +hwlUnlock(void *xlp, int videoLock) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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(void *xlp, int val, CARD32 timeStamp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->agpSync = val; + xl->agpSyncTimeStamp = timeStamp; +} + +CARD32 +viaDMATimeStampLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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 = VIA_MEM_VIDEO; + if ((ret = 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 = 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 = 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(ViaCommandBuffer * cb, XvMCLowLevel * xl) +{ + int ret; + drm_via_cmdbuffer_t b; + unsigned mode = cb->waitFlags; + + finish_header_agp(cb); + b.buf = (char *)cb->buf; + b.size = cb->pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if (((mode == LL_MODE_VIDEO) && (xl->videoBuf == &xl->agpBuf)) || + ((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; + } + cb->pos = 0; + cb->waitFlags = 0; +} + +static void +agpFlush(ViaCommandBuffer * cb, XvMCLowLevel * xl) +{ + drm_via_cmdbuffer_t b; + int ret; + int i; + + finish_header_agp(cb); + if (xl->use_agp) { + b.buf = (char *)cb->buf; + b.size = cb->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 < cb->pos; i += 2) { + printf("0x%x, 0x%x\n", (unsigned)cb->buf[i], + (unsigned)cb->buf[i + 1]); + } + exit(-1); + } else { + cb->pos = 0; + } + cb->waitFlags &= LL_MODE_VIDEO; /* FIXME: Check this! */ + } else { + unsigned mode = cb->waitFlags; + + b.buf = (char *)cb->buf; + b.size = cb->pos * sizeof(CARD32); + if (xl->performLocking) + hwlLock(xl, 0); + if (((mode == LL_MODE_VIDEO) && (cb == &xl->agpBuf)) || + ((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; + } + cb->pos = 0; + cb->waitFlags = 0; + } +} + +#if 0 /* Needs debugging */ +static void +uploadHQVDeinterlace(XvMCLowLevel * xl, unsigned offset, HQVRegister * shadow, + CARD32 cur_offset, CARD32 prev_offset, CARD32 stride, + Bool top_field_first, CARD32 height) +{ + CARD32 tmp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 9); + tmp = GETHQVSHADOW(shadow, 0x3F8); + tmp &= ~(3 << 30); + tmp |= (1 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, prev_offset + + ((top_field_first) ? stride : 0)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, prev_offset + stride * height); + tmp &= ~(3 << 30); + tmp |= (2 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, cur_offset + + ((top_field_first) ? 0 : stride)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, cur_offset + stride * height); + tmp |= (3 << 30); + OUT_RING_QW_AGP(cb, 0x3F8 + offset, tmp); + OUT_RING_QW_AGP(cb, 0x3D4 + offset, cur_offset + + ((top_field_first) ? stride : 0)); + OUT_RING_QW_AGP(cb, 0x3D8 + offset, cur_offset + stride * height); +} + +#endif + +static void +uploadHQVShadow(XvMCLowLevel * xl, unsigned offset, HQVRegister * shadow, + Bool flip) +{ + int i; + CARD32 tmp; + ViaCommandBuffer *cb = xl->videoBuf; + + BEGIN_HEADER6_DATA(cb, xl, HQV_SHADOW_SIZE); + WAITFLAGS(cb, LL_MODE_VIDEO); + + if (shadow[0].set) + OUT_RING_QW_AGP(cb, 0x3CC + offset, 0); + + for (i = 2; i < HQV_SHADOW_SIZE; ++i) { + if (shadow[i].set) { + OUT_RING_QW_AGP(cb, offset + HQV_SHADOW_BASE + (i << 2), + shadow[i].data); + shadow[i].set = FALSE; + } + } + + /* + * Finally the control register for flip. + */ + + if (flip) { + tmp = GETHQVSHADOW(shadow, 0x3D0); + OUT_RING_QW_AGP(cb, offset + HQV_CONTROL + 0x200, + HQV_ENABLE | HQV_GEN_IRQ | HQV_SUBPIC_FLIP | HQV_SW_FLIP | tmp); + } + shadow[0].set = FALSE; + shadow[1].set = FALSE; +} + +unsigned +flushXvMCLowLevel(void *xlp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pciBuf.pos) + pciFlush(&xl->pciBuf, xl); + if (xl->agpBuf.pos) + agpFlush(&xl->agpBuf, xl); + errors = xl->errors; + if (errors) + printf("Error 0x%x\n", errors); + xl->errors = 0; + return errors; +} + +void +flushPCIXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + if (xl->pciBuf.pos) + pciFlush(&xl->pciBuf, xl); + if ((!xl->use_agp && xl->agpBuf.pos)) + agpFlush(&xl->agpBuf, xl); +} + +void +viaMpegSetSurfaceStride(void *xlp, ViaXvMCContext * ctx) +{ + CARD32 y_stride = ctx->yStride; + CARD32 uv_stride = y_stride >> 1; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 1); + OUT_RING_QW_AGP(cb, 0xc50, (y_stride >> 3) | ((uv_stride >> 3) << 16)); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); +} + +void +viaVideoSetSWFLipLocked(void *xlp, unsigned yOffs, unsigned uOffs, + unsigned vOffs, unsigned yStride, unsigned uvStride) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + initHQVShadow(hqvShadow); + setHQVStartAddress(hqvShadow, yOffs, vOffs, yStride, 0); + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + syncVideo(xl, 1); + uploadHQVShadow(xl, REG_HQV1_INDEX, hqvShadow, FALSE); + xl->videoBuf->flushFunc(xl->videoBuf, xl); +} + +void +viaVideoSWFlipLocked(void *xlp, unsigned flags, Bool progressiveSequence) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + setHQVDeinterlacing(hqvShadow, flags); + setHQVDeblocking(hqvShadow, + ((flags & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE), TRUE); + setHQVTripleBuffer(hqvShadow, TRUE); + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + syncVideo(xl, 1); + uploadHQVShadow(xl, REG_HQV1_INDEX, hqvShadow, TRUE); + xl->videoBuf->flushFunc(xl->videoBuf, xl); +} + +void +viaMpegSetFB(void *xlp, unsigned i, + unsigned yOffs, unsigned uOffs, unsigned vOffs) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + i *= (4 * 2); + BEGIN_HEADER6_DATA(cb, xl, 2); + OUT_RING_QW_AGP(cb, 0xc28 + i, yOffs >> 3); + OUT_RING_QW_AGP(cb, 0xc2c + i, vOffs >> 3); + + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); +} + +void +viaMpegBeginPicture(void *xlp, ViaXvMCContext * ctx, + unsigned width, unsigned height, const XvMCMpegControl * control) +{ + + unsigned j, mb_width, mb_height; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + 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(cb, xl, 72); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(cb, 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(cb, 0xc5c, 0); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 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(cb, 0xc5c, 1); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 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(cb, 0xc5c, 2); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 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(cb, 0xc5c, 3); + for (j = 0; j < 64; j += 4) { + OUT_RING_QW_AGP(cb, 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(cb, 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(cb, 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(cb, 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(void *xlp) +{ + int i, j; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + BEGIN_HEADER6_DATA(cb, xl, 99); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + + OUT_RING_QW_AGP(cb, 0xcf0, 0); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(cb, 0xcc0, 0); + OUT_RING_QW_AGP(cb, 0xc0c, 0x43 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + } + + OUT_RING_QW_AGP(cb, 0xc0c, 0x1c3); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + + for (i = 0; i < 19; i++) + OUT_RING_QW_AGP(cb, 0xc08, 0); + + OUT_RING_QW_AGP(cb, 0xc98, 0x400000); + + for (i = 0; i < 6; i++) { + OUT_RING_QW_AGP(cb, 0xcc0, 0); + OUT_RING_QW_AGP(cb, 0xc0c, 0x1c3 | 0x20); + for (j = 0xc10; j < 0xc20; j += 4) + OUT_RING_QW_AGP(cb, j, 0); + } + OUT_RING_QW_AGP(cb, 0xcf0, 0); + +} + +void +viaMpegWriteSlice(void *xlp, CARD8 * slice, int nBytes, CARD32 sCode) +{ + int i, n, r; + CARD32 *buf; + int count; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + 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(cb, xl, 2); + WAITFLAGS(cb, LL_MODE_DECODER_IDLE); + OUT_RING_QW_AGP(cb, 0xc9c, nBytes); + + if (sCode) + OUT_RING_QW_AGP(cb, 0xca0, sCode); + + i = 0; + count = 0; + + do { + count += (LL_AGP_CMDBUF_SIZE - 20); + count = (count > n) ? n : count; + BEGIN_HEADER5_DATA(cb, xl, (count - i), 0xca0); + + for (; i < count; i++) { + OUT_RING_AGP(cb, *buf++); + } + finish_header_agp(cb); + } while (i < n); + + BEGIN_HEADER5_DATA(cb, xl, 3, 0xca0); + + if (r) { + OUT_RING_AGP(cb, *buf & ((1 << (r << 3)) - 1)); + } + OUT_RING_AGP(cb, 0); + OUT_RING_AGP(cb, 0); + finish_header_agp(cb); +} + +void +viaVideoSubPictureOffLocked(void *xlp) +{ + + CARD32 stride; + int proReg = REG_HQV1_INDEX; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = xl->videoBuf; + + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + stride = VIDIN(xl, proReg | SUBP_CONTROL_STRIDE); + WAITFLAGS(cb, LL_MODE_VIDEO); + BEGIN_HEADER6_DATA(cb, xl, 1); + OUT_RING_QW_AGP(cb, proReg | SUBP_CONTROL_STRIDE | 0x200, + stride & ~SUBP_HQV_ENABLE); +} + +void +viaVideoSubPictureLocked(void *xlp, ViaXvMCSubPicture * pViaSubPic) +{ + + unsigned i; + CARD32 cWord; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + int proReg = REG_HQV1_INDEX; + ViaCommandBuffer *cb = xl->videoBuf; + + if (xl->videoBuf == &xl->agpBuf) + syncDMA(xl, 1); + WAITFLAGS(cb, LL_MODE_VIDEO); + BEGIN_HEADER6_DATA(cb, xl, VIA_SUBPIC_PALETTE_SIZE + 2); + for (i = 0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { + OUT_RING_QW_AGP(cb, proReg | RAM_TABLE_CONTROL | 0x200, + pViaSubPic->palette[i]); + } + + cWord = (pViaSubPic->stride & SUBP_STRIDE_MASK) | SUBP_HQV_ENABLE; + cWord |= (pViaSubPic->ia44) ? SUBP_IA44 : SUBP_AI44; + OUT_RING_QW_AGP(cb, proReg | SUBP_STARTADDR | 0x200, pViaSubPic->offset); + OUT_RING_QW_AGP(cb, proReg | SUBP_CONTROL_STRIDE | 0x200, cWord); +} + +void +viaBlit(void *xlp, 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; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + ViaCommandBuffer *cb = &xl->agpBuf; + + if (!w || !h) + return; + + finish_header_agp(cb); + + 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(cb, xl, 20); + WAITFLAGS(cb, LL_MODE_2D); + + OUT_RING_QW_AGP(cb, 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(cb, H1_ADDR(VIA_REG_SRCCOLORKEY), color); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_KEYCONTROL), 0x4000); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + break; + case VIABLIT_FILL: + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), color); + cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); + break; + default: + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_KEYCONTROL), 0x0); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + } + + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCBASE), (srcBase & ~31) >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), (dstBase & ~31) >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCPOS), ((srcY << 16) | srcX)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((dstY << 16) | dstX)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), cmd); +} + +unsigned +syncXvMCLowLevel(void *xlp, unsigned int mode, unsigned int doSleep, + CARD32 timeStamp) +{ + unsigned errors; + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + 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 ((xl->videoBuf == &xl->agpBuf) || (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; +} + +static int +updateLowLevelBuf(XvMCLowLevel * xl, LowLevelBuffer * buf, + unsigned width, unsigned height) +{ + unsigned stride, size; + drm_via_mem_t *mem = &buf->mem; + int ret; + + stride = (width + 31) & ~31; + size = stride * height + (xl->fbDepth >> 3); + + if (size != mem->size) { + if (mem->size) + drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem)); + mem->context = *(xl->drmcontext); + mem->size = size; + mem->type = VIA_MEM_VIDEO; + + if (((ret = drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, mem, + sizeof(mem))) < 0) || mem->size != size) { + mem->size = 0; + return -1; + } + } + + buf->offset = (mem->offset + 31) & ~31; + buf->stride = stride; + buf->height = height; + return 0; +} + +static void +cleanupLowLevelBuf(XvMCLowLevel * xl, LowLevelBuffer * buf) +{ + drm_via_mem_t *mem = &buf->mem; + + if (mem->size) + drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem)); + mem->size = 0; +} + +static void * +releaseXvMCLowLevel(XvMCLowLevel * xl) +{ + switch (xl->state) { + case ll_llBuf: + cleanupLowLevelBuf(xl, &xl->scale); + case ll_timeStamp: + viaDMACleanupTimeStamp(xl); + case ll_pciBuf: + free(xl->pciBuf.buf); + case ll_agpBuf: + free(xl->agpBuf.buf); + case ll_init: + free(xl); + default: + ; + } + return NULL; +} + +void * +initXvMCLowLevel(int fd, drm_context_t * ctx, + drmLockPtr hwLock, drmAddress mmioAddress, + drmAddress fbAddress, unsigned fbStride, unsigned fbDepth, + unsigned width, unsigned height, int useAgp, unsigned chipId) +{ + XvMCLowLevel *xl; + + if (chipId != PCI_CHIP_VT3259 && chipId != PCI_CHIP_VT3364) { + fprintf(stderr, "You are using an XvMC driver for the wrong chip.\n"); + fprintf(stderr, "Chipid is 0x%04x.\n", chipId); + return NULL; + } + + xl = (XvMCLowLevel *) malloc(sizeof(XvMCLowLevel)); + if (!xl) + return NULL; + xl->state = ll_init; + + xl->agpBuf.buf = (CARD32 *) malloc(LL_AGP_CMDBUF_SIZE * sizeof(CARD32)); + if (!xl->agpBuf.buf) + return releaseXvMCLowLevel(xl); + xl->state = ll_agpBuf; + xl->agpBuf.bufSize = LL_AGP_CMDBUF_SIZE; + xl->agpBuf.flushFunc = &agpFlush; + xl->agpBuf.pos = 0; + xl->agpBuf.mode = 0; + xl->agpBuf.waitFlags = 0; + + xl->pciBuf.buf = (CARD32 *) malloc(LL_PCI_CMDBUF_SIZE * sizeof(CARD32)); + if (!xl->pciBuf.buf) + return releaseXvMCLowLevel(xl); + xl->state = ll_pciBuf; + xl->pciBuf.bufSize = LL_PCI_CMDBUF_SIZE; + xl->pciBuf.flushFunc = &pciFlush; + xl->pciBuf.pos = 0; + xl->pciBuf.mode = 0; + xl->pciBuf.waitFlags = 0; + + xl->use_agp = useAgp; + xl->fd = fd; + xl->drmcontext = ctx; + xl->hwLock = hwLock; + xl->mmioAddress = mmioAddress; + xl->fbAddress = fbAddress; + xl->fbDepth = fbDepth; + xl->fbStride = fbStride; + xl->width = width; + xl->height = height; + xl->performLocking = 1; + xl->errors = 0; + xl->agpSync = 0; + xl->chipId = chipId; + + if (viaDMAInitTimeStamp(xl)) + return releaseXvMCLowLevel(xl); + xl->state = ll_timeStamp; + + xl->scale.mem.size = 0; + xl->back.mem.size = 0; + + if (updateLowLevelBuf(xl, &xl->scale, width, height)) + return releaseXvMCLowLevel(xl); + xl->state = ll_llBuf; + +#ifdef VIDEO_DMA + xl->videoBuf = &xl->agpBuf; +#else + xl->videoBuf = &xl->pciBuf; +#endif + + return xl; +} + +void +setLowLevelLocking(void *xlp, int performLocking) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + xl->performLocking = performLocking; +} + +void +closeXvMCLowLevel(void *xlp) +{ + XvMCLowLevel *xl = (XvMCLowLevel *) xlp; + + releaseXvMCLowLevel(xl); +} + +#if 0 /* Under development */ +static CARD32 +computeDownScaling(int dst, int *src) +{ + CARD32 value = 0x800; + + while (*src > dst) { + *src >>= 1; + value--; + } + return value; +} + +static void +computeHQVScaleAndFilter(XvMCLowLevel * xl) +{ + int srcW, srcH; + const XvMCRegion *src = &xl->sRegion, *back = &xl->dRegion; + + xl->downScaling = FALSE; + + if (back->w < src->w || back->h < src->h) { + + xl->downScaling = TRUE; + srcW = src->w; + srcH = src->h; + + xl->downScaleW = (back->w >= srcW) ? 0 : + HQV_SCALE_ENABLE | HQV_SCALE_DOWN | + (computeDownScaling(back->w, &srcW)); + + xl->downScaleH = (back->h >= srcH) ? 0 : + HQV_SCALE_ENABLE | HQV_SCALE_DOWN | + (computeDownScaling(back->h, &srcH)); + + } + + xl->upScaleW = + (back->w == srcW) ? 0 : (0x800 * srcW / back->w) | HQV_SCALE_ENABLE; + xl->upScaleH = + (back->h == srcH) ? 0 : (0x800 * srcH / back->h) | HQV_SCALE_ENABLE; +} + +static int +setupBackBuffer(XvMCLowLevel * xl) +{ + return updateLowLevelBuf(xl, &xl->back, xl->dRegion.w, xl->dRegion.h); +} + +#endif diff --git a/trunk/libxvmc/viaXvMC.c b/trunk/libxvmc/viaXvMC.c new file mode 100644 index 000000000000..bf4692c97c3a --- /dev/null +++ b/trunk/libxvmc/viaXvMC.c @@ -0,0 +1,1947 @@ +/***************************************************************************** + * VIA Unichrome XvMC extension client lib. + * + * Copyright (c) 2004-2005 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. + *Bugfixes by among others Pascal Brisset and Terry Barnaby. + *DRI protocol support by Thomas Hellström, 2005. + */ + +#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 <X11/extensions/Xv.h> +#include <xf86drm.h> +#include <pthread.h> +#include "vldXvMC.h" +#include "xf86dri.h" +#include "driDrawable.h" + +#define SAREAPTR(ctx) ((ViaXvMCSAreaPriv *) \ + (((CARD8 *)(ctx)->sAreaAddress) + \ + (ctx)->sAreaPrivOffset)) + +typedef struct +{ + int major; + int minor; + int patchlevel; +} ViaDRMVersion; + +static int error_base; +static int event_base; +static unsigned numContexts = 0; +static int globalFD; +static drmAddress sAreaAddress; +static drmAddress fbAddress; +static drmAddress mmioAddress; +static const ViaDRMVersion drmExpected = { 2, 0, 0 }; +static const ViaDRMVersion drmCompat = { 2, 0, 0 }; + +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') + +#define ppthread_mutex_lock(arg) \ + { \ + pthread_mutex_lock(arg); \ + } \ + +#define ppthread_mutex_unlock(arg) \ + { \ + pthread_mutex_unlock(arg); \ + } \ + +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_drawHash: + driDestroyHashContents(pViaXvMC->drawHash); + drmHashDestroy(pViaXvMC->drawHash); + case context_lowLevel: + closeXvMCLowLevel(pViaXvMC->xl); + case context_mutex: + pthread_mutex_destroy(&pViaXvMC->ctxMutex); + case context_drmContext: + XLockDisplay(display); + uniDRIDestroyContext(display, pViaXvMC->screen, pViaXvMC->id); + XUnlockDisplay(display); + case context_sAreaMap: + numContexts--; + if (numContexts == 0) + drmUnmap(pViaXvMC->sAreaAddress, pViaXvMC->sAreaSize); + case context_fbMap: + if (numContexts == 0) + drmUnmap(pViaXvMC->fbAddress, pViaXvMC->fbSize); + case context_mmioMap: + if (numContexts == 0) + drmUnmap(pViaXvMC->mmioAddress, pViaXvMC->mmioSize); + case context_fd: + if (numContexts == 0) { + if (pViaXvMC->fd >= 0) + drmClose(pViaXvMC->fd); + } + pViaXvMC->fd = -1; + case context_driConnection: + if (numContexts == 0) { + XLockDisplay(display); + uniDRICloseConnection(display, pViaXvMC->screen); + XUnlockDisplay(display); + } + case context_context: + XLockDisplay(display); + _xvmc_destroy_context(display, context); + XUnlockDisplay(display); + if (!freePrivate) + break; + default: + free(pViaXvMC); + context->privData = NULL; + } + 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; + int isCapable; + + /* + * 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 */ + + 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); + + /* + * Check size and version of returned data. + */ + + tmpComm = (ViaXvMCCreateContextRec *) priv_data; + if (priv_count != (sizeof(ViaXvMCCreateContextRec) >> 2)) { + fprintf(stderr, "_xvmc_create_context() returned incorrect " + "data size!\n"); + fprintf(stderr, "\tExpected %d, got %d\n", + ((int)(sizeof(ViaXvMCCreateContextRec) >> 2)), priv_count); + XFree(priv_data); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_context; + + if ((tmpComm->major != VIAXVMC_MAJOR) || + (tmpComm->minor != VIAXVMC_MINOR)) { + fprintf(stderr, "Version mismatch between the X via driver\n" + "and the XvMC library. Cannot continue!\n"); + XFree(priv_data); + return releaseContextResources(display, context, 1, BadAlloc); + } + + pViaXvMC->ctxNo = tmpComm->ctxNo; + pViaXvMC->fbOffset = tmpComm->fbOffset; + pViaXvMC->fbSize = tmpComm->fbSize; + pViaXvMC->mmioOffset = tmpComm->mmioOffset; + pViaXvMC->mmioSize = tmpComm->mmioSize; + pViaXvMC->sAreaSize = tmpComm->sAreaSize; + pViaXvMC->sAreaPrivOffset = tmpComm->sAreaPrivOffset; + pViaXvMC->decoderOn = 0; + pViaXvMC->xvMCPort = tmpComm->xvmc_port; + pViaXvMC->useAGP = tmpComm->useAGP; + pViaXvMC->attrib = tmpComm->initAttrs; + pViaXvMC->screen = tmpComm->screen; + pViaXvMC->depth = tmpComm->depth; + pViaXvMC->stride = tmpComm->stride; + pViaXvMC->chipId = tmpComm->chipId; + + /* + * Must free the private data we were passed from X + */ + + XFree(priv_data); + priv_data = NULL; + + /* + * Check for direct rendering capable, establish DRI and DRM connections, + * map framebuffer, DRI shared area and read-only register areas. + * Initial checking for drm has already been done by the server. + * Only do this for the first context we create. + */ + + if (numContexts == 0) { + XLockDisplay(display); + ret = + uniDRIQueryDirectRenderingCapable(display, pViaXvMC->screen, + &isCapable); + if (!ret || !isCapable) { + XUnlockDisplay(display); + fprintf(stderr, + "Direct Rendering is not available on this system!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + if (!uniDRIOpenConnection(display, pViaXvMC->screen, + &pViaXvMC->sAreaOffset, &curBusID)) { + XUnlockDisplay(display); + fprintf(stderr, "Could not open DRI connection to X server!\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + strncpy(pViaXvMC->busIdString, curBusID, 20); + pViaXvMC->busIdString[20] = '\0'; + XFree(curBusID); + + pViaXvMC->resources = context_driConnection; + + if ((pViaXvMC->fd = drmOpen("via", pViaXvMC->busIdString)) < 0) { + fprintf(stderr, "DRM Device for via could not be opened.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + globalFD = pViaXvMC->fd; + 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 < drmExpected.major) || + (drmVer->version_major > drmCompat.major) || + ((drmVer->version_major == drmExpected.major) && + (drmVer->version_minor < drmExpected.minor))) { + fprintf(stderr, + "viaXvMC: Kernel drm is not compatible with XvMC.\n"); + fprintf(stderr, + "viaXvMC: Kernel drm version: %d.%d.%d " + "and I can work with versions %d.%d.x - %d.x.x\n" + "Please update either this XvMC driver or your kernel DRM.\n", + drmVer->version_major, drmVer->version_minor, + drmVer->version_patchlevel, drmExpected.major, + drmExpected.minor, drmCompat.major); + drmFreeVersion(drmVer); + return releaseContextResources(display, context, 1, BadAlloc); + } + drmFreeVersion(drmVer); + drmGetMagic(pViaXvMC->fd, &magic); + + XLockDisplay(display); + if (!uniDRIAuthConnection(display, pViaXvMC->screen, magic)) { + XUnlockDisplay(display); + fprintf(stderr, + "viaXvMC: X server did not allow DRI. Check permissions.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + XUnlockDisplay(display); + + /* + * Map the register memory + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->mmioOffset, + pViaXvMC->mmioSize, &mmioAddress) < 0) { + fprintf(stderr, + "Unable to map the display chip mmio registers.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->mmioAddress = mmioAddress; + pViaXvMC->resources = context_mmioMap; + + /* + * Map Framebuffer memory + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->fbOffset, + pViaXvMC->fbSize, &fbAddress) < 0) { + fprintf(stderr, "Unable to map XvMC Framebuffer.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->fbAddress = fbAddress; + pViaXvMC->resources = context_fbMap; + + /* + * Map DRI Sarea. + */ + + if (drmMap(pViaXvMC->fd, pViaXvMC->sAreaOffset, + pViaXvMC->sAreaSize, &sAreaAddress) < 0) { + fprintf(stderr, "Unable to map DRI SAREA.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + } else { + pViaXvMC->fd = globalFD; + pViaXvMC->mmioAddress = mmioAddress; + pViaXvMC->fbAddress = fbAddress; + } + + pViaXvMC->sAreaAddress = sAreaAddress; + pViaXvMC->resources = context_sAreaMap; + numContexts++; + + /* + * Find a matching visual. Important only for direct drawing to the visible + * frame-buffer. + */ + + XLockDisplay(display); + ret = XMatchVisualInfo(display, pViaXvMC->screen, + (pViaXvMC->depth == 32) ? 24 : pViaXvMC->depth, TrueColor, + &pViaXvMC->visualInfo); + XUnlockDisplay(display); + if (!ret) { + fprintf(stderr, + "viaXvMC: Could not find a matching TrueColor visual.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + if (!uniDRICreateContext(display, pViaXvMC->screen, + pViaXvMC->visualInfo.visual, &pViaXvMC->id, + &pViaXvMC->drmcontext)) { + + fprintf(stderr, "viaXvMC: Could not create DRI context.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + + pViaXvMC->resources = context_drmContext; + + for (i = 0; i < VIA_MAX_RENDSURF; ++i) { + pViaXvMC->rendSurf[i] = 0; + } + pViaXvMC->lastSrfDisplaying = ~0; + setupAttribDesc(display, port, &pViaXvMC->attrib, pViaXvMC->attribDesc); + + 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; + setRegion(0, 0, -1, -1, pViaXvMC->sRegion); + setRegion(0, 0, -1, -1, pViaXvMC->dRegion); + + if (NULL == (pViaXvMC->xl = + initXvMCLowLevel(pViaXvMC->fd, &pViaXvMC->drmcontext, + pViaXvMC->hwLock, pViaXvMC->mmioAddress, + pViaXvMC->fbAddress, pViaXvMC->stride, pViaXvMC->depth, + context->width, context->height, + 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); + + if (NULL == (pViaXvMC->drawHash = drmHashCreate())) { + fprintf(stderr, "ViaXvMC: Could not allocate drawable hash table.\n"); + return releaseContextResources(display, context, 1, BadAlloc); + } + pViaXvMC->resources = context_drawHash; + + if (numContexts == 1) { + hwlLock(pViaXvMC->xl, 1); + setLowLevelLocking(pViaXvMC->xl, 0); + viaVideoSubPictureOffLocked(pViaXvMC->xl); + flushXvMCLowLevel(pViaXvMC->xl); + 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; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + if (pViaXvMC == NULL) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return (error_base + XvMCBadContext); + } + + pViaSurface = surface->privData = + (ViaXvMCSurface *) malloc(sizeof(ViaXvMCSurface)); + if (!surface->privData) { + ppthread_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"); + ppthread_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; + ppthread_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); + } + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (!pViaXvMC->haveDecoder) { + fprintf(stderr, "XvMCPutSlice: This context does not own decoder!\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + + viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *) slice, nBytes, sCode); + + flushPCIXvMCLowLevel(pViaXvMC->xl); + ppthread_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); + } + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + + if (!pViaXvMC->haveDecoder) { + fprintf(stderr, "XvMCPutSlice: This context does not own decoder!\n"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAlloc; + } + + viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *) slice, nBytes, 0); + flushPCIXvMCLowLevel(pViaXvMC->xl); + ppthread_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; + drawableInfo *drawInfo; + XvMCRegion sReg, dReg; + Bool forceUpdate = FALSE; + + 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); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + pViaSubPic = pViaSurface->privSubPic; + sAPriv = SAREAPTR(pViaXvMC); + + setRegion(srcx, srcy, srcw, srch, sReg); + setRegion(destx, desty, destw, desth, dReg); + + if ((!regionEqual(sReg, pViaXvMC->sRegion)) || + (!regionEqual(dReg, pViaXvMC->dRegion))) { + + /* + * Force update of the video overlay to match the new format. + */ + + pViaXvMC->sRegion = sReg; + pViaXvMC->dRegion = dReg; + forceUpdate = TRUE; + } + + hwlLock(pViaXvMC->xl, 1); + + if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, + pViaXvMC->screen, draw, 0, pViaXvMC->fd, pViaXvMC->drmcontext, + pViaXvMC->sAreaAddress, FALSE, &drawInfo, sizeof(*drawInfo))) { + + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAccess; + } + + setLowLevelLocking(pViaXvMC->xl, 0); + + /* + * 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), pViaSurface->yStride, + pViaSurface->yStride >> 1); + + while ((lastSurface != dispSurface) || forceUpdate) { + + forceUpdate = FALSE; + flushPCIXvMCLowLevel(pViaXvMC->xl); + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + /* + * We weren't the last to display. Update the overlay before flipping. + */ + + ret = + updateXVOverlay(display, pViaXvMC, pViaSurface, draw, srcx, srcy, + srcw, srch, destx, desty, destw, desth); + if (ret) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + + hwlLock(pViaXvMC->xl, 1); + + if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, + pViaXvMC->screen, draw, 0, pViaXvMC->fd, pViaXvMC->drmcontext, + pViaXvMC->sAreaAddress, FALSE, &drawInfo, + sizeof(*drawInfo))) { + + hwlUnlock(pViaXvMC->xl, 1); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadAccess; + } + + setLowLevelLocking(pViaXvMC->xl, 0); + lastSurface = pViaSurface->srfNo | VIA_XVMC_VALID; + dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; + overlayUpdated = 1; + } + + /* + * 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); + flushXvMCLowLevel(pViaXvMC->xl); + + setLowLevelLocking(pViaXvMC->xl, 1); + hwlUnlock(pViaXvMC->xl, 1); + + if (overlayUpdated || !drawInfo->touched) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + /* + * Update overlay + */ + + ret = + updateXVOverlay(display, pViaXvMC, pViaSurface, draw, srcx, srcy, + srcw, srch, destx, desty, destw, desth); + ppthread_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; + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (grabDecoder(pViaXvMC, &hadDecoderLast)) { + ppthread_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); + ppthread_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->topFieldFirst = (control->flags & XVMC_TOP_FIELD_FIRST); + 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; + ppthread_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); + } + + ppthread_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; + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + if (syncXvMCLowLevel(pViaXvMC->xl, syncMode, 1, + pViaSurface->timeStamp)) { + ppthread_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; + } + } + + ppthread_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); + } + + ppthread_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; + } + ppthread_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; + } + + ppthread_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"); + ppthread_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); + ppthread_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; + ppthread_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); + ppthread_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; + ppthread_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)) { + ppthread_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)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + ppthread_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; + + ppthread_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)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + if (findOverlap(image->width, image->height, + &srcx, &srcy, &dstx, &dsty, &width, &height)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; + } + + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, 0, + pViaSubPic->timeStamp)) { + ppthread_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); + } + + ppthread_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; + } + + ppthread_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); + if (pViaXvMC->chipId != PCI_CHIP_VT3259) { + + /* + * YV12 Chroma blit. + */ + + 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); + } else { + + /* + * NV12 Chroma blit. + */ + + viaBlit(pViaXvMC->xl, 8, vOffs(pViaSSurface), pViaSSurface->yStride, + vOffs(pViaSurface), pViaSurface->yStride, + width, height >> 1, 1, 1, VIABLIT_COPY, 0); + } + pViaSurface->needsSync = 1; + pViaSurface->syncMode = LL_MODE_2D; + pViaSurface->timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); + if (flushXvMCLowLevel(pViaXvMC->xl)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + if (subpicture) { + + if (NULL == (pViaSubPic = subpicture->privData)) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return (error_base + XvMCBadSubpicture); + } + + pViaSurface->privSubPic = pViaSubPic; + } else { + pViaSurface->privSubPic = NULL; + } + ppthread_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; + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (pViaSubPic->needsSync) { + if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, + 0, pViaSubPic->timeStamp)) { + retVal = BadValue; + } + pViaSubPic->needsSync = 0; + } + ppthread_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; + ppthread_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; + ppthread_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; + ppthread_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); + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + 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; + ppthread_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; + } + } + ppthread_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; + } + + ppthread_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; + } + ppthread_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); + } + + ppthread_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) { + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return BadValue; + } + pViaXvMC->attrib.attributes[i].value = value; + found = 1; + pViaXvMC->attribChanged = 1; + break; + } + } + if (!found) { + ppthread_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); + } + ppthread_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); + } + + ppthread_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; + } + } + } + ppthread_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); + } + + ppthread_mutex_lock(&pViaXvMC->ctxMutex); + if (!pViaXvMC->haveXv) { + ppthread_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); + ppthread_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"); + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return ret; + } + ppthread_mutex_unlock(&pViaXvMC->ctxMutex); + return Success; +} diff --git a/trunk/libxvmc/viaXvMCPriv.h b/trunk/libxvmc/viaXvMCPriv.h new file mode 100644 index 000000000000..2b8e63e88a0d --- /dev/null +++ b/trunk/libxvmc/viaXvMCPriv.h @@ -0,0 +1,197 @@ +/***************************************************************************** + * 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 <X11/extensions/XvMC.h> +#include <X11/extensions/XvMClib.h> +#include <stdlib.h> +#include <X11/Xutil.h> +#include "vldXvMC.h" +#include "via_xvmc.h" + +typedef struct +{ + int x; + int y; + int w; + int h; +} XvMCRegion; + +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_drawHash, + context_lowLevel, + context_mutex, + context_sAreaMap, + context_fbMap, + context_mmioMap, + context_drmContext, + context_fd, + context_driConnection, + context_context, + 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 */ + void *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; + CARD32 videoTimeStamp; + XID id; + unsigned screen; + unsigned depth; + unsigned stride; + XVisualInfo visualInfo; + void *drawHash; + CARD32 chipId; + XvMCRegion sRegion; + XvMCRegion dRegion; +} 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; + int topFieldFirst; +} 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 + */ + +#define VIABLIT_TRANSCOPY 0 +#define VIABLIT_COPY 1 +#define VIABLIT_FILL 2 + +#endif diff --git a/trunk/libxvmc/vldXvMC.h b/trunk/libxvmc/vldXvMC.h new file mode 100644 index 000000000000..3b9ceff93bf0 --- /dev/null +++ b/trunk/libxvmc/vldXvMC.h @@ -0,0 +1,178 @@ +/***************************************************************************** + * 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/trunk/libxvmc/xf86dri.c b/trunk/libxvmc/xf86dri.c new file mode 100644 index 000000000000..1feb23297de6 --- /dev/null +++ b/trunk/libxvmc/xf86dri.c @@ -0,0 +1,599 @@ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define uniDRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display * dpy, XExtCodes * extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static +XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info, + xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL) + + static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info) + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ +#if 0 +#include <stdio.h> +#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg); +#else +#define TRACE(msg) +#endif + Bool uniDRIQueryExtension(dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display(dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +Bool +uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display *dpy; + int *majorVersion; + int *minorVersion; + int *patchVersion; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +Bool +uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display *dpy; + int screen; + Bool *isCapable; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +Bool +uniDRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display *dpy; + int screen; + drm_handle_t *hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32; + } +#endif + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +Bool +uniDRIAuthConnection(dpy, screen, magic) + Display *dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +Bool +uniDRICloseConnection(dpy, screen) + Display *dpy; + int screen; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +Bool +uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display *dpy; + int screen; + int *ddxDriverMajorVersion; + int *ddxDriverMinorVersion; + int *ddxDriverPatchVersion; + char **clientDriverName; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = + (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +Bool +uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext) + Display *dpy; + int screen; + int configID; + XID *context; + drm_context_t *hHWContext; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +Bool +uniDRICreateContext(dpy, screen, visual, context, hHWContext) + Display *dpy; + int screen; + Visual *visual; + XID *context; + drm_context_t *hHWContext; +{ + return uniDRICreateContextWithConfig(dpy, screen, visual->visualid, + context, hHWContext); +} + +Bool +uniDRIDestroyContext(Display * ndpy, int screen, XID context) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +Bool +uniDRICreateDrawable(Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +Bool +uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +Bool +uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char *)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char *)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +Bool +uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display *dpy; + int screen; + drm_handle_t *hFrameBuffer; + int *fbOrigin; + int *fbSize; + int *fbStride; + int *devPrivateSize; + void **pDevPrivate; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32; + } +#endif + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} diff --git a/trunk/libxvmc/xf86dri.h b/trunk/libxvmc/xf86dri.h new file mode 100644 index 000000000000..34197874fefb --- /dev/null +++ b/trunk/libxvmc/xf86dri.h @@ -0,0 +1,116 @@ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin <martin@valinux.com> + * \author Jens Owen <jens@tungstengraphics.com> + * \author Rickard E. (Rik) Faith <faith@valinux.com> + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include <X11/Xfuncproto.h> +#include <xf86drm.h> + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + Bool uniDRIQueryExtension(Display * dpy, int *event_base, + int *error_base); + +Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, + int *patchVersion); + +Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen, + Bool * isCapable); + +Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, + char **busIDString); + +Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic); + +Bool uniDRICloseConnection(Display * dpy, int screen); + +Bool uniDRIGetClientDriverName(Display * dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName); + +Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id); + +extern Bool uniDRICreateDrawable(Display * dpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable); + +extern Bool uniDRIDestroyDrawable(Display * dpy, int screen, + Drawable drawable); + +Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects); + +Bool uniDRIGetDeviceInfo(Display * dpy, int screen, + drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate); + +_XFUNCPROTOEND +#endif /* _XF86DRI_SERVER_ */ +#endif /* _XF86DRI_H_ */ diff --git a/trunk/libxvmc/xf86dristr.h b/trunk/libxvmc/xf86dristr.h new file mode 100644 index 000000000000..3b43438e7f70 --- /dev/null +++ b/trunk/libxvmc/xf86dristr.h @@ -0,0 +1,390 @@ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Fiath <faith@valinux.com> + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; + +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; + +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; + +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; + +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; + +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; + +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; + +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; + +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; + +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; + +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; + +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; + +#define sz_xXF86DRICreateContextReq 16 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; + +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; + +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; + +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; + +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; + +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; + +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + +typedef struct _XF86DRIGetDeviceInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; + +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; + +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; + +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; + +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; + +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; + +#define sz_xXF86DRICloseFullScreenReply 32 + +#endif /* _XF86DRISTR_H_ */ diff --git a/trunk/man/Makefile.am b/trunk/man/Makefile.am new file mode 100644 index 000000000000..a16c38724c76 --- /dev/null +++ b/trunk/man/Makefile.am @@ -0,0 +1,62 @@ +# $Id: Makefile.am,v 1.4 2005/10/18 00:01:55 alanc Exp $ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# 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 OPEN GROUP 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. +# +# Except as contained in this notice, the name of the copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +drivermandir = $(mandir)/man$(DRIVER_MAN_SUFFIX) + +driverman_MANFILES = @DRIVER_NAME@.man + +driverman_DATA = $(driverman_MANFILES:man=@DRIVER_MAN_SUFFIX@) + +EXTRA_DIST = @DRIVER_NAME@.man + +CLEANFILES = $(driverman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man + +.man.$(DRIVER_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ + +@DRIVER_NAME@.man: + ln -s -f $(top_srcdir)/src/@DRIVER_NAME@.man . diff --git a/trunk/prepare-ChangeLogSVN.pl b/trunk/prepare-ChangeLogSVN.pl new file mode 100755 index 000000000000..d913dc344725 --- /dev/null +++ b/trunk/prepare-ChangeLogSVN.pl @@ -0,0 +1,603 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 2 -*- + +# Perl script to create a ChangeLog entry with names of files +# and functions from a svn diff. +# +# Darin Adler <darin@bentspoon.com>, started 20 April 2000 +# Java support added by Maciej Stachowiak <mjs@eazel.com> +# Adapted for subversion by Thomas Hellstrom <unichrome-at-shipmail-dot-org> +# last updated 11 May 2005 +# +# (Someone put a license in here, like maybe GPL.) +# +# TODO: +# For new files, just say "New file" instead of listing +# function names. +# List functions that have been removed too. +# Decide what a good logical order is for the changed files +# other than a normal text "sort" (top level first?) +# (group directories?) (.h before .c?) +# Leave a diff file behind if asked, but in unified format. +# Handle C++ and yacc source files too (other languages?). +# Help merge when there are ChangeLog conflicts or if there's +# already a partly written ChangeLog entry. +# Add command line option to put the ChangeLog into a separate +# file or just spew it out stdout. +# Figure out how to allow -z options from .cvsrc to work without +# letting other bad options work. Currently the -f disables +# everything from the .cvsrc. +# Add CVS version numbers for each file too (can't do that until +# the changes are checked in, though). +# Work around diff stupidity where deleting a function that starts +# with a comment makes diff think that the following function +# has been changed (if the following function starts with a comment +# with the same first line, such as /**) +# Work around diff stupidity where deleting an entire function and +# the blank lines before it makes diff think you've changed the +# previous function. + +use diagnostics; +use strict; + +use English; +use Text::Wrap; + +# For each file, build a list of modified lines. +# Use line numbers from the "after" side of each diff. +print STDERR " Running svn diff to find changes.\n"; +my %changed_line_ranges; +my $file; +open DIFF, "svn diff --diff-cmd diff -x -N |" or die "The svn diff failed: $OS_ERROR.\n"; +while (<DIFF>) + { + $file = $1 if /^Index: (\S+)$/; + if (defined $file + and $file ne "ChangeLog" + and (/^\d+(,\d+)?[acd](\d+)(,(\d+))?/ or /^Binary files/) ) + { + push @{$changed_line_ranges{$file}}, [ $2, $4 || $2 ]; + } + } +close DIFF; +if (!%changed_line_ranges) + { + print STDERR " No changes found.\n"; + exit; + } + +# For each ".c" file, convert line range to function list. +print STDERR " Extracting affected function names from C source files.\n"; +my %function_lists; +foreach my $file (keys %changed_line_ranges) + { + # An empty function list still indicates that something changed. + $function_lists{$file} = ""; + + # Only look for function names in .c files. + next unless $file =~ /\.(c|java)/; + + # Find all the functions in the file. + open SOURCE, $file or next; + my @function_ranges = get_function_line_ranges(\*SOURCE, $file); + close SOURCE; + + # Find all the modified functions. + my @functions; + my %saw_function; + my @change_ranges = (@{$changed_line_ranges{$file}}, []); + my @change_range = (0, 0); + FUNCTION: foreach my $function_range_ref (@function_ranges) + { + my @function_range = @$function_range_ref; + + # Advance to successive change ranges. + for (;; @change_range = @{shift @change_ranges}) + { + last FUNCTION unless @change_range; + + # If past this function, move on to the next one. + next FUNCTION if $change_range[0] > $function_range[1]; + + # If an overlap with this function range, record the function name. + if ($change_range[1] >= $function_range[0] + and $change_range[0] <= $function_range[1]) + { + if (!$saw_function{$function_range[2]}) + { + $saw_function{$function_range[2]} = 1; + push @functions, $function_range[2]; + } + next FUNCTION; + } + } + } + + # Format the list of functions now. + $function_lists{$file} = " (" . join("), (", @functions) . "):" if @functions; + } + +# Get some pieces of the ChangeLog we are about to write. +my $date = sprintf "%d-%02d-%02d", + 1900 + (localtime $BASETIME)[5], # year + 1 + (localtime $BASETIME)[4], # month + (localtime $BASETIME)[3]; # day within month +my $name = $ENV{CHANGE_LOG_NAME} + || $ENV{REAL_NAME} + || (getpwuid $REAL_USER_ID)[6] + || "set REAL_NAME environment variable"; +my $email_address = $ENV{CHANGE_LOG_EMAIL_ADDRESS} + || $ENV{EMAIL_ADDRESS} + || "set EMAIL_ADDRESS environment variable"; + +# Find the change logs. +my %has_log; +my %files; +foreach my $file (sort keys %function_lists) + { + my $prefix = $file; + my $has_log = 0; + while ($prefix) + { + $prefix =~ s-/[^/]+/?$-/- or $prefix = ""; + $has_log = $has_log{$prefix}; + if (!defined $has_log) + { + $has_log = -f "${prefix}ChangeLog"; + $has_log{$prefix} = $has_log; + } + last if $has_log; + } + if (!$has_log) + { + print STDERR "No ChangeLog found for $file.\n"; + } + else + { + push @{$files{$prefix}}, $file; + } + } + +# Get the latest ChangeLog files from svn. +my $logs = ""; +foreach my $prefix (sort keys %files) + { + $logs .= " ${prefix}ChangeLog"; + } +if ($logs) + { + print STDERR " Updating ChangeLog files from svn repository.\n"; + open ERRORS, "svn update$logs |" or die "The svn update of ChangeLog files failed: $OS_ERROR.\n"; + print STDERR " $ARG" while <ERRORS>; + close ERRORS; + } + + +# Write out a new ChangeLog file. +foreach my $prefix (sort keys %files) + { + print STDERR " Editing the ${prefix}ChangeLog file.\n"; + open OLD_CHANGE_LOG, "${prefix}ChangeLog" or die "Could not open ${prefix}ChangeLog file: $OS_ERROR.\n"; + # It's less efficient to read the whole thing into memory than it would be + # to read it while we prepend to it later, but I like doing this part first. + my @old_change_log = <OLD_CHANGE_LOG>; + close OLD_CHANGE_LOG; + open CHANGE_LOG, "> ${prefix}ChangeLog" or die "Could not write ${prefix}ChangeLog\n."; + print CHANGE_LOG "$date $name <$email_address>\n\n"; + print CHANGE_LOG "\treviewed by: <delete if not using a buddy>\n\n"; + foreach my $file (sort @{$files{$prefix}}) + { + my $file_stem = substr $file, length $prefix; + my $lines = wrap("\t", "\t", "XX$file_stem:$function_lists{$file}"); + $lines =~ s/^\tXX/\t* /; + print CHANGE_LOG "$lines\n"; + } + print CHANGE_LOG "\n", @old_change_log; + close CHANGE_LOG; + print STDERR " Done editing ${prefix}ChangeLog.\n"; + } + +# Done. +exit; + +sub get_function_line_ranges + { + my ($file_handle, $file_name) = @_; + + if ($file_name =~ /\.c$/) { + return get_function_line_ranges_for_c ($file_handle, $file_name); + } elsif ($file_name =~ /\.java$/) { + return get_function_line_ranges_for_java ($file_handle, $file_name); + } + return (); + } + +# Read a file and get all the line ranges of the things that look like C functions. +# A function name is the last word before an open parenthesis before the outer +# level open brace. A function starts at the first character after the last close +# brace or semicolon before the function name and ends at the close brace. +# Comment handling is simple-minded but will work for all but pathological cases. +# +# Result is a list of triples: [ start_line, end_line, function_name ]. + +sub get_function_line_ranges_for_c + { + my ($file_handle, $file_name) = @_; + + my @ranges; + + my $in_comment = 0; + my $in_macro = 0; + my $in_parentheses = 0; + my $in_braces = 0; + + my $word = ""; + + my $potential_start = 0; + my $potential_name = ""; + + my $start = 0; + my $name = ""; + + while (<$file_handle>) + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match--) + { + warn "mismatched quotes at line $INPUT_LINE_NUMBER in $file_name\n"; + s-$match.*--; + } + } + } + + # Find function names. + while (m-(\w+|[(){};])-g) + { + # Open parenthesis. + if ($1 eq "(") + { + $potential_name = $word unless $in_parentheses; + $in_parentheses++; + next; + } + + # Close parenthesis. + if ($1 eq ")") + { + $in_parentheses--; + next; + } + + # Open brace. + if ($1 eq "{") + { + # Promote potiential name to real function name at the + # start of the outer level set of braces (function body?). + if (!$in_braces and $potential_start) + { + $start = $potential_start; + $name = $potential_name; + } + + $in_braces++; + next; + } + + # Close brace. + if ($1 eq "}") + { + $in_braces--; + + # End of an outer level set of braces. + # This could be a function body. + if (!$in_braces and $name) + { + push @ranges, [ $start, $INPUT_LINE_NUMBER, $name ]; + $name = ""; + } + + $potential_start = 0; + $potential_name = ""; + next; + } + + # Semicolon. + if ($1 eq ";") + { + $potential_start = 0; + $potential_name = ""; + next; + } + + # Word. + $word = $1; + if (!$in_parentheses) + { + $potential_start = 0; + $potential_name = ""; + } + if (!$potential_start) + { + $potential_start = $INPUT_LINE_NUMBER; + $potential_name = ""; + } + } + } + + warn "mismatched braces in $file_name\n" if $in_braces; + warn "mismatched parentheses in $file_name\n" if $in_parentheses; + + return @ranges; + } + + + +# Read a file and get all the line ranges of the things that look like Java +# classes, interfaces and methods. +# +# A class or interface name is the word that immediately follows +# `class' or `interface' when followed by an open curly brace and not +# a semicolon. It can appear at the top level, or inside another class +# or interface block, but not inside a function block +# +# A class or interface starts at the first character after the first close +# brace or after the function name and ends at the close brace. +# +# A function name is the last word before an open parenthesis before +# an open brace rather than a semicolon. It can appear at top level or +# inside a class or interface block, but not inside a function block. +# +# A function starts at the first character after the first close +# brace or after the function name and ends at the close brace. +# +# Comment handling is simple-minded but will work for all but pathological cases. +# +# Result is a list of triples: [ start_line, end_line, function_name ]. + +sub get_function_line_ranges_for_java + { + my ($file_handle, $file_name) = @_; + + my @current_scopes; + + my @ranges; + + my $in_comment = 0; + my $in_macro = 0; + my $in_parentheses = 0; + my $in_braces = 0; + my $in_non_block_braces = 0; + my $class_or_interface_just_seen = 0; + + my $word = ""; + + my $potential_start = 0; + my $potential_name = ""; + my $potential_name_is_class_or_interface = 0; + + my $start = 0; + my $name = ""; + my $current_name_is_class_or_interface = 0; + + while (<$file_handle>) + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match--) + { + warn "mismatched quotes at line $INPUT_LINE_NUMBER in $file_name\n"; + s-$match.*--; + } + } + } + + # Find function names. + while (m-(\w+|[(){};])-g) + { + # Open parenthesis. + if ($1 eq "(") + { + if (!$in_parentheses) { + $potential_name = $word; + $potential_name_is_class_or_interface = 0; + } + $in_parentheses++; + next; + } + + # Close parenthesis. + if ($1 eq ")") + { + $in_parentheses--; + next; + } + + # Open brace. + if ($1 eq "{") + { + # Promote potiential name to real function name at the + # start of the outer level set of braces (function/class/interface body?). + if (!$in_non_block_braces + and (!$in_braces or $current_name_is_class_or_interface) + and $potential_start) + { + if ($name) + { + push @ranges, [ $start, ($INPUT_LINE_NUMBER - 1), + join ('.', @current_scopes) ]; + } + + + $current_name_is_class_or_interface = $potential_name_is_class_or_interface; + + $start = $potential_start; + $name = $potential_name; + + push (@current_scopes, $name); + } else { + $in_non_block_braces++; + } + + $potential_name = ""; + $potential_start = 0; + + $in_braces++; + next; + } + + # Close brace. + if ($1 eq "}") + { + $in_braces--; + + # End of an outer level set of braces. + # This could be a function body. + if (!$in_non_block_braces) + { + if ($name) + { + push @ranges, [ $start, $INPUT_LINE_NUMBER, + join ('.', @current_scopes) ]; + + pop (@current_scopes); + + if (@current_scopes) + { + $current_name_is_class_or_interface = 1; + + $start = $INPUT_LINE_NUMBER + 1; + $name = $current_scopes[$#current_scopes-1]; + } + else + { + $current_name_is_class_or_interface = 0; + $start = 0; + $name = ""; + } + } + } + else + { + $in_non_block_braces-- if $in_non_block_braces; + } + + $potential_start = 0; + $potential_name = ""; + next; + } + + # Semicolon. + if ($1 eq ";") + { + $potential_start = 0; + $potential_name = ""; + next; + } + + if ($1 eq "class" or $1 eq "interface") + { + $class_or_interface_just_seen = 1; + next; + } + + # Word. + $word = $1; + if (!$in_parentheses) + { + if ($class_or_interface_just_seen) { + $potential_name = $word; + $potential_start = $INPUT_LINE_NUMBER; + $class_or_interface_just_seen = 0; + $potential_name_is_class_or_interface = 1; + next; + } + } + if (!$potential_start) + { + $potential_start = $INPUT_LINE_NUMBER; + $potential_name = ""; + } + $class_or_interface_just_seen = 0; + } + } + + warn "mismatched braces in $file_name\n" if $in_braces; + warn "mismatched parentheses in $file_name\n" if $in_parentheses; + + return @ranges; + } diff --git a/trunk/release_notes-0.3.0 b/trunk/release_notes-0.3.0 new file mode 100644 index 000000000000..c50758b4159f --- /dev/null +++ b/trunk/release_notes-0.3.0 @@ -0,0 +1,70 @@ +xf86-video-openchrome-0.3.0 + +This is the first official openchrome driver release. +(http://www.openchrome.org) + +SUPPORTED CHIPSETS : +-------------------- +- CLE266 (VT3122) +- KM400/P4M800 (VT3205) +- K8M800 (VT3204) +- PM800/PM880/CN400 (VT3259) +- VM800/CN700/P4M800Pro (VT3314) +- CX700 (VT3324) +- P4M890 (VT3327) +- K8M890 (VT3336) +- P4M900/VN896 (VT3364) + + +SUPPORTED FEATURES : +-------------------- +- Free modesetting for Unichrome and Unichrome Pro chipset. +- VBE modesetting for everything not natively supported. +- TV-out support. +- EXA acceleration. +- Hardware MPEG2 acceleration. + + +IMPORTANT NOTE : +---------------- +- The driver name is now 'openchrome', and this is what you need to use in + your xorg.conf now (instead of 'via'). The XvMC libraries have also been + renamed, to 'libchromeXvMC.so' and 'libchromeXvMCPro.so'. + + +KNOWN BUGS/LIMITATIONS : +------------------------ +* Laptop panel +- Laptop displays for anything other than CLE266 and KM400/P4M800 are only + supported thru VBE calls. +- Xv is not working on laptop displays for VM800/CN700/P4M800PRO. It is however + working on VGA. +- Virtual terminal is broken on some laptop displays. Use a vesa framebuffer to + work around that (append vga=791 to your kernel command line, for example). + +* XvMC +- The hardware MPEG4 acceleration that is present on some chipsets is not + implemented. +- No XvMC support for CX700 (new, unsupported engine). +- No XvMC support for K8M890, P4M890 and P4M900/VN896 (need to get dri working + for them first). + +* TV output +- TV modes are hardcoded and must be choosen inside a list depending on the TV + encoder. +- Outputs are dependent on each other and will use the least common + denominator. If you're using both VGA/LCD output and TV output, the VGA/LCD + output will be limited by the TV encoder (720x576@50Hz for example). + In other words, there is no dual screen support. + +* Misc. +- Add-on and integrated TMDS encoders are not supported, except thru VBE. + +* Chrome9 +- Chrome9 chipsets' family (P4M900 and K8M890) currently doesn't + support neither AGP DMA nor 3D acceleration. + + +Please note that 3D acceleration is provided by Mesa (http://mesa3d.org) and is +not directly related to openchrome. + diff --git a/trunk/src/Imakefile b/trunk/src/Imakefile new file mode 100644 index 000000000000..e7ca37d0c2b8 --- /dev/null +++ b/trunk/src/Imakefile @@ -0,0 +1,231 @@ +#define IHaveModules +#include <Server.tmpl> + +XCOMM Add a comment into the source if we are building svn code. +all:: svnversion.h + +svnversion.h: + @if [ -f svnrelease.h ]; then \ + echo '#include "svnrelease.h"' > $@.tmp; \ + elif [ -d .svn ]; then \ + echo '#define BUILDCOMMENT "(development build, at svn revision '\ + "`svnversion -nc . | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \ + else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi + + @(chmod 666 $@.tmp 2> /dev/null || /bin/true) + @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@) + +.PHONY: svnversion.h + +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,16,0) +DEFREGIONNULL = -DX_USE_REGION_NULL +#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 +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-core -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 + +#ifdef XF86EXA +EXAINCLUDES = -I$(XF86SRC)/exa +EXADEFINES = -DVIA_HAVE_EXA +#endif + +SRCS = via_driver.c \ + via_3d.c \ + via_accel.c \ + via_bandwidth.c \ + via_ch7xxx.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_3d.o \ + via_accel.o \ + via_bandwidth.o \ + via_ch7xxx.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$(XF86SRC) -I$(SERVERSRC)/render \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \ + -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb \ + -I$(SERVERSRC)/fb $(DRIINCLUDES) $(EXAINCLUDES) +#endif + +DEFINES = $(DRIDEFINES) $(DEFXVPRIV) $(DEFREGIONNULL) \ + $(DEFXAAGETROP) $(DEFI2CSTART) $(DEFXNEEDDRMLOCK) $(EXADEFINES) + +#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_3d.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_3d.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_ch7xxx.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_ch7xxx.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dmabuffer.h,$(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/trunk/src/Makefile.am b/trunk/src/Makefile.am new file mode 100644 index 000000000000..82a8af1bb246 --- /dev/null +++ b/trunk/src/Makefile.am @@ -0,0 +1,99 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on 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 +# ADAM JACKSON 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. + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +EXTRA_DIST = svnversion.h +CONFIG_CLEAN_FILES= svnversion.h +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +openchrome_drv_la_LTLIBRARIES = openchrome_drv.la +openchrome_drv_la_LDFLAGS = -module -avoid-version +openchrome_drv_ladir = @moduledir@/drivers + +openchrome_drv_la_SOURCES = \ + via_3d_reg.h \ + via_3d.c \ + via_3d.h \ + via_accel.c \ + via_bandwidth.c \ + via_bios.h \ + via_ch7xxx.c \ + via_ch7xxx.h \ + via_cursor.c \ + via_dga.c \ + via_dmabuffer.h \ + via_driver.c \ + via_driver.h \ + via.h \ + via_i2c.c \ + via_id.c \ + via_id.h \ + via_memcpy.c \ + via_memcpy.h \ + via_memory.c \ + via_mode.c \ + via_mode.h \ + via_priv.h \ + via_regs.h \ + via_shadow.c \ + via_swov.c \ + via_swov.h \ + via_vbe.c \ + via_vgahw.c \ + via_vgahw.h \ + via_video.c \ + via_video.h \ + via_vt162x.c \ + via_vt162x.h \ + via_xvpriv.h + +if DRI +openchrome_drv_la_SOURCES += \ + via_dri.c \ + via_dri.h \ + via_drmclient.h \ + via_xvmc.c \ + via_xvmc.h + +else +EXTRA_DIST += \ + via_dri.c \ + via_dri.h \ + via_drmclient.h \ + via_xvmc.c \ + via_xvmc.h +endif + +via_driver.lo: svnversion.h +svnversion.h: + @if [ -f svnrelease.h ]; then \ + echo '#include "svnrelease.h"' > $@.tmp; \ + elif [ -d .svn ]; then \ + echo '#define BUILDCOMMENT "(development build, at svn revision '\ + "`svnversion -nc .. | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \ + else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi + + @(chmod 666 $@.tmp 2> /dev/null || /bin/true) + @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@) + +.PHONY: svnversion.h diff --git a/trunk/src/openchrome.man b/trunk/src/openchrome.man new file mode 100644 index 000000000000..8191b53c574a --- /dev/null +++ b/trunk/src/openchrome.man @@ -0,0 +1,234 @@ +.\" Shorthand for double quote that works everywhere, +.\" also within other double quotes: +.ds q \N'34' +.TH OPENCHROME __drivermansuffix__ __vendorversion__ +.SH NAME +openchrome \- video driver for VIA Unichromes +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" string \*q +.B " Driver \*qopenchrome\*q" +\ \ ... +.B EndSection +.fi + +.SH DESCRIPTION +.B openchrome +is an __xservername__ driver for VIA chipsets that have an integrated +Unichrome graphics engine. +.PP +The +.B openchrome +driver supports the following chipsets: CLE266, KM400/KN400, CN400, CN700, +K8M800/K8N800, PM800/PN800, P4M800Pro, VN800, PM880, K8M890/K8N890, +CN896, VN896, and P4M900. +The driver includes 2D acceleration and Xv video overlay extensions. +Flat panel, TV, and VGA outputs are supported, depending on the hardware +configuration. +.PP +3D direct rendering is available using experimental drivers from Mesa +(www.mesa3d.org). There is also an XvMC client library for hardware +acceleration of MPEG1/MPEG2 decoding (not available on the KM/N400) +that uses the Direct Rendering Infrastructure (DRI). +The XvMC client library implements a non-standard +"VLD" extension to the XvMC standard. The current Direct Rendering +Manager (DRM) kernel module is available at dri.sourceforge.net. +.PP +The driver supports free modes for Unichrome Pros (K8M/N800, PM/N800, and +CN400). For plain Unichromes (CLE266, KM/N400), it currently supports +only a limited number of dotclocks, so if you are using X modelines you +must make sure that the dotclock is one of those supported. Supported +dotclocks on plain Unichromes are currently (in MHz): 25.2, 25.312, +26.591, 31.5, 31.704, 32.663, 33.750, 35.5, 36.0, 39.822, 40.0, 41.164, +46.981, 49.5, 50.0, 56.3, 57.284, 64.995, 65.0, 65.028, 74.480, +75.0, 78.8, 81.613, 94.5, 108.0, 108.28, 122.0, 122.726, 135.0, +148.5, 155.8, 157.5, 161.793, 162.0, 175.5, 189.0, 202.5, 204.8, +218.3, 229.5. On top of this, bandwidth restrictions apply for both +Unichromes and Unichrome Pros. +.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 \*qAccelMethod\*q \*q" string \*q +The driver supports "XAA" and "EXA" acceleration methods. The default +method is XAA, since EXA is still experimental. Contrary to XAA, EXA +implements acceleration for screen uploads and downlads (if DRI is +enabled) and for the Render/Composite extension. +.TP +.BI "Option \*qActiveDevice\*q \*q" string \*q +Specifies the active device combination. Any string containing "CRT", +"LCD", "DFP", "TV" should be possible. "CRT" represents anything that +is connected to the VGA port, "LCD" and "DFP" are for laptop panels +(not TFT screens attached to the VGA port), "TV" is self-explanatory. +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 \*qAGPMem\*q \*q" integer \*q +Sets the amount of AGP memory that is allocated at X server startup. +The allocated memory will be "integer" kB. This AGP memory is used for +the AGP command buffer (if option "EnableAGPDMA" is set to "true"), for +DRI textures, and for the EXA scratch area. The driver will allocate at +least one system page of AGP memory and, if the AGP command buffer is +used, at least 2MB + one system page. If there is no room for the EXA +scratch area in AGP space, it will be allocated from VRAM. If there is +no room for DRI textures, they will be allocated from the DRI part of +VRAM (see the option "MaxDRIMem"). The default amount of AGP is +32768kB. Note that the AGP aperture set in the BIOS must be able +to accomodate the amount of AGP memory specified here. Otherwise no +AGP memory will be available. It is safe to set a very large AGP +aperture in the BIOS. +.TP +.BI "Option \*qCenter\*q \*q" boolean \*q +Enables or disables image centering on DVI displays. +.TP +.BI "Option \*qDisableIRQ\*q \*q" boolean \*q +Disables the Vblank IRQ. This is a workaround for some mainboards that +have problems with IRQs from the Unichrome engine. With IRQs disabled, +DRI clients have no way to synchronize drawing to Vblank. (This option +is enabled by default on the KM400 and K8M800 chipsets.) +.TP +.BI "Option \*qDisableVQ\*q \*q" boolean \*q +Disables the use of VQ. VQ is enabled by default. +.TP +.BI "Option \*qEnableAGPDMA\*q \*q" boolean \*q +Enables 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. (This +option is enabled by default on all chipsets except the K8M890 and P4M900.) +.TP +.BI "Option \*qExaNoComposite\*q \*q" boolean \*q +If EXA is enabled (using the option "AccelMethod"), this option enables +or disables acceleration of compositing. Since EXA, and in particular its +composite acceleration, is still experimental, this is a way to disable +a misbehaving composite acceleration. +.TP +.BI "Option \*qExaScratchSize\*q \*q" integer \*q +Sets the size of the EXA scratch area to "integer" kB. This area is +used by EXA as a last place to look for available space for pixmaps. +Too little space will slow compositing down. This option should be set +to the size of the largest pixmap used. If you have a screen width of +over 1024 pixels and use 24 bpp, set this to 8192. Otherwise you can +leave this at the default 4096. The space will be allocated from AGP +memory if available, otherwise from VRAM. +.TP +.BI "Option \*qHWCursor\*q \*q" boolean \*q +Enables or disables the use of hardware cursors. The default is enabled. +.TP +.BI "Option \*qLCDDualEdge\*q \*q" boolean \*q +Enables or disables the use of dual-edge mode to set the LCD. +.TP +.BI "Option \*qMaxDRIMem\*q \*q" integer \*q +Sets the maximum amount of VRAM memory allocated for DRI clients to +"integer" kB. Normally DRI clients get half the available VRAM size, +but in some cases it may make sense to limit this amount. For example, +if you are using a composite manager and you want to give as much memory +as possible to the EXA pixmap storage area. +.TP +.BI "Option \*qMigrationHeuristic\*q \*q" string \*q +Sets the heuristic for EXA pixmap migration. This is an EXA core +option, and on Xorg xserver versions after 1.1.0 this defaults to +"smart". The Openchrome driver performs best with "greedy", so you +should really add this option to your configuration file. The third +possibility is "always", which might become more useful in the future. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disables or enables acceleration. Default: acceleration is enabled. +.TP +.BI "Option \*qNoAGPFor2D\*q \*q" boolean \*q +With this option set, 2D acceleration will not use AGP DMA even if +it is enabled. +.TP +.BI "Option \*qNoXVDMA\*q \*q" boolean \*q +If DRI is enabled, Xv normally uses PCI DMA to transfer video images +from system to frame-buffer memory. This is somewhat slower than +direct copies due to the limitations of the PCI bus, but on the other +hand it decreases CPU usage significantly, particularly on computers +with fast processors. Some video players are buggy and will display +rendering artifacts when PCI DMA is used. If you experience this, +or don't want your PCI bus to be stressed with Xv images, set this +option to "true". This option has no effect when DRI is not enabled. +.TP +.BI "Option \*qPanelSize\*q \*q" string \*q +Specifies the size (width x height) of the LCD panel attached to the +system. The sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050 +are supported. +.TP +.BI "Option \*qRotate\*q \*q" string \*q +Rotates the display either clockwise ("CW") or counterclockwise ("CCW"). +Rotation is only supported unaccelerated. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Uses a shadow frame buffer. This is required when rotating the display, +but otherwise defaults to disabled. +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Enables or disables the use of a software cursor. The default is disabled. +.TP +.BI "Option \*qTVDeflicker\*q \*q" integer \*q +Specifies the deflicker setting for TV output. Valid values are "0", "1", +and "2". 0) No deflicker, 1) 1:1:1 deflicker, 2) 1:2:1 deflicker. +.TP +.BI "Option \*qTVDotCrawl\*q \*q" boolean \*q +Enables or disables dotcrawl. +.TP +.BI "Option \*qTVOutput\*q \*q" string \*q +Specifies which TV output to use. The driver supports "S-Video", +"Composite", "SC", "RGB" and "YCbCr" outputs. Note that on some +EPIA boards the compositer-video port is shared with audio-out and +is selected via a jumper. +.TP +.BI "Option \*qTVType\*q \*q" string \*q +Specifies TV output format. The driver currently supports "NTSC" and +"PAL" timings only. +.TP +.BI "Option \*qVBEModes\*q \*q" boolean \*q +Uses the VBE BIOS calls to set the display mode. This mimics the +behaviour of the vesa video driver but still provides acceleration and +other features. This option may be used if your hardware works with +the vesa driver but not with the Openchrome driver. It may not work +on 64-bit systems. Using "VBEModes" may speed up driver acceleration +significantly due to a more aggressive hardware setting, particularly +on systems with low memory bandwidth. Your refresh rate may be limited +to 60 Hz on some systems. +.TP +.BI "Option \*qVBESaveRestore\*q \*q" boolean \*q +Uses the VBE BIOS calls to save and restore the display state when the +X server is launched. This can be extremely slow on some hardware, and +the system may appear to have locked for 10 seconds or so. The default +is to use the driver builtin function. This option only works if option +"VBEModes" is enabled. +.TP +.BI "Option \*qVideoRAM\*q \*q" integer \*q +Overrides the VideoRAM autodetection. This should never be needed. +.PP +.SH "TV ENCODERS" +Unichromes tend to be paired with several different TV encoders. +.TP +.BI "VIA Technologies VT1621" +Still untested, as no combination with a Unichrome is known or available. +Supports the following normal modes: "640x480" and "800x600". Use +"640x480Over" and "800x600Over" for vertical overscan. These modes +are made available by the driver; modelines provided in __xconfigfile__ +will be ignored. +.TP +.BI "VIA Technologies VT1622, VT1622A, VT1623" +Supports the following modes: "640x480", "800x600", "1024x768", +"848x480", "720x480" (NTSC only) and "720x576" (PAL only). Use +"640x480Over", "800x600Over", "1024x768Over", "848x480Over", +"720x480Over" (NTSC) and "720x576Over" (PAL) for vertical overscan. +The modes "720x480Noscale" (NTSC) and "720x576Noscale" (PAL) (available +on VT1622 only) provide cleaner TV output (unscaled with only minimal +overscan). These modes are made available by the driver; modelines +provided in __xconfigfile__ will be ignored. + +.SH "SEE ALSO" +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) +.SH AUTHORS +Authors include: ... diff --git a/trunk/src/via.h b/trunk/src/via.h new file mode 100644 index 000000000000..9e9c105ac6ae --- /dev/null +++ b/trunk/src/via.h @@ -0,0 +1,667 @@ +/* + * 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 + +#include "xorgVersion.h" + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <stdlib.h> + +/* Video Engines */ +#define VIDEO_ENGINE_UNK 0 /* Unknown video engine */ +#define VIDEO_ENGINE_CLE 1 /* CLE First generaion video engine */ +#define VIDEO_ENGINE_CME 2 /* CME Second generation video engine */ + +/* Video status flag */ + +#define VIDEO_HIDE 0x00000000 /*Video off*/ +#define VIDEO_SHOW 0x80000000 /*Video on*/ +#define VIDEO_ACTIVE 0x10000000 /*Video active*/ +#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 VIDEO_ON 0x00100000 +#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 + +#define PRO_HQV1_OFFSET 0x1000 +/* + * 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 +#define V1_PREFETCH_ON_3336 0x40000000 /*V1_PREFETCH_ON*/ +#define V1_GAMMA_ENABLE_3336 0x20000000 /*V1_Gamma_ENABLE*/ + +/* 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 + +#define VIDEO_FIFO_DEPTH_VT3336 225 +#define VIDEO_FIFO_THRESHOLD_VT3336 200 +#define VIDEO_FIFO_PRETHRESHOLD_VT3336 250 +#define VIDEO_EXPIRE_NUM_VT3336 31 + +/* 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 V3_FIFO_MASK_3314 0x000000FF +#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 +#define HQV_GEN_IRQ 0x00000080 +#define HQV_FIFO_DEPTH_1 0x00010000 + +/* 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 + +#define VBE_DEFAULT_REFRESH 6000 + +#endif /* _VIA_H_ */ diff --git a/trunk/src/via_3d.c b/trunk/src/via_3d.c new file mode 100644 index 000000000000..9ccdaad00856 --- /dev/null +++ b/trunk/src/via_3d.c @@ -0,0 +1,592 @@ +/* + * Copyright 2006 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_3d.h" +#include "via_3d_reg.h" +#include <picturestr.h> + +typedef struct +{ + Bool supported; + CARD32 col0; + CARD32 col1; + CARD32 al0; + CARD32 al1; +} ViaCompositeOperator; + +typedef struct +{ + CARD32 pictFormat; + Bool dstSupported; + Bool texSupported; + CARD32 dstFormat; + CARD32 texFormat; +} Via3DFormat; + +static ViaCompositeOperator viaOperatorModes[256]; +static Via3DFormat via3DFormats[256]; + +#define VIA_NUM_3D_OPCODES 19 +#define VIA_NUM_3D_FORMATS 15 +#define VIA_FMT_HASH(arg) (((((arg) >> 1) + (arg)) >> 8) & 0xFF) + +static const CARD32 viaOpCodes[VIA_NUM_3D_OPCODES][5] = { + {PictOpClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpDst, 0x05, 0x55, 0x40, 0x90}, + {PictOpOver, 0x15, 0x52, 0x50, 0x91}, + {PictOpOverReverse, 0x13, 0x45, 0x52, 0x90}, + {PictOpIn, 0x03, 0x45, 0x42, 0x80}, + {PictOpInReverse, 0x05, 0x42, 0x40, 0x81}, + {PictOpOut, 0x13, 0x45, 0x52, 0x80}, + {PictOpOutReverse, 0x05, 0x52, 0x40, 0x91}, + {PictOpAtop, 0x03, 0x52, 0x42, 0x91}, + {PictOpAtopReverse, 0x13, 0x42, 0x52, 0x81}, + {PictOpXor, 0x15, 0x52, 0x52, 0x91}, + {PictOpAdd, 0x15, 0x55, 0x50, 0x90}, + {PictOpDisjointClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpDisjointSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpDisjointDst, 0x05, 0x55, 0x40, 0x90}, + {PictOpConjointClear, 0x05, 0x45, 0x40, 0x80}, + {PictOpConjointSrc, 0x15, 0x45, 0x50, 0x80}, + {PictOpConjointDst, 0x05, 0x55, 0x40, 0x90} +}; + +static const CARD32 viaFormats[VIA_NUM_3D_FORMATS][5] = { + {PICT_x1r5g5b5, HC_HDBFM_RGB555, HC_HTXnFM_RGB555, 1, 1}, + {PICT_r5g6b5, HC_HDBFM_RGB565, HC_HTXnFM_RGB565, 1, 1}, + {PICT_a4r4g4b4, HC_HDBFM_ARGB4444, HC_HTXnFM_ARGB4444, 1, 1}, + {PICT_a1r5g5b5, HC_HDBFM_ARGB1555, HC_HTXnFM_ARGB1555, 1, 1}, + {PICT_x1b5g5r5, HC_HDBFM_BGR555, HC_HTXnFM_BGR555, 1, 1}, + {PICT_b5g6r5, HC_HDBFM_BGR565, HC_HTXnFM_BGR565, 1, 1}, + {PICT_a4b4g4r4, HC_HDBFM_ABGR4444, HC_HTXnFM_ABGR4444, 1, 1}, + {PICT_a1b5g5r5, HC_HDBFM_ABGR1555, HC_HTXnFM_ABGR1555, 1, 1}, + {PICT_x8r8g8b8, HC_HDBFM_ARGB0888, HC_HTXnFM_ARGB0888, 1, 1}, + {PICT_a8r8g8b8, HC_HDBFM_ARGB8888, HC_HTXnFM_ARGB8888, 1, 1}, + {PICT_x8b8g8r8, HC_HDBFM_ABGR0888, HC_HTXnFM_ABGR0888, 1, 1}, + {PICT_a8b8g8r8, HC_HDBFM_ABGR8888, HC_HTXnFM_ABGR8888, 1, 1}, + {PICT_a8, 0x00, HC_HTXnFM_A8, 0, 1}, + {PICT_a4, 0x00, HC_HTXnFM_A4, 0, 1}, + {PICT_a1, 0x00, HC_HTXnFM_A1, 0, 1} +}; + +static CARD32 +via3DDstFormat(int format) +{ + return via3DFormats[VIA_FMT_HASH(format)].dstFormat; +} + +static CARD32 +via3DTexFormat(int format) +{ + return via3DFormats[VIA_FMT_HASH(format)].texFormat; +} + +static Bool +via3DDstSupported(int format) +{ + Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); + + if (fm->pictFormat != format) + return FALSE; + return fm->dstSupported; +} + +static Bool +via3DTexSupported(int format) +{ + Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); + + if (fm->pictFormat != format) + return FALSE; + return fm->texSupported; +} + +static void +viaSet3DDestination(Via3DState * v3d, CARD32 offset, CARD32 pitch, int format) +{ + v3d->drawingDirty = TRUE; /* Affects planemask format. */ + v3d->destDirty = TRUE; + v3d->destOffset = offset; + v3d->destPitch = pitch; + v3d->destFormat = via3DDstFormat(format); + v3d->destDepth = (v3d->destFormat < HC_HDBFM_ARGB0888) ? 16 : 32; +} + +static void +viaSet3DDrawing(Via3DState * v3d, int rop, + CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha) +{ + v3d->drawingDirty = TRUE; + v3d->rop = rop; + v3d->planeMask = planeMask; + v3d->solidColor = solidColor; + v3d->solidAlpha = solidAlpha; +} + +static void +viaSet3DFlags(Via3DState * v3d, int numTextures, + Bool writeAlpha, Bool writeColor, Bool blend) +{ + v3d->enableDirty = TRUE; + v3d->blendDirty = TRUE; + v3d->numTextures = numTextures; + v3d->writeAlpha = writeAlpha; + v3d->writeColor = writeColor; + v3d->blend = blend; +} + +static Bool +viaOrder(CARD32 val, CARD32 * shift) +{ + *shift = 0; + + while (val > (1 << *shift)) + (*shift)++; + return (val == (1 << *shift)); +} + +static Bool +viaSet3DTexture(Via3DState * v3d, int tex, CARD32 offset, + CARD32 pitch, Bool npot, CARD32 width, CARD32 height, int format, + ViaTextureModes sMode, ViaTextureModes tMode, + ViaTexBlendingModes blendingMode, Bool agpTexture) +{ + ViaTextureUnit *vTex = v3d->tex + tex; + + vTex->textureLevel0Offset = offset; + vTex->npot = npot; + if (!viaOrder(pitch, &vTex->textureLevel0Exp) && !vTex->npot) + return FALSE; + vTex->textureLevel0Pitch = pitch; + if (!viaOrder(width, &vTex->textureLevel0WExp)) + return FALSE; + if (!viaOrder(height, &vTex->textureLevel0HExp)) + return FALSE; + + if (pitch <= 4) { + ErrorF("Warning! texture pitch is leq 4\n"); + } + + vTex->textureFormat = via3DTexFormat(format); + + switch (blendingMode) { + case via_src: + vTex->texCsat = (0x01 << 23) | (0x10 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x0B << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + vTex->texRCa = 0x00000000; + vTex->texRAa = 0x00000000; + vTex->texBColDirty = TRUE; + break; + case via_src_onepix_mask: + vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + break; + case via_src_onepix_comp_mask: + vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; + vTex->texAsat = + (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) | + 0x03; + break; + case via_mask: + vTex->texCsat = (0x01 << 23) | (0x07 << 14) | (0x04 << 7) | 0x00; + vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; + break; + case via_comp_mask: + vTex->texCsat = (0x01 << 23) | (0x03 << 14) | (0x04 << 7) | 0x00; + vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; + break; + default: + return FALSE; + } + + vTex->textureDirty = TRUE; + vTex->textureModesS = sMode - via_single; + vTex->textureModesT = tMode - via_single; + + vTex->agpTexture = agpTexture; + return TRUE; +} + +static void +viaSet3DTexBlendCol(Via3DState * v3d, int tex, Bool component, CARD32 color) +{ + CARD32 alpha; + ViaTextureUnit *vTex = v3d->tex + tex; + + vTex->texRAa = (color >> 8) & 0x00FF0000; + if (component) { + vTex->texRCa = (color & 0x00FFFFFF); + } else { + alpha = color >> 24; + vTex->texRCa = alpha | (alpha << 8) | (alpha << 16) | (alpha << 24); + } + vTex->texBColDirty = TRUE; +} + +/* + * Check if compositing operator is supported and return corresponding register setting. + */ + +static void +viaSet3DCompositeOperator(Via3DState * v3d, CARD8 op) +{ + ViaCompositeOperator *vOp = viaOperatorModes + op; + + v3d->blendDirty = TRUE; + if (v3d && vOp->supported) { + v3d->blendCol0 = vOp->col0 << 4; + v3d->blendCol1 = vOp->col1 << 2; + v3d->blendAl0 = vOp->al0 << 4; + v3d->blendAl1 = vOp->al1 << 2; + } +} + +static Bool +via3DOpSupported(CARD8 op) +{ + return viaOperatorModes[op].supported; +} + +static void +via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY, + int src0X, int src0Y, int src1X, int src1Y, int w, int h) +{ + CARD32 acmd; + float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf; + double scalex, scaley; + int i, numTex; + ViaTextureUnit *vTex; + + numTex = v3d->numTextures; + dx1 = dstX; + dx2 = dstX + w; + dy1 = dstY; + dy2 = dstY + h; + + if (numTex) { + sx1[0] = src0X; + sx1[1] = src1X; + sy1[0] = src0Y; + sy1[1] = src1Y; + for (i = 0; i < numTex; ++i) { + vTex = v3d->tex + i; + scalex = 1. / (double)((1 << vTex->textureLevel0WExp)); + scaley = 1. / (double)((1 << vTex->textureLevel0HExp)); + sx2[i] = sx1[i] + w; + sy2[i] = sy1[i] + h; + sx1[i] *= scalex; + sy1[i] *= scaley; + sx2[i] *= scalex; + sy2[i] *= scaley; + } + } + + wf = 0.05; + + /* + * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate + * is needed for AGP DMA, and the W coordinate is for some obscure + * reason needed for texture mapping to be done correctly. So emit + * a w value after the x and y coordinates. + */ + + BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6); + acmd = ((1 << 14) | (1 << 13) | (1 << 11)); + if (numTex) + acmd |= ((1 << 7) | (1 << 8)); + OUT_RING_SubA(0xEC, acmd); + + acmd = 2 << 16; + OUT_RING_SubA(0xEE, acmd); + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + + OUT_RING(*((CARD32 *) (&dx1))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx1 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy1))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy1 + i))); + } + + OUT_RING(*((CARD32 *) (&dx2))); + OUT_RING(*((CARD32 *) (&dy2))); + OUT_RING(*((CARD32 *) (&wf))); + for (i = 0; i < numTex; ++i) { + OUT_RING(*((CARD32 *) (sx2 + i))); + OUT_RING(*((CARD32 *) (sy2 + i))); + } + OUT_RING_SubA(0xEE, + acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); + OUT_RING_SubA(0xEE, + acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); + + ADVANCE_RING; +} + +static void +via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload) +{ + int i; + Bool saveHas3dState; + ViaTextureUnit *vTex; + + /* + * Destination buffer location, format and pitch. + */ + + if (forceUpload || v3d->destDirty) { + v3d->destDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 3); + + OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF); + OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24); + OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat | + (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local); + } + + if (forceUpload || v3d->blendDirty) { + v3d->blendDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 6); + OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00); + OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00); + OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0); + OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1); + OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0); + OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1); + } + + if (forceUpload || v3d->drawingDirty) { + + CARD32 planeMaskLo, planeMaskHi; + + v3d->drawingDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 4); + + /* + * Raster operation and Planemask. + */ + + if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) { + planeMaskLo = (v3d->planeMask & 0x000000FF) << 16; + planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8; + } else { + planeMaskLo = v3d->planeMask & 0x00FFFFFF; + planeMaskHi = v3d->planeMask >> 24; + } + + OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi); + OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo); + + /* + * Solid shading color and alpha. Pixel center at + * floating coordinates (X.5,Y.5). + */ + + OUT_RING_SubA(HC_SubA_HSolidCL, + (v3d->solidColor & 0x00FFFFFF) | (0 << 23)); + OUT_RING_SubA(HC_SubA_HPixGC, + ((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23) | (v3d-> + solidAlpha & 0xFF)); + } + + if (forceUpload || v3d->enableDirty) { + v3d->enableDirty = FALSE; + BEGIN_H2(HC_ParaType_NotTex, 1); + + OUT_RING_SubA(HC_SubA_HEnable, + ((v3d->writeColor) ? HC_HenCW_MASK : 0) | + ((v3d->blend) ? HC_HenABL_MASK : 0) | + ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) | + ((v3d->writeAlpha) ? HC_HenAW_MASK : 0)); + + if (v3d->numTextures) { + BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2); + OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | + (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1); + OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | + (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0); + } + } + + for (i = 0; i < v3d->numTextures; ++i) { + vTex = v3d->tex + i; + + if (forceUpload || vTex->textureDirty) { + vTex->textureDirty = FALSE; + + BEGIN_H2((HC_ParaType_Tex | + (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), + 13); + + OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat | + (vTex->agpTexture ? HC_HTXnLoc_AGP : HC_HTXnLoc_Local))); + OUT_RING_SubA(HC_SubA_HTXnL0BasL, + vTex->textureLevel0Offset & 0x00FFFFFF); + OUT_RING_SubA(HC_SubA_HTXnL012BasH, + vTex->textureLevel0Offset >> 24); + if (vTex->npot) { + OUT_RING_SubA(HC_SubA_HTXnL0Pit, + (vTex->textureLevel0Pitch & HC_HTXnLnPit_MASK) | + HC_HTXnEnPit_MASK); + } else { + OUT_RING_SubA(HC_SubA_HTXnL0Pit, + vTex->textureLevel0Exp << HC_HTXnLnPitE_SHIFT); + } + OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp); + OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp); + OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00); + OUT_RING_SubA(HC_SubA_HTXnTB, 0x00); + OUT_RING_SubA(HC_SubA_HTXnMPMD, + (((unsigned)vTex->textureModesT) << 19) | (((unsigned)vTex-> + textureModesS) << 16)); + + OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat); + OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) | + (0x00 << 14) | (0x02 << 11) | + (0x00 << 7) | (0x03 << 3) | 0x02); + OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat); + OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00); + } + } + + for (i = 0; i < v3d->numTextures; ++i) { + vTex = v3d->tex + i; + + if (forceUpload || vTex->texBColDirty) { + saveHas3dState = cb->has3dState; + vTex->texBColDirty = FALSE; + BEGIN_H2((HC_ParaType_Tex | + (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), + 2); + OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa); + OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa); + cb->has3dState = saveHas3dState; + } + } +} + +/* + * Cliprect. Considered not important for the DRM 3D State, so restore the + * has3dState flag afterwards. + */ + +static void +via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y, + int w, int h) +{ + Bool saveHas3dState; + + saveHas3dState = cb->has3dState; + BEGIN_H2(HC_ParaType_NotTex, 4); + OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h)); + OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w)); + cb->has3dState = saveHas3dState; +} + +void +viaInit3DState(Via3DState * v3d) +{ + ViaCompositeOperator *op; + int i; + CARD32 tmp, hash; + Via3DFormat *format; + + v3d->setDestination = viaSet3DDestination; + v3d->setDrawing = viaSet3DDrawing; + v3d->setFlags = viaSet3DFlags; + v3d->setTexture = viaSet3DTexture; + v3d->setTexBlendCol = viaSet3DTexBlendCol; + v3d->opSupported = via3DOpSupported; + v3d->setCompositeOperator = viaSet3DCompositeOperator; + v3d->emitQuad = via3DEmitQuad; + v3d->emitState = via3DEmitState; + v3d->emitClipRect = via3DEmitClipRect; + v3d->dstSupported = via3DDstSupported; + v3d->texSupported = via3DTexSupported; + + for (i = 0; i < 256; ++i) { + viaOperatorModes[i].supported = FALSE; + } + + for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) { + op = viaOperatorModes + viaOpCodes[i][0]; + op->supported = TRUE; + op->col0 = viaOpCodes[i][1]; + op->col1 = viaOpCodes[i][2]; + op->al0 = viaOpCodes[i][3]; + op->al1 = viaOpCodes[i][4]; + } + + for (i = 0; i < 256; ++i) { + via3DFormats[i].pictFormat = 0x00; + } + for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) { + tmp = viaFormats[i][0]; + hash = VIA_FMT_HASH(tmp); + format = via3DFormats + hash; + if (format->pictFormat) { + ErrorF("BUG: Bad hash function\n"); + } + format->pictFormat = tmp; + format->dstSupported = (viaFormats[i][3] != 0x00); + format->texSupported = (viaFormats[i][4] != 0x00); + format->dstFormat = viaFormats[i][1]; + format->texFormat = viaFormats[i][2]; + } +} diff --git a/trunk/src/via_3d.h b/trunk/src/via_3d.h new file mode 100644 index 000000000000..c33228e321ae --- /dev/null +++ b/trunk/src/via_3d.h @@ -0,0 +1,121 @@ +/* + * Copyright 2006 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_3D_H +#define VIA_3D_H + +#include "xf86.h" +#include "via_dmabuffer.h" + +#define VIA_NUM_TEXUNITS 2 + +typedef enum +{ + via_single, + via_clamp, + via_repeat, + via_mirror, + via_warp +} ViaTextureModes; + +typedef enum +{ + via_src, + via_src_onepix_mask, + via_src_onepix_comp_mask, + via_mask, + via_comp_mask +} ViaTexBlendingModes; + +typedef struct _ViaTextureUnit +{ + CARD32 textureLevel0Offset; + CARD32 textureLevel0Pitch; + CARD32 textureLevel0Exp; + CARD32 textureLevel0WExp; + CARD32 textureLevel0HExp; + CARD32 textureFormat; + CARD32 textureModesT; + CARD32 textureModesS; + CARD32 texCsat; + CARD32 texRCa; + CARD32 texAsat; + CARD32 texRAa; + Bool agpTexture; + Bool textureDirty; + Bool texBColDirty; + Bool npot; +} ViaTextureUnit; + +typedef struct _Via3DState +{ + Bool destDirty; + Bool blendDirty; + Bool enableDirty; + Bool drawingDirty; + CARD32 rop; + CARD32 planeMask; + CARD32 solidColor; + CARD32 solidAlpha; + CARD32 destOffset; + CARD32 destPitch; + CARD32 destFormat; + int destDepth; + int numTextures; + Bool blend; + CARD32 blendCol0; + CARD32 blendCol1; + CARD32 blendAl0; + CARD32 blendAl1; + Bool writeAlpha; + Bool writeColor; + Bool useDestAlpha; + ViaTextureUnit tex[VIA_NUM_TEXUNITS]; + void (*setDestination) (struct _Via3DState * v3d, CARD32 offset, + CARD32 pitch, int format); + void (*setDrawing) (struct _Via3DState * v3d, int rop, + CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha); + void (*setFlags) (struct _Via3DState * v3d, int numTextures, + Bool writeAlpha, Bool writeColor, Bool blend); + Bool(*setTexture) (struct _Via3DState * v3d, int tex, CARD32 offset, + CARD32 pitch, Bool nPot, CARD32 width, CARD32 height, int format, + ViaTextureModes sMode, ViaTextureModes tMode, + ViaTexBlendingModes blendingMode, Bool agpTexture); + void (*setTexBlendCol) (struct _Via3DState * v3d, int tex, Bool component, + CARD32 color); + void (*setCompositeOperator) (struct _Via3DState * v3d, CARD8 op); + Bool(*opSupported) (CARD8 op); + void (*emitQuad) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + int dstX, int dstY, int src0X, int src0Y, int src1X, int src1Y, int w, + int h); + void (*emitState) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + Bool forceUpload); + void (*emitClipRect) (struct _Via3DState * v3d, ViaCommandBuffer * cb, + int x, int y, int w, int h); + Bool(*dstSupported) (int format); + Bool(*texSupported) (int format); +} Via3DState; + +void viaInit3DState(Via3DState * v3d); + +#endif diff --git a/trunk/src/via_3d_reg.h b/trunk/src/via_3d_reg.h new file mode 100644 index 000000000000..cf61bb514db1 --- /dev/null +++ b/trunk/src/via_3d_reg.h @@ -0,0 +1,1651 @@ +/* + * 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 + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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_3D_REG_H +#define VIA_3D_REG_H +#define HC_REG_BASE 0x0400 + +#define HC_REG_TRANS_SPACE 0x0040 + +#define HC_ParaN_MASK 0xffffffff +#define HC_Para_MASK 0x00ffffff +#define HC_SubA_MASK 0xff000000 +#define HC_SubA_SHIFT 24 +/* Transmission Setting + */ +#define HC_REG_TRANS_SET 0x003c +#define HC_ParaSubType_MASK 0xff000000 +#define HC_ParaType_MASK 0x00ff0000 +#define HC_ParaOS_MASK 0x0000ff00 +#define HC_ParaAdr_MASK 0x000000ff +#define HC_ParaSubType_SHIFT 24 +#define HC_ParaType_SHIFT 16 +#define HC_ParaOS_SHIFT 8 +#define HC_ParaAdr_SHIFT 0 + +#define HC_ParaType_CmdVdata 0x0000 +#define HC_ParaType_NotTex 0x0001 +#define HC_ParaType_Tex 0x0002 +#define HC_ParaType_Palette 0x0003 +#define HC_ParaType_PreCR 0x0010 +#define HC_ParaType_Auto 0x00fe + +/* Transmission Space + */ +#define HC_REG_Hpara0 0x0040 +#define HC_REG_HpataAF 0x02fc + +/* Read + */ +#define HC_REG_HREngSt 0x0000 +#define HC_REG_HRFIFOempty 0x0004 +#define HC_REG_HRFIFOfull 0x0008 +#define HC_REG_HRErr 0x000c +#define HC_REG_FIFOstatus 0x0010 +/* HC_REG_HREngSt 0x0000 + */ +#define HC_HDASZC_MASK 0x00010000 +#define HC_HSGEMI_MASK 0x0000f000 +#define HC_HLGEMISt_MASK 0x00000f00 +#define HC_HCRSt_MASK 0x00000080 +#define HC_HSE0St_MASK 0x00000040 +#define HC_HSE1St_MASK 0x00000020 +#define HC_HPESt_MASK 0x00000010 +#define HC_HXESt_MASK 0x00000008 +#define HC_HBESt_MASK 0x00000004 +#define HC_HE2St_MASK 0x00000002 +#define HC_HE3St_MASK 0x00000001 +/* HC_REG_HRFIFOempty 0x0004 + */ +#define HC_HRZDempty_MASK 0x00000010 +#define HC_HRTXAempty_MASK 0x00000008 +#define HC_HRTXDempty_MASK 0x00000004 +#define HC_HWZDempty_MASK 0x00000002 +#define HC_HWCDempty_MASK 0x00000001 +/* HC_REG_HRFIFOfull 0x0008 + */ +#define HC_HRZDfull_MASK 0x00000010 +#define HC_HRTXAfull_MASK 0x00000008 +#define HC_HRTXDfull_MASK 0x00000004 +#define HC_HWZDfull_MASK 0x00000002 +#define HC_HWCDfull_MASK 0x00000001 +/* HC_REG_HRErr 0x000c + */ +#define HC_HAGPCMErr_MASK 0x80000000 +#define HC_HAGPCMErrC_MASK 0x70000000 +/* HC_REG_FIFOstatus 0x0010 + */ +#define HC_HRFIFOATall_MASK 0x80000000 +#define HC_HRFIFOATbusy_MASK 0x40000000 +#define HC_HRATFGMDo_MASK 0x00000100 +#define HC_HRATFGMDi_MASK 0x00000080 +#define HC_HRATFRZD_MASK 0x00000040 +#define HC_HRATFRTXA_MASK 0x00000020 +#define HC_HRATFRTXD_MASK 0x00000010 +#define HC_HRATFWZD_MASK 0x00000008 +#define HC_HRATFWCD_MASK 0x00000004 +#define HC_HRATTXTAG_MASK 0x00000002 +#define HC_HRATTXCH_MASK 0x00000001 + +/* AGP Command Setting + */ +#define HC_SubA_HAGPBstL 0x0060 +#define HC_SubA_HAGPBendL 0x0061 +#define HC_SubA_HAGPCMNT 0x0062 +#define HC_SubA_HAGPBpL 0x0063 +#define HC_SubA_HAGPBpH 0x0064 +/* HC_SubA_HAGPCMNT 0x0062 + */ +#define HC_HAGPCMNT_MASK 0x00800000 +#define HC_HCmdErrClr_MASK 0x00400000 +#define HC_HAGPBendH_MASK 0x0000ff00 +#define HC_HAGPBstH_MASK 0x000000ff +#define HC_HAGPBendH_SHIFT 8 +#define HC_HAGPBstH_SHIFT 0 +/* HC_SubA_HAGPBpL 0x0063 + */ +#define HC_HAGPBpL_MASK 0x00fffffc +#define HC_HAGPBpID_MASK 0x00000003 +#define HC_HAGPBpID_PAUSE 0x00000000 +#define HC_HAGPBpID_JUMP 0x00000001 +#define HC_HAGPBpID_STOP 0x00000002 +/* HC_SubA_HAGPBpH 0x0064 + */ +#define HC_HAGPBpH_MASK 0x00ffffff + +/* Miscellaneous Settings + */ +#define HC_SubA_HClipTB 0x0070 +#define HC_SubA_HClipLR 0x0071 +#define HC_SubA_HFPClipTL 0x0072 +#define HC_SubA_HFPClipBL 0x0073 +#define HC_SubA_HFPClipLL 0x0074 +#define HC_SubA_HFPClipRL 0x0075 +#define HC_SubA_HFPClipTBH 0x0076 +#define HC_SubA_HFPClipLRH 0x0077 +#define HC_SubA_HLP 0x0078 +#define HC_SubA_HLPRF 0x0079 +#define HC_SubA_HSolidCL 0x007a +#define HC_SubA_HPixGC 0x007b +#define HC_SubA_HSPXYOS 0x007c +#define HC_SubA_HVertexCNT 0x007d + +#define HC_HClipT_MASK 0x00fff000 +#define HC_HClipT_SHIFT 12 +#define HC_HClipB_MASK 0x00000fff +#define HC_HClipB_SHIFT 0 +#define HC_HClipL_MASK 0x00fff000 +#define HC_HClipL_SHIFT 12 +#define HC_HClipR_MASK 0x00000fff +#define HC_HClipR_SHIFT 0 +#define HC_HFPClipBH_MASK 0x0000ff00 +#define HC_HFPClipBH_SHIFT 8 +#define HC_HFPClipTH_MASK 0x000000ff +#define HC_HFPClipTH_SHIFT 0 +#define HC_HFPClipRH_MASK 0x0000ff00 +#define HC_HFPClipRH_SHIFT 8 +#define HC_HFPClipLH_MASK 0x000000ff +#define HC_HFPClipLH_SHIFT 0 +#define HC_HSolidCH_MASK 0x000000ff +#define HC_HPixGC_MASK 0x00800000 +#define HC_HSPXOS_MASK 0x00fff000 +#define HC_HSPXOS_SHIFT 12 +#define HC_HSPYOS_MASK 0x00000fff + +/* Command + * Command A + */ +#define HC_HCmdHeader_MASK 0xfe000000 /*0xffe00000 */ +#define HC_HE3Fire_MASK 0x00100000 +#define HC_HPMType_MASK 0x000f0000 +#define HC_HEFlag_MASK 0x0000e000 +#define HC_HShading_MASK 0x00001c00 +#define HC_HPMValidN_MASK 0x00000200 +#define HC_HPLEND_MASK 0x00000100 +#define HC_HVCycle_MASK 0x000000ff +#define HC_HVCycle_Style_MASK 0x000000c0 +#define HC_HVCycle_ChgA_MASK 0x00000030 +#define HC_HVCycle_ChgB_MASK 0x0000000c +#define HC_HVCycle_ChgC_MASK 0x00000003 +#define HC_HPMType_Point 0x00000000 +#define HC_HPMType_Line 0x00010000 +#define HC_HPMType_Tri 0x00020000 +#define HC_HPMType_TriWF 0x00040000 +#define HC_HEFlag_NoAA 0x00000000 +#define HC_HEFlag_ab 0x00008000 +#define HC_HEFlag_bc 0x00004000 +#define HC_HEFlag_ca 0x00002000 +#define HC_HShading_Solid 0x00000000 +#define HC_HShading_FlatA 0x00000400 +#define HC_HShading_FlatB 0x00000800 +#define HC_HShading_FlatC 0x00000c00 +#define HC_HShading_Gouraud 0x00001000 +#define HC_HVCycle_Full 0x00000000 +#define HC_HVCycle_AFP 0x00000040 +#define HC_HVCycle_One 0x000000c0 +#define HC_HVCycle_NewA 0x00000000 +#define HC_HVCycle_AA 0x00000010 +#define HC_HVCycle_AB 0x00000020 +#define HC_HVCycle_AC 0x00000030 +#define HC_HVCycle_NewB 0x00000000 +#define HC_HVCycle_BA 0x00000004 +#define HC_HVCycle_BB 0x00000008 +#define HC_HVCycle_BC 0x0000000c +#define HC_HVCycle_NewC 0x00000000 +#define HC_HVCycle_CA 0x00000001 +#define HC_HVCycle_CB 0x00000002 +#define HC_HVCycle_CC 0x00000003 + +/* Command B + */ +#define HC_HLPrst_MASK 0x00010000 +#define HC_HLLastP_MASK 0x00008000 +#define HC_HVPMSK_MASK 0x00007f80 +#define HC_HBFace_MASK 0x00000040 +#define HC_H2nd1VT_MASK 0x0000003f +#define HC_HVPMSK_X 0x00004000 +#define HC_HVPMSK_Y 0x00002000 +#define HC_HVPMSK_Z 0x00001000 +#define HC_HVPMSK_W 0x00000800 +#define HC_HVPMSK_Cd 0x00000400 +#define HC_HVPMSK_Cs 0x00000200 +#define HC_HVPMSK_S 0x00000100 +#define HC_HVPMSK_T 0x00000080 + +/* Enable Setting + */ +#define HC_SubA_HEnable 0x0000 +#define HC_HenTXEnvMap_MASK 0x00200000 +#define HC_HenVertexCNT_MASK 0x00100000 +#define HC_HenCPUDAZ_MASK 0x00080000 +#define HC_HenDASZWC_MASK 0x00040000 +#define HC_HenFBCull_MASK 0x00020000 +#define HC_HenCW_MASK 0x00010000 +#define HC_HenAA_MASK 0x00008000 +#define HC_HenST_MASK 0x00004000 +#define HC_HenZT_MASK 0x00002000 +#define HC_HenZW_MASK 0x00001000 +#define HC_HenAT_MASK 0x00000800 +#define HC_HenAW_MASK 0x00000400 +#define HC_HenSP_MASK 0x00000200 +#define HC_HenLP_MASK 0x00000100 +#define HC_HenTXCH_MASK 0x00000080 +#define HC_HenTXMP_MASK 0x00000040 +#define HC_HenTXPP_MASK 0x00000020 +#define HC_HenTXTR_MASK 0x00000010 +#define HC_HenCS_MASK 0x00000008 +#define HC_HenFOG_MASK 0x00000004 +#define HC_HenABL_MASK 0x00000002 +#define HC_HenDT_MASK 0x00000001 + +/* Z Setting + */ +#define HC_SubA_HZWBBasL 0x0010 +#define HC_SubA_HZWBBasH 0x0011 +#define HC_SubA_HZWBType 0x0012 +#define HC_SubA_HZBiasL 0x0013 +#define HC_SubA_HZWBend 0x0014 +#define HC_SubA_HZWTMD 0x0015 +#define HC_SubA_HZWCDL 0x0016 +#define HC_SubA_HZWCTAGnum 0x0017 +#define HC_SubA_HZCYNum 0x0018 +#define HC_SubA_HZWCFire 0x0019 +/* HC_SubA_HZWBType + */ +#define HC_HZWBType_MASK 0x00800000 +#define HC_HZBiasedWB_MASK 0x00400000 +#define HC_HZONEasFF_MASK 0x00200000 +#define HC_HZOONEasFF_MASK 0x00100000 +#define HC_HZWBFM_MASK 0x00030000 +#define HC_HZWBLoc_MASK 0x0000c000 +#define HC_HZWBPit_MASK 0x00003fff +#define HC_HZWBFM_16 0x00000000 +#define HC_HZWBFM_32 0x00020000 +#define HC_HZWBFM_24 0x00030000 +#define HC_HZWBLoc_Local 0x00000000 +#define HC_HZWBLoc_SyS 0x00004000 +/* HC_SubA_HZWBend + */ +#define HC_HZWBend_MASK 0x00ffe000 +#define HC_HZBiasH_MASK 0x000000ff +#define HC_HZWBend_SHIFT 10 +/* HC_SubA_HZWTMD + */ +#define HC_HZWTMD_MASK 0x00070000 +#define HC_HEBEBias_MASK 0x00007f00 +#define HC_HZNF_MASK 0x000000ff +#define HC_HZWTMD_NeverPass 0x00000000 +#define HC_HZWTMD_LT 0x00010000 +#define HC_HZWTMD_EQ 0x00020000 +#define HC_HZWTMD_LE 0x00030000 +#define HC_HZWTMD_GT 0x00040000 +#define HC_HZWTMD_NE 0x00050000 +#define HC_HZWTMD_GE 0x00060000 +#define HC_HZWTMD_AllPass 0x00070000 +#define HC_HEBEBias_SHIFT 8 +/* HC_SubA_HZWCDL 0x0016 + */ +#define HC_HZWCDL_MASK 0x00ffffff +/* HC_SubA_HZWCTAGnum 0x0017 + */ +#define HC_HZWCTAGnum_MASK 0x00ff0000 +#define HC_HZWCTAGnum_SHIFT 16 +#define HC_HZWCDH_MASK 0x000000ff +#define HC_HZWCDH_SHIFT 0 +/* HC_SubA_HZCYNum 0x0018 + */ +#define HC_HZCYNum_MASK 0x00030000 +#define HC_HZCYNum_SHIFT 16 +#define HC_HZWCQWnum_MASK 0x00003fff +#define HC_HZWCQWnum_SHIFT 0 +/* HC_SubA_HZWCFire 0x0019 + */ +#define HC_ZWCFire_MASK 0x00010000 +#define HC_HZWCQWnumLast_MASK 0x00003fff +#define HC_HZWCQWnumLast_SHIFT 0 + +/* Stencil Setting + */ +#define HC_SubA_HSTREF 0x0023 +#define HC_SubA_HSTMD 0x0024 +/* HC_SubA_HSBFM + */ +#define HC_HSBFM_MASK 0x00030000 +#define HC_HSBLoc_MASK 0x0000c000 +#define HC_HSBPit_MASK 0x00003fff +/* HC_SubA_HSTREF + */ +#define HC_HSTREF_MASK 0x00ff0000 +#define HC_HSTOPMSK_MASK 0x0000ff00 +#define HC_HSTBMSK_MASK 0x000000ff +#define HC_HSTREF_SHIFT 16 +#define HC_HSTOPMSK_SHIFT 8 +/* HC_SubA_HSTMD + */ +#define HC_HSTMD_MASK 0x00070000 +#define HC_HSTOPSF_MASK 0x000001c0 +#define HC_HSTOPSPZF_MASK 0x00000038 +#define HC_HSTOPSPZP_MASK 0x00000007 +#define HC_HSTMD_NeverPass 0x00000000 +#define HC_HSTMD_LT 0x00010000 +#define HC_HSTMD_EQ 0x00020000 +#define HC_HSTMD_LE 0x00030000 +#define HC_HSTMD_GT 0x00040000 +#define HC_HSTMD_NE 0x00050000 +#define HC_HSTMD_GE 0x00060000 +#define HC_HSTMD_AllPass 0x00070000 +#define HC_HSTOPSF_KEEP 0x00000000 +#define HC_HSTOPSF_ZERO 0x00000040 +#define HC_HSTOPSF_REPLACE 0x00000080 +#define HC_HSTOPSF_INCRSAT 0x000000c0 +#define HC_HSTOPSF_DECRSAT 0x00000100 +#define HC_HSTOPSF_INVERT 0x00000140 +#define HC_HSTOPSF_INCR 0x00000180 +#define HC_HSTOPSF_DECR 0x000001c0 +#define HC_HSTOPSPZF_KEEP 0x00000000 +#define HC_HSTOPSPZF_ZERO 0x00000008 +#define HC_HSTOPSPZF_REPLACE 0x00000010 +#define HC_HSTOPSPZF_INCRSAT 0x00000018 +#define HC_HSTOPSPZF_DECRSAT 0x00000020 +#define HC_HSTOPSPZF_INVERT 0x00000028 +#define HC_HSTOPSPZF_INCR 0x00000030 +#define HC_HSTOPSPZF_DECR 0x00000038 +#define HC_HSTOPSPZP_KEEP 0x00000000 +#define HC_HSTOPSPZP_ZERO 0x00000001 +#define HC_HSTOPSPZP_REPLACE 0x00000002 +#define HC_HSTOPSPZP_INCRSAT 0x00000003 +#define HC_HSTOPSPZP_DECRSAT 0x00000004 +#define HC_HSTOPSPZP_INVERT 0x00000005 +#define HC_HSTOPSPZP_INCR 0x00000006 +#define HC_HSTOPSPZP_DECR 0x00000007 + +/* Alpha Setting + */ +#define HC_SubA_HABBasL 0x0030 +#define HC_SubA_HABBasH 0x0031 +#define HC_SubA_HABFM 0x0032 +#define HC_SubA_HATMD 0x0033 +#define HC_SubA_HABLCsat 0x0034 +#define HC_SubA_HABLCop 0x0035 +#define HC_SubA_HABLAsat 0x0036 +#define HC_SubA_HABLAop 0x0037 +#define HC_SubA_HABLRCa 0x0038 +#define HC_SubA_HABLRFCa 0x0039 +#define HC_SubA_HABLRCbias 0x003a +#define HC_SubA_HABLRCb 0x003b +#define HC_SubA_HABLRFCb 0x003c +#define HC_SubA_HABLRAa 0x003d +#define HC_SubA_HABLRAb 0x003e +/* HC_SubA_HABFM + */ +#define HC_HABFM_MASK 0x00030000 +#define HC_HABLoc_MASK 0x0000c000 +#define HC_HABPit_MASK 0x000007ff +/* HC_SubA_HATMD + */ +#define HC_HATMD_MASK 0x00000700 +#define HC_HATREF_MASK 0x000000ff +#define HC_HATMD_NeverPass 0x00000000 +#define HC_HATMD_LT 0x00000100 +#define HC_HATMD_EQ 0x00000200 +#define HC_HATMD_LE 0x00000300 +#define HC_HATMD_GT 0x00000400 +#define HC_HATMD_NE 0x00000500 +#define HC_HATMD_GE 0x00000600 +#define HC_HATMD_AllPass 0x00000700 +/* HC_SubA_HABLCsat + */ +#define HC_HABLCsat_MASK 0x00010000 +#define HC_HABLCa_MASK 0x0000fc00 +#define HC_HABLCa_C_MASK 0x0000c000 +#define HC_HABLCa_OPC_MASK 0x00003c00 +#define HC_HABLFCa_MASK 0x000003f0 +#define HC_HABLFCa_C_MASK 0x00000300 +#define HC_HABLFCa_OPC_MASK 0x000000f0 +#define HC_HABLCbias_MASK 0x0000000f +#define HC_HABLCbias_C_MASK 0x00000008 +#define HC_HABLCbias_OPC_MASK 0x00000007 +/*-- Define the input color. + */ +#define HC_XC_Csrc 0x00000000 +#define HC_XC_Cdst 0x00000001 +#define HC_XC_Asrc 0x00000002 +#define HC_XC_Adst 0x00000003 +#define HC_XC_Fog 0x00000004 +#define HC_XC_HABLRC 0x00000005 +#define HC_XC_minSrcDst 0x00000006 +#define HC_XC_maxSrcDst 0x00000007 +#define HC_XC_mimAsrcInvAdst 0x00000008 +#define HC_XC_OPC 0x00000000 +#define HC_XC_InvOPC 0x00000010 +#define HC_XC_OPCp5 0x00000020 +/*-- Define the input Alpha + */ +#define HC_XA_OPA 0x00000000 +#define HC_XA_InvOPA 0x00000010 +#define HC_XA_OPAp5 0x00000020 +#define HC_XA_0 0x00000000 +#define HC_XA_Asrc 0x00000001 +#define HC_XA_Adst 0x00000002 +#define HC_XA_Fog 0x00000003 +#define HC_XA_minAsrcFog 0x00000004 +#define HC_XA_minAsrcAdst 0x00000005 +#define HC_XA_maxAsrcFog 0x00000006 +#define HC_XA_maxAsrcAdst 0x00000007 +#define HC_XA_HABLRA 0x00000008 +#define HC_XA_minAsrcInvAdst 0x00000008 +#define HC_XA_HABLFRA 0x00000009 +/*-- + */ +#define HC_HABLCa_OPC (HC_XC_OPC << 10) +#define HC_HABLCa_InvOPC (HC_XC_InvOPC << 10) +#define HC_HABLCa_OPCp5 (HC_XC_OPCp5 << 10) +#define HC_HABLCa_Csrc (HC_XC_Csrc << 10) +#define HC_HABLCa_Cdst (HC_XC_Cdst << 10) +#define HC_HABLCa_Asrc (HC_XC_Asrc << 10) +#define HC_HABLCa_Adst (HC_XC_Adst << 10) +#define HC_HABLCa_Fog (HC_XC_Fog << 10) +#define HC_HABLCa_HABLRCa (HC_XC_HABLRC << 10) +#define HC_HABLCa_minSrcDst (HC_XC_minSrcDst << 10) +#define HC_HABLCa_maxSrcDst (HC_XC_maxSrcDst << 10) +#define HC_HABLFCa_OPC (HC_XC_OPC << 4) +#define HC_HABLFCa_InvOPC (HC_XC_InvOPC << 4) +#define HC_HABLFCa_OPCp5 (HC_XC_OPCp5 << 4) +#define HC_HABLFCa_Csrc (HC_XC_Csrc << 4) +#define HC_HABLFCa_Cdst (HC_XC_Cdst << 4) +#define HC_HABLFCa_Asrc (HC_XC_Asrc << 4) +#define HC_HABLFCa_Adst (HC_XC_Adst << 4) +#define HC_HABLFCa_Fog (HC_XC_Fog << 4) +#define HC_HABLFCa_HABLRCa (HC_XC_HABLRC << 4) +#define HC_HABLFCa_minSrcDst (HC_XC_minSrcDst << 4) +#define HC_HABLFCa_maxSrcDst (HC_XC_maxSrcDst << 4) +#define HC_HABLFCa_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 4) +#define HC_HABLCbias_HABLRCbias 0x00000000 +#define HC_HABLCbias_Asrc 0x00000001 +#define HC_HABLCbias_Adst 0x00000002 +#define HC_HABLCbias_Fog 0x00000003 +#define HC_HABLCbias_Cin 0x00000004 +/* HC_SubA_HABLCop 0x0035 + */ +#define HC_HABLdot_MASK 0x00010000 +#define HC_HABLCop_MASK 0x00004000 +#define HC_HABLCb_MASK 0x00003f00 +#define HC_HABLCb_C_MASK 0x00003000 +#define HC_HABLCb_OPC_MASK 0x00000f00 +#define HC_HABLFCb_MASK 0x000000fc +#define HC_HABLFCb_C_MASK 0x000000c0 +#define HC_HABLFCb_OPC_MASK 0x0000003c +#define HC_HABLCshift_MASK 0x00000003 +#define HC_HABLCb_OPC (HC_XC_OPC << 8) +#define HC_HABLCb_InvOPC (HC_XC_InvOPC << 8) +#define HC_HABLCb_OPCp5 (HC_XC_OPCp5 << 8) +#define HC_HABLCb_Csrc (HC_XC_Csrc << 8) +#define HC_HABLCb_Cdst (HC_XC_Cdst << 8) +#define HC_HABLCb_Asrc (HC_XC_Asrc << 8) +#define HC_HABLCb_Adst (HC_XC_Adst << 8) +#define HC_HABLCb_Fog (HC_XC_Fog << 8) +#define HC_HABLCb_HABLRCa (HC_XC_HABLRC << 8) +#define HC_HABLCb_minSrcDst (HC_XC_minSrcDst << 8) +#define HC_HABLCb_maxSrcDst (HC_XC_maxSrcDst << 8) +#define HC_HABLFCb_OPC (HC_XC_OPC << 2) +#define HC_HABLFCb_InvOPC (HC_XC_InvOPC << 2) +#define HC_HABLFCb_OPCp5 (HC_XC_OPCp5 << 2) +#define HC_HABLFCb_Csrc (HC_XC_Csrc << 2) +#define HC_HABLFCb_Cdst (HC_XC_Cdst << 2) +#define HC_HABLFCb_Asrc (HC_XC_Asrc << 2) +#define HC_HABLFCb_Adst (HC_XC_Adst << 2) +#define HC_HABLFCb_Fog (HC_XC_Fog << 2) +#define HC_HABLFCb_HABLRCb (HC_XC_HABLRC << 2) +#define HC_HABLFCb_minSrcDst (HC_XC_minSrcDst << 2) +#define HC_HABLFCb_maxSrcDst (HC_XC_maxSrcDst << 2) +#define HC_HABLFCb_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 2) +/* HC_SubA_HABLAsat 0x0036 + */ +#define HC_HABLAsat_MASK 0x00010000 +#define HC_HABLAa_MASK 0x0000fc00 +#define HC_HABLAa_A_MASK 0x0000c000 +#define HC_HABLAa_OPA_MASK 0x00003c00 +#define HC_HABLFAa_MASK 0x000003f0 +#define HC_HABLFAa_A_MASK 0x00000300 +#define HC_HABLFAa_OPA_MASK 0x000000f0 +#define HC_HABLAbias_MASK 0x0000000f +#define HC_HABLAbias_A_MASK 0x00000008 +#define HC_HABLAbias_OPA_MASK 0x00000007 +#define HC_HABLAa_OPA (HC_XA_OPA << 10) +#define HC_HABLAa_InvOPA (HC_XA_InvOPA << 10) +#define HC_HABLAa_OPAp5 (HC_XA_OPAp5 << 10) +#define HC_HABLAa_0 (HC_XA_0 << 10) +#define HC_HABLAa_Asrc (HC_XA_Asrc << 10) +#define HC_HABLAa_Adst (HC_XA_Adst << 10) +#define HC_HABLAa_Fog (HC_XA_Fog << 10) +#define HC_HABLAa_minAsrcFog (HC_XA_minAsrcFog << 10) +#define HC_HABLAa_minAsrcAdst (HC_XA_minAsrcAdst << 10) +#define HC_HABLAa_maxAsrcFog (HC_XA_maxAsrcFog << 10) +#define HC_HABLAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 10) +#define HC_HABLAa_HABLRA (HC_XA_HABLRA << 10) +#define HC_HABLFAa_OPA (HC_XA_OPA << 4) +#define HC_HABLFAa_InvOPA (HC_XA_InvOPA << 4) +#define HC_HABLFAa_OPAp5 (HC_XA_OPAp5 << 4) +#define HC_HABLFAa_0 (HC_XA_0 << 4) +#define HC_HABLFAa_Asrc (HC_XA_Asrc << 4) +#define HC_HABLFAa_Adst (HC_XA_Adst << 4) +#define HC_HABLFAa_Fog (HC_XA_Fog << 4) +#define HC_HABLFAa_minAsrcFog (HC_XA_minAsrcFog << 4) +#define HC_HABLFAa_minAsrcAdst (HC_XA_minAsrcAdst << 4) +#define HC_HABLFAa_maxAsrcFog (HC_XA_maxAsrcFog << 4) +#define HC_HABLFAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 4) +#define HC_HABLFAa_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 4) +#define HC_HABLFAa_HABLFRA (HC_XA_HABLFRA << 4) +#define HC_HABLAbias_HABLRAbias 0x00000000 +#define HC_HABLAbias_Asrc 0x00000001 +#define HC_HABLAbias_Adst 0x00000002 +#define HC_HABLAbias_Fog 0x00000003 +#define HC_HABLAbias_Aaa 0x00000004 +/* HC_SubA_HABLAop 0x0037 + */ +#define HC_HABLAop_MASK 0x00004000 +#define HC_HABLAb_MASK 0x00003f00 +#define HC_HABLAb_OPA_MASK 0x00000f00 +#define HC_HABLFAb_MASK 0x000000fc +#define HC_HABLFAb_OPA_MASK 0x0000003c +#define HC_HABLAshift_MASK 0x00000003 +#define HC_HABLAb_OPA (HC_XA_OPA << 8) +#define HC_HABLAb_InvOPA (HC_XA_InvOPA << 8) +#define HC_HABLAb_OPAp5 (HC_XA_OPAp5 << 8) +#define HC_HABLAb_0 (HC_XA_0 << 8) +#define HC_HABLAb_Asrc (HC_XA_Asrc << 8) +#define HC_HABLAb_Adst (HC_XA_Adst << 8) +#define HC_HABLAb_Fog (HC_XA_Fog << 8) +#define HC_HABLAb_minAsrcFog (HC_XA_minAsrcFog << 8) +#define HC_HABLAb_minAsrcAdst (HC_XA_minAsrcAdst << 8) +#define HC_HABLAb_maxAsrcFog (HC_XA_maxAsrcFog << 8) +#define HC_HABLAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 8) +#define HC_HABLAb_HABLRA (HC_XA_HABLRA << 8) +#define HC_HABLFAb_OPA (HC_XA_OPA << 2) +#define HC_HABLFAb_InvOPA (HC_XA_InvOPA << 2) +#define HC_HABLFAb_OPAp5 (HC_XA_OPAp5 << 2) +#define HC_HABLFAb_0 (HC_XA_0 << 2) +#define HC_HABLFAb_Asrc (HC_XA_Asrc << 2) +#define HC_HABLFAb_Adst (HC_XA_Adst << 2) +#define HC_HABLFAb_Fog (HC_XA_Fog << 2) +#define HC_HABLFAb_minAsrcFog (HC_XA_minAsrcFog << 2) +#define HC_HABLFAb_minAsrcAdst (HC_XA_minAsrcAdst << 2) +#define HC_HABLFAb_maxAsrcFog (HC_XA_maxAsrcFog << 2) +#define HC_HABLFAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 2) +#define HC_HABLFAb_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 2) +#define HC_HABLFAb_HABLFRA (HC_XA_HABLFRA << 2) +/* HC_SubA_HABLRAa 0x003d + */ +#define HC_HABLRAa_MASK 0x00ff0000 +#define HC_HABLRFAa_MASK 0x0000ff00 +#define HC_HABLRAbias_MASK 0x000000ff +#define HC_HABLRAa_SHIFT 16 +#define HC_HABLRFAa_SHIFT 8 +/* HC_SubA_HABLRAb 0x003e + */ +#define HC_HABLRAb_MASK 0x0000ff00 +#define HC_HABLRFAb_MASK 0x000000ff +#define HC_HABLRAb_SHIFT 8 + +/* Destination Setting + */ +#define HC_SubA_HDBBasL 0x0040 +#define HC_SubA_HDBBasH 0x0041 +#define HC_SubA_HDBFM 0x0042 +#define HC_SubA_HFBBMSKL 0x0043 +#define HC_SubA_HROP 0x0044 +/* HC_SubA_HDBFM 0x0042 + */ +#define HC_HDBFM_MASK 0x001f0000 +#define HC_HDBLoc_MASK 0x0000c000 +#define HC_HDBPit_MASK 0x00003fff +#define HC_HDBFM_RGB555 0x00000000 +#define HC_HDBFM_RGB565 0x00010000 +#define HC_HDBFM_ARGB4444 0x00020000 +#define HC_HDBFM_ARGB1555 0x00030000 +#define HC_HDBFM_BGR555 0x00040000 +#define HC_HDBFM_BGR565 0x00050000 +#define HC_HDBFM_ABGR4444 0x00060000 +#define HC_HDBFM_ABGR1555 0x00070000 +#define HC_HDBFM_ARGB0888 0x00080000 +#define HC_HDBFM_ARGB8888 0x00090000 +#define HC_HDBFM_ABGR0888 0x000a0000 +#define HC_HDBFM_ABGR8888 0x000b0000 +#define HC_HDBLoc_Local 0x00000000 +#define HC_HDBLoc_Sys 0x00004000 +/* HC_SubA_HROP 0x0044 + */ +#define HC_HROP_MASK 0x00000f00 +#define HC_HFBBMSKH_MASK 0x000000ff +#define HC_HROP_BLACK 0x00000000 +#define HC_HROP_DPon 0x00000100 +#define HC_HROP_DPna 0x00000200 +#define HC_HROP_Pn 0x00000300 +#define HC_HROP_PDna 0x00000400 +#define HC_HROP_Dn 0x00000500 +#define HC_HROP_DPx 0x00000600 +#define HC_HROP_DPan 0x00000700 +#define HC_HROP_DPa 0x00000800 +#define HC_HROP_DPxn 0x00000900 +#define HC_HROP_D 0x00000a00 +#define HC_HROP_DPno 0x00000b00 +#define HC_HROP_P 0x00000c00 +#define HC_HROP_PDno 0x00000d00 +#define HC_HROP_DPo 0x00000e00 +#define HC_HROP_WHITE 0x00000f00 + +/* Fog Setting + */ +#define HC_SubA_HFogLF 0x0050 +#define HC_SubA_HFogCL 0x0051 +#define HC_SubA_HFogCH 0x0052 +#define HC_SubA_HFogStL 0x0053 +#define HC_SubA_HFogStH 0x0054 +#define HC_SubA_HFogOOdMF 0x0055 +#define HC_SubA_HFogOOdEF 0x0056 +#define HC_SubA_HFogEndL 0x0057 +#define HC_SubA_HFogDenst 0x0058 +/* HC_SubA_FogLF 0x0050 + */ +#define HC_FogLF_MASK 0x00000010 +#define HC_FogEq_MASK 0x00000008 +#define HC_FogMD_MASK 0x00000007 +#define HC_FogMD_LocalFog 0x00000000 +#define HC_FogMD_LinearFog 0x00000002 +#define HC_FogMD_ExponentialFog 0x00000004 +#define HC_FogMD_Exponential2Fog 0x00000005 +/* #define HC_FogMD_FogTable 0x00000003 */ + +/* HC_SubA_HFogDenst 0x0058 + */ +#define HC_FogDenst_MASK 0x001fff00 +#define HC_FogEndL_MASK 0x000000ff + +/* Texture subtype definitions + */ +#define HC_SubType_Tex0 0x00000000 +#define HC_SubType_Tex1 0x00000001 +#define HC_SubType_TexGeneral 0x000000fe + +/* Attribute of texture n + */ +#define HC_SubA_HTXnL0BasL 0x0000 +#define HC_SubA_HTXnL1BasL 0x0001 +#define HC_SubA_HTXnL2BasL 0x0002 +#define HC_SubA_HTXnL3BasL 0x0003 +#define HC_SubA_HTXnL4BasL 0x0004 +#define HC_SubA_HTXnL5BasL 0x0005 +#define HC_SubA_HTXnL6BasL 0x0006 +#define HC_SubA_HTXnL7BasL 0x0007 +#define HC_SubA_HTXnL8BasL 0x0008 +#define HC_SubA_HTXnL9BasL 0x0009 +#define HC_SubA_HTXnLaBasL 0x000a +#define HC_SubA_HTXnLbBasL 0x000b +#define HC_SubA_HTXnLcBasL 0x000c +#define HC_SubA_HTXnLdBasL 0x000d +#define HC_SubA_HTXnLeBasL 0x000e +#define HC_SubA_HTXnLfBasL 0x000f +#define HC_SubA_HTXnL10BasL 0x0010 +#define HC_SubA_HTXnL11BasL 0x0011 +#define HC_SubA_HTXnL012BasH 0x0020 +#define HC_SubA_HTXnL345BasH 0x0021 +#define HC_SubA_HTXnL678BasH 0x0022 +#define HC_SubA_HTXnL9abBasH 0x0023 +#define HC_SubA_HTXnLcdeBasH 0x0024 +#define HC_SubA_HTXnLf1011BasH 0x0025 +#define HC_SubA_HTXnL0Pit 0x002b +#define HC_SubA_HTXnL1Pit 0x002c +#define HC_SubA_HTXnL2Pit 0x002d +#define HC_SubA_HTXnL3Pit 0x002e +#define HC_SubA_HTXnL4Pit 0x002f +#define HC_SubA_HTXnL5Pit 0x0030 +#define HC_SubA_HTXnL6Pit 0x0031 +#define HC_SubA_HTXnL7Pit 0x0032 +#define HC_SubA_HTXnL8Pit 0x0033 +#define HC_SubA_HTXnL9Pit 0x0034 +#define HC_SubA_HTXnLaPit 0x0035 +#define HC_SubA_HTXnLbPit 0x0036 +#define HC_SubA_HTXnLcPit 0x0037 +#define HC_SubA_HTXnLdPit 0x0038 +#define HC_SubA_HTXnLePit 0x0039 +#define HC_SubA_HTXnLfPit 0x003a +#define HC_SubA_HTXnL10Pit 0x003b +#define HC_SubA_HTXnL11Pit 0x003c +#define HC_SubA_HTXnL0_5WE 0x004b +#define HC_SubA_HTXnL6_bWE 0x004c +#define HC_SubA_HTXnLc_11WE 0x004d +#define HC_SubA_HTXnL0_5HE 0x0051 +#define HC_SubA_HTXnL6_bHE 0x0052 +#define HC_SubA_HTXnLc_11HE 0x0053 +#define HC_SubA_HTXnL0OS 0x0077 +#define HC_SubA_HTXnTB 0x0078 +#define HC_SubA_HTXnMPMD 0x0079 +#define HC_SubA_HTXnCLODu 0x007a +#define HC_SubA_HTXnFM 0x007b +#define HC_SubA_HTXnTRCH 0x007c +#define HC_SubA_HTXnTRCL 0x007d +#define HC_SubA_HTXnTBC 0x007e +#define HC_SubA_HTXnTRAH 0x007f +#define HC_SubA_HTXnTBLCsat 0x0080 +#define HC_SubA_HTXnTBLCop 0x0081 +#define HC_SubA_HTXnTBLMPfog 0x0082 +#define HC_SubA_HTXnTBLAsat 0x0083 +#define HC_SubA_HTXnTBLRCa 0x0085 +#define HC_SubA_HTXnTBLRCb 0x0086 +#define HC_SubA_HTXnTBLRCc 0x0087 +#define HC_SubA_HTXnTBLRCbias 0x0088 +#define HC_SubA_HTXnTBLRAa 0x0089 +#define HC_SubA_HTXnTBLRFog 0x008a +#define HC_SubA_HTXnBumpM00 0x0090 +#define HC_SubA_HTXnBumpM01 0x0091 +#define HC_SubA_HTXnBumpM10 0x0092 +#define HC_SubA_HTXnBumpM11 0x0093 +#define HC_SubA_HTXnLScale 0x0094 +#define HC_SubA_HTXSMD 0x0000 +/* HC_SubA_HTXnL012BasH 0x0020 + */ +#define HC_HTXnL0BasH_MASK 0x000000ff +#define HC_HTXnL1BasH_MASK 0x0000ff00 +#define HC_HTXnL2BasH_MASK 0x00ff0000 +#define HC_HTXnL1BasH_SHIFT 8 +#define HC_HTXnL2BasH_SHIFT 16 +/* HC_SubA_HTXnL345BasH 0x0021 + */ +#define HC_HTXnL3BasH_MASK 0x000000ff +#define HC_HTXnL4BasH_MASK 0x0000ff00 +#define HC_HTXnL5BasH_MASK 0x00ff0000 +#define HC_HTXnL4BasH_SHIFT 8 +#define HC_HTXnL5BasH_SHIFT 16 +/* HC_SubA_HTXnL678BasH 0x0022 + */ +#define HC_HTXnL6BasH_MASK 0x000000ff +#define HC_HTXnL7BasH_MASK 0x0000ff00 +#define HC_HTXnL8BasH_MASK 0x00ff0000 +#define HC_HTXnL7BasH_SHIFT 8 +#define HC_HTXnL8BasH_SHIFT 16 +/* HC_SubA_HTXnL9abBasH 0x0023 + */ +#define HC_HTXnL9BasH_MASK 0x000000ff +#define HC_HTXnLaBasH_MASK 0x0000ff00 +#define HC_HTXnLbBasH_MASK 0x00ff0000 +#define HC_HTXnLaBasH_SHIFT 8 +#define HC_HTXnLbBasH_SHIFT 16 +/* HC_SubA_HTXnLcdeBasH 0x0024 + */ +#define HC_HTXnLcBasH_MASK 0x000000ff +#define HC_HTXnLdBasH_MASK 0x0000ff00 +#define HC_HTXnLeBasH_MASK 0x00ff0000 +#define HC_HTXnLdBasH_SHIFT 8 +#define HC_HTXnLeBasH_SHIFT 16 +/* HC_SubA_HTXnLcdeBasH 0x0025 + */ +#define HC_HTXnLfBasH_MASK 0x000000ff +#define HC_HTXnL10BasH_MASK 0x0000ff00 +#define HC_HTXnL11BasH_MASK 0x00ff0000 +#define HC_HTXnL10BasH_SHIFT 8 +#define HC_HTXnL11BasH_SHIFT 16 +/* HC_SubA_HTXnL0Pit 0x002b + */ +#define HC_HTXnLnPit_MASK 0x00003fff +#define HC_HTXnEnPit_MASK 0x00080000 +#define HC_HTXnLnPitE_MASK 0x00f00000 +#define HC_HTXnLnPitE_SHIFT 20 +/* HC_SubA_HTXnL0_5WE 0x004b + */ +#define HC_HTXnL0WE_MASK 0x0000000f +#define HC_HTXnL1WE_MASK 0x000000f0 +#define HC_HTXnL2WE_MASK 0x00000f00 +#define HC_HTXnL3WE_MASK 0x0000f000 +#define HC_HTXnL4WE_MASK 0x000f0000 +#define HC_HTXnL5WE_MASK 0x00f00000 +#define HC_HTXnL1WE_SHIFT 4 +#define HC_HTXnL2WE_SHIFT 8 +#define HC_HTXnL3WE_SHIFT 12 +#define HC_HTXnL4WE_SHIFT 16 +#define HC_HTXnL5WE_SHIFT 20 +/* HC_SubA_HTXnL6_bWE 0x004c + */ +#define HC_HTXnL6WE_MASK 0x0000000f +#define HC_HTXnL7WE_MASK 0x000000f0 +#define HC_HTXnL8WE_MASK 0x00000f00 +#define HC_HTXnL9WE_MASK 0x0000f000 +#define HC_HTXnLaWE_MASK 0x000f0000 +#define HC_HTXnLbWE_MASK 0x00f00000 +#define HC_HTXnL7WE_SHIFT 4 +#define HC_HTXnL8WE_SHIFT 8 +#define HC_HTXnL9WE_SHIFT 12 +#define HC_HTXnLaWE_SHIFT 16 +#define HC_HTXnLbWE_SHIFT 20 +/* HC_SubA_HTXnLc_11WE 0x004d + */ +#define HC_HTXnLcWE_MASK 0x0000000f +#define HC_HTXnLdWE_MASK 0x000000f0 +#define HC_HTXnLeWE_MASK 0x00000f00 +#define HC_HTXnLfWE_MASK 0x0000f000 +#define HC_HTXnL10WE_MASK 0x000f0000 +#define HC_HTXnL11WE_MASK 0x00f00000 +#define HC_HTXnLdWE_SHIFT 4 +#define HC_HTXnLeWE_SHIFT 8 +#define HC_HTXnLfWE_SHIFT 12 +#define HC_HTXnL10WE_SHIFT 16 +#define HC_HTXnL11WE_SHIFT 20 +/* HC_SubA_HTXnL0_5HE 0x0051 + */ +#define HC_HTXnL0HE_MASK 0x0000000f +#define HC_HTXnL1HE_MASK 0x000000f0 +#define HC_HTXnL2HE_MASK 0x00000f00 +#define HC_HTXnL3HE_MASK 0x0000f000 +#define HC_HTXnL4HE_MASK 0x000f0000 +#define HC_HTXnL5HE_MASK 0x00f00000 +#define HC_HTXnL1HE_SHIFT 4 +#define HC_HTXnL2HE_SHIFT 8 +#define HC_HTXnL3HE_SHIFT 12 +#define HC_HTXnL4HE_SHIFT 16 +#define HC_HTXnL5HE_SHIFT 20 +/* HC_SubA_HTXnL6_bHE 0x0052 + */ +#define HC_HTXnL6HE_MASK 0x0000000f +#define HC_HTXnL7HE_MASK 0x000000f0 +#define HC_HTXnL8HE_MASK 0x00000f00 +#define HC_HTXnL9HE_MASK 0x0000f000 +#define HC_HTXnLaHE_MASK 0x000f0000 +#define HC_HTXnLbHE_MASK 0x00f00000 +#define HC_HTXnL7HE_SHIFT 4 +#define HC_HTXnL8HE_SHIFT 8 +#define HC_HTXnL9HE_SHIFT 12 +#define HC_HTXnLaHE_SHIFT 16 +#define HC_HTXnLbHE_SHIFT 20 +/* HC_SubA_HTXnLc_11HE 0x0053 + */ +#define HC_HTXnLcHE_MASK 0x0000000f +#define HC_HTXnLdHE_MASK 0x000000f0 +#define HC_HTXnLeHE_MASK 0x00000f00 +#define HC_HTXnLfHE_MASK 0x0000f000 +#define HC_HTXnL10HE_MASK 0x000f0000 +#define HC_HTXnL11HE_MASK 0x00f00000 +#define HC_HTXnLdHE_SHIFT 4 +#define HC_HTXnLeHE_SHIFT 8 +#define HC_HTXnLfHE_SHIFT 12 +#define HC_HTXnL10HE_SHIFT 16 +#define HC_HTXnL11HE_SHIFT 20 +/* HC_SubA_HTXnL0OS 0x0077 + */ +#define HC_HTXnL0OS_MASK 0x003ff000 +#define HC_HTXnLVmax_MASK 0x00000fc0 +#define HC_HTXnLVmin_MASK 0x0000003f +#define HC_HTXnL0OS_SHIFT 12 +#define HC_HTXnLVmax_SHIFT 6 +/* HC_SubA_HTXnTB 0x0078 + */ +#define HC_HTXnTB_MASK 0x00f00000 +#define HC_HTXnFLSe_MASK 0x0000e000 +#define HC_HTXnFLSs_MASK 0x00001c00 +#define HC_HTXnFLTe_MASK 0x00000380 +#define HC_HTXnFLTs_MASK 0x00000070 +#define HC_HTXnFLDs_MASK 0x0000000f +#define HC_HTXnTB_NoTB 0x00000000 +#define HC_HTXnTB_TBC_S 0x00100000 +#define HC_HTXnTB_TBC_T 0x00200000 +#define HC_HTXnTB_TB_S 0x00400000 +#define HC_HTXnTB_TB_T 0x00800000 +#define HC_HTXnFLSe_Nearest 0x00000000 +#define HC_HTXnFLSe_Linear 0x00002000 +#define HC_HTXnFLSe_NonLinear 0x00004000 +#define HC_HTXnFLSe_Sharp 0x00008000 +#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000 +#define HC_HTXnFLSs_Nearest 0x00000000 +#define HC_HTXnFLSs_Linear 0x00000400 +#define HC_HTXnFLSs_NonLinear 0x00000800 +#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800 +#define HC_HTXnFLTe_Nearest 0x00000000 +#define HC_HTXnFLTe_Linear 0x00000080 +#define HC_HTXnFLTe_NonLinear 0x00000100 +#define HC_HTXnFLTe_Sharp 0x00000180 +#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300 +#define HC_HTXnFLTs_Nearest 0x00000000 +#define HC_HTXnFLTs_Linear 0x00000010 +#define HC_HTXnFLTs_NonLinear 0x00000020 +#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060 +#define HC_HTXnFLDs_Tex0 0x00000000 +#define HC_HTXnFLDs_Nearest 0x00000001 +#define HC_HTXnFLDs_Linear 0x00000002 +#define HC_HTXnFLDs_NonLinear 0x00000003 +#define HC_HTXnFLDs_Dither 0x00000004 +#define HC_HTXnFLDs_ConstLOD 0x00000005 +#define HC_HTXnFLDs_Ani 0x00000006 +#define HC_HTXnFLDs_AniDither 0x00000007 +/* HC_SubA_HTXnMPMD 0x0079 + */ +#define HC_HTXnMPMD_SMASK 0x00070000 +#define HC_HTXnMPMD_TMASK 0x00380000 +#define HC_HTXnLODDTf_MASK 0x00000007 +#define HC_HTXnXY2ST_MASK 0x00000008 +#define HC_HTXnMPMD_Tsingle 0x00000000 +#define HC_HTXnMPMD_Tclamp 0x00080000 +#define HC_HTXnMPMD_Trepeat 0x00100000 +#define HC_HTXnMPMD_Tmirror 0x00180000 +#define HC_HTXnMPMD_Twrap 0x00200000 +#define HC_HTXnMPMD_Ssingle 0x00000000 +#define HC_HTXnMPMD_Sclamp 0x00010000 +#define HC_HTXnMPMD_Srepeat 0x00020000 +#define HC_HTXnMPMD_Smirror 0x00030000 +#define HC_HTXnMPMD_Swrap 0x00040000 +/* HC_SubA_HTXnCLODu 0x007a + */ +#define HC_HTXnCLODu_MASK 0x000ffc00 +#define HC_HTXnCLODd_MASK 0x000003ff +#define HC_HTXnCLODu_SHIFT 10 +/* HC_SubA_HTXnFM 0x007b + */ +#define HC_HTXnFM_MASK 0x00ff0000 +#define HC_HTXnLoc_MASK 0x00000003 +#define HC_HTXnFM_INDEX 0x00000000 +#define HC_HTXnFM_Intensity 0x00080000 +#define HC_HTXnFM_Lum 0x00100000 +#define HC_HTXnFM_Alpha 0x00180000 +#define HC_HTXnFM_DX 0x00280000 +#define HC_HTXnFM_ARGB16 0x00880000 +#define HC_HTXnFM_ARGB32 0x00980000 +#define HC_HTXnFM_ABGR16 0x00a80000 +#define HC_HTXnFM_ABGR32 0x00b80000 +#define HC_HTXnFM_RGBA16 0x00c80000 +#define HC_HTXnFM_RGBA32 0x00d80000 +#define HC_HTXnFM_BGRA16 0x00e80000 +#define HC_HTXnFM_BGRA32 0x00f80000 +#define HC_HTXnFM_BUMPMAP 0x00380000 +#define HC_HTXnFM_Index1 (HC_HTXnFM_INDEX | 0x00000000) +#define HC_HTXnFM_Index2 (HC_HTXnFM_INDEX | 0x00010000) +#define HC_HTXnFM_Index4 (HC_HTXnFM_INDEX | 0x00020000) +#define HC_HTXnFM_Index8 (HC_HTXnFM_INDEX | 0x00030000) +#define HC_HTXnFM_T1 (HC_HTXnFM_Intensity | 0x00000000) +#define HC_HTXnFM_T2 (HC_HTXnFM_Intensity | 0x00010000) +#define HC_HTXnFM_T4 (HC_HTXnFM_Intensity | 0x00020000) +#define HC_HTXnFM_T8 (HC_HTXnFM_Intensity | 0x00030000) +#define HC_HTXnFM_L1 (HC_HTXnFM_Lum | 0x00000000) +#define HC_HTXnFM_L2 (HC_HTXnFM_Lum | 0x00010000) +#define HC_HTXnFM_L4 (HC_HTXnFM_Lum | 0x00020000) +#define HC_HTXnFM_L8 (HC_HTXnFM_Lum | 0x00030000) +#define HC_HTXnFM_AL44 (HC_HTXnFM_Lum | 0x00040000) +#define HC_HTXnFM_AL88 (HC_HTXnFM_Lum | 0x00050000) +#define HC_HTXnFM_A1 (HC_HTXnFM_Alpha | 0x00000000) +#define HC_HTXnFM_A2 (HC_HTXnFM_Alpha | 0x00010000) +#define HC_HTXnFM_A4 (HC_HTXnFM_Alpha | 0x00020000) +#define HC_HTXnFM_A8 (HC_HTXnFM_Alpha | 0x00030000) +#define HC_HTXnFM_DX1 (HC_HTXnFM_DX | 0x00010000) +#define HC_HTXnFM_DX23 (HC_HTXnFM_DX | 0x00020000) +#define HC_HTXnFM_DX45 (HC_HTXnFM_DX | 0x00030000) +#define HC_HTXnFM_RGB555 (HC_HTXnFM_ARGB16 | 0x00000000) +#define HC_HTXnFM_RGB565 (HC_HTXnFM_ARGB16 | 0x00010000) +#define HC_HTXnFM_ARGB1555 (HC_HTXnFM_ARGB16 | 0x00020000) +#define HC_HTXnFM_ARGB4444 (HC_HTXnFM_ARGB16 | 0x00030000) +#define HC_HTXnFM_ARGB0888 (HC_HTXnFM_ARGB32 | 0x00000000) +#define HC_HTXnFM_ARGB8888 (HC_HTXnFM_ARGB32 | 0x00010000) +#define HC_HTXnFM_BGR555 (HC_HTXnFM_ABGR16 | 0x00000000) +#define HC_HTXnFM_BGR565 (HC_HTXnFM_ABGR16 | 0x00010000) +#define HC_HTXnFM_ABGR1555 (HC_HTXnFM_ABGR16 | 0x00020000) +#define HC_HTXnFM_ABGR4444 (HC_HTXnFM_ABGR16 | 0x00030000) +#define HC_HTXnFM_ABGR0888 (HC_HTXnFM_ABGR32 | 0x00000000) +#define HC_HTXnFM_ABGR8888 (HC_HTXnFM_ABGR32 | 0x00010000) +#define HC_HTXnFM_RGBA5550 (HC_HTXnFM_RGBA16 | 0x00000000) +#define HC_HTXnFM_RGBA5551 (HC_HTXnFM_RGBA16 | 0x00020000) +#define HC_HTXnFM_RGBA4444 (HC_HTXnFM_RGBA16 | 0x00030000) +#define HC_HTXnFM_RGBA8880 (HC_HTXnFM_RGBA32 | 0x00000000) +#define HC_HTXnFM_RGBA8888 (HC_HTXnFM_RGBA32 | 0x00010000) +#define HC_HTXnFM_BGRA5550 (HC_HTXnFM_BGRA16 | 0x00000000) +#define HC_HTXnFM_BGRA5551 (HC_HTXnFM_BGRA16 | 0x00020000) +#define HC_HTXnFM_BGRA4444 (HC_HTXnFM_BGRA16 | 0x00030000) +#define HC_HTXnFM_BGRA8880 (HC_HTXnFM_BGRA32 | 0x00000000) +#define HC_HTXnFM_BGRA8888 (HC_HTXnFM_BGRA32 | 0x00010000) +#define HC_HTXnFM_VU88 (HC_HTXnFM_BUMPMAP | 0x00000000) +#define HC_HTXnFM_LVU655 (HC_HTXnFM_BUMPMAP | 0x00010000) +#define HC_HTXnFM_LVU888 (HC_HTXnFM_BUMPMAP | 0x00020000) +#define HC_HTXnLoc_Local 0x00000000 +#define HC_HTXnLoc_Sys 0x00000002 +#define HC_HTXnLoc_AGP 0x00000003 +/* HC_SubA_HTXnTRAH 0x007f + */ +#define HC_HTXnTRAH_MASK 0x00ff0000 +#define HC_HTXnTRAL_MASK 0x0000ff00 +#define HC_HTXnTBA_MASK 0x000000ff +#define HC_HTXnTRAH_SHIFT 16 +#define HC_HTXnTRAL_SHIFT 8 +/* HC_SubA_HTXnTBLCsat 0x0080 + *-- Define the input texture. + */ +#define HC_XTC_TOPC 0x00000000 +#define HC_XTC_InvTOPC 0x00000010 +#define HC_XTC_TOPCp5 0x00000020 +#define HC_XTC_Cbias 0x00000000 +#define HC_XTC_InvCbias 0x00000010 +#define HC_XTC_0 0x00000000 +#define HC_XTC_Dif 0x00000001 +#define HC_XTC_Spec 0x00000002 +#define HC_XTC_Tex 0x00000003 +#define HC_XTC_Cur 0x00000004 +#define HC_XTC_Adif 0x00000005 +#define HC_XTC_Fog 0x00000006 +#define HC_XTC_Atex 0x00000007 +#define HC_XTC_Acur 0x00000008 +#define HC_XTC_HTXnTBLRC 0x00000009 +#define HC_XTC_Ctexnext 0x0000000a +/*-- + */ +#define HC_HTXnTBLCsat_MASK 0x00800000 +#define HC_HTXnTBLCa_MASK 0x000fc000 +#define HC_HTXnTBLCb_MASK 0x00001f80 +#define HC_HTXnTBLCc_MASK 0x0000003f +#define HC_HTXnTBLCa_TOPC (HC_XTC_TOPC << 14) +#define HC_HTXnTBLCa_InvTOPC (HC_XTC_InvTOPC << 14) +#define HC_HTXnTBLCa_TOPCp5 (HC_XTC_TOPCp5 << 14) +#define HC_HTXnTBLCa_0 (HC_XTC_0 << 14) +#define HC_HTXnTBLCa_Dif (HC_XTC_Dif << 14) +#define HC_HTXnTBLCa_Spec (HC_XTC_Spec << 14) +#define HC_HTXnTBLCa_Tex (HC_XTC_Tex << 14) +#define HC_HTXnTBLCa_Cur (HC_XTC_Cur << 14) +#define HC_HTXnTBLCa_Adif (HC_XTC_Adif << 14) +#define HC_HTXnTBLCa_Fog (HC_XTC_Fog << 14) +#define HC_HTXnTBLCa_Atex (HC_XTC_Atex << 14) +#define HC_HTXnTBLCa_Acur (HC_XTC_Acur << 14) +#define HC_HTXnTBLCa_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14) +#define HC_HTXnTBLCa_Ctexnext (HC_XTC_Ctexnext << 14) +#define HC_HTXnTBLCb_TOPC (HC_XTC_TOPC << 7) +#define HC_HTXnTBLCb_InvTOPC (HC_XTC_InvTOPC << 7) +#define HC_HTXnTBLCb_TOPCp5 (HC_XTC_TOPCp5 << 7) +#define HC_HTXnTBLCb_0 (HC_XTC_0 << 7) +#define HC_HTXnTBLCb_Dif (HC_XTC_Dif << 7) +#define HC_HTXnTBLCb_Spec (HC_XTC_Spec << 7) +#define HC_HTXnTBLCb_Tex (HC_XTC_Tex << 7) +#define HC_HTXnTBLCb_Cur (HC_XTC_Cur << 7) +#define HC_HTXnTBLCb_Adif (HC_XTC_Adif << 7) +#define HC_HTXnTBLCb_Fog (HC_XTC_Fog << 7) +#define HC_HTXnTBLCb_Atex (HC_XTC_Atex << 7) +#define HC_HTXnTBLCb_Acur (HC_XTC_Acur << 7) +#define HC_HTXnTBLCb_HTXnTBLRC (HC_XTC_HTXnTBLRC << 7) +#define HC_HTXnTBLCb_Ctexnext (HC_XTC_Ctexnext << 7) +#define HC_HTXnTBLCc_TOPC (HC_XTC_TOPC << 0) +#define HC_HTXnTBLCc_InvTOPC (HC_XTC_InvTOPC << 0) +#define HC_HTXnTBLCc_TOPCp5 (HC_XTC_TOPCp5 << 0) +#define HC_HTXnTBLCc_0 (HC_XTC_0 << 0) +#define HC_HTXnTBLCc_Dif (HC_XTC_Dif << 0) +#define HC_HTXnTBLCc_Spec (HC_XTC_Spec << 0) +#define HC_HTXnTBLCc_Tex (HC_XTC_Tex << 0) +#define HC_HTXnTBLCc_Cur (HC_XTC_Cur << 0) +#define HC_HTXnTBLCc_Adif (HC_XTC_Adif << 0) +#define HC_HTXnTBLCc_Fog (HC_XTC_Fog << 0) +#define HC_HTXnTBLCc_Atex (HC_XTC_Atex << 0) +#define HC_HTXnTBLCc_Acur (HC_XTC_Acur << 0) +#define HC_HTXnTBLCc_HTXnTBLRC (HC_XTC_HTXnTBLRC << 0) +#define HC_HTXnTBLCc_Ctexnext (HC_XTC_Ctexnext << 0) +/* HC_SubA_HTXnTBLCop 0x0081 + */ +#define HC_HTXnTBLdot_MASK 0x00c00000 +#define HC_HTXnTBLCop_MASK 0x00380000 +#define HC_HTXnTBLCbias_MASK 0x0007c000 +#define HC_HTXnTBLCshift_MASK 0x00001800 +#define HC_HTXnTBLAop_MASK 0x00000380 +#define HC_HTXnTBLAbias_MASK 0x00000078 +#define HC_HTXnTBLAshift_MASK 0x00000003 +#define HC_HTXnTBLCop_Add 0x00000000 +#define HC_HTXnTBLCop_Sub 0x00080000 +#define HC_HTXnTBLCop_Min 0x00100000 +#define HC_HTXnTBLCop_Max 0x00180000 +#define HC_HTXnTBLCop_Mask 0x00200000 +#define HC_HTXnTBLCbias_Cbias (HC_XTC_Cbias << 14) +#define HC_HTXnTBLCbias_InvCbias (HC_XTC_InvCbias << 14) +#define HC_HTXnTBLCbias_0 (HC_XTC_0 << 14) +#define HC_HTXnTBLCbias_Dif (HC_XTC_Dif << 14) +#define HC_HTXnTBLCbias_Spec (HC_XTC_Spec << 14) +#define HC_HTXnTBLCbias_Tex (HC_XTC_Tex << 14) +#define HC_HTXnTBLCbias_Cur (HC_XTC_Cur << 14) +#define HC_HTXnTBLCbias_Adif (HC_XTC_Adif << 14) +#define HC_HTXnTBLCbias_Fog (HC_XTC_Fog << 14) +#define HC_HTXnTBLCbias_Atex (HC_XTC_Atex << 14) +#define HC_HTXnTBLCbias_Acur (HC_XTC_Acur << 14) +#define HC_HTXnTBLCbias_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14) +#define HC_HTXnTBLCshift_1 0x00000000 +#define HC_HTXnTBLCshift_2 0x00000800 +#define HC_HTXnTBLCshift_No 0x00001000 +#define HC_HTXnTBLCshift_DotP 0x00001800 +/*=* John Sheng [2003.7.18] texture combine *=*/ +#define HC_HTXnTBLDOT3 0x00080000 +#define HC_HTXnTBLDOT4 0x000C0000 + +#define HC_HTXnTBLAop_Add 0x00000000 +#define HC_HTXnTBLAop_Sub 0x00000080 +#define HC_HTXnTBLAop_Min 0x00000100 +#define HC_HTXnTBLAop_Max 0x00000180 +#define HC_HTXnTBLAop_Mask 0x00000200 +#define HC_HTXnTBLAbias_Inv 0x00000040 +#define HC_HTXnTBLAbias_Adif 0x00000000 +#define HC_HTXnTBLAbias_Fog 0x00000008 +#define HC_HTXnTBLAbias_Acur 0x00000010 +#define HC_HTXnTBLAbias_HTXnTBLRAbias 0x00000018 +#define HC_HTXnTBLAbias_Atex 0x00000020 +#define HC_HTXnTBLAshift_1 0x00000000 +#define HC_HTXnTBLAshift_2 0x00000001 +#define HC_HTXnTBLAshift_No 0x00000002 +/* #define HC_HTXnTBLAshift_DotP 0x00000003 */ +/* HC_SubA_HTXnTBLMPFog 0x0082 + */ +#define HC_HTXnTBLMPfog_MASK 0x00e00000 +#define HC_HTXnTBLMPfog_0 0x00000000 +#define HC_HTXnTBLMPfog_Adif 0x00200000 +#define HC_HTXnTBLMPfog_Fog 0x00400000 +#define HC_HTXnTBLMPfog_Atex 0x00600000 +#define HC_HTXnTBLMPfog_Acur 0x00800000 +#define HC_HTXnTBLMPfog_GHTXnTBLRFog 0x00a00000 +/* HC_SubA_HTXnTBLAsat 0x0083 + *-- Define the texture alpha input. + */ +#define HC_XTA_TOPA 0x00000000 +#define HC_XTA_InvTOPA 0x00000008 +#define HC_XTA_TOPAp5 0x00000010 +#define HC_XTA_Adif 0x00000000 +#define HC_XTA_Fog 0x00000001 +#define HC_XTA_Acur 0x00000002 +#define HC_XTA_HTXnTBLRA 0x00000003 +#define HC_XTA_Atex 0x00000004 +#define HC_XTA_Atexnext 0x00000005 +/*-- + */ +#define HC_HTXnTBLAsat_MASK 0x00800000 +#define HC_HTXnTBLAMB_MASK 0x00700000 +#define HC_HTXnTBLAa_MASK 0x0007c000 +#define HC_HTXnTBLAb_MASK 0x00000f80 +#define HC_HTXnTBLAc_MASK 0x0000001f +#define HC_HTXnTBLAMB_SHIFT 20 +#define HC_HTXnTBLAa_TOPA (HC_XTA_TOPA << 14) +#define HC_HTXnTBLAa_InvTOPA (HC_XTA_InvTOPA << 14) +#define HC_HTXnTBLAa_TOPAp5 (HC_XTA_TOPAp5 << 14) +#define HC_HTXnTBLAa_Adif (HC_XTA_Adif << 14) +#define HC_HTXnTBLAa_Fog (HC_XTA_Fog << 14) +#define HC_HTXnTBLAa_Acur (HC_XTA_Acur << 14) +#define HC_HTXnTBLAa_HTXnTBLRA (HC_XTA_HTXnTBLRA << 14) +#define HC_HTXnTBLAa_Atex (HC_XTA_Atex << 14) +#define HC_HTXnTBLAa_Atexnext (HC_XTA_Atexnext << 14) +#define HC_HTXnTBLAb_TOPA (HC_XTA_TOPA << 7) +#define HC_HTXnTBLAb_InvTOPA (HC_XTA_InvTOPA << 7) +#define HC_HTXnTBLAb_TOPAp5 (HC_XTA_TOPAp5 << 7) +#define HC_HTXnTBLAb_Adif (HC_XTA_Adif << 7) +#define HC_HTXnTBLAb_Fog (HC_XTA_Fog << 7) +#define HC_HTXnTBLAb_Acur (HC_XTA_Acur << 7) +#define HC_HTXnTBLAb_HTXnTBLRA (HC_XTA_HTXnTBLRA << 7) +#define HC_HTXnTBLAb_Atex (HC_XTA_Atex << 7) +#define HC_HTXnTBLAb_Atexnext (HC_XTA_Atexnext << 7) +#define HC_HTXnTBLAc_TOPA (HC_XTA_TOPA << 0) +#define HC_HTXnTBLAc_InvTOPA (HC_XTA_InvTOPA << 0) +#define HC_HTXnTBLAc_TOPAp5 (HC_XTA_TOPAp5 << 0) +#define HC_HTXnTBLAc_Adif (HC_XTA_Adif << 0) +#define HC_HTXnTBLAc_Fog (HC_XTA_Fog << 0) +#define HC_HTXnTBLAc_Acur (HC_XTA_Acur << 0) +#define HC_HTXnTBLAc_HTXnTBLRA (HC_XTA_HTXnTBLRA << 0) +#define HC_HTXnTBLAc_Atex (HC_XTA_Atex << 0) +#define HC_HTXnTBLAc_Atexnext (HC_XTA_Atexnext << 0) +/* HC_SubA_HTXnTBLRAa 0x0089 + */ +#define HC_HTXnTBLRAa_MASK 0x00ff0000 +#define HC_HTXnTBLRAb_MASK 0x0000ff00 +#define HC_HTXnTBLRAc_MASK 0x000000ff +#define HC_HTXnTBLRAa_SHIFT 16 +#define HC_HTXnTBLRAb_SHIFT 8 +#define HC_HTXnTBLRAc_SHIFT 0 +/* HC_SubA_HTXnTBLRFog 0x008a + */ +#define HC_HTXnTBLRFog_MASK 0x0000ff00 +#define HC_HTXnTBLRAbias_MASK 0x000000ff +#define HC_HTXnTBLRFog_SHIFT 8 +#define HC_HTXnTBLRAbias_SHIFT 0 +/* HC_SubA_HTXnLScale 0x0094 + */ +#define HC_HTXnLScale_MASK 0x0007fc00 +#define HC_HTXnLOff_MASK 0x000001ff +#define HC_HTXnLScale_SHIFT 10 +/* HC_SubA_HTXSMD 0x0000 + */ +#define HC_HTXSMD_MASK 0x00000080 +#define HC_HTXTMD_MASK 0x00000040 +#define HC_HTXNum_MASK 0x00000038 +#define HC_HTXTRMD_MASK 0x00000006 +#define HC_HTXCHCLR_MASK 0x00000001 +#define HC_HTXNum_SHIFT 3 + +/* Texture Palette n + */ +#define HC_SubType_TexPalette0 0x00000000 +#define HC_SubType_TexPalette1 0x00000001 +#define HC_SubType_FogTable 0x00000010 +#define HC_SubType_Stipple 0x00000014 +/* HC_SubA_TexPalette0 0x0000 + */ +#define HC_HTPnA_MASK 0xff000000 +#define HC_HTPnR_MASK 0x00ff0000 +#define HC_HTPnG_MASK 0x0000ff00 +#define HC_HTPnB_MASK 0x000000ff +/* HC_SubA_FogTable 0x0010 + */ +#define HC_HFPn3_MASK 0xff000000 +#define HC_HFPn2_MASK 0x00ff0000 +#define HC_HFPn1_MASK 0x0000ff00 +#define HC_HFPn_MASK 0x000000ff +#define HC_HFPn3_SHIFT 24 +#define HC_HFPn2_SHIFT 16 +#define HC_HFPn1_SHIFT 8 + +/* Auto Testing & Security + */ +#define HC_SubA_HenFIFOAT 0x0000 +#define HC_SubA_HFBDrawFirst 0x0004 +#define HC_SubA_HFBBasL 0x0005 +#define HC_SubA_HFBDst 0x0006 +/* HC_SubA_HenFIFOAT 0x0000 + */ +#define HC_HenFIFOAT_MASK 0x00000020 +#define HC_HenGEMILock_MASK 0x00000010 +#define HC_HenFBASwap_MASK 0x00000008 +#define HC_HenOT_MASK 0x00000004 +#define HC_HenCMDQ_MASK 0x00000002 +#define HC_HenTXCTSU_MASK 0x00000001 +/* HC_SubA_HFBDrawFirst 0x0004 + */ +#define HC_HFBDrawFirst_MASK 0x00000800 +#define HC_HFBQueue_MASK 0x00000400 +#define HC_HFBLock_MASK 0x00000200 +#define HC_HEOF_MASK 0x00000100 +#define HC_HFBBasH_MASK 0x000000ff + +/* GEMI Setting + */ +#define HC_SubA_HTArbRCM 0x0008 +#define HC_SubA_HTArbRZ 0x000a +#define HC_SubA_HTArbWZ 0x000b +#define HC_SubA_HTArbRTX 0x000c +#define HC_SubA_HTArbRCW 0x000d +#define HC_SubA_HTArbE2 0x000e +#define HC_SubA_HArbRQCM 0x0010 +#define HC_SubA_HArbWQCM 0x0011 +#define HC_SubA_HGEMITout 0x0020 +#define HC_SubA_HFthRTXD 0x0040 +#define HC_SubA_HFthRTXA 0x0044 +#define HC_SubA_HCMDQstL 0x0050 +#define HC_SubA_HCMDQendL 0x0051 +#define HC_SubA_HCMDQLen 0x0052 +/* HC_SubA_HTArbRCM 0x0008 + */ +#define HC_HTArbRCM_MASK 0x0000ffff +/* HC_SubA_HTArbRZ 0x000a + */ +#define HC_HTArbRZ_MASK 0x0000ffff +/* HC_SubA_HTArbWZ 0x000b + */ +#define HC_HTArbWZ_MASK 0x0000ffff +/* HC_SubA_HTArbRTX 0x000c + */ +#define HC_HTArbRTX_MASK 0x0000ffff +/* HC_SubA_HTArbRCW 0x000d + */ +#define HC_HTArbRCW_MASK 0x0000ffff +/* HC_SubA_HTArbE2 0x000e + */ +#define HC_HTArbE2_MASK 0x0000ffff +/* HC_SubA_HArbRQCM 0x0010 + */ +#define HC_HTArbRQCM_MASK 0x0000ffff +/* HC_SubA_HArbWQCM 0x0011 + */ +#define HC_HArbWQCM_MASK 0x0000ffff +/* HC_SubA_HGEMITout 0x0020 + */ +#define HC_HGEMITout_MASK 0x000f0000 +#define HC_HNPArbZC_MASK 0x0000ffff +#define HC_HGEMITout_SHIFT 16 +/* HC_SubA_HFthRTXD 0x0040 + */ +#define HC_HFthRTXD_MASK 0x00ff0000 +#define HC_HFthRZD_MASK 0x0000ff00 +#define HC_HFthWZD_MASK 0x000000ff +#define HC_HFthRTXD_SHIFT 16 +#define HC_HFthRZD_SHIFT 8 +/* HC_SubA_HFthRTXA 0x0044 + */ +#define HC_HFthRTXA_MASK 0x000000ff + +/****************************************************************************** +** Define the Halcyon Internal register access constants. For simulator only. +******************************************************************************/ +#define HC_SIMA_HAGPBstL 0x0000 +#define HC_SIMA_HAGPBendL 0x0001 +#define HC_SIMA_HAGPCMNT 0x0002 +#define HC_SIMA_HAGPBpL 0x0003 +#define HC_SIMA_HAGPBpH 0x0004 +#define HC_SIMA_HClipTB 0x0005 +#define HC_SIMA_HClipLR 0x0006 +#define HC_SIMA_HFPClipTL 0x0007 +#define HC_SIMA_HFPClipBL 0x0008 +#define HC_SIMA_HFPClipLL 0x0009 +#define HC_SIMA_HFPClipRL 0x000a +#define HC_SIMA_HFPClipTBH 0x000b +#define HC_SIMA_HFPClipLRH 0x000c +#define HC_SIMA_HLP 0x000d +#define HC_SIMA_HLPRF 0x000e +#define HC_SIMA_HSolidCL 0x000f +#define HC_SIMA_HPixGC 0x0010 +#define HC_SIMA_HSPXYOS 0x0011 +#define HC_SIMA_HCmdA 0x0012 +#define HC_SIMA_HCmdB 0x0013 +#define HC_SIMA_HEnable 0x0014 +#define HC_SIMA_HZWBBasL 0x0015 +#define HC_SIMA_HZWBBasH 0x0016 +#define HC_SIMA_HZWBType 0x0017 +#define HC_SIMA_HZBiasL 0x0018 +#define HC_SIMA_HZWBend 0x0019 +#define HC_SIMA_HZWTMD 0x001a +#define HC_SIMA_HZWCDL 0x001b +#define HC_SIMA_HZWCTAGnum 0x001c +#define HC_SIMA_HZCYNum 0x001d +#define HC_SIMA_HZWCFire 0x001e +/* #define HC_SIMA_HSBBasL 0x001d */ +/* #define HC_SIMA_HSBBasH 0x001e */ +/* #define HC_SIMA_HSBFM 0x001f */ +#define HC_SIMA_HSTREF 0x0020 +#define HC_SIMA_HSTMD 0x0021 +#define HC_SIMA_HABBasL 0x0022 +#define HC_SIMA_HABBasH 0x0023 +#define HC_SIMA_HABFM 0x0024 +#define HC_SIMA_HATMD 0x0025 +#define HC_SIMA_HABLCsat 0x0026 +#define HC_SIMA_HABLCop 0x0027 +#define HC_SIMA_HABLAsat 0x0028 +#define HC_SIMA_HABLAop 0x0029 +#define HC_SIMA_HABLRCa 0x002a +#define HC_SIMA_HABLRFCa 0x002b +#define HC_SIMA_HABLRCbias 0x002c +#define HC_SIMA_HABLRCb 0x002d +#define HC_SIMA_HABLRFCb 0x002e +#define HC_SIMA_HABLRAa 0x002f +#define HC_SIMA_HABLRAb 0x0030 +#define HC_SIMA_HDBBasL 0x0031 +#define HC_SIMA_HDBBasH 0x0032 +#define HC_SIMA_HDBFM 0x0033 +#define HC_SIMA_HFBBMSKL 0x0034 +#define HC_SIMA_HROP 0x0035 +#define HC_SIMA_HFogLF 0x0036 +#define HC_SIMA_HFogCL 0x0037 +#define HC_SIMA_HFogCH 0x0038 +#define HC_SIMA_HFogStL 0x0039 +#define HC_SIMA_HFogStH 0x003a +#define HC_SIMA_HFogOOdMF 0x003b +#define HC_SIMA_HFogOOdEF 0x003c +#define HC_SIMA_HFogEndL 0x003d +#define HC_SIMA_HFogDenst 0x003e +/*---- start of texture 0 setting ---- + */ +#define HC_SIMA_HTX0L0BasL 0x0040 +#define HC_SIMA_HTX0L1BasL 0x0041 +#define HC_SIMA_HTX0L2BasL 0x0042 +#define HC_SIMA_HTX0L3BasL 0x0043 +#define HC_SIMA_HTX0L4BasL 0x0044 +#define HC_SIMA_HTX0L5BasL 0x0045 +#define HC_SIMA_HTX0L6BasL 0x0046 +#define HC_SIMA_HTX0L7BasL 0x0047 +#define HC_SIMA_HTX0L8BasL 0x0048 +#define HC_SIMA_HTX0L9BasL 0x0049 +#define HC_SIMA_HTX0LaBasL 0x004a +#define HC_SIMA_HTX0LbBasL 0x004b +#define HC_SIMA_HTX0LcBasL 0x004c +#define HC_SIMA_HTX0LdBasL 0x004d +#define HC_SIMA_HTX0LeBasL 0x004e +#define HC_SIMA_HTX0LfBasL 0x004f +#define HC_SIMA_HTX0L10BasL 0x0050 +#define HC_SIMA_HTX0L11BasL 0x0051 +#define HC_SIMA_HTX0L012BasH 0x0052 +#define HC_SIMA_HTX0L345BasH 0x0053 +#define HC_SIMA_HTX0L678BasH 0x0054 +#define HC_SIMA_HTX0L9abBasH 0x0055 +#define HC_SIMA_HTX0LcdeBasH 0x0056 +#define HC_SIMA_HTX0Lf1011BasH 0x0057 +#define HC_SIMA_HTX0L0Pit 0x0058 +#define HC_SIMA_HTX0L1Pit 0x0059 +#define HC_SIMA_HTX0L2Pit 0x005a +#define HC_SIMA_HTX0L3Pit 0x005b +#define HC_SIMA_HTX0L4Pit 0x005c +#define HC_SIMA_HTX0L5Pit 0x005d +#define HC_SIMA_HTX0L6Pit 0x005e +#define HC_SIMA_HTX0L7Pit 0x005f +#define HC_SIMA_HTX0L8Pit 0x0060 +#define HC_SIMA_HTX0L9Pit 0x0061 +#define HC_SIMA_HTX0LaPit 0x0062 +#define HC_SIMA_HTX0LbPit 0x0063 +#define HC_SIMA_HTX0LcPit 0x0064 +#define HC_SIMA_HTX0LdPit 0x0065 +#define HC_SIMA_HTX0LePit 0x0066 +#define HC_SIMA_HTX0LfPit 0x0067 +#define HC_SIMA_HTX0L10Pit 0x0068 +#define HC_SIMA_HTX0L11Pit 0x0069 +#define HC_SIMA_HTX0L0_5WE 0x006a +#define HC_SIMA_HTX0L6_bWE 0x006b +#define HC_SIMA_HTX0Lc_11WE 0x006c +#define HC_SIMA_HTX0L0_5HE 0x006d +#define HC_SIMA_HTX0L6_bHE 0x006e +#define HC_SIMA_HTX0Lc_11HE 0x006f +#define HC_SIMA_HTX0L0OS 0x0070 +#define HC_SIMA_HTX0TB 0x0071 +#define HC_SIMA_HTX0MPMD 0x0072 +#define HC_SIMA_HTX0CLODu 0x0073 +#define HC_SIMA_HTX0FM 0x0074 +#define HC_SIMA_HTX0TRCH 0x0075 +#define HC_SIMA_HTX0TRCL 0x0076 +#define HC_SIMA_HTX0TBC 0x0077 +#define HC_SIMA_HTX0TRAH 0x0078 +#define HC_SIMA_HTX0TBLCsat 0x0079 +#define HC_SIMA_HTX0TBLCop 0x007a +#define HC_SIMA_HTX0TBLMPfog 0x007b +#define HC_SIMA_HTX0TBLAsat 0x007c +#define HC_SIMA_HTX0TBLRCa 0x007d +#define HC_SIMA_HTX0TBLRCb 0x007e +#define HC_SIMA_HTX0TBLRCc 0x007f +#define HC_SIMA_HTX0TBLRCbias 0x0080 +#define HC_SIMA_HTX0TBLRAa 0x0081 +#define HC_SIMA_HTX0TBLRFog 0x0082 +#define HC_SIMA_HTX0BumpM00 0x0083 +#define HC_SIMA_HTX0BumpM01 0x0084 +#define HC_SIMA_HTX0BumpM10 0x0085 +#define HC_SIMA_HTX0BumpM11 0x0086 +#define HC_SIMA_HTX0LScale 0x0087 +/*---- end of texture 0 setting ---- 0x008f + */ +#define HC_SIMA_TX0TX1_OFF 0x0050 +/*---- start of texture 1 setting ---- + */ +#define HC_SIMA_HTX1L0BasL (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L1BasL (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L2BasL (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L3BasL (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L4BasL (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L5BasL (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6BasL (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L7BasL (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L8BasL (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9BasL (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LaBasL (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LbBasL (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcBasL (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LdBasL (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LeBasL (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LfBasL (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L10BasL (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L11BasL (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L012BasH (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L345BasH (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L678BasH (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9abBasH (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcdeBasH (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lf1011BasH (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0Pit (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L1Pit (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L2Pit (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L3Pit (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L4Pit (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L5Pit (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6Pit (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L7Pit (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L8Pit (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L9Pit (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LaPit (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LbPit (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LcPit (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LdPit (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LePit (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LfPit (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L10Pit (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L11Pit (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0_5WE (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6_bWE (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lc_11WE (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0_5HE (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L6_bHE (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1Lc_11HE (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1L0OS (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TB (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1MPMD (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1CLODu (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1FM (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRCH (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRCL (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBC (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TRAH (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LTC (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LTA (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLCsat (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLCop (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLMPfog (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLAsat (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCa (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCb (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCc (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRCbias (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRAa (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1TBLRFog (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM00 (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM01 (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM10 (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1BumpM11 (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF) +#define HC_SIMA_HTX1LScale (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF) +/*---- end of texture 1 setting ---- 0xaf + */ +#define HC_SIMA_HTXSMD 0x00b0 +#define HC_SIMA_HenFIFOAT 0x00b1 +#define HC_SIMA_HFBDrawFirst 0x00b2 +#define HC_SIMA_HFBBasL 0x00b3 +#define HC_SIMA_HTArbRCM 0x00b4 +#define HC_SIMA_HTArbRZ 0x00b5 +#define HC_SIMA_HTArbWZ 0x00b6 +#define HC_SIMA_HTArbRTX 0x00b7 +#define HC_SIMA_HTArbRCW 0x00b8 +#define HC_SIMA_HTArbE2 0x00b9 +#define HC_SIMA_HGEMITout 0x00ba +#define HC_SIMA_HFthRTXD 0x00bb +#define HC_SIMA_HFthRTXA 0x00bc +/* Define the texture palette 0 + */ +#define HC_SIMA_HTP0 0x0100 +#define HC_SIMA_HTP1 0x0200 +#define HC_SIMA_FOGTABLE 0x0300 +#define HC_SIMA_STIPPLE 0x0400 +#define HC_SIMA_HE3Fire 0x0440 +#define HC_SIMA_TRANS_SET 0x0441 +#define HC_SIMA_HREngSt 0x0442 +#define HC_SIMA_HRFIFOempty 0x0443 +#define HC_SIMA_HRFIFOfull 0x0444 +#define HC_SIMA_HRErr 0x0445 +#define HC_SIMA_FIFOstatus 0x0446 + +/****************************************************************************** +** Define the AGP command header. +******************************************************************************/ +#define HC_ACMD_MASK 0xfe000000 +#define HC_ACMD_SUB_MASK 0x0c000000 +#define HC_ACMD_HCmdA 0xee000000 +#define HC_ACMD_HCmdB 0xec000000 +#define HC_ACMD_HCmdC 0xea000000 +#define HC_ACMD_H1 0xf0000000 +#define HC_ACMD_H2 0xf2000000 +#define HC_ACMD_H3 0xf4000000 +#define HC_ACMD_H4 0xf6000000 + +#define HC_ACMD_H1IO_MASK 0x000001ff +#define HC_ACMD_H2IO1_MASK 0x001ff000 +#define HC_ACMD_H2IO2_MASK 0x000001ff +#define HC_ACMD_H2IO1_SHIFT 12 +#define HC_ACMD_H2IO2_SHIFT 0 +#define HC_ACMD_H3IO_MASK 0x000001ff +#define HC_ACMD_H3COUNT_MASK 0x01fff000 +#define HC_ACMD_H3COUNT_SHIFT 12 +#define HC_ACMD_H4ID_MASK 0x000001ff +#define HC_ACMD_H4COUNT_MASK 0x01fffe00 +#define HC_ACMD_H4COUNT_SHIFT 9 + +/******************************************************************************** +** Define Header +********************************************************************************/ +#define HC_HEADER2 0xF210F110 + +/******************************************************************************** +** Define Dummy Value +********************************************************************************/ +#define HC_DUMMY 0xCCCCCCCC +/******************************************************************************** +** Define for DMA use +********************************************************************************/ +#define HALCYON_HEADER2 0XF210F110 +#define HALCYON_FIRECMD 0XEE100000 +#define HALCYON_FIREMASK 0XFFF00000 +#define HALCYON_CMDB 0XEC000000 +#define HALCYON_CMDBMASK 0XFFFE0000 +#define HALCYON_SUB_ADDR0 0X00000000 +#define HALCYON_HEADER1MASK 0XFFFFFC00 +#define HALCYON_HEADER1 0XF0000000 +#define HC_SubA_HAGPBstL 0x0060 +#define HC_SubA_HAGPBendL 0x0061 +#define HC_SubA_HAGPCMNT 0x0062 +#define HC_SubA_HAGPBpL 0x0063 +#define HC_SubA_HAGPBpH 0x0064 +#define HC_HAGPCMNT_MASK 0x00800000 +#define HC_HCmdErrClr_MASK 0x00400000 +#define HC_HAGPBendH_MASK 0x0000ff00 +#define HC_HAGPBstH_MASK 0x000000ff +#define HC_HAGPBendH_SHIFT 8 +#define HC_HAGPBstH_SHIFT 0 +#define HC_HAGPBpL_MASK 0x00fffffc +#define HC_HAGPBpID_MASK 0x00000003 +#define HC_HAGPBpID_PAUSE 0x00000000 +#define HC_HAGPBpID_JUMP 0x00000001 +#define HC_HAGPBpID_STOP 0x00000002 +#define HC_HAGPBpH_MASK 0x00ffffff + + +#define VIA_VIDEO_HEADER5 0xFE040000 +#define VIA_VIDEO_HEADER6 0xFE050000 +#define VIA_VIDEO_HEADER7 0xFE060000 +#define VIA_VIDEOMASK 0xFFFF0000 +#endif diff --git a/trunk/src/via_accel.c b/trunk/src/via_accel.c new file mode 100644 index 000000000000..7150ab41de78 --- /dev/null +++ b/trunk/src/via_accel.c @@ -0,0 +1,2723 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2006 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. + * + * Mostly rewritten and modified for EXA support by Thomas Hellstrom 2005. + */ + +/************************************************************************* + * + * File: via_accel.c + * Content: 2D acceleration function for VIA/S3G UniChrome + * + ************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xarch.h> +#include "xaalocal.h" +#include "xaarop.h" +#include "miline.h" + +#include "via.h" +#include "via_driver.h" +#include "via_regs.h" +#include "via_id.h" +#include "via_dmabuffer.h" + +#ifdef X_HAVE_XAAGETROP +#define VIAACCELPATTERNROP(vRop) (XAAGetPatternROP(vRop) << 24) +#define VIAACCELCOPYROP(vRop) (XAAGetCopyROP(vRop) << 24) +#else +#define VIAACCELPATTERNROP(vRop) (XAAPatternROP[vRop] << 24) +#define VIAACCELCOPYROP(vRop) (XAACopyROP[vRop] << 24) +#endif + +/* + * Use PCI MMIO to flush the command buffer when AGP DMA is not available. + */ + +static void +viaDumpDMA(ViaCommandBuffer * buf) +{ + register CARD32 *bp = buf->buf; + CARD32 *endp = bp + buf->pos; + + while (bp != endp) { + if (((bp - buf->buf) & 3) == 0) { + ErrorF("\n %04lx: ", (unsigned long)(bp - buf->buf)); + } + ErrorF("0x%08x ", (unsigned)*bp++); + } + ErrorF("\n"); +} + +void +viaFlushPCI(ViaCommandBuffer * buf) +{ + register CARD32 *bp = buf->buf; + CARD32 transSetting; + CARD32 *endp = bp + buf->pos; + unsigned loop = 0; + register CARD32 offset = 0; + register CARD32 value; + VIAPtr pVia = VIAPTR(buf->pScrn); + + while (bp < endp) { + if (*bp == HALCYON_HEADER2) { + if (++bp == endp) + return; + VIASETREG(VIA_REG_TRANSET, transSetting = *bp++); + while (bp < endp) { + if ((transSetting != HC_ParaType_CmdVdata) && + ((*bp == HALCYON_HEADER2) + || (*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1)) + break; + VIASETREG(VIA_REG_TRANSPACE, *bp++); + } + } else if ((*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1) { + + while (bp < endp) { + if (*bp == HALCYON_HEADER2) + break; + if (offset == 0) { + /* + * 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. + */ + if (pVia->Chipset != VIA_P4M890 && pVia->Chipset != VIA_K8M890 && + pVia->Chipset != VIA_P4M900) { + 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)) ; + } + offset = (*bp++ & 0x0FFFFFFF) << 2; + value = *bp++; + VIASETREG(offset, value); + } + } else { + ErrorF("Command stream parser error.\n"); + } + } + buf->pos = 0; + buf->mode = 0; + buf->has3dState = FALSE; +} + +/* + * Flush the command buffer using DRM. If in PCI mode, we can bypass DRM, + * but not for command buffers that contains 3D engine state, since then + * the DRM command verifier will lose track of the 3D engine state. + */ + +#ifdef XF86DRI +static void +viaFlushDRIEnabled(ViaCommandBuffer * cb) +{ + ScrnInfoPtr pScrn = cb->pScrn; + VIAPtr pVia = VIAPTR(pScrn); + char *tmp = (char *)cb->buf; + int tmpSize; + drm_via_cmdbuffer_t b; + + /* + * Align command buffer end for AGP DMA. + */ + + OUT_RING_H1(0x2f8, 0x67676767); + if (pVia->agpDMA && cb->mode == 2 && cb->rindex != HC_ParaType_CmdVdata + && (cb->pos & 1)) { + OUT_RING(HC_DUMMY); + } + + tmpSize = cb->pos * sizeof(CARD32); + if (pVia->agpDMA || (pVia->directRenderingEnabled && cb->has3dState)) { + cb->mode = 0; + cb->has3dState = FALSE; + while (tmpSize > 0) { + b.size = (tmpSize > VIA_DMASIZE) ? VIA_DMASIZE : tmpSize; + tmpSize -= b.size; + b.buf = tmp; + tmp += b.size; + if (drmCommandWrite(pVia->drmFD, + ((pVia->agpDMA) ? DRM_VIA_CMDBUFFER : DRM_VIA_PCICMD), &b, + sizeof(b))) { + ErrorF("DRM command buffer submission failed.\n"); + viaDumpDMA(cb); + return; + } + } + cb->pos = 0; + } else { + viaFlushPCI(cb); + } +} +#endif + +/* + * Initialize a command buffer. Some fields are currently not used since they + * are intended for Unichrome Pro group A video commands. + */ + +int +viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, unsigned size) +{ +#ifdef XF86DRI + VIAPtr pVia = VIAPTR(pScrn); +#endif + + buf->pScrn = pScrn; + buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2; + buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32)); + if (!buf->buf) + return BadAlloc; + buf->waitFlags = 0; + buf->pos = 0; + buf->mode = 0; + buf->header_start = 0; + buf->rindex = 0; + buf->has3dState = FALSE; + buf->flushFunc = viaFlushPCI; +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + buf->flushFunc = viaFlushDRIEnabled; + } +#endif + return Success; +} + +/* + * Free resources associated with a command buffer. + */ + +void +viaTearDownCBuffer(ViaCommandBuffer * buf) +{ + if (buf && buf->buf) + xfree(buf->buf); + buf->buf = NULL; +} + +/* + * Leftover from VIA's code. + */ +static void +viaInitPCIe(VIAPtr pVia) +{ + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, 0x680A0000); + VIASETREG(0x420, 0x02000000); +} + +static void +viaInitAgp(VIAPtr pVia) +{ + VIASETREG(VIA_REG_TRANSET, 0x00100000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); + VIASETREG(VIA_REG_TRANSPACE, 0x00333004); + VIASETREG(VIA_REG_TRANSPACE, 0x60000000); + VIASETREG(VIA_REG_TRANSPACE, 0x61000000); + VIASETREG(VIA_REG_TRANSPACE, 0x62000000); + VIASETREG(VIA_REG_TRANSPACE, 0x63000000); + VIASETREG(VIA_REG_TRANSPACE, 0x64000000); + VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); + + VIASETREG(VIA_REG_TRANSET, 0xfe020000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); +} + +/* + * Initialize the virtual command queue. Header 2 commands can be put + * in this queue for buffering. AFAIK it doesn't handle Header 1 + * commands, which is really a pity, since it has to be idled before + * issuing a H1 command. + */ + +static void +viaEnableAgpVQ(VIAPtr pVia) +{ + CARD32 + vqStartAddr = pVia->VQStart, + vqEndAddr = pVia->VQEnd, + vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), + vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), + vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | + ((vqEndAddr & 0xFF000000) >> 16), + vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); + + + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); + VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); + VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); + VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); + VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); + VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); + VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); + VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); + VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); + VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); + VIASETREG(VIA_REG_TRANSPACE, 0x00000006); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); + + VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); + VIASETREG(VIA_REG_TRANSPACE, vqStartL); + VIASETREG(VIA_REG_TRANSPACE, vqEndL); + VIASETREG(VIA_REG_TRANSPACE, vqLen); +} + +static void +viaEnablePCIeVQ(VIAPtr pVia) +{ + CARD32 + vqStartAddr = pVia->VQStart, + vqEndAddr = pVia->VQEnd, + vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), + vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), + vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | + ((vqEndAddr & 0xFF000000) >> 16), + vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); + + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, vqStartEndH); + VIASETREG(0x420, vqStartL); + VIASETREG(0x420, vqEndL); + VIASETREG(0x420, vqLen); + VIASETREG(0x420, 0x74301001); + VIASETREG(0x420, 0x00000000); +} + +/* + * Disable the virtual command queue. + */ + +void +viaDisableVQ(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + switch ( pVia->Chipset ) + { + case VIA_P4M890: + case VIA_K8M890: + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, 0x74301000); + break; + default: + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000004); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); + break; + } +} + +/* + * Update our 2D state (TwoDContext) with a new mode. + */ + +static Bool +viaAccelSetMode(int bpp, ViaTwodContext * tdc) +{ + switch (bpp) { + case 16: + tdc->mode = VIA_GEM_16bpp; + tdc->bytesPPShift = 1; + return TRUE; + case 32: + tdc->mode = VIA_GEM_32bpp; + tdc->bytesPPShift = 2; + return TRUE; + case 8: + tdc->mode = VIA_GEM_8bpp; + tdc->bytesPPShift = 0; + return TRUE; + default: + tdc->bytesPPShift = 0; + return FALSE; + } +} + +/* + * Initialize the 2D engine and set the 2D context mode to the + * current screen depth. Also enable the virtual queue. + */ + +void +viaInitialize2DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int i; + + /* + * init 2D engine regs to reset 2D engine + */ + + for (i = 0x04; i < 0x44; i += 4) { + VIASETREG(i, 0x0); + } + + switch( pVia->Chipset ) { + case VIA_K8M890: + viaInitPCIe(pVia); + break; + default: + viaInitAgp(pVia); + break; + } + + if (pVia->VQStart != 0) { + switch( pVia->Chipset ) { + case VIA_K8M890: + viaEnablePCIeVQ(pVia); + break; + default: + viaEnableAgpVQ(pVia); + break; + } + } else { + viaDisableVQ(pScrn); + } + + viaAccelSetMode(pScrn->bitsPerPixel, tdc); +} + +/* + * Wait for acceleration engines idle. An expensive way to sync. + */ + +void +viaAccelSync(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int loop = 0; + + mem_barrier(); + + switch (pVia->Chipset) { + case VIA_P4M890: + case VIA_K8M890: + case VIA_P4M900: + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY)) && + (loop++ < MAXLOOP)) ; + break; + default: + 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)) ; + break; + } +} + +/* + * Set 2D state clipping on. + */ + +static void +viaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + tdc->clipping = TRUE; + tdc->clipX1 = (x1 & 0xFFFF); + tdc->clipY1 = y1; + tdc->clipX2 = (x2 & 0xFFFF); + tdc->clipY2 = y2; +} + +/* + * Set 2D state clipping off. + */ + +static void +viaDisableClipping(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + tdc->clipping = FALSE; +} + +/* + * Emit clipping borders to the command buffer and update the 2D context + * current command with clipping info. + */ + +static int +viaAccelClippingHelper(ViaCommandBuffer * cb, int refY, ViaTwodContext * tdc) +{ + if (tdc->clipping) { + refY = (refY < tdc->clipY1) ? refY : tdc->clipY1; + tdc->cmd |= VIA_GEC_CLIP_ENABLE; + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_CLIPTL, + ((tdc->clipY1 - refY) << 16) | tdc->clipX1); + OUT_RING_H1(VIA_REG_CLIPBR, + ((tdc->clipY2 - refY) << 16) | tdc->clipX2); + } else { + tdc->cmd &= ~VIA_GEC_CLIP_ENABLE; + } + return refY; + +} + +/* + * Emit a solid blit operation to the command buffer. + */ + +static void +viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h, + unsigned fbBase, CARD32 mode, unsigned pitch, CARD32 fg, CARD32 cmd) +{ + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_GEMODE, mode); + OUT_RING_H1(VIA_REG_DSTBASE, fbBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (pitch >> 3) << 16); + OUT_RING_H1(VIA_REG_DSTPOS, (y << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); + OUT_RING_H1(VIA_REG_FGCOLOR, fg); + OUT_RING_H1(VIA_REG_GECMD, cmd); +} + +/* + * Check if we can use a planeMask and update the 2D context accordingly. + */ + +static Bool +viaAccelPlaneMaskHelper(ViaTwodContext * tdc, CARD32 planeMask) +{ + CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1; + CARD32 curMask = 0x00000000; + CARD32 curByteMask; + int i; + + if ((planeMask & modeMask) != modeMask) { + + /* + * Masking doesn't work in 8bpp. + */ + + if (modeMask == 0xFF) { + tdc->keyControl &= 0x0FFFFFFF; + return FALSE; + } + + /* + * Translate the bit planemask to a byte planemask. + */ + + for (i = 0; i < (1 << tdc->bytesPPShift); ++i) { + curByteMask = (0xFF << (i << 3)); + + if ((planeMask & curByteMask) == 0) { + curMask |= (1 << i); + } else if ((planeMask & curByteMask) != curByteMask) { + tdc->keyControl &= 0x0FFFFFFF; + return FALSE; + } + } + ErrorF("DEBUG: planeMask 0x%08x, curMask 0%02x\n", + (unsigned)planeMask, (unsigned)curMask); + + tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28); + } + + return TRUE; +} + +/* + * Emit transparency state and color to the command buffer. + */ + +static void +viaAccelTransparentHelper(ViaTwodContext * tdc, ViaCommandBuffer * cb, + CARD32 keyControl, CARD32 transColor, Bool usePlaneMask) +{ + tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000); + tdc->keyControl |= (keyControl & 0x0FFFFFFF); + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl); + if (keyControl) { + OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor); + } +} + +/* + * Emit a copy blit operation to the command buffer. + */ + +static void +viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd, + int w, int h, unsigned srcFbBase, unsigned dstFbBase, CARD32 mode, + unsigned srcPitch, unsigned dstPitch, CARD32 cmd) +{ + if (cmd & VIA_GEC_DECY) { + ys += h - 1; + yd += h - 1; + } + + if (cmd & VIA_GEC_DECX) { + xs += w - 1; + xd += w - 1; + } + + BEGIN_RING(16); + OUT_RING_H1(VIA_REG_GEMODE, mode); + OUT_RING_H1(VIA_REG_SRCBASE, srcFbBase >> 3); + OUT_RING_H1(VIA_REG_DSTBASE, dstFbBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((dstPitch >> 3) << 16) | (srcPitch >> 3)); + OUT_RING_H1(VIA_REG_SRCPOS, (ys << 16) | (xs & 0xFFFF)); + OUT_RING_H1(VIA_REG_DSTPOS, (yd << 16) | (xd & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); + OUT_RING_H1(VIA_REG_GECMD, cmd); +} + +/* + * XAA functions. Note that the 2047 line blitter limit has been worked around by adding + * min(y1, y2, clipping y) * stride to the offset (which is recommended by VIA docs). + * The y values (including clipping) must be subtracted accordingly. + */ + +static void +viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, + unsigned planemask, int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 cmd; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIAACCELCOPYROP(rop); + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + tdc->cmd = cmd; + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + sub = viaAccelClippingHelper(cb, y2, tdc); + viaAccelCopyHelper(cb, x1, 0, x2, y2 - sub, w, h, + pScrn->fbOffset + pVia->Bpl * y1, pScrn->fbOffset + pVia->Bpl * sub, + tdc->mode, pVia->Bpl, pVia->Bpl, tdc->cmd); + ADVANCE_RING; +} + +/* + * SetupForSolidFill is also called to set up for lines. + */ + +static void +viaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); +} + +static void +viaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelSolidHelper(cb, x, y - sub, w, h, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, tdc->fgColor, + tdc->cmd); + ADVANCE_RING; +} + +/* + * Original VIA comment: + * 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; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO | + VIAACCELPATTERNROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MPAT_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + tdc->pattern0 = pattern0; + tdc->pattern1 = pattern1; + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + +} + +static void +viaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patOffset; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(22); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + OUT_RING_H1(VIA_REG_PATADDR, patOffset); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0); + OUT_RING_H1(VIA_REG_MONOPAT1, tdc->pattern1); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); + ADVANCE_RING; +} + +static void +viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, + int rop, unsigned planemask, int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop); + tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patAddr; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + if (!w || !h) + return; + + patAddr = (tdc->patternAddr >> 3) | + ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + OUT_RING_H1(VIA_REG_PATADDR, patAddr); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); + ADVANCE_RING; +} + +/* + * CPU to screen functions cannot use AGP due to complicated syncing. Therefore the + * command buffer is flushed before new command emissions and viaFluchPCI is called + * explicitly instead of cb->flushFunc() at the end of each CPU to screen function. + * Should the buffer get completely filled again by a CPU to screen command emission, + * a horrible error will occur. + */ + +static void +viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | + VIAACCELCOPYROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MSRC_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + + ADVANCE_RING; + + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); +} + +static void +viaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (skipleft) { + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); + } + + sub = viaAccelClippingHelper(cb, y, tdc); + BEGIN_RING(4); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); + + viaFlushPCI(cb); + viaDisableClipping(pScrn); +} + +static void +viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned planemask, + int trans_color, int bpp, int depth) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop); + ADVANCE_RING; + viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); +} + +static void +viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, + int skipleft) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + int sub; + + RING_VARS; + + if (skipleft) { + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); + } + + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); + + viaFlushPCI(cb); + viaDisableClipping(pScrn); +} + +static void +viaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + tdc->cmd = VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; + tdc->dashed = FALSE; + + BEGIN_RING(6); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_MONOPAT0, 0xFF); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); +} + +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; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc); + cmd = tdc->cmd | 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; + } + + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + y1 -= sub; + y2 -= sub; + + BEGIN_RING(14); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 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)) + */ + + OUT_RING_H1(VIA_REG_LINE_K1K2, + ((((dy << 1) & 0x3fff) << 16) | (((dy - dx) << 1) & 0x3fff))); + OUT_RING_H1(VIA_REG_LINE_XY, ((y1 << 16) | (x1 & 0xFFFF))); + OUT_RING_H1(VIA_REG_DIMENSION, dx); + OUT_RING_H1(VIA_REG_LINE_ERROR, + (((dy << 1) - dx - error) & 0x3fff) | ((tdc->dashed) ? 0xFF0000 : 0)); + OUT_RING_H1(VIA_REG_GECMD, cmd); + ADVANCE_RING; + +} + +static void +viaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + RING_VARS; + + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING(10); + OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3); + OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16)); + + if (dir == DEGREES_0) { + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, (len - 1)); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT); + } else { + OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF)); + OUT_RING_H1(VIA_REG_DIMENSION, ((len - 1) << 16)); + OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT); + } + ADVANCE_RING; +} + +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; + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE); + cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + + if (bg == -1) { + cmd |= VIA_GEC_MPAT_TRANS; + } + + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = 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; + } + + tdc->pattern0 = pat; + tdc->dashed = TRUE; + + BEGIN_RING(8); + OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); + OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); + OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor); + OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0); +} + +static void +viaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int flags, int phase) +{ + viaSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags); +} + +static int +viaInitXAA(ScreenPtr pScreen) +{ + + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + XAAInfoRecPtr xaaptr; + + /* + * 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; + + 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; + + xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForSolidFill = viaSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + viaSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | 0; + + xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + viaSubsequentColor8x8PatternFillRect; + xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0; + + xaaptr->SetupForSolidLine = viaSetupForSolidLine; + xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine; + xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine; + xaaptr->SolidBresenhamLineErrorTermBits = 14; + xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + 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; + + 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; + + 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; + + /* + * Most Unichromes are much faster using processor to + * framebuffer writes than using the 2D engine for this. + * test with x11perf -shmput500! + */ + + if (pVia->Chipset != VIA_K8M800 && pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900) + xaaptr->ImageWriteFlags |= NO_GXCOPY; + + xaaptr->SetupForImageWrite = viaSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect; + xaaptr->ImageWriteBase = pVia->BltBase; + xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; + + return XAAInit(pScreen, xaaptr); + +} + +/* + * Mark Sync using the 2D blitter for AGP. NoOp for PCI. + * In the future one could even launch a NULL PCI DMA command + * to have an interrupt generated, provided it is possible to + * write to the PCI DMA engines from the AGP command stream. + */ + +int +viaAccelMarkSync(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + + RING_VARS; + + ++pVia->curMarker; + + /* + * Wrap around without possibly affecting the int sign bit. + */ + + pVia->curMarker &= 0x7FFFFFFF; + + if (pVia->agpDMA) { + BEGIN_RING(2); + OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00); + viaAccelSolidHelper(cb, 0, 0, 1, 1, pVia->markerOffset, + VIA_GEM_32bpp, 4, pVia->curMarker, + (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT); + ADVANCE_RING; + } + return pVia->curMarker; +} + +/* + * Wait for the value to get blitted, or in the PCI case for engine idle. + */ + +void +viaAccelWaitMarker(ScreenPtr pScreen, int marker) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 uMarker = marker; + + if (pVia->agpDMA) { + while ((pVia->lastMarkerRead - uMarker) > (1 << 24)) + pVia->lastMarkerRead = *pVia->markerBuf; + } else { + viaAccelSync(pScrn); + } +} + +#ifdef VIA_HAVE_EXA + +/* + * Exa functions. It is assumed that EXA does not exceed the blitter limits. + */ + +static Bool +viaExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + if (exaGetPixmapPitch(pPixmap) & 7) + return FALSE; + + if (!viaAccelSetMode(pPixmap->drawable.depth, tdc)) + return FALSE; + + if (!viaAccelPlaneMaskHelper(tdc, planeMask)) + return FALSE; + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE); + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu); + + tdc->fgColor = fg; + + return TRUE; +} + +static void +viaExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 dstPitch, dstOffset; + + RING_VARS; + + int w = x2 - x1, h = y2 - y1; + + dstPitch = exaGetPixmapPitch(pPixmap); + dstOffset = exaGetPixmapOffset(pPixmap); + + viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset, + tdc->mode, dstPitch, tdc->fgColor, tdc->cmd); + ADVANCE_RING; +} + +static void +viaExaDoneSolidCopy(PixmapPtr pPixmap) +{ +} + +static Bool +viaExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + + RING_VARS; + + if (pSrcPixmap->drawable.bitsPerPixel != + pDstPixmap->drawable.bitsPerPixel) + return FALSE; + + if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3) + return FALSE; + + if (exaGetPixmapPitch(pDstPixmap) & 7) + return FALSE; + + tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap); + + tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu); + if (xdir < 0) + tdc->cmd |= VIA_GEC_DECX; + if (ydir < 0) + tdc->cmd |= VIA_GEC_DECY; + + if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc)) + return FALSE; + + if (!viaAccelPlaneMaskHelper(tdc, planeMask)) + return FALSE; + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE); + + return TRUE; +} + +static void +viaExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + CARD32 srcOffset = tdc->srcOffset; + CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap); + + RING_VARS; + + if (!width || !height) + return; + + viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height, + srcOffset, dstOffset, tdc->mode, tdc->srcPitch, + exaGetPixmapPitch(pDstPixmap), tdc->cmd); + ADVANCE_RING; +} + +#ifdef VIA_DEBUG_COMPOSITE +static void +viaExaCompositePictDesc(PicturePtr pict, char *string, int n) +{ + char format[20]; + char size[20]; + + if (!pict) { + snprintf(string, n, "None"); + return; + } + + switch (pict->format) { + case PICT_x8r8g8b8: + snprintf(format, 20, "RGB8888"); + break; + case PICT_a8r8g8b8: + snprintf(format, 20, "ARGB8888"); + break; + case PICT_r5g6b5: + snprintf(format, 20, "RGB565 "); + break; + case PICT_x1r5g5b5: + snprintf(format, 20, "RGB555 "); + break; + case PICT_a8: + snprintf(format, 20, "A8 "); + break; + case PICT_a1: + snprintf(format, 20, "A1 "); + break; + default: + snprintf(format, 20, "0x%x", (int)pict->format); + break; + } + + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, + pict->pDrawable->height, pict->repeat ? " R" : ""); + + snprintf(string, n, "0x%lx: fmt %s (%s)", (long)pict->pDrawable, format, + size); +} + +static void +viaExaPrintComposite(CARD8 op, + PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) +{ + char sop[20]; + char srcdesc[40], maskdesc[40], dstdesc[40]; + + switch (op) { + case PictOpSrc: + sprintf(sop, "Src"); + break; + case PictOpOver: + sprintf(sop, "Over"); + break; + default: + sprintf(sop, "0x%x", (int)op); + break; + } + + viaExaCompositePictDesc(pSrc, srcdesc, 40); + viaExaCompositePictDesc(pMask, maskdesc, 40); + viaExaCompositePictDesc(pDst, dstdesc, 40); + + ErrorF("Composite fallback: op %s, \n" + " src %s, \n" + " mask %s, \n" + " dst %s, \n", sop, srcdesc, maskdesc, dstdesc); +} +#endif /* VIA_DEBUG_COMPOSITE */ + +/* + * Helper for bitdepth expansion. + */ + +static CARD32 +viaBitExpandHelper(CARD32 component, CARD32 bits) +{ + CARD32 tmp, mask; + + mask = (1 << (8 - bits)) - 1; + tmp = component << (8 - bits); + return ((component & 1) ? tmp | mask : tmp); +} + +/* + * Extract the components from a pixel of format "format" to an + * argb8888 pixel. This is used to extract data from one-pixel repeat pixmaps. + * Assumes little endian. + */ + +static void +viaPixelARGB8888(unsigned format, void *pixelP, CARD32 * argb8888) +{ + CARD32 bits, shift, pixel, bpp; + + bpp = PICT_FORMAT_BPP(format); + + if (bpp <= 8) { + pixel = *((CARD8 *) pixelP); + } else if (bpp <= 16) { + pixel = *((CARD16 *) pixelP); + } else { + pixel = *((CARD32 *) pixelP); + } + + switch (PICT_FORMAT_TYPE(format)) { + case PICT_TYPE_A: + bits = PICT_FORMAT_A(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 24; + return; + case PICT_TYPE_ARGB: + shift = 0; + bits = PICT_FORMAT_B(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits); + shift += bits; + bits = PICT_FORMAT_G(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 8; + shift += bits; + bits = PICT_FORMAT_R(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 16; + shift += bits; + bits = PICT_FORMAT_A(format); + *argb8888 |= ((bits) ? + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) : 0xFF) << 24; + return; + case PICT_TYPE_ABGR: + shift = 0; + bits = PICT_FORMAT_B(format); + *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 16; + shift += bits; + bits = PICT_FORMAT_G(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) << 8; + shift += bits; + bits = PICT_FORMAT_R(format); + *argb8888 |= + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), bits); + shift += bits; + bits = PICT_FORMAT_A(format); + *argb8888 |= ((bits) ? + viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), + bits) : 0xFF) << 24; + return; + default: + break; + } + return; +} + +/* + * Check if the above function will work. + */ + +static Bool +viaExpandablePixel(int format) +{ + int formatType = PICT_FORMAT_TYPE(format); + + return (formatType == PICT_TYPE_A || + formatType == PICT_TYPE_ABGR || formatType == PICT_TYPE_ARGB); +} + +/* + * Check if we need to force upload of the whole 3D state (when other + * clients or subsystems have touched the 3D engine). Also tell DRI + * clients and subsystems that we have touched the 3D engine. + */ + +static Bool +viaCheckUpload(ScrnInfoPtr pScrn, Via3DState * v3d) +{ + VIAPtr pVia = VIAPTR(pScrn); + Bool forceUpload; + + forceUpload = (pVia->lastToUpload != v3d); + pVia->lastToUpload = v3d; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *) + DRIGetSAREAPrivate(pScrn->pScreen); + int myContext = DRIGetContext(pScrn->pScreen); + + forceUpload = forceUpload || (saPriv->ctxOwner != myContext); + saPriv->ctxOwner = myContext; + } +#endif + return forceUpload; +} + +static Bool +viaOrder(CARD32 val, CARD32 * shift) +{ + *shift = 0; + + while (val > (1 << *shift)) + (*shift)++; + return (val == (1 << *shift)); +} + +#ifdef XF86DRI + +static int +viaAccelDMADownload(ScrnInfoPtr pScrn, unsigned long fbOffset, + unsigned srcPitch, unsigned char *dst, + unsigned dstPitch, unsigned w, unsigned h) +{ + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit[2], *curBlit; + unsigned char *sysAligned = NULL; + Bool doSync[2], useBounceBuffer; + unsigned pitch, numLines[2]; + int curBuf, err, i, ret, blitHeight; + + ret = 0; + + useBounceBuffer = (((unsigned long)dst & 15) || (dstPitch & 15)); + doSync[0] = FALSE; + doSync[1] = FALSE; + curBuf = 1; + blitHeight = h; + pitch = dstPitch; + if (useBounceBuffer) { + pitch = ALIGN_TO(dstPitch, 16); + blitHeight = VIA_DMA_DL_SIZE / pitch; + } + + while (doSync[0] || doSync[1] || h != 0) { + curBuf = 1 - curBuf; + curBlit = &blit[curBuf]; + if (doSync[curBuf]) { + + do { + err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &curBlit->sync, sizeof(curBlit->sync)); + } while (err == -EAGAIN); + + if (err) + return err; + + doSync[curBuf] = FALSE; + if (useBounceBuffer) { + for (i = 0; i < numLines[curBuf]; ++i) { + memcpy(dst, curBlit->mem_addr, w); + dst += dstPitch; + curBlit->mem_addr += pitch; + } + } + } + + if (h == 0) + continue; + + curBlit->num_lines = (h > blitHeight) ? blitHeight : h; + h -= curBlit->num_lines; + numLines[curBuf] = curBlit->num_lines; + + sysAligned = + (unsigned char *)pVia->dBounce + (curBuf * VIA_DMA_DL_SIZE); + sysAligned = (unsigned char *) + ALIGN_TO((unsigned long)sysAligned, 16); + + curBlit->mem_addr = (useBounceBuffer) ? sysAligned : dst; + curBlit->line_length = w; + curBlit->mem_stride = pitch; + curBlit->fb_addr = fbOffset; + curBlit->fb_stride = srcPitch; + curBlit->to_fb = 0; + fbOffset += curBlit->num_lines * srcPitch; + + do { + err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit, + sizeof(*curBlit)); + } while (err == -EAGAIN); + + if (err) { + ret = err; + h = 0; + continue; + } + + doSync[curBuf] = TRUE; + } + + return ret; +} + +/* + * Use PCI DMA if we can. If the system alignments don't match, we're using + * an aligned bounce buffer for pipelined PCI DMA and memcpy. + * Throughput for large transfers is around 65 MB/s. + */ + +static Bool +viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + unsigned srcPitch = exaGetPixmapPitch(pSrc); + unsigned wBytes = (pSrc->drawable.bitsPerPixel * w + 7) >> 3; + unsigned srcOffset; + char *bounceAligned = NULL; + unsigned totSize; + + if (!w || !h) + return TRUE; + + srcOffset = x * pSrc->drawable.bitsPerPixel; + if (srcOffset & 3) + return FALSE; + srcOffset = exaGetPixmapOffset(pSrc) + y * srcPitch + (srcOffset >> 3); + + totSize = wBytes * h; + + exaWaitSync(pScrn->pScreen); + if (totSize < VIA_MIN_DOWNLOAD) { + bounceAligned = (char *)pVia->FBBase + srcOffset; + while (h--) { + memcpy(dst, bounceAligned, wBytes); + dst += dst_pitch; + bounceAligned += srcPitch; + } + return TRUE; + } + + if (!pVia->directRenderingEnabled) + return FALSE; + + if ((srcPitch & 3) || (srcOffset & 3)) { + ErrorF("VIA EXA download src_pitch misaligned\n"); + return FALSE; + } + + if (viaAccelDMADownload(pScrn, srcOffset, srcPitch, (unsigned char *)dst, + dst_pitch, wBytes, h)) + return FALSE; + + return TRUE; +} + +/* + * Upload to framebuffer memory using memcpy to AGP pipelined with a + * 3D engine texture operation from AGP to framebuffer. The AGP buffers (2) + * should be kept rather small for optimal pipelining. + */ + +static Bool +viaExaTexUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstPitch = exaGetPixmapPitch(pDst); + unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3; + unsigned dstOffset; + CARD32 texWidth, texHeight, texPitch; + int format; + char *dst; + int i, sync[2], yOffs, bufH, bufOffs, height; + Bool buf; + Via3DState *v3d = &pVia->v3d; + + if (!w || !h) + return TRUE; + + if (wBytes * h < VIA_MIN_TEX_UPLOAD) { + dstOffset = x * pDst->drawable.bitsPerPixel; + if (dstOffset & 3) + return FALSE; + dst = + (char *)pVia->FBBase + (exaGetPixmapOffset(pDst) + y * dstPitch + + (dstOffset >> 3)); + exaWaitSync(pScrn->pScreen); + + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += src_pitch; + } + return TRUE; + } + + if (!pVia->texAddr) + return FALSE; + + switch (pDst->drawable.bitsPerPixel) { + case 32: + format = PICT_a8r8g8b8; + break; + case 16: + format = PICT_r5g6b5; + break; + default: + return FALSE; + } + + dstOffset = exaGetPixmapOffset(pDst); + + if (pVia->nPOT[0]) { + texPitch = ALIGN_TO(wBytes, 32); + height = VIA_AGP_UPL_SIZE / texPitch; + } else { + viaOrder(wBytes, &texPitch); + if (texPitch < 3) + texPitch = 3; + height = VIA_AGP_UPL_SIZE >> texPitch; + texPitch = 1 << texPitch; + } + + if (height > 1024) + height = 1024; + viaOrder(w, &texWidth); + texWidth = 1 << texWidth; + + texHeight = height << 1; + bufOffs = texPitch * height; + + v3d->setDestination(v3d, dstOffset, dstPitch, format); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); + v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); + if (!v3d->setTexture(v3d, 0, pVia->texOffset + pVia->agpAddr, texPitch, + pVia->nPOT[0], texWidth, texHeight, format, via_single, + via_single, via_src, TRUE)) + return FALSE; + + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, + pDst->drawable.height); + + buf = 1; + yOffs = 0; + sync[0] = -1; + sync[1] = -1; + + while (h) { + buf = (buf) ? 0 : 1; + bufH = (h > height) ? height : h; + dst = pVia->texAddr + ((buf) ? bufOffs : 0); + + if (sync[buf] >= 0) + viaAccelWaitMarker(pScrn->pScreen, sync[buf]); + + for (i = 0; i < bufH; ++i) { + memcpy(dst, src, wBytes); + dst += texPitch; + src += src_pitch; + } + + v3d->emitQuad(v3d, &pVia->cb, x, y + yOffs, 0, (buf) ? height : 0, 0, + 0, w, bufH); + + sync[buf] = viaAccelMarkSync(pScrn->pScreen); + + h -= bufH; + yOffs += bufH; + } + + if (sync[buf] >= 0) + viaAccelWaitMarker(pScrn->pScreen, sync[buf]); + + return TRUE; +} + +/* + * I'm not sure PCI DMA upload is necessary. Seems buggy for widths below 65, + * and I'd guess that in most situations CPU direct writes are faster. + * Use DMA only when alignments match. At least it saves some CPU cycles. + */ + +static Bool +viaExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit; + unsigned dstPitch = exaGetPixmapPitch(pDst); + unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3; + unsigned dstOffset; + char *dst; + int err; + + dstOffset = x * pDst->drawable.bitsPerPixel; + if (dstOffset & 3) + return FALSE; + dstOffset = exaGetPixmapOffset(pDst) + y * dstPitch + (dstOffset >> 3); + + if (wBytes * h < VIA_MIN_UPLOAD || wBytes < 65) { + dst = (char *)pVia->FBBase + dstOffset; + + exaWaitSync(pScrn->pScreen); + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += src_pitch; + } + return TRUE; + } + + if (!pVia->directRenderingEnabled) + return FALSE; + + if (((unsigned long)src & 15) || (src_pitch & 15)) + return FALSE; + + if ((dstPitch & 3) || (dstOffset & 3)) + return FALSE; + + blit.line_length = wBytes; + blit.num_lines = h; + blit.fb_addr = dstOffset; + blit.fb_stride = dstPitch; + blit.mem_addr = (unsigned char *)src; + blit.mem_stride = src_pitch; + blit.to_fb = 1; + + exaWaitSync(pScrn->pScreen); + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (err < 0) + return FALSE; + + while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &blit.sync, sizeof(blit.sync)))) ; + return (err == 0); +} + +#endif /* XF86DRI */ + +static Bool +viaExaUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst) +{ + + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + char *src, *dst; + unsigned w, wBytes, srcPitch, h; + CARD32 dstPitch; + + if (!pVia->scratchAddr) + return FALSE; + + *pDst = *pSrc; + w = pSrc->drawable.width; + h = pSrc->drawable.height; + wBytes = (w * pSrc->drawable.bitsPerPixel + 7) >> 3; + + viaOrder(wBytes, &dstPitch); + dstPitch = 1 << dstPitch; + if (dstPitch < 8) + dstPitch = 8; + if (dstPitch * h > pVia->exaScratchSize * 1024) { + ErrorF("EXA UploadToScratch Failed %u %u %u %u\n", + dstPitch, h, dstPitch * h, pVia->exaScratchSize * 1024); + return FALSE; + } + + pDst->devKind = dstPitch; + pDst->devPrivate.ptr = dst = pVia->scratchAddr; + src = pSrc->devPrivate.ptr; + srcPitch = exaGetPixmapPitch(pSrc); + + /* + * Copying to AGP needs not be HW accelerated. + * If scratch is in FB, we are without DRI and HW accel. + */ + + viaAccelSync(pScrn); + + while (h--) { + memcpy(dst, src, wBytes); + dst += dstPitch; + src += srcPitch; + } + + return TRUE; +} + +static Bool +viaExaCheckComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture) +{ + + ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + + /* + * Reject small composites early. They are done much faster in software. + */ + + if (!pSrcPicture->repeat && + pSrcPicture->pDrawable->width * + pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE) + return FALSE; + + if (pMaskPicture && + !pMaskPicture->repeat && + pMaskPicture->pDrawable->width * + pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE) + return FALSE; + + if (pMaskPicture && pMaskPicture->componentAlpha) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Component Alpha operation\n"); +#endif + return FALSE; + } + + if (!v3d->opSupported(op)) { +#ifdef VIA_DEBUG_COMPOSITE +#warning Composite verbose debug turned on. + ErrorF("Operator not supported\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + + /* + * FIXME: A8 destination formats are currently not supported and do not + * seem supported by the hardware, although there are some leftover + * register settings apparent in the via_3d_reg.h file. We need to fix this + * (if important), by using component ARGB8888 operations with bitmask. + */ + + if (!v3d->dstSupported(pDstPicture->format)) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Destination format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + + if (v3d->texSupported(pSrcPicture->format)) { + if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 || + !v3d->texSupported(pMaskPicture->format))) { +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Mask format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; + } + return TRUE; + } +#ifdef VIA_DEBUG_COMPOSITE + ErrorF("Src format not supported:\n"); + viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture); +#endif + return FALSE; +} + +static Bool +viaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset) +{ +#ifdef XF86DRI + unsigned long offs; + + if (pVia->directRenderingEnabled && !pVia->IsPCI) { + offs = (unsigned long)pPix->devPrivate.ptr - + (unsigned long)pVia->agpMappedAddr; + + if ((offs - pVia->scratchOffset) < pVia->agpSize) { + *offset = offs + pVia->agpAddr; + return TRUE; + } + } +#endif + return FALSE; +} + +static Bool +viaIsOffscreen(VIAPtr pVia, PixmapPtr pPix) +{ + return ((unsigned long)pPix->devPrivate.ptr - + (unsigned long)pVia->FBBase) < pVia->videoRambytes; +} + +static Bool +viaExaPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + CARD32 height, width; + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + int curTex = 0; + ViaTexBlendingModes srcMode; + Bool isAGP; + unsigned long offset; + + v3d->setDestination(v3d, exaGetPixmapOffset(pDst), + exaGetPixmapPitch(pDst), pDstPicture->format); + v3d->setCompositeOperator(v3d, op); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF); + + viaOrder(pSrc->drawable.width, &width); + viaOrder(pSrc->drawable.height, &height); + + /* + * For one-pixel repeat mask pictures we avoid using multitexturing by + * modifying the src's texture blending equation and feed the pixel + * value as a constant alpha for the src's texture. Multitexturing on the + * unichromes seems somewhat slow, so this speeds up translucent windows. + */ + + srcMode = via_src; + pVia->maskP = NULL; + if (pMaskPicture && + (pMaskPicture->pDrawable->height == 1) && + (pMaskPicture->pDrawable->width == 1) && + pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) { + pVia->maskP = pMask->devPrivate.ptr; + pVia->maskFormat = pMaskPicture->format; + pVia->componentAlpha = pMaskPicture->componentAlpha; + srcMode = + (pMaskPicture-> + componentAlpha) ? via_src_onepix_comp_mask : via_src_onepix_mask; + } + + /* + * One-Pixel repeat src pictures go as solid color instead of textures. + * Speeds up window shadows. + */ + + pVia->srcP = NULL; + if (pSrcPicture && + (pSrcPicture->pDrawable->height == 1) && + (pSrcPicture->pDrawable->width == 1) && + pSrcPicture->repeat && viaExpandablePixel(pSrcPicture->format)) { + pVia->srcP = pSrc->devPrivate.ptr; + pVia->srcFormat = pSrcPicture->format; + } + + /* + * Exa should be smart enough to eliminate this IN operation. + */ + + if (pVia->srcP && pVia->maskP) { + ErrorF + ("Bad one-pixel IN composite operation. EXA needs to be smarter.\n"); + return FALSE; + } + + if (!pVia->srcP) { + offset = exaGetPixmapOffset(pSrc); + isAGP = viaIsAGP(pVia, pSrc, &offset); + if (!isAGP && !viaIsOffscreen(pVia, pSrc)) + return FALSE; + if (!v3d->setTexture(v3d, curTex, offset, + exaGetPixmapPitch(pSrc), pVia->nPOT[curTex], 1 << width, + 1 << height, pSrcPicture->format, via_repeat, via_repeat, + srcMode, isAGP)) { + return FALSE; + } + curTex++; + } + + if (pMaskPicture && !pVia->maskP) { + offset = exaGetPixmapOffset(pMask); + isAGP = viaIsAGP(pVia, pMask, &offset); + if (!isAGP && !viaIsOffscreen(pVia, pMask)) + return FALSE; + viaOrder(pMask->drawable.width, &width); + viaOrder(pMask->drawable.height, &height); + if (!v3d->setTexture(v3d, curTex, offset, + exaGetPixmapPitch(pMask), pVia->nPOT[curTex], 1 << width, + 1 << height, pMaskPicture->format, via_repeat, via_repeat, + (pMaskPicture->componentAlpha) ? via_comp_mask : via_mask, + isAGP)) { + return FALSE; + } + curTex++; + } + + v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE); + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, + pDst->drawable.height); + + return TRUE; +} + +static void +viaExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + Via3DState *v3d = &pVia->v3d; + CARD32 col; + + if (pVia->maskP) { + viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col); + v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col); + } + if (pVia->srcP) { + viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24); + srcX = maskX; + srcY = maskY; + } + + if (pVia->maskP || pVia->srcP) + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + + v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, width, + height); +} + +#if (EXA_VERSION_MAJOR >= 2) + +static ExaDriverPtr +viaInitExa(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ExaDriverPtr pExa = exaDriverAlloc(); + + memset(pExa, 0, sizeof(*pExa)); + + if (!pExa) + return NULL; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + pExa->memoryBase = pVia->FBBase; + pExa->memorySize = pVia->FBFreeEnd; + pExa->offScreenBase = pScrn->virtualY * pVia->Bpl; + pExa->pixmapOffsetAlign = 32; + pExa->pixmapPitchAlign = 16; + pExa->flags = EXA_OFFSCREEN_PIXMAPS | + (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT); + pExa->maxX = 2047; + pExa->maxY = 2047; + pExa->WaitMarker = viaAccelWaitMarker; + pExa->MarkSync = viaAccelMarkSync; + pExa->PrepareSolid = viaExaPrepareSolid; + pExa->Solid = viaExaSolid; + pExa->DoneSolid = viaExaDoneSolidCopy; + pExa->PrepareCopy = viaExaPrepareCopy; + pExa->Copy = viaExaCopy; + pExa->DoneCopy = viaExaDoneSolidCopy; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { +#ifdef linux + if ((pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) { + pExa->DownloadFromScreen = viaExaDownloadFromScreen; + } +#endif /* linux */ + switch (pVia->Chipset) { + case VIA_K8M800: + case VIA_KM400: + pExa->UploadToScreen = viaExaTexUploadToScreen; + break; + default: + pExa->UploadToScreen = NULL; + break; + } + } +#endif /* XF86DRI */ + + pExa->UploadToScratch = viaExaUploadToScratch; + + if (!pVia->noComposite) { + pExa->CheckComposite = viaExaCheckComposite; + pExa->PrepareComposite = viaExaPrepareComposite; + pExa->Composite = viaExaComposite; + pExa->DoneComposite = viaExaDoneSolidCopy; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Disabling EXA accelerated composite.\n"); + } + + + if (!exaDriverInit(pScreen, pExa)) { + xfree(pExa); + return NULL; + } + + viaInit3DState(&pVia->v3d); + return pExa; +} + +#else + +/* + * Init EXA. Alignments are 2D engine constraints. + */ + +static ExaDriverPtr +viaInitExa(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ExaDriverPtr pExa = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1); + + if (!pExa) + return NULL; + + pExa->card.memoryBase = pVia->FBBase; + pExa->card.memorySize = pVia->FBFreeEnd; + pExa->card.offScreenBase = pScrn->virtualY * pVia->Bpl; + pExa->card.pixmapOffsetAlign = 32; + pExa->card.pixmapPitchAlign = 16; + pExa->card.flags = EXA_OFFSCREEN_PIXMAPS | + (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT); + pExa->card.maxX = 2047; + pExa->card.maxY = 2047; + + pExa->accel.WaitMarker = viaAccelWaitMarker; + pExa->accel.MarkSync = viaAccelMarkSync; + pExa->accel.PrepareSolid = viaExaPrepareSolid; + pExa->accel.Solid = viaExaSolid; + pExa->accel.DoneSolid = viaExaDoneSolidCopy; + pExa->accel.PrepareCopy = viaExaPrepareCopy; + pExa->accel.Copy = viaExaCopy; + pExa->accel.DoneCopy = viaExaDoneSolidCopy; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { +#ifdef linux + if ((pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) { + if (pVia->Chipset != VIA_K8M800) + pExa->accel.UploadToScreen = viaExaUploadToScreen; + pExa->accel.DownloadFromScreen = viaExaDownloadFromScreen; + } +#endif /* linux */ + if (pVia->Chipset == VIA_K8M800) + pExa->accel.UploadToScreen = viaExaTexUploadToScreen; + } +#endif /* XF86DRI */ + + pExa->accel.UploadToScratch = viaExaUploadToScratch; + + if (!pVia->noComposite) { + pExa->accel.CheckComposite = viaExaCheckComposite; + pExa->accel.PrepareComposite = viaExaPrepareComposite; + pExa->accel.Composite = viaExaComposite; + pExa->accel.DoneComposite = viaExaDoneSolidCopy; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Disabling EXA accelerated composite.\n"); + } + + if (!exaDriverInit(pScreen, pExa)) { + xfree(pExa); + return NULL; + } + + viaInit3DState(&pVia->v3d); + return pExa; +} + +#endif /* EXA_VERSION_MAJOR */ +#endif /* VIA_HAVE_EXA */ + +/* + * Acceleration init function. Sets up offscreen memory disposition, initializes engines + * and acceleration method. + */ + +Bool +viaInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + BoxRec AvailFBArea; + int maxY; + Bool nPOTSupported; + + pVia->VQStart = 0; + if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && + pVia->VQEnable) { + 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; + pVia->CursorStart = pVia->FBFreeEnd; + } + + viaInitialize2DEngine(pScrn); + + /* + * Sync marker space. + */ + + pVia->FBFreeEnd -= 32; + pVia->markerOffset = (pVia->FBFreeEnd + 31) & ~31; + pVia->markerBuf = (CARD32 *) ((char *)pVia->FBBase + pVia->markerOffset); + *pVia->markerBuf = 0; + pVia->curMarker = 0; + pVia->lastMarkerRead = 0; + + /* + * nPOT textures. DRM versions below 2.11.0 don't allow them. + * Also some CLE266 hardware may not allow nPOT textures for + * texture engine 1. We need to figure that out. + */ + + nPOTSupported = TRUE; +#ifdef XF86DRI + nPOTSupported = (!pVia->directRenderingEnabled) || + (pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 11)); +#endif + pVia->nPOT[0] = nPOTSupported; + pVia->nPOT[1] = nPOTSupported; + +#ifdef VIA_HAVE_EXA +#ifdef XF86DRI + pVia->texAddr = NULL; + pVia->dBounce = NULL; + pVia->scratchAddr = NULL; +#endif /* XF86DRI */ + if (pVia->useEXA) { + pVia->exaDriverPtr = viaInitExa(pScreen); + if (!pVia->exaDriverPtr) { + + /* + * Docs recommend turning off also Xv here, but we handle this + * case with the old linear offscreen FB manager through + * VIAInitLinear. + */ + + pVia->NoAccel = TRUE; + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Trying to enable EXA acceleration.\n"); + + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + + if ((pVia->driSize > (pVia->maxDriSize * 1024)) + && pVia->maxDriSize > 0) + pVia->driSize = pVia->maxDriSize * 1024; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[EXA] Enabled EXA acceleration.\n"); + return TRUE; + } +#endif /* VIA_HAVE_EXA */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + + /* + * Memory distribution for XAA is tricky. We'd like to make the + * pixmap cache no larger than 3 x visible screen size, otherwise + * XAA may get slow for some undetermined reason. + */ + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); + } else +#endif + { + maxY = pVia->FBFreeEnd / pVia->Bpl; + } + if (maxY > 4 * pScrn->virtualY) + maxY = 4 * pScrn->virtualY; + + pVia->FBFreeStart = (maxY + 1) * pVia->Bpl; + + AvailFBArea.y2 = maxY; + xf86InitFBManager(pScreen, &AvailFBArea); + VIAInitLinear(pScreen); + + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl); + if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) + pVia->driSize = pVia->maxDriSize * 1024; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + AvailFBArea.y2 - pScrn->virtualY)); + + return viaInitXAA(pScreen); +} + +/* + * Free the used acceleration resources. + */ + +void +viaExitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + + viaAccelSync(pScrn); + viaTearDownCBuffer(&pVia->cb); + +#ifdef VIA_HAVE_EXA + if (pVia->useEXA) { +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + if (pVia->texAddr) { + drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM, + &pVia->texAGPBuffer, sizeof(drm_via_mem_t)); + pVia->texAddr = NULL; + } + if (pVia->scratchAddr && !pVia->IsPCI && + ((unsigned long)pVia->scratchAddr - + (unsigned long)pVia->agpMappedAddr == + pVia->scratchOffset)) { + drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM, + &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t)); + pVia->scratchAddr = NULL; + } + } + if (pVia->dBounce) + xfree(pVia->dBounce); +#endif /* XF86DRI */ + if (pVia->scratchAddr) { + exaOffscreenFree(pScreen, pVia->scratchFBBuffer); + pVia->scratchAddr = NULL; + } + if (pVia->exaDriverPtr) { + exaDriverFini(pScreen); + } + xfree(pVia->exaDriverPtr); + pVia->exaDriverPtr = NULL; + return; + } +#endif /* VIA_HAVE_EXA */ + if (pVia->AccelInfoRec) { + XAADestroyInfoRec(pVia->AccelInfoRec); + pVia->AccelInfoRec = NULL; + } +} + +/* + * Allocate a command buffer and buffers for accelerated upload, download, + * and EXA scratch area. The scratch area resides primarily in AGP memory, + * but reverts to FB if AGP is not available. + */ + +void +viaFinishInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + +#ifdef VIA_HAVE_EXA +#ifdef XF86DRI + int size, ret; + + if (pVia->directRenderingEnabled && pVia->useEXA) { + + pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1); + + if (!pVia->IsPCI) { + + /* + * Allocate upload and scratch space. + */ +#if (EXA_VERSION_MAJOR >= 2) + if (pVia->exaDriverPtr->UploadToScreen == viaExaTexUploadToScreen) { +#else + if (pVia->exaDriverPtr->accel.UploadToScreen == + viaExaTexUploadToScreen) { +#endif + size = VIA_AGP_UPL_SIZE * 2 + 32; + pVia->texAGPBuffer.context = 1; + pVia->texAGPBuffer.size = size; + pVia->texAGPBuffer.type = VIA_MEM_AGP; + ret = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM, + &pVia->texAGPBuffer, sizeof(drm_via_mem_t)); + + if (ret || size != pVia->texAGPBuffer.size) { + pVia->texAGPBuffer.size = 0; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of AGP memory for system to frame-buffer transfer.\n", + size / 1024); + pVia->texOffset = (pVia->texAGPBuffer.offset + 31) & ~31; + pVia->texAddr = + (char *)pVia->agpMappedAddr + pVia->texOffset; + } + + } + + size = pVia->exaScratchSize * 1024 + 32; + pVia->scratchAGPBuffer.context = 1; + pVia->scratchAGPBuffer.size = size; + pVia->scratchAGPBuffer.type = VIA_MEM_AGP; + ret = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM, + &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t)); + if (ret || size != pVia->scratchAGPBuffer.size) { + pVia->scratchAGPBuffer.size = 0; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of AGP memory for EXA scratch area.\n", + size / 1024); + pVia->scratchOffset = + (pVia->scratchAGPBuffer.offset + 31) & ~31; + pVia->scratchAddr = + (char *)pVia->agpMappedAddr + pVia->scratchOffset; + } + + } + } +#endif /* XF86DRI */ + if (!pVia->scratchAddr && pVia->useEXA) { + + pVia->scratchFBBuffer = + exaOffscreenAlloc(pScreen, pVia->exaScratchSize * 1024, + 32, TRUE, NULL, NULL); + if (pVia->scratchFBBuffer) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %u kiB of framebuffer memory for EXA scratch area.\n", + pVia->exaScratchSize); + pVia->scratchOffset = pVia->scratchFBBuffer->offset; + pVia->scratchAddr = (char *)pVia->FBBase + pVia->scratchOffset; + } + + } +#endif /* VIA_HAVE_EXA */ + if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) { + pVia->NoAccel = TRUE; + viaExitAccel(pScreen); + return; + } +} + +/* + * DGA accelerated functions go here and let them be independent of acceleration + * method. + */ + +void +viaAccelBlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + unsigned dstOffset = pScrn->fbOffset + dsty * pVia->Bpl; + unsigned srcOffset = pScrn->fbOffset + srcy * pVia->Bpl; + + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + CARD32 cmd = VIA_GEC_BLT | VIAACCELCOPYROP(GXcopy); + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset, + tdc->mode, pVia->Bpl, pVia->Bpl, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned long color) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstBase = pScrn->fbOffset + y * pVia->Bpl; + ViaTwodContext *tdc = &pVia->td; + CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | + VIAACCELPATTERNROP(GXcopy); + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode, + pVia->Bpl, color, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelFillPixmap(ScrnInfoPtr pScrn, + unsigned long offset, + unsigned long pitch, + int depth, int x, int y, int w, int h, unsigned long color) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned dstBase = offset + y * pitch; + ViaTwodContext *tdc = &pVia->td; + CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | + VIAACCELPATTERNROP(GXcopy); + RING_VARS; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + viaAccelSetMode(depth, tdc); + viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE); + viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode, + pitch, color, cmd); + pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen); + ADVANCE_RING; + } +} + +void +viaAccelSyncMarker(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + viaAccelWaitMarker(pScrn->pScreen, pVia->accelMarker); +} + +void +viaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset, + unsigned srcPitch, unsigned w, unsigned h, unsigned srcX, unsigned srcY, + unsigned srcFormat, unsigned long dstOffset, unsigned dstPitch, + unsigned dstX, unsigned dstY, unsigned dstFormat, int rotate) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned wOrder, hOrder; + Via3DState *v3d = &pVia->v3d; + + viaOrder(w, &wOrder); + viaOrder(h, &hOrder); + + v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat); + v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); + v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); + v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE, 1 << wOrder, + 1 << hOrder, srcFormat, via_single, via_single, via_src, FALSE); + v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); + v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h); + v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h); +} diff --git a/trunk/src/via_bandwidth.c b/trunk/src/via_bandwidth.c new file mode 100644 index 000000000000..e09ca192d0ff --- /dev/null +++ b/trunk/src/via_bandwidth.c @@ -0,0 +1,401 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } + } else { /* Single view or Simultaneous case */ +#if 0 + if (mode->HDisplay > 1024) { + ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ + hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ + hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ + } +#endif + } + /* 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; + 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; + 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; + case VIA_VM800: + hwp->writeSeq(hwp, 0x17, 0x2F); + ViaSeqMask(hwp, 0x16, 0x14, 0xBF); + ViaSeqMask(hwp, 0x18, 0x08, 0xBF); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaSeqMask(hwp, 0x22, 0x10, 0x1F); + else + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); + break; + case VIA_K8M890: + case VIA_P4M900: + hwp->writeSeq(hwp, 0x16, 0x92); + hwp->writeSeq(hwp, 0x17, 0xB3); + hwp->writeSeq(hwp, 0x18, 0x8A); + break; + case VIA_P4M890: + break; + case VIA_CX700: + hwp->writeSeq(hwp, 0x16, 0x26); + hwp->writeSeq(hwp, 0x17, 0x5F); + hwp->writeSeq(hwp, 0x18, 0x66); + hwp->writeSeq(hwp, 0x22, 0x1F); + break; + 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; + 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; + 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; + case VIA_VM800: + ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + case VIA_P4M890: + case VIA_K8M890: + case VIA_P4M900: + break; + case VIA_CX700: + ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); + ViaCrtcMask(hwp, 0x94, 0x00, 0x80); + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + + ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x10, 0x70); + + ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); + ViaCrtcMask(hwp, 0x95, 0x00, 0x07); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) + ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); + else + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + 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/trunk/src/via_bios.h b/trunk/src/via_bios.h new file mode 100644 index 000000000000..0b3f8f35836d --- /dev/null +++ b/trunk/src/via_bios.h @@ -0,0 +1,184 @@ +/* + * 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_PANEL12X8 7 +#define VIA_PANEL_INVALID 255 + +#define TVTYPE_NONE 0x00 +#define TVTYPE_NTSC 0x01 +#define TVTYPE_PAL 0x02 +#define TVTYPE_480P 0X03 +#define TVTYPE_576P 0X04 +#define TVTYPE_720P 0X05 +#define TVTYPE_1080I 0X06 + +#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_CH7011 5 +#define VIA_CH7019A 6 +#define VIA_CH7019B 7 +#define VIA_CH7017 8 +#define VIA_CH7304 9 +#define VIA_CH7305 10 + + +#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_DDR533 0x07 +#define VIA_MEM_DDR667 0x08 +#define VIA_MEM_END 0x09 +#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 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]; + int TVNumRegs; + + /* 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); + void (*LCDPower) (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 ViaModeSecondaryVGAOffset(ScrnInfoPtr pScrn); +void ViaModeSecondaryVGAFetchCount(ScrnInfoPtr pScrn, int width); +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); + +/* via_ch7xxx.c */ +I2CDevPtr ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); +void ViaCH7xxxInit(ScrnInfoPtr pScrn); + +#endif /* _VIA_BIOS_H_ */ diff --git a/trunk/src/via_ch7xxx.c b/trunk/src/via_ch7xxx.c new file mode 100644 index 000000000000..64e3e1f31463 --- /dev/null +++ b/trunk/src/via_ch7xxx.c @@ -0,0 +1,650 @@ +/* + * Copyright 2005 Terry Lewis. All Rights Reserved. + * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions) + * 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 + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via_driver.h" +#include "via_vgahw.h" +#include "via_ch7xxx.h" +#include "via_id.h" + +#ifdef HAVE_DEBUG +/* + * + */ +static void +CH7xxxPrintRegs(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 < pBIOSInfo->TVNumRegs; 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"); +} +#endif /* HAVE_DEBUG */ + +/* + * + */ +I2CDevPtr +ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + I2CDevPtr pDev = xf86CreateI2CDevRec(); + CARD8 buf; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxDetect\n")); + + pDev->DevName = "CH7xxx"; + pDev->SlaveAddr = Address; + pDev->pI2CBus = pBus; + + if (!xf86I2CDevInit(pDev)) { + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + + if (!xf86I2CReadByte(pDev, 0x4B, &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 0x17: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7011 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7011; + pDev->DevName="CH7011"; + break; + case 0x19: + xf86I2CReadByte(pDev, 0x4A, &buf); + if (buf == 0x81) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019A LVDS Transmitter/TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7019A; + pDev->DevName="CH7019A"; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019B LVDS Transmitter/TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7019B; + pDev->DevName="CH7019B"; + } + break; + case 0x1B: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7017 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7017; + pDev->DevName="CH7017"; + break; + case 0x3A: + /* single init table --> single channel LVDS transmitter ? */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7304 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7304; + pDev->DevName="CH7304"; + break; + case 0x3B: + /* dual init table --> dual channel LVDS transmitter ? */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7305 LVDS Transmitter\n"); + pBIOSInfo->TVEncoder = VIA_CH7305; + pDev->DevName="CH7305"; + break; + default: + pBIOSInfo->TVEncoder = VIA_NONETV; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown CH7xxx" + " device found. [%x:0x1B contains %x]\n", + Address, buf); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown CH7xxx encoder found\n"); + + xf86DestroyI2CDevRec(pDev,TRUE); + pDev = NULL; + break; + } + + return pDev; +} + +/* + * + */ + +static void +CH7xxxSave(ScrnInfoPtr pScrn) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxSave\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); +} + + +static void +CH7xxxRestore(ScrnInfoPtr pScrn) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxRestore\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); +} + +static CARD8 +CH7xxxDACSenseI2C(I2CDevPtr pDev) +{ + CARD8 save, sense; + + /* Turn all DACP on*/ + xf86I2CWriteByte(pDev, 0x49, 0x20); + + /* Make sure Bypass mode is disabled (DACBP) bit0 is set to '0' */ + xf86I2CReadByte(pDev, 0x21, &save); + xf86I2CWriteByte(pDev, 0x21, save & ~0x01); + + /* Set Sense bit0 to '1' */ + xf86I2CReadByte(pDev, 0x20, &save); + xf86I2CWriteByte(pDev, 0x20, save | 0x01); + + /* Set Sense bit0 back to '0' */ + xf86I2CReadByte(pDev, 0x20, &save); + xf86I2CWriteByte(pDev, 0x20, save & ~0x01); + + /* Read DACT status bits */ + xf86I2CReadByte(pDev, 0x20, &sense); + + return (sense & 0x1F); +} + +/* + * A CH7xxx hack. (T. Lewis. S-Video fixed by P. Langdale) + * + * CH7xxx Cable types (C+S and YcBcR untested and almost certainly wrong) + * 0x10 = Composite + * 0x0C = S-Video + * 0x02 = Composite+S-Video + * 0x04 = YcBcR + * 0x00 = Nothing Connected + */ + +static Bool +CH7xxxDACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxDACDetect\n")); + +/* is this needed? IH */ + if (!pBIOSInfo->TVI2CDev || + !pBIOSInfo->TVEncoder) + return FALSE; + + sense = CH7xxxDACSenseI2C(pBIOSInfo->TVI2CDev); + + /* I'm sure these case values are correct, + * but we should get something in any case. + * 0x10 (Composite), 0x0C (S-Video) and 0x00 (Nothing connected) + * seem to be correct however. + */ + switch (sense) { + case 0x10: + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Composite connected.\n"); + return TRUE; + case 0x0C: + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: S-Video connected.\n"); + return TRUE; + case 0x02: + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: Composite+S-Video connected.\n"); + return TRUE; + case 0x04: + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: YcBcR Connected.\n"); + return TRUE; + case 0x00: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Nothing connected.\n"); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7xxx: Unknown cable combination: 0x0%2X.\n",sense); + return FALSE; + } +} + +static CARD8 +CH7011ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7011ModeIndex\n")); + for (i = 0; CH7011Table[i].Width; i++) { + if ((CH7011Table[i].Width == mode->CrtcHDisplay) && + (CH7011Table[i].Height == mode->CrtcVDisplay) && + (CH7011Table[i].Standard == pBIOSInfo->TVType) && + !(strcmp(CH7011Table[i].name, mode->name))) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7011ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +static CARD8 +CH7019ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7019ModeIndex\n")); + for (i = 0; CH7019Table[i].Width; i++) { + if ((CH7019Table[i].Width == mode->CrtcHDisplay) && + (CH7019Table[i].Height == mode->CrtcVDisplay) && + (CH7019Table[i].Standard == pBIOSInfo->TVType) && + !(strcmp(CH7019Table[i].name, mode->name))) + return i; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7019ModeIndex:" + " Mode \"%s\" not found in Table\n", mode->name); + return 0xFF; +} + +/* + * + */ +static ModeStatus +CH7xxxModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxModeValid\n")); + + if ((mode->PrivSize != sizeof(struct CH7xxxModePrivate)) || + ((mode->Private != (void *) &CH7xxxModePrivateNTSC) && + (mode->Private != (void *) &CH7xxxModePrivatePAL))) { + 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 *) &CH7xxxModePrivateNTSC)) { + 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 *) &CH7xxxModePrivatePAL)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n"); + return MODE_BAD; + } + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + if (CH7011ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + } + else + { + if (CH7019ModeIndex(pScrn, mode) != 0xFF) + return MODE_OK; + } + return MODE_BAD; +} + +static void +CH7xxxModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + CARD8 i, j; + + VIABIOSTVMASKTableRec Mask; + struct CH7xxxTableRec Table; + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + Table = CH7011Table[CH7011ModeIndex(pScrn, mode)]; + Mask = ch7011MaskTable; + } + else + { + Table = CH7019Table[CH7019ModeIndex(pScrn, mode)]; + Mask = ch7019MaskTable; + } + + DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7011ModeI2C\n")); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0); + + for (i = 0,j = 0; (j < Mask.numTV) && (i < VIA_BIOS_TABLE_NUM_TV_REG); i++) { + if (Mask.TV[i] == 0xFF) { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); + j++; + } else { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); + } + } + + if ((pBIOSInfo->TVType == TVTYPE_NTSC) && pBIOSInfo->TVDotCrawl) { + CARD16 *DotCrawl = Table.DotCrawlNTSC; + CARD8 address, save; + + for (i = 1; i < (DotCrawl[0] + 1); i++) { + address = (CARD8)(DotCrawl[i] & 0xFF); + + save = (CARD8)(DotCrawl[i] >> 8); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, address, save); + } + } + + /* + * Only Composite and SVideo have been tested. + */ + switch(pBIOSInfo->TVOutput){ + case TVOUTPUT_COMPOSITE: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x2E); + break; + case TVOUTPUT_SVIDEO: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x32); + break; + case TVOUTPUT_SC: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3C); + break; + case TVOUTPUT_YCBCR: + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3A); + break; + default: + break; + } + + if (pVia->IsSecondary) { /* Patch as setting 2nd path */ + j = (CARD8)(Mask.misc2 >> 5); + for (i = 0; i < j; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, Table.Patch2[i] & 0xFF, Table.Patch2[i] >> 8); + } +} + +static void +CH7xxxModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + CARD8 *CRTC, *Misc; + int i, j; + + VIABIOSTVMASKTableRec Mask; + struct CH7xxxTableRec Table; + + if (pBIOSInfo->TVEncoder == VIA_CH7011) + { + Table = CH7011Table[CH7011ModeIndex(pScrn, mode)]; + Mask = ch7011MaskTable; + } + else + { + Table = CH7019Table[CH7019ModeIndex(pScrn, mode)]; + Mask = ch7019MaskTable; + } + + DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7xxxModeCrtc\n")); + + if (pVia->IsSecondary) { + switch (pScrn->bitsPerPixel) { + case 16: + CRTC = Table.CRTC2_16BPP; + break; + case 24: + case 32: + CRTC = Table.CRTC2_32BPP; + break; + case 8: + default: + CRTC = Table.CRTC2_8BPP; + break; + } + Misc = Table.Misc2; + + + for (i = 0, j = 0; i < Mask.numCRTC2; j++) { + if (Mask.CRTC2[j] == 0xFF) { + hwp->writeCrtc(hwp, j + 0x50, CRTC[j]); + i++; + } + } + + if (Mask.misc2 & 0x18) { + pBIOSInfo->Clock = (Misc[3] << 8) & Misc[4]; + /* VIASetUseExternalClock(hwp); */ + } + + ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); + ViaCrtcMask(hwp, 0x6B, 0x01, 0x01); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); + + /* Disable LCD Scaling */ + if (!pVia->SAMM || pVia->FirstInit) + hwp->writeCrtc(hwp, 0x79, 0x00);} + else { + + CRTC = Table.CRTC1; + Misc = Table.Misc1; + + for (i = 0, j = 0; i < Mask.numCRTC1; j++) { + if (Mask.CRTC1[j] == 0xFF) { + hwp->writeCrtc(hwp, j, CRTC[j]); + i++; + } + } + + ViaCrtcMask(hwp, 0x33, Misc[0], 0x20); + hwp->writeCrtc(hwp, 0x6A, Misc[1]); + + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) { + hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x81); + /* Fix TV clock Polarity for CLE266A2 */ + if (pVia->ChipRev == 0x02) + hwp->writeCrtc(hwp, 0x6C, Misc[3] | 0x01); + } else + hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x01); + + if (Mask.misc1 & 0x30) { + /* CLE266Ax use 2x XCLK */ + if ((pVia->Chipset == VIA_CLE266) && + CLE266_REV_IS_AX(pVia->ChipRev)) + pBIOSInfo->Clock = 0x471C; + else + pBIOSInfo->Clock = (Misc[4] << 8) | Misc[5]; + } + + ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); + ViaCrtcMask(hwp, 0x6B, 0x01, 0x01); + ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); + } + + ViaSeqMask(hwp, 0x1E, 0xC0, 0xC0); /* Enable DI0/DVP0 */ +} + + +/* + * + */ +static void +CH7xxxTVPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + if (On){ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: On\n")); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20); + }else{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: Off\n")); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0); + } +} + +static void +CH7019LCDPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 W_Buffer[2], R_Buffer[1]; + int i; + + if (On){ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: On\n")); + W_Buffer[0] = 0x63; + W_Buffer[1] = 0x4B; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + W_Buffer[0] = 0x66; + W_Buffer[1] = 0x20; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + + for (i = 0; i < 10; i++) { + W_Buffer[0] = 0x63; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + usleep(100); + W_Buffer[0] = 0x63; + W_Buffer[1] = (R_Buffer[0] | 0x40); + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1])); + usleep(1); + W_Buffer[0] = 0x63; + W_Buffer[1] &= ~0x40; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1])); + usleep(100); + W_Buffer[0] = 0x66; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + + if (((R_Buffer[0] & 0x44) == 0x44) || (i >= 9)) { + /* PLL lock OK, Turn on VDD */ + usleep(500); + W_Buffer[1] = R_Buffer[0] | 0x01; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: CH7019 PLL lock ok!\n")); + /* reset data path */ + W_Buffer[0] = 0x48; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] = R_Buffer[0] & ~0x08; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + usleep(1); + W_Buffer[1] = R_Buffer[0]; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + break; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]CH7019 PLL lock fail!\n", i+1)); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CH7xxxLCDPower: [%d]0x66 = %X!\n", i+1, R_Buffer[0])); + } + }else{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: Off\n")); + /* Turn off VDD (Turn off backlignt only) */ + W_Buffer[0] = 0x66; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] &= ~0x01; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + usleep(100); + /* Turn off LVDS path */ + W_Buffer[0] = 0x63; + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1); + W_Buffer[1] = (R_Buffer[0] | 0x40); + xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0); + } +} + +/* + * + */ +void +ViaCH7xxxInit(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxInit\n")); + + switch (pBIOSInfo->TVEncoder) { + case VIA_CH7011: + pBIOSInfo->TVSave = CH7xxxSave; + pBIOSInfo->TVRestore = CH7xxxRestore; + pBIOSInfo->TVDACSense = CH7xxxDACSense; + pBIOSInfo->TVModeValid = CH7xxxModeValid; + pBIOSInfo->TVModeI2C = CH7xxxModeI2C; + pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc; + pBIOSInfo->TVPower = CH7xxxTVPower; + pBIOSInfo->TVModes = CH7011Modes; + pBIOSInfo->LCDPower = NULL; + pBIOSInfo->TVNumRegs = CH_7011_MAX_NUM_REG; +#ifdef HAVE_DEBUG + pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs; +#endif + break; + case VIA_CH7019A: + case VIA_CH7019B: + pBIOSInfo->TVDACSense = CH7xxxDACSense; + pBIOSInfo->TVSave = CH7xxxSave; + pBIOSInfo->TVRestore = CH7xxxRestore; + pBIOSInfo->TVModeValid = CH7xxxModeValid; + pBIOSInfo->TVModeI2C = CH7xxxModeI2C; + pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc; + pBIOSInfo->TVPower = CH7xxxTVPower; + pBIOSInfo->TVModes = CH7019Modes; + pBIOSInfo->LCDPower = CH7019LCDPower; + pBIOSInfo->TVNumRegs = CH_7019_MAX_NUM_REG; +#ifdef HAVE_DEBUG + pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs; +#endif + break; + default: + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCH7xxxInit missing\n")); + break; + } + + /* Save before continuing */ + if (pBIOSInfo->TVSave) + pBIOSInfo->TVSave(pScrn); +} diff --git a/trunk/src/via_ch7xxx.h b/trunk/src/via_ch7xxx.h new file mode 100644 index 000000000000..f74264202b35 --- /dev/null +++ b/trunk/src/via_ch7xxx.h @@ -0,0 +1,737 @@ +/* + * Copyright 2005 Terry Lewis. All Rights Reserved. + * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions) + * 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 + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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_CH7xxx_H_ +#define _VIA_CH7xxx_H_ 1 + +/*+#define VIA_BIOS_MAX_NUM_TV_REG 0x80 ++#define VIA_BIOS_MAX_NUM_TV_CRTC 32 ++#define VIA_BIOS_NUM_TV_SPECIAL_REG 8 ++#define VIA_BIOS_MAX_NUM_TV_PATCH 8 ++#define VIA_BIOS_NUM_TV_OTHER 16 +*/ + +#define VIA_BIOS_TABLE_NUM_TV_REG 0x23 /* 0x00 - 0x22 */ + +#define CH_7011_MAX_NUM_REG 0x4C /* 0x00 - 0x4B */ +#define CH_7019_MAX_NUM_REG 0x80 /* 0x00 - 0x7F */ + +#define VIA_BIOS_MAX_NUM_TV_CRTC 32 +#define VIA_BIOS_NUM_TV_SPECIAL_REG 8 +#define VIA_BIOS_MAX_NUM_TV_PATCH 8 +#define VIA_BIOS_NUM_TV_OTHER 16 + +struct CH7xxxModePrivate { + char id[12]; /* "CH7xxx" */ + CARD8 Standard; +}; + +static struct CH7xxxModePrivate CH7xxxModePrivateNTSC = { + { 'C', 'H', '7', 'x', 'x', 'x', 0, 0, 0, 0, 0, 0 }, + TVTYPE_NTSC, +}; + +static struct CH7xxxModePrivate CH7xxxModePrivatePAL = { + { 'C', 'H', '7', 'x', 'x', '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 CH7xxxModePrivate),(void *)&CH7xxxModePrivateNTSC,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 CH7xxxModePrivate),(void *)&CH7xxxModePrivatePAL,0,0.0,0.0 + +/* dotclock is just for modeline validation */ +static DisplayModeRec CH7011Modes[]={ + { 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("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("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("720x480Noscale"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { 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 }, +}; + +static DisplayModeRec CH7019Modes[]={ + { 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("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(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + + +typedef struct _VIATVMASKTABLE { + CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG]; + CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 misc1; + CARD8 misc2; + int numTV; + int numCRTC1; + int numCRTC2; +} VIABIOSTVMASKTableRec, *VIABIOSTVMASKTablePtr; + +struct CH7xxxTableRec { + char* name; + CARD16 Width; + CARD16 Height; + int Standard; + + CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG]; /*35*/ + CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 Misc1[VIA_BIOS_NUM_TV_SPECIAL_REG]; + CARD8 Misc2[VIA_BIOS_NUM_TV_SPECIAL_REG]; +/*merge these three*/ + CARD8 CRTC2_8BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2_16BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD8 CRTC2_32BPP[VIA_BIOS_MAX_NUM_TV_CRTC]; + CARD16 Patch2[VIA_BIOS_MAX_NUM_TV_PATCH]; + CARD16 DotCrawlNTSC[VIA_BIOS_NUM_TV_OTHER]; +}; + + +static struct CH7xxxTableRec +CH7011Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, + { 0X6A, /* 0x00 Mode 17 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 0x7E) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */ + 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */ + 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */ + 0X05, /* 0x06 VP Default 0x00 (was 0x04) */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X7E, /* 0x0B PLLN Default 0x7E */ + 0X20, /* 0x0C FSCI Default 0x20 */ + 0X80, /* 0x0D FSCI Default 0x80 */ + 0X00, /* 0x0E FSCI Default 0x08 (was 00) */ + 0X00, /* 0x0F FSCI Default 0xEB (was 00) */ + 0, /* 0x10 CIVC */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C */ + 0X40, /* 0x1D */ + 0XD2, /* 0x1E */ + 0X80, /* 0x1F */ + 0X40, /* 0x20 */ + 0, /* 0x21 */ + 0, /* 0x22 */ }, + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480", 640, 480, TVTYPE_PAL, + { 0X61, /* 0x00 PAL Mode 14 non-OS 640x480 1:1 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 0x7E) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */ + 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */ + 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */ + 0X05, /* 0x06 VP Default 0x00 (was 0x04) */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X01, /* 0x08 CE Default 0x03 */ + 0X81, /* 0x09 TPC Default 0x80 */ + 0X04, /* 0x0A PLLM Default 0x3F */ + 0X09, /* 0x0B PLLN Default 0x7E */ + 0X26, /* 0x0C FSCI Default 0x20 */ + 0X6F, /* 0x0D FSCI Default 0x80 */ + 0X1F, /* 0x0E FSCI Default 0x08 */ + 0XD0, /* 0x0F FSCI Default 0xEB */ + 0, /* 0x10 CIVC */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C */ + 0X40, /* 0x1D */ + 0XD2, /* 0x1E */ + 0X80, /* 0x1F */ + 0X40, /* 0x20 */ + 0, /* 0x21 */ + 0, /* 0x22 */ }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3284, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_NTSC, + { 0XCF, /* 0x00 Mode 29 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 0x76) */ + 0X8B, /* 0x03 TE Decent Text 0x8B (was 8F) */ + 0X59, /* 0x04 SAV*/ + 0X3C, /* 0x05 HP */ + 0X15, /* 0x06 VP */ + 0X66, /* 0x07 BL Default 0x83 */ + 0X3, /* 0x08 CE Default 0x03 */ + 0X88, + 0X59, + 0X2E, + 0X19, + 0X8B, + 0X3A, + 0X63, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_PAL, + { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + +/*check these two modes*/ + { "1024x768", 1024, 768, TVTYPE_NTSC, + { 0XEE, + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, + 0X87, + 0X49, + 0X32, + 0X9, + 0X83, + 0X3, + 0X88, + 0X47, + 0X4D, + 0X1B, + 0XE4, + 0X89, + 0X51, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X4A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X6717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768", 1024, 768, TVTYPE_PAL, + { 0XE5, 0X7F, 0XE0, 0X8F, 0XC1, 0X3E, 0X4A, 0X70, 0, 0X81, 0X7, 0X2A, 0X20, 0X6D, 0XC2, 0XD7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X83, 0X97, 0XE6, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XFF, 0, 0, 0XFF, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0XC284, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480Over", 640, 480, TVTYPE_NTSC, + { 0X69, /* 0x00 DM Mode 16 640x480 1/1 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */ + 0X18, /* 0x04 SAV Default 0x50 (was 10) */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X6E, /* 0x0B PLLN Default 0x7E */ + 0X25, /* 0x0C FSCI Default 0x25 */ + 0X24, /* 0x0D FSCI Default 0x24 */ + 0X92, /* 0x0E FSCI Default 0x9C (was 92) */ + 0X49, /* 0x0F FSCI Default 0x7A (was 49) */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, +/* why is this #ifed, what's the difference? */ +#if 0 + { 0X55, 0X4F, 0X4F, 0X99, 0X51, 0X18, 0X2E, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE7, 0, 0XDF, 0, 0, 0XDF, 0X2F, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0, 0, 0X87, 0X1C, 0, 0 }, + { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X7107, 0, 0, 0, 0, 0, 0, 0 }, + { 0X3, 0X811, 0XF416, 0X9F17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +#else + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0XB, 0X3E, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XEE, 0, 0XDF, 0, 0, 0XDF, 0XC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X1184, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XAD17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +#endif + }, + + { "640x480Over", 640, 480, TVTYPE_PAL, + { 0X60, /* 0x00 DM Mode 13 PAL 640x480 OS 5/4 */ + 0X27, /* 0x01 FF Default 0x27 (was 7F) */ + 0XBE, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X83, /* 0x03 TE Decent text 0x8B (was 8D) */ + 0X10, /* 0x04 SAV Default 0x50 */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 */ + 0X01, /* 0x08 CE Default 0x03 */ + 0X81, /* 0x09 TPC Default 0x80 */ + 0X0D, /* 0x0A PLLM Default 0x3F */ + 0X0B, /* 0x0B PLLN Default 0x7E */ + 0X30, /* 0x0C FSCI Default 0x25 */ + 0X0A, /* 0x0D FSCI Default 0x24 */ + 0XE7, /* 0x0E FSCI Default 0x9C */ + 0XC4, /* 0x0F FSCI Default 0x7A */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0XF2, 0X1F, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE5, 0, 0XDF, 0, 0, 0XDF, 0XF3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600Over", 800, 600, TVTYPE_NTSC, + { 0XCE, /* 0x00 Mode 28 */ + 0X27, /* 0x01 Default 0x27 (was 7F) */ + 0XBE, /* 0x02 Default 0xBE (was 76) */ + 0X8F, /* 0x03 */ + 0X51, /* 0x04 */ + 0X2E, /* 0x05 */ + 0X10, /* 0x06 */ + 0X83, /* 0x07 */ + 0X3, /* 0x08 */ + 0X81, /* 0x09 */ + 0X13, /* 0x0A */ + 0X3E, /* 0x0B */ + 0X1C, /* 0x0C */ + 0, /* 0x0D */ + 0, /* 0x0E */ + 0, /* 0x0F */ + 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, 0, 0, }, + { 0X7D, 0X63, 0X63, 0X81, 0X69, 0X18, 0XBA, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5A, 0, 0X57, 0, 0, 0X57, 0XBB, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XD017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600Over", 800, 600, TVTYPE_PAL, + { 0XC1, 0X7F, 0XE0, 0X8F, 0X20, 0X1D, 0X36, 0X70, 0X3, 0X94, 0X39, 0X87, 0X26, 0X79, 0X8C, 0XC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0X71, 0X63, 0X63, 0X95, 0X67, 0X90, 0X6F, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X57, 0, 0X57, 0, 0, 0X57, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768Over", 1024, 768, TVTYPE_NTSC, + { 0XED, + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, + 0X87, + 0X49, + 0X20, + 0, + 0X83, + 0X3, + 0X90, + 0X89, + 0X35, + 0X1F, + 0X61, + 0X1A, + 0X7C, + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0X48, + 0X40, + 0XD2, + 0X80, + 0X40, + 0, + 0, }, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0X46, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X4, 0, 0XFF, 0, 0, 0XFF, 0X47, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5084, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X4517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768Over", 1024, 768, TVTYPE_PAL, + { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, + 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XB184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "720x480", 720, 480, TVTYPE_NTSC, + { 0X89, /* 0x00 DM Mode 19 720x480 1/1 */ + 0X3F, /* 0x01 FF Default 0x27 (was 7F) */ + 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */ + 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */ + 0X18, /* 0x04 SAV Default 0x50 (was 10) */ + 0X19, /* 0x05 HP Default 0x50 */ + 0XFB, /* 0x06 VP Default 0x00 */ + 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */ + 0X03, /* 0x08 CE Default 0x03 */ + 0X80, /* 0x09 TPC Default 0x80 */ + 0X3F, /* 0x0A PLLM Default 0x3F */ + 0X7C, /* 0x0B PLLN Default 0x7C */ + 0X21, /* 0x0C FSCI Default 0x25 */ + 0X04, /* 0x0D FSCI Default 0x04 */ + 0X10, /* 0x0E FSCI Default 0x10 */ + 0X41, /* 0x0F FSCI Default 0x41 */ + 0X00, /* 0x10 CIVC Default 0x01 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */ + 0X48, /* 0x1C CM Default 0x00 */ + 0X40, /* 0x1D IC Default 0x88 */ + 0XD2, /* 0x1E GPIO Default 0xC0 */ + 0X80, /* 0x1F IDF Default 0x00 */ + 0X40, /* 0x20 CD */ + 0X00, /* 0x21 DC */ + 0X00, /* 0x22 BCO Default 0x00 */ }, + { 0X64, 0X59, 0X59, 0X88, 0X5B, 0X81, 0X56, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XFF, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0, 0X4, 0X87, 0X1C, 0, 0 }, + { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X2D, 0X5A, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X5A, 0XB4, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0XB4, 0X68, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 }, + { 0X6E07, 0, 0, 0, 0, 0, 0, 0 }, + { 0X3, 0X811, 0XC316, 0X4C17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + +/* don't we want 720x576 for pal? */ + { "720x480", 720, 480, TVTYPE_PAL, + { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, + 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0, }, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XB184, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, +}; + +static struct CH7xxxTableRec +CH7019Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, + { 0X6A, 0X7F, 0X7E, 0X8D, 0X21, 0X2E, 0X4, 0X83, 0X3, 0X80, 0X3F, 0X7E, 0X20, 0X80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0 }, + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480", 640, 480, TVTYPE_PAL, + { 0X61, 0X7F, 0XE0, 0X8F, 0X31, 0X35, 0X33, 0X6E, 0X3, 0X81, 0X4, 0X9, 0X26, 0X6F, 0X1F, 0XD0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0 }, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3284, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_NTSC, + { 0XCF, 0X7F, 0X76, 0X8F, 0X59, 0X3C, 0X15, 0X83, 0X3, 0X88, 0X59, 0X2E, 0X19, 0X8B, 0X3A, 0X63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600", 800, 600, TVTYPE_PAL, + { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3A84, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768", 1024, 768, TVTYPE_NTSC, + { 0XEE, 0X7F, 0X7E, 0X87, 0X49, 0X32, 0X9, 0X83, 0X3, 0X88, 0X47, 0X4D, 0X1B, 0XE4, 0X89, 0X51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X4A84, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X6717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + + { "1024x768", 1024, 768, TVTYPE_PAL, + { 0XE5, 0X7F, 0XE0, 0X8F, 0XC1, 0X3E, 0X4A, 0X70, 0, 0X81, 0X7, 0X2A, 0X20, 0X6D, 0XC2, 0XD7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X83, 0X97, 0XE6, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XFF, 0, 0, 0XFF, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 }, + { 0XC284, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "640x480Over", 640, 480, TVTYPE_NTSC, + { 0X69, 0X7F, 0X7E, 0X8D, 0X10, 0X19, 0, 0X83, 0X3, 0X80, 0X3F, 0X6E, 0X25, 0X24, 0X92, 0X49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0XB, 0X3E, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XEE, 0, 0XDF, 0, 0, 0XDF, 0XC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X1184, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XAD17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + + { "640x480Over", 640, 480, TVTYPE_PAL, + { 0X60, 0X7F, 0XE0, 0X8F, 0X31, 0X1B, 0X2D, 0X6E, 0X3, 0X81, 0XD, 0X14, 0X30, 0XA, 0XE7, 0XC4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0XF2, 0X1F, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE5, 0, 0XDF, 0, 0, 0XDF, 0XF3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X3184, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "800x600Over", 800, 600, TVTYPE_NTSC, + { 0XCE, 0X7F, 0X76, 0X8F, 0X51, 0X2E, 0X10, 0X83, 0X3, 0X81, 0X13, 0X3E, 0X1C, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X7D, 0X63, 0X63, 0X81, 0X69, 0X18, 0XBA, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5A, 0, 0X57, 0, 0, 0X57, 0XBB, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5284, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0XD017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + + { "800x600Over", 800, 600, TVTYPE_PAL, + { 0XC1, 0X7F, 0XE0, 0X8F, 0X20, 0X1D, 0X36, 0X70, 0X3, 0X94, 0X39, 0X87, 0X26, 0X79, 0X8C, 0XC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X71, 0X63, 0X63, 0X95, 0X67, 0X90, 0X6F, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X57, 0, 0X57, 0, 0, 0X57, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X2184, 0, 0, 0, 0, 0, 0, 0 }, + }, + + { "1024x768Over", 1024, 768, TVTYPE_NTSC, + { 0XED, 0X7F, 0X7E, 0X87, 0X49, 0X20, 0, 0X83, 0X3, 0X90, 0X89, 0X35, 0X1F, 0X61, 0X1A, 0X7C, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0X46, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X4, 0, 0XFF, 0, 0, 0XFF, 0X47, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X5084, 0, 0, 0, 0, 0, 0, 0 }, + { 0X2, 0X811, 0X4517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + + { "1024x768Over", 1024, 768, TVTYPE_PAL, + { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, 0X1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80, + 0X40, 0, 0}, + { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 }, + { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 }, + { 0XB184, 0, 0, 0, 0, 0, 0, 0 }, + } +}; + +static const VIABIOSTVMASKTableRec ch7011MaskTable = { + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF }, + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0, 0XFF, 0, 0, 0, 0, 0, 0, + 0XFF, 0, 0XFF, 0, 0, 0XFF, 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0 }, + 0X3F, 0X38,24,13,22 +}; + +static const VIABIOSTVMASKTableRec ch7019MaskTable = { + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF }, + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0, 0XFF, 0, 0, 0, 0, 0, 0, + 0XFF, 0, 0XFF, 0, 0, 0XFF, 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0 }, + 0X3F, 0X38,24,13,22 +}; + +#endif diff --git a/trunk/src/via_cursor.c b/trunk/src/via_cursor.c new file mode 100644 index 000000000000..74b7c2180fa7 --- /dev/null +++ b/trunk/src/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 + * + ************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.h" +#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/trunk/src/via_dga.c b/trunk/src/via_dga.c new file mode 100644 index 000000000000..3c1367438ac3 --- /dev/null +++ b/trunk/src/via_dga.c @@ -0,0 +1,321 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 +DGAFunctionRec VIADGAFuncs = { + VIADGAOpenFramebuffer, + NULL, /* CloseFrameBuffer */ + VIADGASetMode, + VIADGASetViewport, + VIADGAGetViewport, + viaAccelSyncMarker, + viaAccelFillRect, + viaAccelBlitRect, + 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 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/trunk/src/via_dmabuffer.h b/trunk/src/via_dmabuffer.h new file mode 100644 index 000000000000..39eeb7e95baa --- /dev/null +++ b/trunk/src/via_dmabuffer.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) Thomas Hellstrom (2005) + * + * 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_DMABUFFER_H +#define VIA_DMABUFFER_H + +#include "via_3d_reg.h" + +typedef struct _ViaCommandBuffer +{ + ScrnInfoPtr pScrn; + CARD32 *buf; + CARD32 waitFlags; + unsigned pos; + unsigned bufSize; + int mode; + int header_start; + int rindex; + Bool has3dState; + void (*flushFunc) (struct _ViaCommandBuffer * cb); +} ViaCommandBuffer; + +#define VIA_DMASIZE 16384 + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(flags) \ + (cb)->waitFlags |= (flags) + +#define BEGIN_RING(size) \ + do { \ + if (cb->flushFunc && (cb->pos > (cb->bufSize-(size)))) { \ + cb->flushFunc(cb); \ + } \ + } while(0) + +#define BEGIN_H2(paraType, h2size) \ + do{ \ + BEGIN_RING((h2size)+6); \ + if (cb->mode == 2 && (paraType) == cb->rindex) \ + break; \ + if (cb->pos & 1) \ + OUT_RING(HC_DUMMY); \ + cb->header_start = cb->pos; \ + cb->rindex = paraType; \ + cb->mode = 2; \ + OUT_RING(HALCYON_HEADER2); \ + OUT_RING((paraType) << 16); \ + if (!cb->has3dState && ((paraType) != HC_ParaType_CmdVdata)) { \ + cb->has3dState = TRUE; \ + } \ + } while(0); + +#define OUT_RING(val) do{ \ + (cb)->buf[(cb)->pos++] = (val); \ + } while(0); + +#define OUT_RING_QW(val1, val2) \ + do { \ + (cb)->buf[(cb)->pos++] = (val1); \ + (cb)->buf[(cb)->pos++] = (val2); \ + } while (0) + +#define ADVANCE_RING \ + cb->flushFunc(cb) + +#define RING_VARS \ + ViaCommandBuffer *cb = &pVia->cb + +#define OUT_RING_H1(val1, val2) \ + OUT_RING_QW(H1_ADDR(val1), val2) + +#define OUT_RING_SubA(val1, val2) \ + OUT_RING(((val1) << HC_SubA_SHIFT) | ((val2) & HC_Para_MASK)) + +extern int viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, + unsigned size); +extern void viaTearDownCBuffer(ViaCommandBuffer * buf); +extern void viaFlushPCI(ViaCommandBuffer * buf); + +#endif diff --git a/trunk/src/via_dri.c b/trunk/src/via_dri.c new file mode 100644 index 000000000000..30da5e8b77dc --- /dev/null +++ b/trunk/src/via_dri.c @@ -0,0 +1,1102 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Priv.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#define _XF86DRI_SERVER_ +#include "GL/glxtokens.h" +#include "sarea.h" + +#include "via.h" +#include "via_driver.h" +#include "via_drm.h" +#include "via_dri.h" +#include "via_id.h" +#include "xf86drm.h" + +#ifndef DRIINFO_MAJOR_VERSION +#define DRIINFO_MAJOR_VERSION 4 +#endif +#ifndef DRIINFO_MINOR_VERSION +#define DRIINFO_MINOR_VERSION 0 +#endif + +#define VIDEO 0 +#define AGP 1 +#define AGP_CMDBUF_PAGES 512 +#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) +#define VIA_AGP_MODE_MASK 0x17 +#define VIA_AGPv3_MODE 0x08 +#define VIA_AGPv3_8X_MODE 0x02 +#define VIA_AGPv3_4X_MODE 0x01 +#define VIA_AGP_4X_MODE 0x04 +#define VIA_AGP_2X_MODE 0x02 +#define VIA_AGP_1X_MODE 0x01 +#define VIA_AGP_FW_MODE 0x10 + +extern void GlxSetVisualConfigs( + int nconfigs, + __GLXvisualConfig *configs, + void **configprivs +); + +typedef struct { + int major; + int minor; + int patchlevel; +} ViaDRMVersion; + +static char VIAKernelDriverName[] = "via"; +static char VIAClientDriverName[] = "unichrome"; +static const ViaDRMVersion drmExpected = {1, 3, 0}; +static const ViaDRMVersion drmCompat = {2, 0, 0}; + +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; + + if (((pVia->drmVerMajor == 1) && (pVia->drmVerMinor <= 3))) { + return FALSE; + } + + /* + * Info frome code-snippet on DRI-DEVEL list; Erdi Chen. + */ + + switch (pVia->ChipId) { + case PCI_CHIP_VT3314: + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3324: + 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 VIASetAgpMode(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + CARD32 mode = drmAgpGetMode(pVia->drmFD); + unsigned int vendor = drmAgpVendorId(pVia->drmFD); + unsigned int device = drmAgpDeviceId(pVia->drmFD); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Detected AGP vendor 0x%04x, device 0x04%x\n", + vendor, device); + + mode &= ~VIA_AGP_MODE_MASK; + if ((mode & VIA_AGPv3_MODE)) { + mode |= VIA_AGPv3_8X_MODE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Found AGP v3 compatible device. " + "Trying AGP 8X mode.\n"); + } else { + mode |= VIA_AGP_4X_MODE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Didn't find any AGP v3 compatible device. " + "Trying AGP 4X mode.\n"); + } + + mode |= VIA_AGP_FW_MODE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Trying to enable AGP fast writes.\n"); + + if (drmAgpEnable(pVia->drmFD, mode) < 0) { + return FALSE; + } + return TRUE; +} + +static Bool +VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia) +{ + int agpPages; + unsigned long agpCmdSize; + 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 (!VIASetAgpMode(xf86Screens[pScreen->myNum])) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] VIASetAgpMode failed\n"); + drmAgpRelease(pVia->drmFD); + return FALSE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n"); + + agpCmdSize = (pVia->agpEnable) ? AGP_CMDBUF_SIZE : 0; + + if (pVia->agpMem*1024 < agpCmdSize + AGP_PAGE_SIZE) { + pVia->agpMem = (agpCmdSize + AGP_PAGE_SIZE) / 1024; + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Forcing AGP size to %d kB\n", pVia->agpMem); + } + + agpPages = (pVia->agpMem*1024 + AGP_PAGE_SIZE - 1) / AGP_PAGE_SIZE; + + if (drmAgpAlloc(pVia->drmFD, agpPages*AGP_PAGE_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 = agpPages*AGP_PAGE_SIZE - agpCmdSize; + 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; + } + + 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 = pVia->agpSize; + 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) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int FBSize = pVia->driSize; + int FBOffset; + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + if (FBSize < pVia->Bpl) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] No DRM framebuffer heap available.\n"); + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Please increase the frame buffer\n"); + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] memory area in BIOS. Disabling DRI.\n"); + return FALSE; + } + if (FBSize < 3*(pScrn->virtualY * pVia->Bpl)) { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] The DRM Heap and Pixmap cache memory could be too small\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] for optimal performance. Please increase the frame buffer\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] memory area in BIOS.\n"); + } + + pVia->driOffScreenMem.pool = 0; + if (Success != viaOffScreenLinear(&pVia->driOffScreenMem, pScrn, FBSize)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] failed to allocate offscreen frame buffer area\n"); + return FALSE; + } + + FBOffset = pVia->driOffScreenMem.base; + + pVIADRI->fbOffset = FBOffset; + pVIADRI->fbSize = FBSize; + + { + 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] Using %d bytes for DRM memory heap.\n", 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; + drmVersionPtr drmVer; + + /* 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("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 != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] VIADRIScreenInit failed because of a version mismatch.\n" + "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n" + "[dri] Disabling DRI.\n", + major, minor, patch, + DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); + 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_DRIDDX_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH; +#if (DRIINFO_MAJOR_VERSION == 5) + pDRIInfo->frameBufferPhysicalAddress = (pointer) pVia->FrameBufferBase; +#else + pDRIInfo->frameBufferPhysicalAddress = pVia->FrameBufferBase; +#endif + 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(drm_via_sarea_t) > 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 (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { + VIADRICloseScreen(pScreen); + return FALSE; + } + pVia->drmVerMajor = drmVer->version_major; + pVia->drmVerMinor = drmVer->version_minor; + pVia->drmVerPL = drmVer->version_patchlevel; + + if ((drmVer->version_major < drmExpected.major) || + (drmVer->version_major > drmCompat.major) || + ((drmVer->version_major == drmExpected.major ) && + (drmVer->version_minor < drmExpected.minor))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[dri] Kernel drm is not compatible with this driver.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[dri] Kernel drm version: %d.%d.%d " + "and I can work with versions %d.%d.x - %d.x.x\n", + drmVer->version_major,drmVer->version_minor, + drmVer->version_patchlevel, drmExpected.major, + drmExpected.minor, drmCompat.major); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[dri] Please update either this 2D driver or your kernel DRM. " + "Disabling DRI.\n"); + drmFreeVersion(drmVer); + VIADRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(drmVer); + + + 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.handle = pVia->registerHandle; + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n", + (unsigned long) pVIADRI->regs.handle); + + pVIADRI->drixinerama = FALSE; + + 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); + VIAFreeLinear(&pVia->driOffScreenMem); + + 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 */ + { + drm_via_sarea_t *saPriv; + + saPriv=(drm_via_sarea_t *)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->frameBufferHandle; + 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", + (unsigned long) pVia->registerHandle); + if (drmAddMap(pVia->drmFD, pVia->FrameBufferBase, pVia->videoRambytes, + DRM_FRAME_BUFFER, 0, &pVia->frameBufferHandle) < 0) { + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = 0x%08lx\n", + (unsigned long) pVia->frameBufferHandle); + + return TRUE; +} + +#define DRM_VIA_BLIT_MAX_SIZE (2048*2048*4) + +static int +viaDRIFBMemcpy(int fd, unsigned long fbOffset, unsigned char *addr, + unsigned long size, Bool toFB) +{ + int err; + drm_via_dmablit_t blit; + unsigned long curSize; + + do { + curSize = (size > DRM_VIA_BLIT_MAX_SIZE) ? DRM_VIA_BLIT_MAX_SIZE : + size; + + blit.num_lines = 1; + blit.line_length = curSize; + blit.fb_addr = fbOffset; + blit.fb_stride = ALIGN_TO(curSize, 16); + blit.mem_addr = addr; + blit.mem_stride = blit.fb_stride; + blit.to_fb = (toFB) ? 1 : 0; + + do { + err = drmCommandWriteRead(fd, DRM_VIA_DMA_BLIT, + &blit, sizeof(blit)); + } while (-EAGAIN == err); + + if (err) + return err; + + do { + err = drmCommandWriteRead(fd, DRM_VIA_BLIT_SYNC, + &blit.sync, sizeof(blit.sync)); + } while (-EAGAIN == err); + if (err) + return err; + + fbOffset += curSize; + addr += curSize; + size -= curSize; + + } while (size > 0); + return 0; +} + + + +void +viaDRIOffscreenSave(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset; + unsigned long saveSize = pVIADRI->fbSize; + unsigned long curSize; + int err; + + + if (pVia->driOffScreenSave) + free(pVia->driOffScreenSave); + + pVia->driOffScreenSave = malloc(saveSize + 16); + if (pVia->driOffScreenSave) { + if ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 8)) { + err = viaDRIFBMemcpy(pVia->drmFD, pVIADRI->fbOffset, + (unsigned char *) + ALIGN_TO((unsigned long) + pVia->driOffScreenSave, 16), + saveSize, FALSE); + if (!err) + return; + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware backup of DRI offscreen memory failed: %s.\n" + "\tUsing slow software backup instead.\n", + strerror(-err)); + } + memcpy((void *)ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16), + saveAddr, saveSize); + + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Out of memory trying to backup DRI offscreen memory.\n"); + } + return; +} + + +void +viaDRIOffscreenRestore(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset; + unsigned long saveSize = pVIADRI->fbSize; + + if (pVia->driOffScreenSave) { + memcpy(saveAddr, + (void *)ALIGN_TO((unsigned long)pVia->driOffScreenSave, 16), + saveSize); + free(pVia->driOffScreenSave); + pVia->driOffScreenSave = NULL; + } +} diff --git a/trunk/src/via_dri.h b/trunk/src/via_dri.h new file mode 100644 index 000000000000..cce2e6a5f778 --- /dev/null +++ b/trunk/src/via_dri.h @@ -0,0 +1,78 @@ +/* + * 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. + */ +/* + * Keep this file in perfect sync between the ddx and dri drivers. + * At least bump the VIA_DRIDDX_VERSION defines appropriately. + * + */ +#ifndef _VIA_DRI_H_ +#define _VIA_DRI_H_ 1 + +#define VIA_MAX_DRAWABLES 256 + +#define VIA_DRIDDX_VERSION_MAJOR 5 +#define VIA_DRIDDX_VERSION_MINOR 0 +#define VIA_DRIDDX_VERSION_PATCH 0 + +#if !defined(XFree86Server) && !defined(_XDEFS_H) +typedef int Bool; +#endif + +typedef struct { + drm_handle_t handle; + drmSize size; +} 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; + +#endif /* _VIA_DRI_H_ */ diff --git a/trunk/src/via_driver.c b/trunk/src/via_driver.c new file mode 100644 index 000000000000..6198e5f885b3 --- /dev/null +++ b/trunk/src/via_driver.c @@ -0,0 +1,2954 @@ +/* + * Copyright 2005-2007 The Openchrome Project [openchrome.org] + * Copyright 2004-2006 Luc Verhaegen. + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86RAC.h" +#include "shadowfb.h" + +#include "globals.h" +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "svnversion.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 VIASetupDefaultOptions(ScrnInfoPtr pScrn); +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); + +static void VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual); + +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/K8N800"}, + {VIA_PM800, "PM800/PM880/CN400"}, + {VIA_VM800, "P4M800Pro/VN800/CN700"}, + {VIA_K8M890, "K8M890/K8N890"}, + {VIA_P4M900, "P4M900/VN896/CN896"}, + {VIA_CX700, "CX700/VX700"}, + {VIA_P4M890, "P4M890"}, + {-1, NULL } +}; + +/* Mapping a PCI device ID to a chipset family identifier. */ +static PciChipsets VIAPciChipsets[] = { + {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}, + {VIA_VM800, PCI_CHIP_VT3314, RES_SHARED_VGA}, + {VIA_K8M890, PCI_CHIP_VT3336, RES_SHARED_VGA}, + {VIA_P4M900, PCI_CHIP_VT3364, RES_SHARED_VGA}, + {VIA_CX700, PCI_CHIP_VT3324, RES_SHARED_VGA}, + {VIA_P4M890, PCI_CHIP_VT3327, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; + +int gVIAEntityIndex = -1; + +typedef enum { +#ifdef HAVE_DEBUG + OPTION_PRINTVGAREGS, + OPTION_PRINTTVREGS, + OPTION_I2CSCAN, +#endif + OPTION_VBEMODES, + OPTION_NOACCEL, +#ifdef VIA_HAVE_EXA + OPTION_ACCELMETHOD, + OPTION_EXA_NOCOMPOSITE, + OPTION_EXA_SCRATCH_SIZE, +#endif + OPTION_SWCURSOR, + OPTION_HWCURSOR, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_VIDEORAM, + OPTION_ACTIVEDEVICE, + OPTION_BUSWIDTH, + OPTION_CENTER, + OPTION_PANELSIZE, + OPTION_FORCEPANEL, + OPTION_TVDOTCRAWL, + OPTION_TVPROGRESSIVE, + OPTION_TVTYPE, + OPTION_TVOUTPUT, + OPTION_DISABLEVQ, + OPTION_DRIXINERAMA, + OPTION_DISABLEIRQ, + OPTION_TVDEFLICKER, + OPTION_AGP_DMA, + OPTION_2D_DMA, + OPTION_XV_DMA, + OPTION_VBE_SAVERESTORE, + OPTION_MAX_DRIMEM, + OPTION_AGPMEM, + OPTION_DISABLE_XV_BW_CHECK +} VIAOpts; + + +static OptionInfoRec VIAOptions[] = { +#ifdef HAVE_DEBUG /* Don't document these three. */ + {OPTION_PRINTVGAREGS, "PrintVGARegs", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_PRINTTVREGS, "PrintTVRegs", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_I2CSCAN, "I2CScan", OPTV_BOOLEAN, {0}, FALSE}, +#endif + {OPTION_VBEMODES, "VBEModes", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, +#ifdef VIA_HAVE_EXA + {OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, + {OPTION_EXA_NOCOMPOSITE, "ExaNoComposite", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_EXA_SCRATCH_SIZE, "ExaScratchSize", OPTV_INTEGER, {0}, FALSE}, +#endif + {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_BUSWIDTH, "BusWidth", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_CENTER, "Center", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_PANELSIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE}, + /* Forcing use of panel is a last resort - don't document this one. */ + {OPTION_FORCEPANEL, "ForcePanel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TVDOTCRAWL, "TVDotCrawl", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TVDEFLICKER, "TVDeflicker", OPTV_INTEGER, {0}, FALSE}, + {OPTION_TVPROGRESSIVE, "TVProgressive", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TVTYPE, "TVType", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVOUTPUT, "TVOutput", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_DISABLEVQ, "DisableVQ", 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}, + {OPTION_XV_DMA, "NoXVDMA", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_VBE_SAVERESTORE, "VbeSaveRestore", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DISABLE_XV_BW_CHECK, "DisableXvBWCheck", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_MAX_DRIMEM, "MaxDRIMem", OPTV_INTEGER, {0}, FALSE}, + {OPTION_AGPMEM, "AGPMem", OPTV_INTEGER, {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", + "vgaHWGetIndex", /* Through VGAHWPTR() */ + 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", + "xf86Int10AllocPages", + "xf86Int10FreePages", + 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 +}; + +#ifdef VIA_HAVE_EXA +static const char *exaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + "exaGetPixmapPitch", + "exaGetPixmapOffset", + "exaWaitSync", +#if (EXA_VERSION_MAJOR >= 2) + "exaDriverAlloc", +#else + "exaGetVersion", +#endif + NULL +}; +#endif + +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", + "drmCommandWriteRead", + "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, +#ifdef XORG_VERSION_CURRENT + XORG_VERSION_CURRENT, +#else + XF86_VERSION_CURRENT, +#endif + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +XF86ModuleData openchromeModuleData = { &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, +#ifdef VIA_HAVE_EXA + exaSymbols, +#endif + 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("OPENCHROME", "Driver for VIA Chrome 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, refer to http://www.openchrome.org/.\n"); + +#ifdef BUILDCOMMENT + xf86Msg(X_NOTICE, BUILDCOMMENT); +#endif + + 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 = "CHROME"; + 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 +VIASetupDefaultOptions(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions\n")); + + pVia->shadowFB = FALSE; + pVia->NoAccel = FALSE; +#ifdef VIA_HAVE_EXA + pVia->noComposite = FALSE; + pVia->exaScratchSize = VIA_SCRATCH_SIZE / 1024; +#endif /* VIA_HAVE_EXA */ + pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE; + pVia->VQEnable = TRUE; + pVia->DRIIrqEnable = TRUE; + pVia->agpEnable = TRUE; + pVia->dma2d = TRUE; + pVia->dmaXV = TRUE; + pVia->useVBEModes = FALSE; + pVia->vbeSR = FALSE; +#ifdef HAVE_DEBUG + pVia->disableXvBWCheck = FALSE; +#endif + pVia->maxDriSize = 0; + pVia->agpMem = AGP_SIZE / 1024; + pVia->ActiveDevice = 0x00; + pVia->VideoEngine = VIDEO_ENGINE_CLE; +#ifdef HAVE_DEBUG + pVia->PrintVGARegs = FALSE; +#endif + pVia->swov.maxWInterp = 800 ; + pVia->swov.maxHInterp = 600 ; + pVia->useLegacyVBE = TRUE; + + switch (pVia->Chipset) + { + case VIA_KM400: + /* IRQ is not broken on KM400A */ + /* But test below is not enough to make sure we have a KM400A */ + /* if (pVia->ChipRev < 0x80) */ + pVia->DRIIrqEnable = FALSE; + break; + case VIA_K8M800: + pVia->DRIIrqEnable = FALSE; + break; + case VIA_P4M900: + pVia->useLegacyVBE = FALSE; + /* FIXME: It needs to be tested */ + pVia->dmaXV = FALSE; + /* no break here */ + case VIA_K8M890: + pVia->VideoEngine = VIDEO_ENGINE_CME; + pVia->agpEnable = FALSE; + break; + case VIA_PM800: + case VIA_CX700: + pVia->VideoEngine = VIDEO_ENGINE_CME; + pVia->swov.maxWInterp = 1920 ; + pVia->swov.maxHInterp = 1080 ; + break; + case VIA_P4M890: + pVia->VideoEngine = VIDEO_ENGINE_CME; + break; + } + + return TRUE; +} + + +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; + + 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; + + 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); + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + + if (pEnt->device->chipRev >= 0) { + pVia->ChipRev = pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pVia->ChipRev); + } else { + /* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip revision */ + pVia->ChipRev = pciReadByte(pciTag(0, 0, 0), 0xF6); + } + + if (pVia->Chipset == VIA_CLE266) + ViaDoubleCheckCLE266Revision(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset revision: %d\n", pVia->ChipRev); + + xfree(pEnt); + + /* Detect the amount of installed RAM */ + from = X_PROBED; + switch (pVia->Chipset) { + case VIA_CLE266: + case VIA_KM400: + pScrn->videoRam = ( 1 << ( ( pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70 ) >> 4 ) ) << 10 ; + break; + case VIA_PM800: + case VIA_VM800: + case VIA_K8M800: + pScrn->videoRam = ( 1 << ( ( pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70 ) >> 4 ) ) << 10 ; + break; + case VIA_K8M890: + case VIA_P4M890: + case VIA_P4M900: + case VIA_CX700: + pScrn->videoRam = ( 1 << ( ( pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70 ) >> 4 ) ) << 12 ; + break; + default: + if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Using old memory-detection method.\n"); + 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 { + from = X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Memory size detection failed: using 16 MB.\n"); + pScrn->videoRam = 16 << 10; + } + } else { + from = X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "No memory-detection done. Use VideoRAM option.\n"); + } + } + + if (from == X_PROBED) + xf86DrvMsg(pScrn->scrnIndex, from, + "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting up default chipset options...\n"); + if (!VIASetupDefaultOptions(pScrn)) { + VIAFreeRec(pScrn); + return FALSE; + } + + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Starting to parse config file options...\n"); + + if (xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM, &pScrn->videoRam)) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Setting amount of VideoRAM to %d kB\n", pScrn->videoRam); + + //pVia->shadowFB = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_SHADOW_FB, &pVia->shadowFB) ? + X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "ShadowFB is %s.\n", + pVia->shadowFB ? "enabled" : "disabled"); + + 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" + "counterclockwise - 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"); + } + } + + //pVia->NoAccel = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_NOACCEL, &pVia->NoAccel) ? + X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Acceleration is %s.\n", + !pVia->NoAccel ? "enabled" : "disabled"); + + if (pVia->shadowFB && !pVia->NoAccel) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "HW acceleration not supported with \"shadowFB\".\n"); + pVia->NoAccel = TRUE; + } + +#ifdef VIA_HAVE_EXA + if(!pVia->NoAccel) { + from = X_DEFAULT; + if((s = (char *)xf86GetOptValString(VIAOptions, OPTION_ACCELMETHOD))) { + if(!xf86NameCmp(s,"XAA")) { + from = X_CONFIG; + pVia->useEXA = FALSE; + } + else if(!xf86NameCmp(s,"EXA")) { + from = X_CONFIG; + pVia->useEXA = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture.\n", + pVia->useEXA ? "EXA" : "XAA"); + + //pVia->noComposite = FALSE; + if (pVia->useEXA) { + from = xf86GetOptValBool(VIAOptions, OPTION_EXA_NOCOMPOSITE, + &pVia->noComposite) ? + X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, + "EXA composite acceleration %s.\n", + !pVia->noComposite ? "enabled" : "disabled"); + + //pVia->exaScratchSize = VIA_SCRATCH_SIZE / 1024; + from = xf86GetOptValInteger(VIAOptions, OPTION_EXA_SCRATCH_SIZE, + &pVia->exaScratchSize) ? + X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, + "EXA scratch area size is %d kB.\n", + pVia->exaScratchSize); + } + } +#endif /* VIA_HAVE_EXA */ + + /* + * The SWCursor setting takes priority over HWCursor. The default + * if neither is specified is HW. + */ + + //pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE; + from = X_DEFAULT; + if (xf86GetOptValBool(VIAOptions, OPTION_HWCURSOR, &pVia->hwcursor)) + from = X_CONFIG; + if (xf86GetOptValBool(VIAOptions, OPTION_SWCURSOR, &pVia->hwcursor)) { + pVia->hwcursor = !pVia->hwcursor; + from = X_CONFIG; + } + if (pVia->IsSecondary) + pVia->hwcursor = FALSE; + if (pVia->hwcursor) + xf86DrvMsg(pScrn->scrnIndex, from, "Hardware two-color cursors; " + "software full-color cursors.\n"); + else + xf86DrvMsg(pScrn->scrnIndex, from, "Using software cursors.\n"); + + //pVia->VQEnable = TRUE; + from = xf86GetOptValBool(VIAOptions, OPTION_DISABLEVQ, &pVia->VQEnable) + ? X_CONFIG : X_DEFAULT; + if (from == X_CONFIG) + pVia->VQEnable = !pVia->VQEnable; + xf86DrvMsg(pScrn->scrnIndex, from, "GPU virtual command queue will be %s.\n", + (pVia->VQEnable) ? "enabled" : "disabled"); + + //pVia->DRIIrqEnable = TRUE; + from = xf86GetOptValBool(VIAOptions, OPTION_DISABLEIRQ, + &pVia->DRIIrqEnable) + ? X_CONFIG : X_DEFAULT; + if (from == X_CONFIG) + pVia->DRIIrqEnable = !pVia->DRIIrqEnable; + xf86DrvMsg(pScrn->scrnIndex, from, "DRI IRQ will be %s if DRI is enabled.\n", + (pVia->DRIIrqEnable) ? "enabled" : "disabled"); + + //pVia->agpEnable = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_AGP_DMA, &pVia->agpEnable) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "AGP DMA will be %s if DRI is enabled.\n", + (pVia->agpEnable) ? "enabled" : "disabled"); + + //pVia->dma2d = TRUE; + if (pVia->agpEnable) { + from = xf86GetOptValBool(VIAOptions, OPTION_2D_DMA, &pVia->dma2d) + ? X_CONFIG : X_DEFAULT; + if (from == X_CONFIG) + pVia->dma2d = !pVia->dma2d; + xf86DrvMsg(pScrn->scrnIndex, from, "AGP DMA will %sbe used for 2D " + "acceleration.\n", + (pVia->dma2d) ? "" : "not "); + } + + //pVia->dmaXV = TRUE; + from = xf86GetOptValBool(VIAOptions, OPTION_XV_DMA, &pVia->dmaXV) + ? X_CONFIG : X_DEFAULT; + if (from == X_CONFIG) + pVia->dmaXV = !pVia->dmaXV; + xf86DrvMsg(pScrn->scrnIndex, from, "PCI DMA will %sbe used for XV " + "image transfer if DRI is enabled.\n", + (pVia->dmaXV) ? "" : "not "); + + //pVia->useVBEModes = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_VBEMODES, &pVia->useVBEModes) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Will %senable VBE modes.\n", + (pVia->useVBEModes) ? "" : "not "); + + //pVia->vbeSR = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_VBE_SAVERESTORE, &pVia->vbeSR) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "VBE VGA register save & restore " + "will %sbe used\n\tif VBE modes are enabled.\n", + (pVia->vbeSR) ? "" : "not "); + +#ifdef HAVE_DEBUG + //pVia->disableXvBWCheck = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_DISABLE_XV_BW_CHECK, + &pVia->disableXvBWCheck) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Xv Bandwidth check is %s.\n", + pVia->disableXvBWCheck ? "disabled" : "enabled"); + if (pVia->disableXvBWCheck) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "You may get a \"snowy\" screen" + " when using the Xv overlay.\n"); + } +#endif + + //pVia->maxDriSize = 0; + from = xf86GetOptValInteger(VIAOptions, OPTION_MAX_DRIMEM, + &pVia->maxDriSize) + ? X_CONFIG : X_DEFAULT; + if (pVia->maxDriSize > 0) + xf86DrvMsg(pScrn->scrnIndex, from, + "Will impose a %d kB limit on video RAM reserved for DRI.\n", + pVia->maxDriSize); + else + xf86DrvMsg(pScrn->scrnIndex, from, + "Will not impose a limit on video RAM reserved for DRI.\n"); + + //pVia->agpMem = AGP_SIZE / 1024; + from = xf86GetOptValInteger(VIAOptions, OPTION_AGPMEM, + &pVia->agpMem) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, + "Will try to allocate %d kB of AGP memory.\n", + pVia->agpMem); + + /* 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; + } + + /* Digital Output Bus Width Option */ + pBIOSInfo->BusWidth = VIA_DI_12BIT; + from = X_DEFAULT; + if ((s = xf86GetOptValString(VIAOptions, OPTION_BUSWIDTH))) { + from = X_CONFIG; + if (!xf86NameCmp(s, "12BIT")) { + pBIOSInfo->BusWidth = VIA_DI_12BIT; + } else if (!xf86NameCmp(s, "24BIT")) { + pBIOSInfo->BusWidth = VIA_DI_24BIT; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Digital output bus width is %d bits.\n", + (pBIOSInfo->BusWidth == VIA_DI_12BIT) ? 12:24); + + + /* LCD Center/Expend Option */ + pBIOSInfo->Center = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_CENTER, &pBIOSInfo->Center) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "DVI Center is %s.\n", + pBIOSInfo->Center ? "enabled" : "disabled"); + + + /* 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, "1280x800")) { + pBIOSInfo->PanelSize = VIA_PANEL12X8; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1280x800\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"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, + "Panel size is not selected from config file.\n"); + } + + + /* Force the use of the Panel? */ + pBIOSInfo->ForcePanel = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_FORCEPANEL, + &pBIOSInfo->ForcePanel) + ? X_CONFIG:X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, + "Panel will %sbe forced.\n", + pBIOSInfo->ForcePanel ? "" : "not "); + + pBIOSInfo->TVDotCrawl = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_TVDOTCRAWL, + &pBIOSInfo->TVDotCrawl) + ? X_CONFIG:X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "TV dotCrawl is %s.\n", + pBIOSInfo->TVDotCrawl ? "enabled" : "disabled"); + + /* TV Deflicker */ + pBIOSInfo->TVDeflicker = 0; + from = xf86GetOptValInteger(VIAOptions, OPTION_TVDEFLICKER, + &pBIOSInfo->TVDeflicker) + ? X_CONFIG:X_DEFAULT; + xf86DrvMsg( pScrn->scrnIndex, from, "TV deflicker is set to %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"); + } + else if(!xf86NameCmp(s, "480P")) { + pBIOSInfo->TVType = TVTYPE_480P; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is SDTV 480P.\n"); + } + else if(!xf86NameCmp(s, "576P")) { + pBIOSInfo->TVType = TVTYPE_576P; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is SDTV 576P.\n"); + } + else if(!xf86NameCmp(s, "720P")) { + pBIOSInfo->TVType = TVTYPE_720P; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is HDTV 720P.\n"); + } + else if(!xf86NameCmp(s, "1080I")) { + pBIOSInfo->TVType = TVTYPE_1080I; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is HDTV 1080i.\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, + "No default TV type is set.\n"); + } + + /* TV output 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"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, + "No default TV output signal type is set.\n"); + } + + VIAVidHWDiffInit(pScrn); + + /* maybe throw in some more sanity checks here */ + + 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 + //pVia->PrintVGARegs = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_PRINTVGAREGS, + &pVia->PrintVGARegs) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Will %sprint VGA registers.\n", + pVia->PrintVGARegs ? "" : "not "); + if (pVia->PrintVGARegs) + ViaVgahwPrint(VGAHWPTR(pScrn)); /* Do this as early as possible */ + + pVia->I2CScan = FALSE; + from = xf86GetOptValBool(VIAOptions, OPTION_I2CSCAN, &pVia->I2CScan) + ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Will %sscan I2C buses.\n", + pVia->I2CScan ? "" : "not "); +#endif /* HAVE_DEBUG */ + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "...Finished parsing config file options.\n"); + + 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; + } + + /* 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; + + 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) || + (pVia->Chipset == VIA_VM800) || + (pVia->Chipset == VIA_P4M890) || + (pVia->Chipset == VIA_K8M890) || + (pVia->Chipset == VIA_CX700) || + (pVia->Chipset == VIA_P4M900))) { + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Panel on K8M800, PM800, VM800, P4M890, K8M890, CX700 or " + "P4M900 is currently not supported.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Using VBE to set modes to work around this.\n"); + + pVia->useVBEModes = TRUE; + } + + pVia->pVbe = NULL; + if (pVia->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 */ + 32*8, /* 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) { +#ifdef VIA_HAVE_EXA + if(pVia->useEXA) { +#if (EXA_VERSION_MAJOR >= 2) + XF86ModReqInfo req; + int errmaj, errmin; + + memset(&req, 0, sizeof(req)); + req.majorversion = 2; + req.minorversion = 0; + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + VIAFreeRec(pScrn); + return FALSE; + } + +#else + + if(!xf86LoadSubModule(pScrn, "exa")) { + VIAFreeRec(pScrn); + return FALSE; + } +#endif /* EXA_VERSION */ + xf86LoaderReqSymLists(exaSymbols, NULL); + } +#endif /* VIA_HAVE_EXA */ + 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) { + if (pVia->vbeSR) + ViaVbeSaveRestore(pScrn, MODE_SAVE); + else + VIASave(pScrn); + ret = ViaVbeSetMode(pScrn, pScrn->currentMode); + } else { + VIASave(pScrn); + ret = VIAWriteMode(pScrn, pScrn->currentMode); + } + vgaHWUnlock(hwp); + + VIASaveScreen(pScrn->pScreen, SCREEN_SAVER_ON); + + + /* Patch for APM suspend resume, HWCursor has garbage */ + if (pVia->hwcursor) + ViaCursorRestore(pScrn); + + /* restore video status */ + if (!pVia->IsSecondary) + viaRestoreVideo(pScrn); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + kickVblank(pScrn); + VIADRIRingBufferInit(pScrn); + viaDRIOffscreenRestore(pScrn); + } +#endif + + if (pVia->NoAccel) { + memset(pVia->FBBase, 0x00, pVia->Bpl * pScrn->virtualY); + } else { + viaAccelFillRect(pScrn, 0, 0, pScrn->displayWidth, pScrn->virtualY, + 0x00000000); + viaAccelSyncMarker(pScrn); + } + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + 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) { + volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *) + DRIGetSAREAPrivate(pScrn->pScreen); + + DRILock(screenInfo.screens[scrnIndex], 0); + saPriv->ctxOwner = ~0; + } +#endif + + viaAccelSync(pScrn); + + /* + * A soft reset helps fix 3D hang on VT switch. + */ + if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900) + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + VIADRIRingBufferCleanup(pScrn); + viaDRIOffscreenSave(pScrn); + } +#endif + + if (pVia->VQEnable) + viaDisableVQ(pScrn); + + /* Save video status and turn off all video activities */ + + if (!pVia->IsSecondary) + viaSaveVideo(pScrn); + + if (pVia->hwcursor) + ViaCursorStore(pScrn); + + if (pVia->pVbe && pVia->vbeSR) + 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; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Secondary\n")); + + 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 { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Primary\n")); + + 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); + + switch (pVia->Chipset) + { + case VIA_CLE266: + case VIA_KM400: + break; + default: + Regs->SR4A = hwp->readSeq(hwp, 0x4A); + Regs->SR4B = hwp->readSeq(hwp, 0x4B); + Regs->SR4C = hwp->readSeq(hwp, 0x4C); + break; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Crtc...\n")); + + 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); + + Regs->CR49 = hwp->readCrtc(hwp, 0x49); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TVSave...\n")); + if (pBIOSInfo->TVI2CDev) + ViaTVSave(pScrn); + + /* Save LCD control regs */ + for (i = 0; i < 68; i++) + Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50); + + Regs->CRA0 = hwp->readCrtc(hwp, 0xA0); + Regs->CRA1 = hwp->readCrtc(hwp, 0xA1); + Regs->CRA2 = hwp->readCrtc(hwp, 0xA2); + + Regs->CR97 = hwp->readCrtc(hwp, 0x97); + Regs->CR99 = hwp->readCrtc(hwp, 0x99); + Regs->CR9B = hwp->readCrtc(hwp, 0x9B); + Regs->CR9F = hwp->readCrtc(hwp, 0x9F); + + 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); + + switch (pVia->Chipset) + { + case VIA_CLE266: + case VIA_KM400: + break; + default: + hwp->writeSeq(hwp, 0x4A, Regs->SR4A); + hwp->writeSeq(hwp, 0x4B, Regs->SR4B); + hwp->writeSeq(hwp, 0x4C, Regs->SR4C); + break; + } + + /* 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); + + hwp->writeCrtc(hwp, 0x49, Regs->CR49); + + /* Restore LCD control regs */ + for (i = 0; i < 68; i++) + hwp->writeCrtc(hwp, i + 0x50, Regs->CRTCRegs[i]); + + hwp->writeCrtc(hwp, 0xA0, Regs->CRA0); + hwp->writeCrtc(hwp, 0xA1, Regs->CRA1); + hwp->writeCrtc(hwp, 0xA2, Regs->CRA2); +/* + hwp->writeCrtc(hwp, 0x97, Regs->CR97); + hwp->writeCrtc(hwp, 0x99, Regs->CR99); + hwp->writeCrtc(hwp, 0x9B, Regs->CR9B); + hwp->writeCrtc(hwp, 0x9F, Regs->CR9F); +*/ + 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 +VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual) +{ + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + + int i, j, index; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n")); + + hwp->enablePalette(hwp); + hwp->writeDacMask(hwp, 0xFF); + + /* We need the same palette contents for both 16 and 24 bits, but X doesn't + * play: X's colormap handling is hopelessly intertwined with almost every + * X subsystem. So we just space out RGB values over the 256*3. */ + + switch (pScrn->bitsPerPixel) { + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + hwp->writeDacWriteAddr(hwp, index * 4); + for (j = 0; j < 4; j++) { + hwp->writeDacData(hwp, colors[index/2].red); + hwp->writeDacData(hwp, colors[index].green); + hwp->writeDacData(hwp, colors[index/2].blue); + } + } + break; + case 8: + case 24: + case 32: + 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); + } + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel); + break; + } + hwp->disablePalette(hwp); +} + +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) { + switch(pVia->Chipset) { + case VIA_CLE266: + case VIA_KM400: + ViaSeqMask(hwp, 0x16, 0x80, 0x80); + break; + case VIA_P4M900: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VIALoadPalette: Function not implemented for this chipset.\n"); + return; + default: + ViaCrtcMask(hwp, 0x33, 0x80, 0x80); + break; + } + + ViaSeqMask(hwp, 0x1A, 0x00, 0x01); + VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual); + + /* If secondary is enabled, adjust its palette too. */ + if (hwp->readCrtc(hwp, 0x6A) & 0x80) { + ViaSeqMask(hwp, 0x1A, 0x01, 0x01); + ViaCrtcMask(hwp, 0x6A, 0x02, 0x02); + switch(pVia->Chipset) { + case VIA_K8M800: + case VIA_PM800: + break; + default: + ViaSeqMask(hwp, 0x6A, 0x20, 0x20); + break; + } + VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual); + } + + 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); + + pScrn->pScreen = pScreen; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n")); + + if (!VIAMapFB(pScrn)) + return FALSE; + + if (!VIAMapMMIO(pScrn)) + return FALSE; + + if (pVia->pVbe && pVia->vbeSR) { + ViaVbeSaveRestore(pScrn, MODE_SAVE); + } else { + VIASave(pScrn); + } + + vgaHWUnlock(hwp); + + pVia->FirstInit = TRUE; + if (pVia->pVbe) { + vgaHWBlankScreen(pScrn, FALSE); + if (!ViaVbeSetMode(pScrn, pScrn->currentMode)) { + vgaHWBlankScreen(pScrn, TRUE); + 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); + } + + 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, 8, VIALoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH + | CMAP_PALETTED_TRUECOLOR)) + return FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n")); + + 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")); + pVia->agpDMA = FALSE; + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen); + + if (pVia->directRenderingEnabled) { + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); + pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); + } +#endif + if (!pVia->NoAccel) + viaFinishInitAccel(pScreen); + + if (pVia->NoAccel) { + memset(pVia->FBBase, 0x00, pVia->videoRambytes); + } else { +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + DRILock(screenInfo.screens[scrnIndex], 0); +#endif + viaAccelFillRect(pScrn, pScrn->frameX0, pScrn->frameY0, + pScrn->displayWidth, pScrn->virtualY, + 0x00000000); + viaAccelSyncMarker(pScrn); +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + DRIUnlock(screenInfo.screens[scrnIndex]); +#endif + } + vgaHWBlankScreen(pScrn, TRUE); + + if (pVia->NoAccel) { + + /* + * This is only for Xv in Noaccel path, 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; + pVia->FBFreeStart=(AvailFBArea.y2 + 1)*pVia->Bpl; + xf86InitFBManager(pScreen, &AvailFBArea); + VIAInitLinear(pScreen); + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl); + } + + 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; + + pScrn->vtSema = TRUE; + + if (!pVia->pVbe) { + + if (!vgaHWInit(pScrn, mode)) + return FALSE; + + if (!pVia->IsSecondary) + ViaModePrimary(pScrn, mode); + else + ViaModeSecondary(pScrn, mode); + + } else { + + if (!ViaVbeSetMode(pScrn, mode)) + return FALSE; + /* + * FIXME: pVia->IsSecondary is not working here. + * We should be able to detect when the display + * is using the secondary head. + * TODO: This should be enabled for others + * chipsets as well + */ + if (pVia->Chipset == VIA_P4M900 && + pVia->pBIOSInfo->PanelActive) { + /* + * Since we are using virtual, we need to adjust + * the offset to match the framebuffer alignment + */ + if (pScrn->displayWidth != mode->HDisplay) + ViaModeSecondaryVGAOffset(pScrn); + // ViaModeSecondaryVGAFixAlignment(pScrn, mode); + } + } + + /* Enable the graphics engine. */ + if (!pVia->NoAccel) { +#if defined(XF86DRI) || defined(VIA_HAVE_EXA) + VIAInitialize3DEngine(pScrn); +#endif + viaInitialize2DEngine(pScrn); + } + + 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); + + + /* A soft reset Fixes 3D Hang after X restart */ + if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900) + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); + + if (!pVia->IsSecondary) { + /* Turn off all video activities */ + viaExitVideo(pScrn); + + VIAHideCursor(pScrn); + } + + if (pVia->VQEnable) + viaDisableVQ(pScrn); + } + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) + VIADRICloseScreen(pScreen); +#endif + + viaExitAccel(pScreen); + 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 && pVia->vbeSR) + 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); + } else { + + 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) + viaDisableVQ(pScrn); + + ret = VIAWriteMode(pScrn, mode); + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + kickVblank(pScrn); + 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; +} + +#if defined(XF86DRI) || defined(VIA_HAVE_EXA) +void +VIAInitialize3DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i; + + VIASETREG(VIA_REG_TRANSET, 0x00010000); + + for (i = 0; i <= 0x7D; i++) + { + VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); + } + + VIASETREG(VIA_REG_TRANSET, 0x00020000); + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); + } + + VIASETREG(VIA_REG_TRANSPACE, 0x82400000); + + VIASETREG(VIA_REG_TRANSET, 0x01020000); + + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); + } + + VIASETREG(VIA_REG_TRANSPACE, 0x82400000); + VIASETREG(VIA_REG_TRANSET, 0xfe020000); + + for (i = 0; i <= 0x03; i++) + { + VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); + } + + VIASETREG(VIA_REG_TRANSET, 0x00030000); + + for (i = 0; i <= 0xff; i++) + { + VIASETREG(VIA_REG_TRANSPACE, 0); + } + VIASETREG(VIA_REG_TRANSET, 0x00100000); + VIASETREG(VIA_REG_TRANSPACE, 0x00333004); + VIASETREG(VIA_REG_TRANSPACE, 0x10000002); + VIASETREG(VIA_REG_TRANSPACE, 0x60000000); + VIASETREG(VIA_REG_TRANSPACE, 0x61000000); + VIASETREG(VIA_REG_TRANSPACE, 0x62000000); + VIASETREG(VIA_REG_TRANSPACE, 0x63000000); + VIASETREG(VIA_REG_TRANSPACE, 0x64000000); + + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + + if (pVia->ChipRev >= 3 ) + VIASETREG(VIA_REG_TRANSPACE,0x40008c0f); + else + VIASETREG(VIA_REG_TRANSPACE,0x4000800f); + + VIASETREG(VIA_REG_TRANSPACE,0x44000000); + VIASETREG(VIA_REG_TRANSPACE,0x45080C04); + VIASETREG(VIA_REG_TRANSPACE,0x46800408); + VIASETREG(VIA_REG_TRANSPACE,0x50000000); + VIASETREG(VIA_REG_TRANSPACE,0x51000000); + VIASETREG(VIA_REG_TRANSPACE,0x52000000); + VIASETREG(VIA_REG_TRANSPACE,0x53000000); + + + VIASETREG(VIA_REG_TRANSET,0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE,0x08000001); + VIASETREG(VIA_REG_TRANSPACE,0x0A000183); + VIASETREG(VIA_REG_TRANSPACE,0x0B00019F); + VIASETREG(VIA_REG_TRANSPACE,0x0C00018B); + VIASETREG(VIA_REG_TRANSPACE,0x0D00019B); + VIASETREG(VIA_REG_TRANSPACE,0x0E000000); + VIASETREG(VIA_REG_TRANSPACE,0x0F000000); + VIASETREG(VIA_REG_TRANSPACE,0x10000000); + VIASETREG(VIA_REG_TRANSPACE,0x11000000); + VIASETREG(VIA_REG_TRANSPACE,0x20000000); +} +#endif diff --git a/trunk/src/via_driver.h b/trunk/src/via_driver.h new file mode 100644 index 000000000000..113c7be6a197 --- /dev/null +++ b/trunk/src/via_driver.h @@ -0,0 +1,476 @@ +/* + * 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 1 + +#ifdef HAVE_DEBUG +#define DEBUG(x) x +#else +#define DEBUG(x) +#endif + +#include "vgaHW.h" +#include "xf86.h" +#include "xf86Resources.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" +#include "via_dmabuffer.h" +#include "via_3d.h" + +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "sarea.h" +#include "dri.h" +#include "GL/glxint.h" +#include "via_dri.h" +#endif + +#ifdef VIA_HAVE_EXA +#include "exa.h" +#define VIA_AGP_UPL_SIZE (1024*128) +#define VIA_DMA_DL_SIZE (1024*128) +#define VIA_SCRATCH_SIZE (4*1024*1024) + +/* + * Pixmap sizes below which we don't try to do hw accel. + */ + +#define VIA_MIN_COMPOSITE 400 +#define VIA_MIN_UPLOAD 4000 +#define VIA_MIN_TEX_UPLOAD 200 +#define VIA_MIN_DOWNLOAD 200 +#endif + +#define AGP_PAGE_SIZE 4096 +#define AGP_PAGES 8192 +#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES) + +#define DRIVER_NAME "openchrome" +#define VERSION_MAJOR 0 +#define VERSION_MINOR 2 +#ifdef USE_NEW_XVABI +#define PATCHLEVEL 901 +#else +#define PATCHLEVEL 0 +#endif +#define VIA_VERSION ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL) + +#define VIA_CURSOR_SIZE (4 * 1024) +#define VIA_VQ_SIZE (256 * 1024) + +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; + CARD8 SR4A, SR4B, SR4C; + + /* 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 CR97, CR99, CR9B, CR9F, CRA0, CRA1, CRA2; + 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; + CARD32 cmd; + CARD32 fgColor; + CARD32 bgColor; + CARD32 pattern0; + CARD32 pattern1; + CARD32 patternAddr; + CARD32 keyControl; + unsigned srcOffset; + unsigned srcPitch; + unsigned Bpp; + unsigned bytesPPShift; + Bool clipping; + Bool dashed; + int clipX1; + int clipX2; + int clipY1; + int clipY2; +} ViaTwodContext; + +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; + + Bool FirstInit; + unsigned long videoRambytes; + int videoRamKbytes; + int FBFreeStart; + int FBFreeEnd; + int driSize; + int maxDriSize; + 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; + + /* Here are all the Options */ + Bool VQEnable; + Bool hwcursor; + Bool NoAccel; + Bool shadowFB; + int rotate; + Bool vbeSR; + int agpMem; + + CloseScreenProcPtr CloseScreen; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + int ChipId; + int ChipRev; + int EntityIndex; + + /* vbe */ + vbeInfoPtr pVbe; + ViaVbeModeInfo vbeMode; + Bool useVBEModes; + Bool useLegacyVBE; + + /* Support for shadowFB and rotation */ + unsigned char* ShadowPtr; + int ShadowPitch; + void (*PointerMoved)(int index, int x, int y); + + /* Support for XAA acceleration */ + XAAInfoRecPtr AccelInfoRec; + ViaTwodContext td; + Via3DState v3d; + Via3DState *lastToUpload; + ViaCommandBuffer cb; + int accelMarker; + CARD32 markerOffset; + CARD32 *markerBuf; + CARD32 curMarker; + CARD32 lastMarkerRead; + Bool agpDMA; + Bool nPOT[VIA_NUM_TEXUNITS]; +#ifdef VIA_HAVE_EXA + ExaDriverPtr exaDriverPtr; + ExaOffscreenArea *exa_scratch; + unsigned int exa_scratch_next; + Bool useEXA; + void *maskP; + CARD32 maskFormat; + Bool componentAlpha; + void *srcP; + CARD32 srcFormat; + ExaOffscreenArea *scratchFBBuffer; + unsigned scratchOffset; + int exaScratchSize; + char * scratchAddr; + Bool noComposite; +#ifdef XF86DRI + drm_via_mem_t scratchAGPBuffer; + drm_via_mem_t texAGPBuffer; + unsigned texOffset; + char * texAddr; + char * dBounce; +#endif +#endif + + /* 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; + drm_handle_t agpHandle; + drm_handle_t registerHandle; + drm_handle_t frameBufferHandle; + unsigned long agpAddr; + drmAddress agpMappedAddr; + unsigned char *agpBase; + unsigned int agpSize; + Bool IsPCI; + ViaXvMC xvmc; + int drmVerMajor; + int drmVerMinor; + int drmVerPL; + VIAMem driOffScreenMem; + void * driOffScreenSave; +#endif + Bool DRIIrqEnable; + Bool agpEnable; + Bool dma2d; + Bool dmaXV; + + CARD8 ActiveDevice; /* Option */ + unsigned char *CursorImage; + CARD32 CursorFG; + CARD32 CursorBG; + CARD32 CursorMC; + + /* Video */ + int VideoEngine; + 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; + Bool useDmaBlit; +#ifdef HAVE_DEBUG + Bool disableXvBWCheck; + 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. */ +#if defined(XF86DRI) || defined(VIA_HAVE_EXA) +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 viaDisableVQ(ScrnInfoPtr); +void viaExitAccel(ScreenPtr); +void viaAccelBlitRect(ScrnInfoPtr, int, int, int, int, int, int); +void viaAccelFillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +void viaAccelSyncMarker(ScrnInfoPtr); +void viaFinishInitAccel(ScreenPtr); +void viaAccelWaitMarker(ScreenPtr, int); +int viaAccelMarkSync(ScreenPtr); +void viaAccelFillPixmap(ScrnInfoPtr, unsigned long, unsigned long, + int, int, int, int, int, unsigned long); +void viaAccelTextureBlit(ScrnInfoPtr, unsigned long, unsigned, unsigned, + unsigned, unsigned, unsigned, unsigned, + unsigned long, unsigned, unsigned, + unsigned, unsigned, int); + + + +/* 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); +int VIAAllocLinear(VIAMemPtr, ScrnInfoPtr, unsigned long); +int viaOffscreenLinear(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); + +#ifdef XF86DRI +Bool VIADRIScreenInit(ScreenPtr pScreen); +void VIADRICloseScreen(ScreenPtr pScreen); +Bool VIADRIFinishScreenInit(ScreenPtr pScreen); +void VIADRIRingBufferCleanup(ScrnInfoPtr pScrn); +Bool VIADRIRingBufferInit(ScrnInfoPtr pScrn); +void viaDRIOffscreenRestore(ScrnInfoPtr pScrn); +void viaDRIOffscreenSave(ScrnInfoPtr pScrn); + +#endif /* XF86DRI */ + +#endif /* _VIA_DRIVER_H_ */ diff --git a/trunk/src/via_drm.h b/trunk/src/via_drm.h new file mode 100644 index 000000000000..9d85a1e84c0b --- /dev/null +++ b/trunk/src/via_drm.h @@ -0,0 +1,270 @@ +/* + * 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 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_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_ + +#if !defined(__KERNEL__) && !defined(_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_VIA_DMA_BLIT 0x0e +#define DRM_VIA_BLIT_SYNC 0x0f + +#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) +#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t) +#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_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 VIA_MEM_VIDEO 0 /* matches drm constant */ +#define VIA_MEM_AGP 1 /* matches drm constant */ +#define VIA_MEM_SYSTEM 2 +#define VIA_MEM_MIXED 3 +#define VIA_MEM_UNKNOWN 4 + +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 __user *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 */ + + /* Used by the 3d driver only at this point, for pageflipping: + */ + + unsigned int pfCurrentOffset; +} 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 + +enum drm_via_irqs{drm_via_irq_hqv0 = 0, + drm_via_irq_hqv1, + drm_via_irq_dma0_dd, + drm_via_irq_dma0_td, + drm_via_irq_dma1_dd, + drm_via_irq_dma1_td, + drm_via_irq_num}; + +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; + +typedef struct drm_via_blitsync { + uint32_t sync_handle; + unsigned engine; +} drm_via_blitsync_t; + +typedef struct drm_via_dmablit { + uint32_t num_lines; + uint32_t line_length; + + uint32_t fb_addr; + uint32_t fb_stride; + + unsigned char *mem_addr; + uint32_t mem_stride; + + int bounce_buffer; + int to_fb; + + drm_via_blitsync_t sync; +} drm_via_dmablit_t; + + +#endif /* _VIA_DRM_H_ */ diff --git a/trunk/src/via_drmclient.h b/trunk/src/via_drmclient.h new file mode 100644 index 000000000000..120d00f6b869 --- /dev/null +++ b/trunk/src/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 "stdint.h" +#include "drm.h" +#include "xf86drm.h" + +#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 +#define __user + +#endif diff --git a/trunk/src/via_i2c.c b/trunk/src/via_i2c.c new file mode 100644 index 000000000000..8a52729520e9 --- /dev/null +++ b/trunk/src/via_i2c.c @@ -0,0 +1,428 @@ +/* + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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, 0x80, 0xC0); + b->I2CUDelay(b, b->RiseFallTime/5); + ViaSeqMask(hwp, 0x2c, 0xA0, 0xA0); + b->I2CUDelay(b, 3*b->HoldTime); + b->I2CUDelay(b, timeout); + + if (hwp->readSeq(hwp, 0x2C) & 0x04) + ret = TRUE; + else + ret = FALSE; + + ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); + b->I2CUDelay(b, b->HoldTime); + 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; + + pI2CBus->HoldTime = 10; + pI2CBus->BitTimeout = 10; + pI2CBus->ByteTimeout = 10; + pI2CBus->StartTimeout = 10; + + 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/trunk/src/via_id.c b/trunk/src/via_id.c new file mode 100644 index 000000000000..4ac06493aaba --- /dev/null +++ b/trunk/src/via_id.c @@ -0,0 +1,241 @@ +/* + * 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. + */ + +/* + * A big structure with card-ID information, plus some checking functions. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via_driver.h" +#include "via_id.h" + +/* + * There's no reason for this to be known outside of via_id.o; + * only a pointer to a single entry will ever be used outside. + */ +static struct ViaCardIdStruct ViaCardId[] = { + /*** CLE266 ***/ + {"LT21 VA28", VIA_CLE266, 0x1019, 0x1B44, VIA_DEVICE_CRT}, + {"ECS G320", VIA_CLE266, 0x1019, 0xB320, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Asustek Terminator C3V", VIA_CLE266, 0x1043, 0x8155, VIA_DEVICE_CRT}, + {"VIA VT3122 (CLE266)-EPIA M/MII/...", VIA_CLE266, 0x1106, 0x3122, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"MSI MS-6723", VIA_CLE266, 0x1462, 0X7238, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Clevo T200V", VIA_CLE266, 0x1558, 0x200A, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar ARKplus III", VIA_CLE266, 0x1565, 0x3204, VIA_DEVICE_CRT | VIA_DEVICE_TV}, /* FS454 TV encoder */ + + /*** KM400, KM400A, KN400, P4M800 ***/ + {"ECS KM400-M2", VIA_KM400, 0x1019, 0x1842, VIA_DEVICE_CRT}, + {"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-LA", VIA_KM400, 0x1043, 0x80F9, VIA_DEVICE_CRT}, + {"Asustek A7V8X-MX SE / A7V400-MX", VIA_KM400, 0x1043, 0x8118, VIA_DEVICE_CRT}, + {"Asustek Terminator A7VT", VIA_KM400, 0x1043, 0x813E, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"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 */ + {"VIA VT3205 (KM400)", VIA_KM400, 0x1106, 0x3205, VIA_DEVICE_CRT | VIA_DEVICE_TV}, /* borrowed by Soltek SL-B7C-FGR */ + {"VIA VT7205 (KM400A)", VIA_KM400, 0x1106, 0x7205, VIA_DEVICE_CRT}, /* borrowed by Biostar iDEQ 200V/Chaintech 7VIF4 */ + {"Shuttle FX43", VIA_KM400, 0x1297, 0xF643, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Giga-byte 7VM400(A)M", VIA_KM400, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI KM4(A)M-V", VIA_KM400, 0x1462, 0x7061, VIA_DEVICE_CRT}, /* aka "DFI KM400-MLV" */ + {"MSI PM8M2-V", VIA_KM400, 0x1462, 0x7071, VIA_DEVICE_CRT}, + {"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}, + {"Abit VA-20", VIA_KM400, 0x147B, 0x1411, VIA_DEVICE_CRT}, + {"Averatec 322x", VIA_KM400, 0x14FF, 0x030D, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"FIC K7M-400A", VIA_KM400, 0x1509, 0x9233, VIA_DEVICE_CRT}, + {"Biostar M7VIZ", VIA_KM400, 0x1565, 0x1200, VIA_DEVICE_CRT}, + {"Biostar P4M800-M7", VIA_KM400, 0x1565, 0x1202, VIA_DEVICE_CRT}, + {"Uniwill 755CI", VIA_KM400, 0x1584, 0x800A, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "Gericom Hummer Advance", "Maxdata M-Book 1200X" */ + {"Packard Bell Quasar2 (MSI MS6786)", VIA_KM400, 0x1631, 0xD002, VIA_DEVICE_CRT}, + {"Epox EP-8KMM3I", VIA_KM400, 0x1695, 0x9023, VIA_DEVICE_CRT}, + {"ASRock Inc. K7VM2/3/4", VIA_KM400, 0x1849, 0x7205, VIA_DEVICE_CRT}, + {"ACorp KM400QP", VIA_KM400, 0x1915, 0x1100, VIA_DEVICE_CRT| VIA_DEVICE_TV}, + {"Soyo K7VME", VIA_KM400, 0xA723, 0x10FD, VIA_DEVICE_CRT}, + + /*** K8M800, K8N800, K8N800A ***/ + {"ZX-5360", VIA_K8M800, 0x1019, 0x0F60, VIA_DEVICE_CRT | VIA_DEVICE_LCD }, + {"ECS K8M800-M2 (1.0)", VIA_K8M800, 0x1019, 0x1828, VIA_DEVICE_CRT}, + {"ECS K8M800-M2 (2.0)", VIA_K8M800, 0x1019, 0x1B45, VIA_DEVICE_CRT}, + {"Acer Aspire 136x", VIA_K8M800, 0x1025, 0x006E, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Asustek K8V-MX", VIA_K8M800, 0x1043, 0x8129, VIA_DEVICE_CRT}, + {"Mitac 8399", VIA_K8M800, 0x1071, 0x8399, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "Pogolinux Konabook 3100" */ + {"Mitac 8889", VIA_K8M800, 0x1071, 0x8889, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"VIA VT3108 (K8M800)", VIA_K8M800, 0x1106, 0x3108, VIA_DEVICE_CRT}, /* borrowed by Asustek A8V-MX */ + {"Shuttle FX21", VIA_K8M800, 0x1297, 0x3052, VIA_DEVICE_CRT}, + {"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-V", VIA_K8M800, 0x1462, 0x7142, VIA_DEVICE_CRT}, + {"MSI K8MM3-V", VIA_K8M800, 0x1462, 0x7181, VIA_DEVICE_CRT}, + {"MSI K8MM-ILSR", VIA_K8M800, 0x1462, 0x7410, VIA_DEVICE_CRT}, + {"Abit KV-80", VIA_K8M800, 0x147B, 0x1419, VIA_DEVICE_CRT}, + {"Abit KV-81", VIA_K8M800, 0x147B, 0x141A, VIA_DEVICE_CRT}, + {"Averatec 327x", VIA_K8M800, 0x14FF, 0x0315, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Twinhead N14RA", VIA_K8M800, 0x14FF, 0x0321, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Averatec 3715", VIA_K8M800, 0x14FF, 0x0322, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Averatec 54xx", VIA_K8M800, 0x1509, 0x3930, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"FIC K8M-800M", VIA_K8M800, 0x1509, 0x6001, VIA_DEVICE_CRT}, + {"Clevo L570W", VIA_K8M800, 0x1558, 0x0570, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Mesh Pegasus", VIA_K8M800, 0x1558, 0x4702, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar K8VGA-M", VIA_K8M800, 0x1565, 0x1203, VIA_DEVICE_CRT}, + {"DFI K8M800-MLVF", VIA_K8M800, 0x15BD, 0x1002, VIA_DEVICE_CRT}, + {"Packard Bell Easynote E6116/E63xx", VIA_K8M800, 0x1631, 0xC008, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Packard Bell Easynote B3 800/B3340", VIA_K8M800, 0x1631, 0xC009, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Packard Bell Imedia 2097", VIA_K8M800, 0x1631, 0xD007, VIA_DEVICE_CRT}, + {"Fujitsu-Siemens Amilo K7610", VIA_K8M800, 0x1734, 0x10B3, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"ASRock K8Upgrade-VM800", VIA_K8M800, 0x1849, 0x3108, VIA_DEVICE_CRT}, + + /*** PM800, PM880, PN800, CN400 ***/ + {"VIA VT3118 (PM800)", VIA_PM800, 0x1106, 0x3118, VIA_DEVICE_CRT}, /* borrowed by ECS PM800-M2 */ + {"Hasee F700C", VIA_PM800, 0x1071, 0x8650, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Mitac 8666", VIA_PM800, 0x1071, 0x8666, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Medion MIM2080", VIA_PM800, 0x1071, 0x8965, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"TwinHead E12BL", VIA_PM800, 0x14FF, 0x0314, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"MaxSelect Optima C4", VIA_PM800, 0x1558, 0x5402, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar P4VMA-M", VIA_PM800, 0x1565, 0x1202, VIA_DEVICE_CRT}, + {"Sotec WA2330S5", VIA_PM800, 0x161F, 0x2037, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Packard Bell Easynote R1100", VIA_PM800, 0x1631, 0xC015, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo Pro V2010", VIA_PM800, 0x1734, 0x1078, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, + {"Fujitsu/Siemens Amilo L7310", VIA_PM800, 0x1734, 0x10AB, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"ASRock P4VM8", VIA_PM800, 0x1849, 0x3118, VIA_DEVICE_CRT}, + {"Chaintech MPM800-3", VIA_PM800, 0x270F, 0x7671, VIA_DEVICE_CRT}, + + /*** P4M800Pro, VN800, CN700 ***/ + {"Clevo/RoverBook Partner E419L", VIA_VM800, 0x1019, 0x0F75, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"PCChips P23G", VIA_VM800, 0x1019, 0x1623, VIA_DEVICE_CRT}, + {"ECS P4M800PRO-M", VIA_VM800, 0x1019, 0x2122, VIA_DEVICE_CRT}, + {"ECS C7VCM", VIA_VM800, 0x1019, 0xAA2D, VIA_DEVICE_CRT}, + {"PCChips V21G", VIA_VM800, 0x1019, 0xAA51, VIA_DEVICE_CRT}, + {"Asustek P5VDC-MX", VIA_VM800, 0x1043, 0x3344, VIA_DEVICE_CRT}, + {"Asustek P5VDC-TVM", VIA_VM800, 0x1043, 0x81CE, VIA_DEVICE_CRT}, + {"Gateway MX3210", VIA_VM800, 0x107B, 0x0216, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"VIA VT3344 (VM800) - EPIA EN", VIA_VM800, 0x1106, 0x3344, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Gigabyte GA-8VM800M-775", VIA_VM800, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI PM8M-V", VIA_VM800, 0x1462, 0x7104, VIA_DEVICE_CRT}, + {"MSI Fuzzy CN700/CN700T/CN700G", VIA_VM800, 0x1462, 0x7199, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"MSI PM8M3-V", VIA_VM800, 0x1462, 0x7211, VIA_DEVICE_CRT}, + {"MSI PM8PM", VIA_VM800, 0x1462, 0x7222, VIA_DEVICE_CRT}, + {"RoverBook Partner W500", VIA_VM800, 0x1509, 0x4330, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo/RoverBook Voyager V511L", VIA_VM800, 0x1558, 0x0662, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo M5xxS", VIA_VM800, 0x1558, 0x5406, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar P4M80-M4 / P4VMA-M", VIA_VM800, 0x1565, 0x1202, VIA_DEVICE_CRT}, + {"Fujitsu/Siemens Amilo Pro V2030", VIA_VM800, 0x1734, 0x109B, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo Pro V2035", VIA_VM800, 0x1734, 0x10AE, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo Pro V2055", VIA_VM800, 0x1734, 0x10CA, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo L7320", VIA_VM800, 0x1734, 0x10CD, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"ASRock P4VM800", VIA_VM800, 0x1849, 0x3344, VIA_DEVICE_CRT}, + {"Asustek P5V800-MX", VIA_VM800, 0x3344, 0x1122, VIA_DEVICE_CRT}, + + /*** K8M890 ***/ + {"ASUS A8V-VM", VIA_K8M890, 0x1043, 0x81B5, VIA_DEVICE_CRT}, + {"Foxconn K8M890M2MA-RS2H", VIA_K8M890, 0x105B, 0x0C84, VIA_DEVICE_CRT}, + {"Shuttle FX22V1", VIA_K8M890, 0x1297, 0x3080, VIA_DEVICE_CRT}, + {"MSI K9VGM-V", VIA_K8M890, 0x1462, 0x7253, VIA_DEVICE_CRT}, + {"Averatec 226x", VIA_K8M890, 0x14FF, 0xA002, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo La 1703", VIA_K8M890, 0x1734, 0x10D9, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + + /*** P4M900, VN896, CN896 ***/ + {"Asustek P5VD2-VM", VIA_P4M900, 0x1043, 0x81CE, VIA_DEVICE_CRT}, + {"VIA VT3364 (P4M900)", VIA_P4M900, 0x1106, 0x3371, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Gigabyte GA-VM900M", VIA_P4M900, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI P4M900M / P4M900M2-F/L", VIA_P4M900, 0x1462, 0x7255, VIA_DEVICE_CRT}, + {"Everex NC1501/NC1503", VIA_P4M900, 0x1509, 0x1E30, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo M660SE", VIA_P4M900, 0x1558, 0x0664, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Neo Endura 540SLe", VIA_P4M900, 0x1558, 0x5408, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar P4M900M-M7 SE", VIA_P4M900, 0x1565, 0x1207, VIA_DEVICE_CRT}, + {"Fujitsu/Siemens Amilo Pro V3515", VIA_P4M900, 0x1734, 0x10CB, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo Li1705", VIA_P4M900, 0x1734, 0x10F7, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + + /*** CX700 ***/ + {"VIA VT8454B", VIA_CX700, 0x0908, 0x1975, VIA_DEVICE_CRT}, /* Evaluation board, reference possibly wrong */ + {"VIA VT3324 (CX700)", VIA_CX700, 0x1106, 0x3157, VIA_DEVICE_CRT}, + {"FIC CE260", VIA_CX700, 0x1509, 0x2D30, VIA_DEVICE_LCD}, + + /*** P4M890, VN890 ***/ + {"PCChips P29G", VIA_P4M890, 0x1019, 0x1629, VIA_DEVICE_CRT}, + {"Asustek P5V-VM ULTRA", VIA_P4M890, 0x1043, 0x81B5, VIA_DEVICE_CRT}, + {"Asustek P5V-VM DH", VIA_P4M890, 0x1043, 0x81CE, VIA_DEVICE_CRT}, + {"Mitac 8615", VIA_P4M890, 0x1071, 0x8615, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"VIA VT3343 (P4M890)", VIA_P4M890, 0x1106, 0x3343, VIA_DEVICE_CRT}, + {"MSI P4M890M-L/IL (MS-7255)", VIA_P4M890, 0x1462, 0x7255, VIA_DEVICE_CRT}, + {"ASRock P4VM890", VIA_P4M890, 0x1849, 0x3343, VIA_DEVICE_CRT}, + + /* keep this */ + {NULL, VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE} +}; + + +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|%4X); please report to openchrome-users@openchrome.org\n", + pVia->PciInfo->chipType, pVia->PciInfo->subsysVendor, pVia->PciInfo->subsysCard); + pVia->Id = NULL; +} + diff --git a/trunk/src/via_id.h b/trunk/src/via_id.h new file mode 100644 index 000000000000..3063ce922bbb --- /dev/null +++ b/trunk/src/via_id.h @@ -0,0 +1,73 @@ +/* + * 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 + +/* Chip tags, used to group the adapters into families. */ +enum VIACHIPTAGS { + VIA_UNKNOWN = 0, + VIA_CLE266, + VIA_KM400, + VIA_K8M800, + VIA_PM800, + VIA_VM800, + VIA_K8M890, + VIA_P4M900, + VIA_CX700, + VIA_P4M890, + VIA_LAST +}; + + +#define PCI_VIA_VENDOR_ID 0x1106 + +#define PCI_CHIP_CLE3122 0x3122 /* CLE266 */ +#define PCI_CHIP_VT3205 0x7205 /* KM400 */ +#define PCI_CHIP_VT3204 0x3108 /* K8M800 */ +#define PCI_CHIP_VT3259 0x3118 /* PM800 */ +#define PCI_CHIP_VT3314 0x3344 /* VM800 */ +#define PCI_CHIP_VT3336 0x3230 /* K8M890 */ +#define PCI_CHIP_VT3364 0x3371 /* P4M900 */ +#define PCI_CHIP_VT3324 0x3157 /* CX700 */ +#define PCI_CHIP_VT3327 0x3343 /* P4M890 */ + +/* There is some conflicting information about the two major revisions of + * the CLE266, often labelled Ax and Cx. The dividing line seems to be + * either 0x0f or 0x10. */ +#define CLE266_REV_IS_AX(x) ((x) < 0x10) +#define CLE266_REV_IS_CX(x) ((x) >= 0x10) + +struct ViaCardIdStruct { + char* String; /* full identification string */ + CARD8 Chip; /* which family of unichrome */ + CARD16 Vendor; /* PCI subsystem Vendor ID */ + CARD16 Device; /* PCI subsystem Device ID */ + CARD8 Outputs; /* whether it supports CRT, LCD, and TV */ +}; + +void ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn); +void ViaCheckCardId(ScrnInfoPtr pScrn); + +#endif /* _VIA_ID_H_ */ diff --git a/trunk/src/via_memcpy.c b/trunk/src/via_memcpy.c new file mode 100644 index 000000000000..1a6d1b701e2b --- /dev/null +++ b/trunk/src/via_memcpy.c @@ -0,0 +1,695 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.h" +#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); + + 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/trunk/src/via_memcpy.h b/trunk/src/via_memcpy.h new file mode 100644 index 000000000000..bc908e44c57b --- /dev/null +++ b/trunk/src/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/trunk/src/via_memory.c b/trunk/src/via_memory.c new file mode 100644 index 000000000000..63206d3569f4 --- /dev/null +++ b/trunk/src/via_memory.c @@ -0,0 +1,194 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + +#include "via.h" + +#ifdef XF86DRI +#include "xf86drm.h" +#endif + +#include "via_driver.h" +#include "via_priv.h" +#include "via_swov.h" +#ifdef XF86DRI +#include "via_drm.h" +#endif + +/* + * Isolate the wonders of X memory allocation and 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 + * 2 - DRM + */ + +static void +viaExaFBSave(ScreenPtr pScreen, ExaOffscreenArea *exa) +{ + FatalError("Xserver is not properly patched and incompatible with OpenChrome exa.\n" + "\tPlease look at Xorg bugzilla bug #7639, and\n" + "\thttp://wiki.openchrome.org/tikiwiki/tiki-index.php?page=EXAAcceleration .\n"); +} + + +void VIAFreeLinear(VIAMemPtr mem) +{ + DEBUG(ErrorF("Freed %lu (pool %d)\n", mem->base, mem->pool)); + switch(mem->pool) { + case 0: + return; + case 1: +#ifdef VIA_HAVE_EXA + { + VIAPtr pVia = VIAPTR(mem->pScrn); + if (pVia->useEXA && !pVia->NoAccel) { + exaOffscreenFree(mem->pScrn->pScreen, mem->exa); + mem->linear = NULL; + mem->pool = 0; + return; + } + } +#endif + 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; + } +} + +int +viaOffScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, + unsigned long size) { + + int depth = pScrn->bitsPerPixel >> 3; + +#ifdef VIA_HAVE_EXA + VIAPtr pVia = VIAPTR(pScrn); + + if (pVia->useEXA && !pVia->NoAccel) { + + mem->exa = exaOffscreenAlloc(pScrn->pScreen, size, + 32, TRUE, NULL,NULL); + if (mem->exa == NULL) + return BadAlloc; + mem->exa->save = viaExaFBSave; + mem->base = mem->exa->offset; + mem->pool = 1; + mem->pScrn = pScrn; + return Success; + } +#endif + + 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; + mem->pScrn = pScrn; + return Success; + +} + +int +VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size) +{ + +#ifdef XF86DRI + VIAPtr pVia = VIAPTR(pScrn); + int ret; + + if(mem->pool) + ErrorF("VIA Double Alloc.\n"); + + if(pVia->directRenderingEnabled) { + mem->pScrn = pScrn; + mem->drm_fd = pVia->drmFD; + mem->drm.context = DRIGetContext(pScrn->pScreen); + mem->drm.size = size; + mem->drm.type = VIA_MEM_VIDEO; + ret = drmCommandWriteRead(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm, + sizeof(drm_via_mem_t)); + if (ret || (size != mem->drm.size)) { + + /* + * Try X Offsceen fallback before failing. + */ + + if (Success == viaOffScreenLinear(mem, pScrn, size)) + return Success; + 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 Success; + } +#endif + { + if (Success == viaOffScreenLinear(mem, pScrn, size)) + return Success; + ErrorF("Linear memory allocation failed\n"); + return BadAlloc; + } + return Success; +} + +void VIAInitLinear(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + +#ifdef VIA_HAVE_EXA + if (pVia->useEXA && !pVia->NoAccel) { + return; + } else +#endif + { + unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp; + long size = pVia->FBFreeEnd / pVia->Bpp - offset; + if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size); + } +} + diff --git a/trunk/src/via_mode.c b/trunk/src/via_mode.c new file mode 100644 index 000000000000..3e8570275331 --- /dev/null +++ b/trunk/src/via_mode.c @@ -0,0 +1,2054 @@ +/* + * 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.h" +#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; + pBIOSInfo->LCDPower = NULL; + pBIOSInfo->TVNumRegs = 0; + + /* + * On an SK43G (KM400/Ch7011), false positive detections at a VT162x + * chip were observed, so try to detect the Ch7011 first. + */ + if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEC)) + pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEC); + else 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); + else if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEA)) + pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEA); + else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0xEA)) + pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus3, 0xEA); + + 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: + case VIA_VT1625: + ViaVT162xInit(pScrn); + break; + case VIA_CH7011: + case VIA_CH7019A: + case VIA_CH7019B: + ViaCH7xxxInit(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; + pBIOSInfo->TVNumRegs = 0; + + 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; + } + + /* + * FIXME: xf86I2CProbeAddress(pVia->pI2CBus3, 0x40) + * disables the panel on P4M900 + * See ViaTVDetect. + */ + if (pVia->Chipset == VIA_P4M900 && pBIOSInfo->PanelPresent) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Will not try to detect TV encoder."); + } else { + /* 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: 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: + /* 0x84 is earliest public device, 0x80 is more likely though */ + if (pVia->ChipRev < 0x84) + 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]; + case VIA_VM800: + return ViaBandwidthTable[VIA_BW_VM800].Bandwidth[pVia->MemClk]; + case VIA_K8M890: + return ViaBandwidthTable[VIA_BW_K8M890].Bandwidth[pVia->MemClk]; + case VIA_P4M900: + return ViaBandwidthTable[VIA_BW_P4M900].Bandwidth[pVia->MemClk]; + case VIA_CX700: + return ViaBandwidthTable[VIA_BW_CX700].Bandwidth[pVia->MemClk]; + case VIA_P4M890: + return ViaBandwidthTable[VIA_BW_P4M890].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\" is 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%06x\n", (unsigned)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%06x\n", (unsigned)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_NVSYNC) + 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) /* FIXME */ + 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) /* FIXME */ + 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) /* FIXME */ + 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) /* FIXME */ + 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 +ViaComputeDotClock(unsigned clock) +{ + double fvco, fout, fref, err, minErr; + CARD32 dr, dn, dm, maxdm, maxdn; + CARD32 factual, best; + + fref = 14.31818e6; + fout = (double)clock * 1.e3; + + factual = ~0; + maxdm = 127; + maxdn = 7; + minErr = 1e10; + best = 0; + + for (dr = 0; dr < 4; ++dr) { + for (dn = (dr == 0) ? 2 : 1; dn <= maxdn; ++dn) { + for (dm = 1; dm <= maxdm; ++dm) { + factual = fref * dm; + factual /= (dn << dr); + err = fabs((double)factual / fout - 1.); + if (err < minErr) { + minErr = err; + best = (dm & 127) | ((dn & 31) << 8) | (dr << 14); + } + } + } + } + return best; +} + +static CARD32 +ViaComputeProDotClock(unsigned clock) +{ + double fvco, fout, fref, err, minErr; + CARD32 dr = 0, dn, dm, maxdm, maxdn; + CARD32 factual, bestClock; + + fref = 14.318e6; + fout = (double)clock * 1.e3; + + factual = ~0; + maxdm = factual / 14318000U - 2; + minErr = 1.e10; + bestClock = 0U; + + do { + fvco = fout * (1 << dr); + } while (fvco < 300.e6 && dr++ < 8); + + if (dr == 8) { + return 0; + } + + if (clock < 30000) + maxdn = 6; + else if (clock < 45000) + maxdn = 5; + else if (clock < 170000) + maxdn = 4; + else + maxdn = 3; + + for (dn = 0; dn < maxdn; ++dn) { + for (dm = 0; dm < maxdm; ++dm) { + factual = 14318000U * (dm + 2); + factual /= (dn + 2) << dr; + if ((err = fabs((double)factual / fout - 1.)) < 0.005) { + if (err < minErr) { + minErr = err; + bestClock = ((dm & 0xff) << 16) | + (((1 << 7) | (dr << 2) | ((dm & 0x300) >> 8)) << 8) + | (dn & 0x7f); + } + } + } + } + + return bestClock; +} + +/* + * + */ +static CARD32 +ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i; + + if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) { + CARD32 best1 = 0, best2; + + for (i = 0; ViaDotClocks[i].DotClock; i++) + if (ViaDotClocks[i].DotClock == mode->Clock) { + best1 = ViaDotClocks[i].UniChrome; + break; + } + + best2 = ViaComputeDotClock(mode->Clock); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "ViaComputeDotClock %d : %04x : %04x\n", + mode->Clock, best1, best2)); + return best2; + } else { + for (i = 0; ViaDotClocks[i].DotClock; i++) + if (ViaDotClocks[i].DotClock == mode->Clock) + return ViaDotClocks[i].UniChromePro; + return ViaComputeProDotClock(mode->Clock); + } + + return 0; +} + +/* + * + */ +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; + + /* Enable MMIO & PCI burst (1 wait state) */ + ViaSeqMask(hwp, 0x1A, 0x06, 0x06); + + if (!pBIOSInfo->CrtActive) + ViaCrtcMask(hwp, 0x36, 0x30, 0x30); + else + ViaSeqMask(hwp, 0x16, 0x00, 0x40); + + 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 uses 2x XCLK */ + else if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) + ViaSetPrimaryDotclock(pScrn, 0x529001); + 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 uses 2x XCLK */ + else if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) + ViaSetPrimaryDotclock(pScrn, 0x529001); + else + ViaSetPrimaryDotclock(pScrn, 0x871C); + if (pVia->Chipset == VIA_CLE266 || pVia->Chipset == VIA_KM400) + 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); +} + +void +ViaModeSecondaryVGAFetchCount(ScrnInfoPtr pScrn, int width) +{ + + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD16 temp; + + /* fetch count */ + temp = (width * (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 +ViaModeSecondaryVGAOffset(ScrnInfoPtr pScrn) +{ + + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD16 temp; + + /* 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); + +} + +/* + * + */ +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) /* FIXME */ + 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) /* FIXME */ + 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) /* FIXME */ + 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) /* FIXME */ + 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); + + ViaModeSecondaryVGAOffset(pScrn); + ViaModeSecondaryVGAFetchCount(pScrn, mode->CrtcHDisplay); + +} + +/* + * + */ +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/trunk/src/via_mode.h b/trunk/src/via_mode.h new file mode 100644 index 000000000000..0f6933691b87 --- /dev/null +++ b/trunk/src/via_mode.h @@ -0,0 +1,928 @@ +/* + * 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_VM800 6 +#define VIA_BW_K8M890 7 +#define VIA_BW_P4M900 8 +#define VIA_BW_CX700 9 +#define VIA_BW_P4M890 10 +#define VIA_BW_ALL 11 + +/* + * 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_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_MIN, VIA_BW_MIN } }, + { VIA_BW_KM400, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN } }, + { VIA_BW_KM400A, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, VIA_BW_MIN, VIA_BW_MIN } }, + { VIA_BW_K8M800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, VIA_BW_MIN, VIA_BW_MIN } }, + { VIA_BW_PM800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, VIA_BW_MIN } }, + { VIA_BW_VM800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, VIA_BW_MIN } }, + { VIA_BW_K8M890, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, 922000000 } }, + { VIA_BW_P4M900, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, 922000000 } }, + { VIA_BW_CX700, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, VIA_BW_MIN } }, + { VIA_BW_P4M890, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000, VIA_BW_MIN } } +}; + +/* + * simple lookup table for dotclocks + * + */ +static struct ViaDotClock { + int DotClock; + CARD16 UniChrome; + CARD32 UniChromePro; +} ViaDotClocks[] = { + { 25200, 0x513C, 0xa79004 }, + { 25312, 0xC763, 0xc49005 }, + { 26591, 0x471A, 0xce9005 }, + { 31500, 0xC558, 0xae9003 }, + { 31704, 0x471F, 0xaf9002 }, + { 32663, 0xC449, 0x479000 }, + { 33750, 0x4721, 0x959002 }, + { 35500, 0x5877, 0x759001 }, + { 36000, 0x5879, 0x9f9002 }, + { 39822, 0xC459, 0x578c02 }, + { 40000, 0x515F, 0x848c04 }, + { 41164, 0x4417, 0x2c8c00 }, + { 46981, 0x5069, 0x678c02 }, + { 49500, 0xC353, 0xa48c04 }, + { 50000, 0xC354, 0x368c00 }, + { 56300, 0x4F76, 0x3d8c00 }, + { 57284, 0x4E70, 0x3e8c00 }, + { 64995, 0x0D3B, 0x6b8c01 }, + { 65000, 0x0D3B, 0x6b8c01 }, /* Slightly unstable on PM800 */ + { 65028, 0x866D, 0x6b8c01 }, + { 74480, 0x156E, 0x288800 }, + { 75000, 0x156E, 0x288800 }, + { 78800, 0x442C, 0x2a8800 }, + { 81135, 0x0622, 0x428801 }, + { 81613, 0x4539, 0x708803 }, + { 94500, 0x4542, 0x4d8801 }, + { 108000, 0x0B53, 0x778802 }, + { 108280, 0x4879, 0x778802 }, + { 122000, 0x0D6F, 0x428800 }, + { 122726, 0x073C, 0x878802 }, + { 135000, 0x0742, 0x6f8801 }, + { 148500, 0x0853, 0x518800 }, + { 155800, 0x0857, 0x558402 }, + { 157500, 0x422C, 0x2a8400 }, + { 161793, 0x4571, 0x6f8403 }, + { 162000, 0x0A71, 0x6f8403 }, + { 175500, 0x4231, 0x2f8400 }, + { 189000, 0x0542, 0x4d8401 }, + { 202500, 0x0763, 0x6F8402 }, + { 204800, 0x0764, 0x548401 }, + { 218300, 0x043D, 0x3b8400 }, + { 229500, 0x0660, 0x3e8400 }, /* Not tested on Pro */ + { 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_800X480 17 +#define VIA_RES_1280X800 18 +#define VIA_RES_1280X720 19 +#define VIA_RES_1920X1080 20 +#define VIA_RES_1366X768 22 +#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_1280X800, VIA_PANEL12X8, 1280, 800}, + {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/trunk/src/via_priv.h b/trunk/src/via_priv.h new file mode 100644 index 000000000000..098ef5d58aab --- /dev/null +++ b/trunk/src/via_priv.h @@ -0,0 +1,199 @@ +/* + * Copyright 2006-2007 The Openchrome Project [openchrome.org] + * 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_PRIV_H_ +#define _VIA_PRIV_H_ 1 + +#ifdef XF86DRI +#include "via_drm.h" +#endif +#ifdef VIA_HAVE_EXA +#include "exa.h" +#endif + +/* + * Alignment macro functions + */ +#define ALIGN_TO(f, alignment) (((f) + ((alignment)-1)) & ~((alignment)-1)) + +/* + * FOURCC definitions + */ + +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') +#define FOURCC_RV15 (('5' << 24) + ('1' << 16) + ('V' << 8) + 'R') +#define FOURCC_RV16 (('6' << 24) + ('1' << 16) + ('V' << 8) + 'R') +#define FOURCC_RV32 (('2' << 24) + ('3' << 16) + ('V' << 8) + 'R') + +/* + * 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 + void *pVia; /* VIA driver pointer */ + FBLinearPtr linear; /* X linear pool info ptr */ +#ifdef VIA_HAVE_EXA + ExaOffscreenArea *exa; +#endif + ScrnInfoPtr pScrn; +} 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_x; + int panning_y; + int oldPanningX; + int oldPanningY; + +/* Maximum resolution with interpolation */ + unsigned long maxWInterp; + unsigned long maxHInterp; + +} swovRec, *swovPtr; + +#endif /* _VIA_PRIV_H_ */ diff --git a/trunk/src/via_regs.h b/trunk/src/via_regs.h new file mode 100644 index 000000000000..65383884f89f --- /dev/null +++ b/trunk/src/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 0x20000 + + +/* 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 0x00000002 /* 2D Engine is busy */ +#define VIA_3D_ENG_BUSY 0x00000001 /* 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/trunk/src/via_shadow.c b/trunk/src/via_shadow.c new file mode 100644 index 000000000000..4b2d5873f49e --- /dev/null +++ b/trunk/src/via_shadow.c @@ -0,0 +1,313 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.h" +#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/trunk/src/via_swov.c b/trunk/src/via_swov.c new file mode 100644 index 000000000000..7566a5a8c2bd --- /dev/null +++ b/trunk/src/via_swov.c @@ -0,0 +1,2297 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + +#include "via.h" +#ifdef XF86DRI +#include "xf86drm.h" +#endif + +#include "via_driver.h" +#include "via_priv.h" +#include "via_swov.h" +#ifdef XF86DRI +#include "via_drm.h" +#endif +#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 + */ + +/* + * 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) +#define VIA_FIRETIMEOUT 40000 + +static void +viaWaitVideoCommandFire(VIAPtr pVia) +{ +/* + * Uncached PCI reading throughput is about 9 MB/s; so 8 bytes/loop means about + * 1M loops/second. We want to time out after 50 ms, which means 50000 loops. + */ + unsigned count = 50000; + CARD32 volatile *pdwState = + (CARD32 volatile *)(pVia->VidMapBase + V_COMPOSE_MODE); + + while (--count && ((*pdwState & V1_COMMAND_FIRE) + || (*pdwState & V3_COMMAND_FIRE))) ; + if (!count) { + ErrorF("viaWaitVideoCommandFire: Timeout.\n"); + } +} + +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 = PRO_HQV1_OFFSET; + + pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg)); + + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { + while (*pdwState & (HQV_SUBPIC_FLIP | HQV_SW_FLIP)) ; + } else { + while (!(*pdwState & HQV_FLIP_STATUS)) ; + } +} + +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 = PRO_HQV1_OFFSET; + + pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg)); + 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; + HWDiff->dwNeedV1Prefetch = 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + } + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + case VIA_VM800: + case VIA_P4M900: + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + case VIA_K8M890: + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_TRUE; + break; + case VIA_P4M890: + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + case VIA_CX700: + 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; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + break; + 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) +{ + if (videoFlag & VIDEO_HQV_INUSE) { + switch (pVia->swov.SrcFourCC) { + case FOURCC_YV12: + case FOURCC_XVMC: + *pHQVCtl |= HQV_YUV420; + break; + case FOURCC_YUY2: + *pHQVCtl |= HQV_YUV422; + break; + case FOURCC_RV32: + *pVidCtl |= V1_RGB32; + *pHQVCtl |= HQV_RGB32; + break; + case FOURCC_RV15: + *pVidCtl |= V1_RGB15; + *pHQVCtl |= HQV_RGB15; + break; + case FOURCC_RV16: + *pVidCtl |= V1_RGB16; + *pHQVCtl |= HQV_RGB16; + break; + default: + DBG_DD(ErrorF("viaOverlayGetV1V3Format: " + "Invalid FOURCC format (0x%lx).\n", + pVia->swov.SrcFourCC)); + return FALSE; + } + *pVidCtl |= V1_SWAP_HW_HQV; + *pHQVCtl |= HQV_SRC_SW | HQV_ENABLE | HQV_SW_FLIP; + } else { + switch (pVia->swov.SrcFourCC) { + case FOURCC_YV12: + case FOURCC_XVMC: + if (vport == 1) { + *pVidCtl |= V1_YCbCr420; + } else { + DBG_DD(ErrorF("viaOverlayGetV1V3Format: " + "V3 does not support planar YUV.\n")); + return FALSE; + } + break; + case FOURCC_YUY2: + *pVidCtl |= V1_YUV422; + break; + case FOURCC_RV32: + case FOURCC_RV15: + case FOURCC_RV16: + ErrorF("viaOverlayGetV1V3Format: " + "Can't display RGB video in this configuration.\n"); + return FALSE; + default: + DBG_DD(ErrorF("viaOverlayGetV1V3Format: " + "Invalid FOURCC format (0x%lx).\n", + pVia->swov.SrcFourCC)); + return FALSE; + } + } + *pVidCtl |= V1_COLORSPACE_SIGN; + return TRUE; +} + +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; + + int n = 1; + + if ((pUpdate->SrcLeft != 0) || (pUpdate->SrcTop != 0)) { + switch (pVia->swov.SrcFourCC) { + case FOURCC_RV32: + n = 2; + case FOURCC_YUY2: + case FOURCC_UYVY: + case FOURCC_RV15: + case FOURCC_RV16: + + if (videoFlag & VIDEO_HQV_INUSE) { + offset = (((pUpdate->SrcTop & ~3) * srcPitch) + + ((pUpdate->SrcLeft << n) & ~31)); + + if (srcHeight > dstHeight) + srcTopOffset = ((pUpdate->SrcTop & ~3) + * dstHeight / srcHeight) * srcPitch; + else + srcTopOffset = (pUpdate->SrcTop & ~3) * srcPitch; + + if (srcWidth > dstWidth) + srcLeftOffset = (((pUpdate->SrcLeft << n) & ~31) + * dstWidth / srcWidth); + else + srcLeftOffset = (pUpdate->SrcLeft << n) & ~31; + *pHQVoffset = srcTopOffset + srcLeftOffset; + } else + offset = ((pUpdate->SrcTop * srcPitch) + + ((pUpdate->SrcLeft << n) & ~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 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, instead of: + * //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, instead of: + * //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: + case FOURCC_RV15: + case FOURCC_RV16: + n = 1; /* 2^n = 2 bytes per pixel (packed YUV) */ + break; + case FOURCC_RV32: + n = 2; + 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. Coefficients 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: + case PCI_CHIP_VT3314: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3364: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3327: + 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: + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: + 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_VT3327: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3364: + case PCI_CHIP_CLE3122: + 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: + DBG_DD(ErrorF("Unknown DeviceID\n")); + break; + } +} + +static unsigned long +ViaInitVideoStatusFlag(VIAPtr pVia) +{ + switch (pVia->ChipId) { + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3204: + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: + return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_3_INUSE; + case PCI_CHIP_VT3327: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3364: + return (VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE + | VIDEO_ACTIVE | VIDEO_SHOW); + 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: + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: + return V3_ENABLE | V3_EXPIRE_NUM_3205; + case PCI_CHIP_VT3327: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3364: + return V3_ENABLE | VIDEO_EXPIRE_NUM_VT3336; + 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; + default: + DBG_DD(ErrorF("Unknown DeviceID\n")); + break; + } + } + return 0; +} + +/* + * 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 = PRO_HQV1_OFFSET; + + 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. + * 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 = FALSE; + switch (FourCC) { + case FOURCC_YV12: + case FOURCC_XVMC: + isplanar = TRUE; + pitch = ALIGN_TO(Width, 32); + fbsize = pitch * Height * 1.5; + break; + case FOURCC_RV32: + pitch = ALIGN_TO(Width << 2, 32); + fbsize = pitch * Height; + break; + default: + pitch = ALIGN_TO(Width << 1, 32); + fbsize = pitch * Height; + break; + } + + if (doalloc) { + VIAFreeLinear(&pVia->swov.SWfbMem); + 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) + && (FourCC == pPriv->FourCC)) + return Success; + + pPriv->FourCC = FourCC; + switch (FourCC) { + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + case FOURCC_RV32: + retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE); + if (retCode != Success) + break; + if ((pVia->swov.gdwVideoFlagSW & SW_USE_HQV)) + retCode = AddHQVSurface(pScrn, numbuf, FourCC); + 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: + case FOURCC_RV16: + case FOURCC_RV32: + case FOURCC_RV15: + 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: + VIAFreeLinear(&pVia->swov.SWfbMem); + case FOURCC_XVMC: + pVia->swov.SrcFourCC = 0; + + VIAFreeLinear(&pVia->swov.HQVMem); + pVia->swov.gdwVideoFlagSW = 0; + break; + } + + pPriv->FourCC = 0; + pVia->VideoStatus &= ~VIDEO_SWOV_SURFACE_CREATED; + + } else + DBG_DD(ErrorF("ViaSwovSurfaceDestroy: No SW 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) +{ + if ((pVia->ChipId == PCI_CHIP_VT3314) + || (pVia->ChipId == PCI_CHIP_VT3324) + || (pVia->ChipId == PCI_CHIP_VT3327)) { + 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_3314) | (prethreshold & 0xff)); + } else { + 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_VT3327: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3364: + SetFIFO_V3(pVia, 225, 200, 250); + break; + case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 100, 89, 89); + break; + case PCI_CHIP_VT3314: + SetFIFO_V3(pVia, 64, 61, 61); + break; + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3259: + 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_VT3327: + case PCI_CHIP_VT3336: + case PCI_CHIP_VT3324: + case PCI_CHIP_VT3364: + SetFIFO_V3(pVia, 225, 200, 250); + break; + case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 100, 89, 89); + break; + case PCI_CHIP_VT3314: + SetFIFO_V3(pVia, 64, 61, 61); + break; + case PCI_CHIP_VT3205: + case PCI_CHIP_VT3259: + 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; + if (pVia->VideoEngine == VIDEO_ENGINE_CME) + keyLow |= 0x40000000; + + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V_COLOR_KEY, keyLow); + } else { + if (pVia->HWDiff.dwSupportTwoColorKey) /*CLE_C0 */ + SaveVideoRegister(pVia, V3_COLOR_KEY, keyLow); + } + + /*CLE_C0 */ + compose = ((compose & ~0x0f) | SELECT_VIDEO_IF_COLOR_KEY | + SELECT_VIDEO3_IF_COLOR_KEY); + + 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); + + if (pVia->VideoEngine == VIDEO_ENGINE_CME) + 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 HW 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 = PRO_HQV1_OFFSET; + + if (!pVia->HWDiff.dwHQVFetchByteUnit) { /* CLE_C0 */ + srcFetch >>= 3; /* fetch unit is 8 bytes */ + } + + SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg, + ((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 both the CRT and DVI, then change resolution. + * If the resolution is smaller than the panel's 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); + } +} + +/* + * 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; + + DBG_DD(ErrorF("videoflag=%p\n", videoFlag)); + + if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE)) + proReg = PRO_HQV1_OFFSET; + + 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); + + if (hwDiff->dwNeedV1Prefetch) { + DBG_DD(ErrorF("NEEDV1PREFETCH\n")); + vidCtl |= V1_PREFETCH_ON_3336; + } + + /* + * FIXME: + * Enable video on secondary + */ + if (pVia->Chipset == VIA_P4M900 && pVia->pBIOSInfo->PanelActive) { + /* V1_ON_SND_DISPLAY */ + vidCtl |= 0x80000000; + /* SECOND_DISPLAY_COLOR_KEY_ENABLE */ + compose |= 0x00010000 | 0x1; + } + + viaOverlayGetV1V3Format(pVia, (videoFlag & VIDEO_1_INUSE) ? 1 : 3, + videoFlag, &vidCtl, &hqvCtl); + + if (hwDiff->dwThreeHQVBuffer) { /* CLE_C0: HQV supports triple-buffering */ + hqvCtl &= ~HQV_SW_FLIP; + hqvCtl |= HQV_TRIPLE_BUFF | HQV_FLIP_STATUS; + } + + /* Starting address of source and Source offset */ + dwOffset = viaOverlayGetSrcStartAddress(pVia, videoFlag, pUpdate, + srcPitch, &hqvOffset); + DBG_DD(ErrorF("===dwOffset= 0x%lx \n", dwOffset)); + + 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) { + YCbCr = viaOverlayGetYCbCrStartAddress(videoFlag, startAddr, + pVia->swov.overlayRecordV1.dwOffset, + pVia->swov.overlayRecordV1.dwUVoffset, + srcPitch, oriSrcHeight); + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg, + YCbCr.dwY); + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U + proReg, + YCbCr.dwCB); + } else { + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y, YCbCr.dwY); + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U, YCbCr.dwCR); + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_V, YCbCr.dwCB); + } + } + } else { + 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->VideoEngine == VIDEO_ENGINE_CME) + SaveVideoRegister(pVia, 0x1cc + proReg, dwOffset); + + SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg, 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); + + if (pVia->HWDiff.dwHQVFetchByteUnit) + SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, + ((srcPitch >> 1) << 16) | srcPitch | + HQV_FIFO_DEPTH_1); + else + SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, + ((srcPitch >> 1) << 16) | srcPitch); + + SaveVideoRegister(pVia, HQV_DST_STRIDE + proReg, (srcPitch << 1)); + } else { + if (videoFlag & VIDEO_1_INUSE) + SaveVideoRegister(pVia, V1_STRIDE, srcPitch); + else + SaveVideoRegister(pVia, V3_STRIDE, srcPitch); + + SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, srcPitch); + SaveVideoRegister(pVia, HQV_DST_STRIDE + proReg, 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; + + /* Set up 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); + + /* Set up 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; + /* Disable X interpolation if the height exceeds + * the maximum supported by the hardware */ + if (srcHeight >= pVia->swov.maxHInterp) + miniCtl &= ~V1_X_INTERPOLY; + tmp = zoomCtl & 0xffff0000; + } + + if (haveHQVzoomV) { + miniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; + /* Disable Y interpolation if the width exceeds + * the maximum supported by the hardware */ + if (srcWidth >= pVia->swov.maxWInterp) + miniCtl &= ~V1_Y_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, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl); + SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, 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); + + /* Set up 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(HQV_CONTROL + proReg, hqvCtl); + viaWaitHQVFlip(pVia); + } + DBG_DD(ErrorF(" done.\n")); + } else { /* CLE_C0 */ + CARD32 volatile *HQVCtrl = + (CARD32 volatile *)(pVia->VidMapBase + HQV_CONTROL + + proReg); + + /* Check that 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); + } + + if (pVia->VideoEngine == VIDEO_ENGINE_CME) + hqvCtl |= HQV_GEN_IRQ; + + VIDOutD(HQV_CONTROL + proReg, hqvCtl & ~HQV_SW_FLIP); + VIDOutD(HQV_CONTROL + proReg, hqvCtl | HQV_SW_FLIP); + + DBG_DD(ErrorF("HQV control wf5 - %08lx\n", *HQVCtrl)); + DBG_DD(ErrorF(" Wait flips5")); + + if (pVia->VideoEngine != VIDEO_ENGINE_CME) { + for (i = 0; (i < 50) && !(*HQVCtrl & HQV_FLIP_STATUS); + i++) { + DBG_DD(ErrorF(" HQV wait %d %08lx\n", i, *HQVCtrl)); + *HQVCtrl |= HQV_SW_FLIP | HQV_FLIP_STATUS; + usleep(1); + } + } else { + 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")); + 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, HQV_CONTROL + proReg, + 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: updates the overlay image parameter. + */ +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; + panDY = pVia->swov.panning_y; + pVia->swov.oldPanningX = pVia->swov.panning_x; + pVia->swov.oldPanningY = pVia->swov.panning_y; + + 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_RV15) || + (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || + (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 = PRO_HQV1_OFFSET; + + 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(HQV_SRC_STARTADDR_Y + proReg); + + 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 parameters */ + + if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || + (pVia->swov.SrcFourCC == FOURCC_RV15) || + (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || + (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; + + 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_RV15) || + (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || + (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 = PRO_HQV1_OFFSET; + + 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, HQV_CONTROL + proReg, + VIDInD(HQV_CONTROL + proReg) & ~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; + pVia->VideoStatus &= ~VIDEO_SWOV_ON; +} diff --git a/trunk/src/via_swov.h b/trunk/src/via_swov.h new file mode 100644 index 000000000000..d93aa83d30d3 --- /dev/null +++ b/trunk/src/via_swov.h @@ -0,0 +1,85 @@ +/* + * 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 dwNeedV1Prefetch; /*V1 pre-fetch function for K8*/ + /*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/trunk/src/via_vbe.c b/trunk/src/via_vbe.c new file mode 100644 index 000000000000..4122558bdeed --- /dev/null +++ b/trunk/src/via_vbe.c @@ -0,0 +1,451 @@ +/* + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.h" +#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); +} +/* + * Default values for pInt10 + */ +static void ViaVbeInitInt10(vbeInfoPtr pVbe) { + + pVbe->pInt10->ax = 0x4F14; + pVbe->pInt10->cx = 0; + pVbe->pInt10->dx = 0; + pVbe->pInt10->di = 0; + pVbe->pInt10->num = 0x10; +} + +static int ViaVbeGetRefreshRateIndex(int maxRefresh) { + + int rri ; + rri = 0 ; + + if (maxRefresh >= 120) { + rri = 10; + } else if (maxRefresh >= 100) { + rri = 9; + } else if (maxRefresh >= 85) { + rri = 7; + } else if (maxRefresh >= 75) { + rri = 5; + } else { + rri = 0; + } + + return rri ; +} + +/* + * + */ +static int ViaVbeGetActiveDevices(ScrnInfoPtr pScrn) { + + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + int activeDevices; + activeDevices = 0 ; + + /* Set Active Device and Translate BIOS byte definition */ + if (pBIOSInfo->CrtActive) + activeDevices = 0x01; + if (pBIOSInfo->PanelActive) + activeDevices |= 0x02; + if (pBIOSInfo->TVActive) + activeDevices |= 0x04; + + /* TODO: Add others devices */ + + return activeDevices ; + +} + +/* + * Sets the requested mode, refresh rate and active devices + */ +static Bool ViaVbeSetActiveDevices( ScrnInfoPtr pScrn, int mode, int refresh ) { + + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + vbeInfoPtr pVbe = pVia->pVbe; + + ViaVbeInitInt10(pVbe); + pVbe->pInt10->bx = 0x8003; + pVbe->pInt10->cx = ViaVbeGetActiveDevices(pScrn); + pVbe->pInt10->dx = mode & 0x1FF; + pVbe->pInt10->di = ViaVbeGetRefreshRateIndex(refresh); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "ViaVbeSetActiveDevices mode: %x, refresh: %d active devices: 0x%2x\n", + mode, refresh, pVbe->pInt10->cx )); + + xf86ExecX86int10(pVbe->pInt10); + if (pVbe->pInt10->ax != 0x4F) + return FALSE ; + + return TRUE; +} + +/* + * Sets the panel mode (expand or center) + */ +static Bool ViaVbeSetPanelMode(ScrnInfoPtr pScrn, Bool expand) { + + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + vbeInfoPtr pVbe = pVia->pVbe; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVbeSetPanelMode\n")); + + ViaVbeInitInt10(pVbe); + pVbe->pInt10->ax = 0x4F14; + pVbe->pInt10->bx = 0x0306; + pVbe->pInt10->cx = 0x80 | expand; + + xf86ExecX86int10(pVbe->pInt10); + + if (pVbe->pInt10->ax != 0x4F) + return FALSE; + + return TRUE; +} + +static Bool +ViaVbeSetRefresh(ScrnInfoPtr pScrn, int maxRefresh) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVbeSetRefresh\n")); + vbeInfoPtr pVbe = pVia->pVbe; + + ViaVbeInitInt10(pVbe); + pVbe->pInt10->bx = 0x0001; + pVbe->pInt10->cx = ViaVbeGetActiveDevices(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Active Device: %d\n", + pVbe->pInt10->cx)); + + pVbe->pInt10->di = ViaVbeGetRefreshRateIndex(maxRefresh); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Refresh Rate Index: %d\n", + pVbe->pInt10->di)); + + /* Real execution */ + xf86ExecX86int10(pVbe->pInt10); + + if (pVbe->pInt10->ax != 0x4F) + return FALSE; + + return TRUE; +} + +Bool +ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) +{ + VIAPtr pVia; + VbeModeInfoData *data; + pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + int mode; + int refreshRate; + + pVia->OverlaySupported = FALSE; + + data = (VbeModeInfoData*)pMode->Private; + + mode = data->mode | (1 << 15); + + /* enable linear addressing */ + mode |= 1 << 14; + + if (data->block) { + refreshRate = data->block->RefreshRate; + } else { + refreshRate = VBE_DEFAULT_REFRESH; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unable to determine the refresh rate, using %.2f. " + "Please check your configuration.\n", refreshRate/100.); + } + + 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) refreshRate/100.); + + if (pVia->useLegacyVBE) { + + ViaVbeSetRefresh(pScrn, 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"); + xfree(data->block); + data->block = NULL; + data->mode &= ~(1 << 11); + } + else { + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); + return (FALSE); + } + } + } else { + + if (pBIOSInfo->PanelActive && !pVia->useLegacyVBE) { + /* + * FIXME: should we always set the panel expansion? + * does it depend on the resolution? + */ + if (!ViaVbeSetPanelMode(pScrn, !pBIOSInfo->Center)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to set the panel mode.\n"); + } + } + + data->mode &= ~(1 << 11); + if (VBESetVBEMode(pVia->pVbe, data->mode, NULL) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed.\n"); + return (FALSE); + } + + if (!ViaVbeSetActiveDevices(pScrn, data->mode, refreshRate/100)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to set the active devices.\n"); + return (FALSE); + } + } + + if (data->data->XResolution != pScrn->displayWidth) + VBESetLogicalScanline(pVia->pVbe, pScrn->displayWidth); + + pScrn->vtSema = TRUE; + + return (TRUE); +} + +Bool +ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) +{ + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ViaVbeSaveRestore\n")); + + 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))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"VBESaveRestore failed\n"); + 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) { + if (!VBESetVBEMode(pVia->pVbe, pVia->vbeMode.stateMode, NULL)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"VBESetVBEMode failed\n"); + } + } + + 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) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VBEGetVBEInfo failed\n"); + 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 != NULL && 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/trunk/src/via_vgahw.c b/trunk/src/via_vgahw.c new file mode 100644 index 000000000000..a6aac3e0c239 --- /dev/null +++ b/trunk/src/via_vgahw.c @@ -0,0 +1,194 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "via.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/trunk/src/via_vgahw.h b/trunk/src/via_vgahw.h new file mode 100644 index 000000000000..10047bb7a2f8 --- /dev/null +++ b/trunk/src/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/trunk/src/via_video.c b/trunk/src/via_video.c new file mode 100644 index 000000000000..3e041776a79f --- /dev/null +++ b/trunk/src/via_video.c @@ -0,0 +1,1640 @@ +/* + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.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 <X11/extensions/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) +{ +} + +void +viaExitVideo(ScrnInfoPtr pScrn) +{ +} +void +viaSaveVideo(ScrnInfoPtr pScrn) +{ +} +void +viaRestoreVideo(ScrnInfoPtr pScrn) +{ +} +void +VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y) +{ +} +#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 +#ifdef USE_NEW_XVABI + , DrawablePtr +#endif +); +static void nv12Blit(unsigned char *nv12Chroma, + const unsigned char *uBuffer, + const unsigned char *vBuffer, + unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines); + +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 6 + +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}, + { /* RGB 555 */ + FOURCC_RV15, + XvRGB, + LSBFirst, + {'R', 'V', '1', '5', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00}, + 16, + XvPacked, + 1, + 15, 0x7C00, 0x03E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B', 0, + 0, 0, 0, 0, 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}, + { /* RGB 565 */ + FOURCC_RV16, + XvRGB, + LSBFirst, + {'R', 'V', '1', '6', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00}, + 16, + XvPacked, + 1, + 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B', 0, + 0, 0, 0, 0, 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}, + { /* RGB 888 */ + FOURCC_RV32, + XvRGB, + LSBFirst, + {'R', 'V', '3', '2', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00}, + 32, + XvPacked, + 1, + 24, 0xff0000, 0x00ff00, 0x0000ff, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B', 0, + 0, 0, 0, 0, 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; + +#ifdef HAVE_DEBUG + if (pVia->disableXvBWCheck) + return TRUE; +#endif + + /* 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 && + pVia->ChipId != PCI_CHIP_VT3259 && + pVia->ChipId != PCI_CHIP_VT3314 && + pVia->ChipId != PCI_CHIP_VT3327 && + pVia->ChipId != PCI_CHIP_VT3336 && + pVia->ChipId != PCI_CHIP_VT3364 && + pVia->ChipId != PCI_CHIP_VT3324) { + 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 */ + memEfficiency = (float)SINGLE_3205_100; + break; + case VIA_MEM_SDR133: + mClock = 66.5; + memEfficiency = (float)SINGLE_3205_100; + break; + case VIA_MEM_DDR200: + mClock = 100; + memEfficiency = (float)SINGLE_3205_100; + break; + case VIA_MEM_DDR266: + mClock = 133; + memEfficiency = (float)SINGLE_3205_133; + break; + case VIA_MEM_DDR333: + mClock = 166; + memEfficiency = (float)SINGLE_3205_133; + break; + case VIA_MEM_DDR400: + mClock = 200; + memEfficiency = (float)SINGLE_3205_133; + break; + case VIA_MEM_DDR533: + mClock = 266; + memEfficiency = (float)SINGLE_3205_133; + break; + case VIA_MEM_DDR667: + mClock = 333; + memEfficiency = (float)SINGLE_3205_133; + break; + default: + /*Unknow DRAM Type */ + DBG_DD(ErrorF("Unknow DRAM Type!\n")); + mClock = 166; + 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 const char *viaXvErrMsg[xve_numerr] = { "No Error.", + "Bandwidth is insufficient. Check bios memory settings.", + "PCI DMA blit failed. You probably encountered a bug.", + "Not enough resources to complete the request. Probably out of memory.", + "General Error. I wish I could be more specific.", + "Wrong adaptor used. Try another port number." +}; + +static void +viaXvError(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, XvError error) +{ + if (error == xve_none) { + pPriv->xvErr = xve_none; + return; + } + if (error == pPriv->xvErr) { + return; + } + pPriv->xvErr = error; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[Xv] Port %d: %s\n", + pPriv->xv_portnum, viaXvErrMsg[error]); +} + +static void +viaResetVideo(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + + DBG_DD(ErrorF(" via_video.c : viaResetVideo: \n")); + + viaVidEng->video1_ctl = 0; + 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 = 0; + 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; + XF86VideoAdaptorPtr curAdapt; + int i, j, numPorts; + + DBG_DD(ErrorF(" via_video.c : viaExitVideo : \n")); + +#ifdef XF86DRI + ViaCleanupXVMC(pScrn, viaAdaptPtr, XV_ADAPT_NUM); +#endif + + viaVidEng->video1_ctl = 0; + 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) { + numPorts = numAdaptPort[i]; + for (j = 0; j < numPorts; ++j) { + viaStopVideo(pScrn, + (viaPortPrivPtr) curAdapt->pPortPrivates->ptr + j, + TRUE); + } + 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; + + pVia->useDmaBlit = FALSE; +#ifdef XF86DRI + pVia->useDmaBlit = pVia->directRenderingEnabled && + ((pVia->Chipset == VIA_CLE266) || + (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_K8M800) || + (pVia->Chipset == VIA_PM800) || + (pVia->Chipset == VIA_VM800) || + (pVia->Chipset == VIA_K8M890) || + (pVia->Chipset == VIA_P4M900) || + (pVia->Chipset == VIA_CX700) || + (pVia->Chipset == VIA_P4M890)); + if ((pVia->drmVerMajor < 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor < 9))) + pVia->useDmaBlit = FALSE; +#endif + pVia->useDmaBlit = pVia->useDmaBlit && pVia->dmaXV; + + if (pVia->useDmaBlit) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[Xv] Using PCI DMA for Xv image transfer.\n"); + + if (!viaFastVidCpy) + viaFastVidCpy = viaVidCopyInit("video", pScreen); + + if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) || + (pVia->Chipset == VIA_VM800) || (pVia->Chipset == VIA_K8M890) || + (pVia->Chipset == VIA_P4M900) || (pVia->Chipset == VIA_CX700) || + (pVia->Chipset == VIA_P4M890)) { + 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); + pVia->swov.panning_x = 0; + pVia->swov.panning_y = 0; + pVia->swov.oldPanningX = 0; + pVia->swov.oldPanningY = 0; + } +} + +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; +} + +#ifdef USE_NEW_XVABI + +static void +viaVideoFillPixmap(ScrnInfoPtr pScrn, + char *base, + unsigned long pitch, + int depth, + int x, int y, int w, int h, + unsigned long color) +{ + int i; + + ErrorF("pitch %lu, depth %d, x %d, y %d, w %d h %d, color 0x%08x\n", + pitch, depth, x, y, w, h, color); + + depth = (depth + 7) >> 3; + + base += y*pitch + x*depth; + + switch(depth) { + case 4: + while(h--) { + register CARD32 *p = (CARD32 *)base; + for (i=0; i<w; ++i) { + *p++ = color; + } + base += pitch; + } + break; + case 2: { + register CARD16 col = color & 0x0000FFFF; + while(h--) { + register CARD16 *p = (CARD16 *)base; + for (i=0; i<w; ++i) { + *p++ = col; + } + base += pitch; + } + break; + } + case 1: { + register CARD8 col = color & 0xFF; + while(h--) { + register CARD8 *p = (CARD8 *)base; + for (i=0; i<w; ++i) { + *p++ = col; + } + base += pitch; + } + break; + } + default: + break; + } +} + + + +static int +viaPaintColorkey(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, RegionPtr clipBoxes, + DrawablePtr pDraw) +{ + + if (pDraw->type == DRAWABLE_WINDOW) { + + VIAPtr pVia = VIAPTR(pScrn); + PixmapPtr pPix = (pScrn->pScreen->GetWindowPixmap)((WindowPtr) pDraw); + unsigned long pitch = pPix->devKind; + long offset = (long) pPix->devPrivate.ptr - + (long) pVia->FBBase; + int x,y; + BoxPtr pBox; + int nBox; + + + REGION_TRANSLATE(pScrn->pScreen, clipBoxes, - pPix->screen_x, + - pPix->screen_y); + + nBox = REGION_NUM_RECTS(clipBoxes); + pBox = REGION_RECTS(clipBoxes); + + while(nBox--) { + if (pVia->NoAccel || offset < 0 || + offset > pScrn->videoRam*1024) { + viaVideoFillPixmap(pScrn, pPix->devPrivate.ptr, pitch, + pDraw->bitsPerPixel, pBox->x1, pBox->y1, + pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, + pPriv->colorKey); + } else { + viaAccelFillPixmap(pScrn, offset, pitch, + pDraw->bitsPerPixel, pBox->x1, pBox->y1, + pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, + pPriv->colorKey); + } + pBox++; + } + + DamageDamageRegion(pPix, clipBoxes); + } + + return 0; +} +#endif + + +/* + * This one gets called, for example, on panning. + */ + +static int +viaReputImage(ScrnInfoPtr pScrn, + short drw_x, short drw_y, RegionPtr clipBoxes, pointer data +#ifdef USE_NEW_XVABI + , DrawablePtr pDraw +#endif + ) +{ + + DDUPDATEOVERLAY UpdateOverlay_Video; + LPDDUPDATEOVERLAY lpUpdateOverlay = &UpdateOverlay_Video; + viaPortPrivPtr pPriv = (viaPortPrivPtr) data; + VIAPtr pVia = VIAPTR(pScrn); + + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + if (pPriv->autoPaint) { +#ifdef USE_NEW_XVABI + if (pDraw->type == DRAWABLE_WINDOW) { + viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw); + } else { + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, + clipBoxes); + } +#else + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, + clipBoxes); +#endif + } + } + + if (drw_x == pPriv->old_drw_x && + drw_y == pPriv->old_drw_y && + pVia->swov.oldPanningX == pVia->swov.panning_x && + pVia->swov.oldPanningY == pVia->swov.panning_y) { + viaXvError(pScrn, pPriv, xve_none); + return Success; + } + + lpUpdateOverlay->SrcLeft = pPriv->old_src_x; + lpUpdateOverlay->SrcTop = pPriv->old_src_y; + lpUpdateOverlay->SrcRight = pPriv->old_src_x + pPriv->old_src_w; + lpUpdateOverlay->SrcBottom = pPriv->old_src_y + pPriv->old_src_h; + + lpUpdateOverlay->DstLeft = drw_x; + lpUpdateOverlay->DstTop = drw_y; + lpUpdateOverlay->DstRight = drw_x + pPriv->old_drw_w; + lpUpdateOverlay->DstBottom = drw_y + pPriv->old_drw_h; + pPriv->old_drw_x = drw_x; + pPriv->old_drw_y = drw_y; + + lpUpdateOverlay->dwFlags = DDOVER_KEYDEST; + + if (pScrn->bitsPerPixel == 8) + lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff; + else + lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; + + VIAVidUpdateOverlay(pScrn, lpUpdateOverlay); + + viaXvError(pScrn, pPriv, xve_none); + return Success; +} + +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]->ReputImage = viaReputImage; + viaAdaptPtr[i]->QueryImageAttributes = viaQueryImageAttributes; + for (j = 0; j < numPorts; ++j) { + viaPortPriv[j].dmaBounceBuffer = NULL; + viaPortPriv[j].dmaBounceStride = 0; + viaPortPriv[j].dmaBounceLines = 0; + 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].FourCC = 0; + viaPortPriv[j].xv_portnum = j + usedPorts; + viaPortPriv[j].xvErr = xve_none; + +#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 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); + if (pPriv->dmaBounceBuffer) + xfree(pPriv->dmaBounceBuffer); + pPriv->dmaBounceBuffer = 0; + pPriv->dmaBounceStride = 0; + pPriv->dmaBounceLines = 0; + 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 = PRO_HQV1_OFFSET; + + switch (fourcc) { + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + case FOURCC_RV32: + 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 + + proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS); + break; + + case FOURCC_YV12: + default: + while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP)) ; + VIDOutD(HQV_SRC_STARTADDR_Y + proReg, + pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { + VIDOutD(HQV_SRC_STARTADDR_U + proReg, + pVia->swov.SWDevice.dwSWCrPhysicalAddr[DisplayBufferIndex]); + } else { + 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) +{ + /* + * Blit luma component as a fake YUY2 assembler blit. + */ + + (*viaFastVidCpy) (dst, src, dstPitch, w >> 1, h, TRUE); + nv12Blit(dst + dstPitch * h, src + w * h + (w >> 1) * (h >> 1), + src + w * h, w >> 1, w >> 1, dstPitch, h >> 1); +} + +#ifdef XF86DRI + +static int +viaDmaBlitImage(VIAPtr pVia, + viaPortPrivPtr pPort, + unsigned char *src, + CARD32 dst, unsigned width, unsigned height, unsigned lumaStride, int id) +{ + Bool bounceBuffer; + drm_via_dmablit_t blit; + drm_via_blitsync_t *chromaSync = &blit.sync; + drm_via_blitsync_t lumaSync; + unsigned char *base; + unsigned char *bounceBase; + unsigned bounceStride; + unsigned bounceLines; + unsigned size; + int err = 0; + Bool nv12Conversion; + + bounceBuffer = ((unsigned long)src & 15); + nv12Conversion = (pVia->VideoEngine == VIDEO_ENGINE_CME && + id == FOURCC_YV12); + + switch (id) { + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + bounceStride = ALIGN_TO(2 * width, 16); + bounceLines = height; + break; + case FOURCC_RV32: + bounceStride = ALIGN_TO(4 * width, 16); + bounceLines = height; + break; + + case FOURCC_YV12: + default: + bounceStride = ALIGN_TO(width, 16); + bounceLines = height; + break; + } + + if (bounceBuffer || nv12Conversion) { + if (!pPort->dmaBounceBuffer || + pPort->dmaBounceStride != bounceStride || + pPort->dmaBounceLines != bounceLines) { + if (pPort->dmaBounceBuffer) { + xfree(pPort->dmaBounceBuffer); + pPort->dmaBounceBuffer = 0; + } + size = bounceStride * bounceLines + 16; + if (FOURCC_YV12 == id) + size += ALIGN_TO(bounceStride >> 1, 16) * bounceLines; + pPort->dmaBounceBuffer = (unsigned char *)malloc(size); + pPort->dmaBounceLines = bounceLines; + pPort->dmaBounceStride = bounceStride; + } + } + + bounceBase = + (unsigned char *)ALIGN_TO((unsigned long)(pPort->dmaBounceBuffer), + 16); + base = (bounceBuffer) ? bounceBase : src; + + if (bounceBuffer) { + (*viaFastVidCpy) (base, src, bounceStride, bounceStride >> 1, height, + 1); + } + + blit.num_lines = height; + blit.line_length = bounceStride; + blit.fb_addr = dst; + blit.fb_stride = lumaStride; + blit.mem_addr = base; + blit.mem_stride = bounceStride; + blit.to_fb = 1; +#ifdef XV_DEBUG + ErrorF + ("Addr: 0x%lx, Offset 0x%lx\n Fb_stride: %u, Mem_stride: %u\n width: %u num_lines: %u\n", + (unsigned long)blit.mem_addr, (unsigned long)blit.fb_addr, + (unsigned)blit.fb_stride, (unsigned)blit.mem_stride, + (unsigned)blit.line_length, (unsigned)blit.num_lines); +#endif + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (err < 0) + return -1; + + lumaSync = blit.sync; + + if (id == FOURCC_YV12) { + unsigned tmp = ALIGN_TO(width >> 1, 16); + + if (nv12Conversion) { + nv12Blit(bounceBase + bounceStride * height, + src + bounceStride * height + tmp * (height >> 1), + src + bounceStride * height, width >> 1, tmp, + bounceStride, height >> 1); + } else if (bounceBuffer) { + (*viaFastVidCpy) (base + bounceStride * height, + src + bounceStride * height, tmp, tmp >> 1, height, 1); + } + + if (nv12Conversion) { + blit.num_lines = height >> 1; + blit.line_length = bounceStride; + blit.mem_addr = bounceBase + bounceStride * height; + blit.fb_stride = lumaStride; + blit.mem_stride = bounceStride; + } else { + blit.num_lines = height; + blit.line_length = tmp; + blit.mem_addr = base + bounceStride * height; + blit.fb_stride = lumaStride >> 1; + blit.mem_stride = tmp; + } + + blit.fb_addr = dst + lumaStride * height; + blit.to_fb = 1; + + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (err < 0) + return -1; + + } + + while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + chromaSync, sizeof(*chromaSync)))) ; + if (err < 0) + return -1; + + return Success; +} + +#endif + + +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 +#ifdef USE_NEW_XVABI + , DrawablePtr pDraw +#endif + ) +{ + 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_adaptor) { + 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")); + viaXvError(pScrn, pPriv, xve_mem); + 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; + + if (pVia->useDmaBlit) { +#ifdef XF86DRI + if (viaDmaBlitImage(pVia, pPriv, buf, + (unsigned char *)pVia->swov.SWDevice. + lpSWOverlaySurface[pVia->dwFrameNum & 1] - + (unsigned char *)pVia->FBBase, width, height, + dstPitch, id)) { + viaXvError(pScrn, pPriv, xve_dmablit); + return BadAccess; + } +#endif + } else { + switch (id) { + case FOURCC_YV12: + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { + 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_RV32: + (*viaFastVidCpy) (pVia->swov.SWDevice. + lpSWOverlaySurface[pVia->dwFrameNum & 1], buf, + dstPitch, width << 1, height, 1); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + 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")); + viaXvError(pScrn, pPriv, xve_bandwidth); + 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)) { + viaXvError(pScrn, pPriv, xve_none); + 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) { +#ifdef USE_NEW_XVABI + if (pDraw->type == DRAWABLE_WINDOW) { + viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw); + } else { + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, + clipBoxes); + } +#else + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, + clipBoxes); +#endif + } + } + /* + * 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")); + viaXvError(pScrn, pPriv, xve_none); + return Success; + } + break; + } + default: + DBG_DD(ErrorF(" via_video.c : XVPort not supported\n")); + viaXvError(pScrn, pPriv, xve_adaptor); + break; + } + DBG_DD(ErrorF(" via_video.c : PutImage done OK\n")); + viaXvError(pScrn, pPriv, xve_none); + return Success; +} + +static int +viaQueryImageAttributes(ScrnInfoPtr pScrn, + int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) +{ + int size, tmp; + VIAPtr pVia = VIAPTR(pScrn); + + 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 (pVia->useDmaBlit) + size = (size + 15) & ~15; + if (pitches) + pitches[0] = size; + size *= *h; + if (offsets) + offsets[1] = size; + tmp = (*w >> 1); + if (pVia->useDmaBlit) + tmp = (tmp + 15) & ~15; + 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_RV32: + size = *w << 2; + if (pVia->useDmaBlit) + size = (size + 15) & ~15; + if (pitches) + pitches[0] = size; + size *= *h; + break; + case FOURCC_UYVY: /*Packed format : UYVY -4:2:2 */ + case FOURCC_YUY2: /*Packed format : YUY2 -4:2:2 */ + case FOURCC_RV15: + case FOURCC_RV16: + default: + size = *w << 1; + if (pVia->useDmaBlit) + size = (size + 15) & ~15; + 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; +} + +/* + * Blit the chroma field from one buffer to another while at the same time converting from + * YV12 to NV12. + */ + +static void +nv12Blit(unsigned char *nv12Chroma, + const unsigned char *uBuffer, + const unsigned char *vBuffer, + unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines) +{ + int x; + int dstAdd; + int srcAdd; + + dstAdd = dstPitch - (width << 1); + srcAdd = srcPitch - width; + + while (lines--) { + x = width; + while (x > 3) { + register CARD32 + dst32, + src32 = *((CARD32 *) vBuffer), + src32_2 = *((CARD32 *) uBuffer); + dst32 = + (src32_2 & 0xff) | ((src32 & 0xff) << 8) | + ((src32_2 & 0x0000ff00) << 8) | ((src32 & 0x0000ff00) << 16); + *((CARD32 *) nv12Chroma) = dst32; + nv12Chroma += 4; + dst32 = + ((src32_2 & 0x00ff0000) >> 16) | ((src32 & 0x00ff0000) >> 8) | + ((src32_2 & 0xff000000) >> 8) | (src32 & 0xff000000); + *((CARD32 *) nv12Chroma) = dst32; + nv12Chroma += 4; + x -= 4; + vBuffer += 4; + uBuffer += 4; + } + while (x--) { + *nv12Chroma++ = *uBuffer++; + *nv12Chroma++ = *vBuffer++; + } + nv12Chroma += dstAdd; + vBuffer += srcAdd; + uBuffer += srcAdd; + } +} + +#endif /* !XvExtension */ diff --git a/trunk/src/via_video.h b/trunk/src/via_video.h new file mode 100644 index 000000000000..47a4d24fb8ff --- /dev/null +++ b/trunk/src/via_video.h @@ -0,0 +1,113 @@ +/* + * 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/trunk/src/via_vt162x.c b/trunk/src/via_vt162x.c new file mode 100644 index 000000000000..ac01a92a3b91 --- /dev/null +++ b/trunk/src/via_vt162x.c @@ -0,0 +1,846 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 < pBIOSInfo->TVNumRegs; 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"); + pBIOSInfo->TVEncoder = VIA_VT1625; + pDev->DevName = "VT1625"; + 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) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xSave\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; i++) + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); + +} + +/* + * + */ +static void +VT162xRestore(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xRestore\n")); + + for (i = 0; i < pBIOSInfo->TVNumRegs; 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); +} + +/* + * VT1625 moves DACa through DACd from bits 0-3 to 2-5 + */ +static CARD8 +VT1625DACSenseI2C(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 & 0x3F); +} + +/* + * 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; + } +} + +/* + * VT1625 knows composite, s-video, RGB and YCBCR + */ +static Bool +VT1625DACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625DACSense\n")); + + sense = VT1625DACSenseI2C(pBIOSInfo->TVI2CDev); + switch (sense) { + case 0x00: /* DAC A,B,C,D,E,F */ + pBIOSInfo->TVOutput = TVOUTPUT_RGB; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1625: RGB connected.\n"); + return TRUE; + case 0x07: /* DAC A,B,C */ + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "VT1625: S-Video & Composite connected.\n"); + return TRUE; + case 0x37: /* DAC C */ + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "VT1625: Composite connected.\n"); + return TRUE; + case 0x38: /* DAC D,E,F */ + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1625: YCbCr connected.\n"); + return TRUE; + case 0x0F: /* DAC A,B */ + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1625: S-Video connected.\n"); + return TRUE; + case 0x3F: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VT1625: Nothing connected.\n"); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VT1625: 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, "VT1621ModeIndex:" + " 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 if (pBIOSInfo->TVEncoder == VIA_VT1625) + Table = VT1625Table; + else + Table = VT1623Table; + + for (i = 0; Table[i].Width; i++) { + +xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "width=%d:%d, height=%d:%d, std=%d:%d, name=%s:%s.\n", +Table[i].Width, mode->CrtcHDisplay, +Table[i].Height, mode->CrtcVDisplay, +Table[i].Standard, pBIOSInfo->TVType, +Table[i].name, mode->name); + + 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 ModeStatus +VT1625ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625ModeValid\n")); + + if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || + ((mode->Private != (void *) &VT162xModePrivateNTSC) && + (mode->Private != (void *) &VT162xModePrivatePAL) && + (mode->Private != (void *) &VT162xModePrivate480P) && + (mode->Private != (void *) &VT162xModePrivate576P) && + (mode->Private != (void *) &VT162xModePrivate720P) && + (mode->Private != (void *) &VT162xModePrivate1080I))) { + 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 an incompatible 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 an incompatible mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_480P) && + (mode->Private != (void *) &VT162xModePrivate480P)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is 480P. This is an incompatible mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_576P) && + (mode->Private != (void *) &VT162xModePrivate576P)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is 576P. This is an incompatible mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_720P) && + (mode->Private != (void *) &VT162xModePrivate720P)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is 720P. This is an incompatible mode.\n"); + return MODE_BAD; + } else if ((pBIOSInfo->TVType == TVTYPE_1080I) && + (mode->Private != (void *) &VT162xModePrivate1080I)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is 1080I. This is an incompatible 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, VT1625 + */ +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 if (pBIOSInfo->TVEncoder == VIA_VT1625) + Table = VT1625Table[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, VT1625 + */ +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 if (pBIOSInfo->TVEncoder == VIA_VT1625) + Table = VT1625Table[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, 0xF0, 0xF0); /* 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); +} + +/* + * + */ +static void +VT1625Power(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625Power\n")); + + if (On) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); + else + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x3F); +} + +/* + * + */ +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; + pBIOSInfo->TVNumRegs = 0x68; + 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; + pBIOSInfo->TVNumRegs = 0x68; + 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; + pBIOSInfo->TVNumRegs = 0x6C; + break; + case VIA_VT1625: + pBIOSInfo->TVSave = VT162xSave; + pBIOSInfo->TVRestore = VT162xRestore; + pBIOSInfo->TVDACSense = VT1625DACSense; + pBIOSInfo->TVModeValid = VT1625ModeValid; + pBIOSInfo->TVModeI2C = VT1622ModeI2C; + pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; + pBIOSInfo->TVPower = VT1625Power; + pBIOSInfo->TVModes = VT1625Modes; + pBIOSInfo->TVPrintRegs = VT162xPrintRegs; + pBIOSInfo->TVNumRegs = 0x6C; + break; + default: + break; + } +} diff --git a/trunk/src/via_vt162x.h b/trunk/src/via_vt162x.h new file mode 100644 index 000000000000..44e0456ddd63 --- /dev/null +++ b/trunk/src/via_vt162x.h @@ -0,0 +1,998 @@ +/* + * 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; +}; + +/* Hmm this seemed like a reasonable approach initially. perhaps not. */ +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,}; +static struct VT162xModePrivate VT162xModePrivate480P = { { 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, TVTYPE_480P,}; +static struct VT162xModePrivate VT162xModePrivate576P = { { 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, TVTYPE_576P,}; +static struct VT162xModePrivate VT162xModePrivate720P = { { 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, TVTYPE_720P,}; +static struct VT162xModePrivate VT162xModePrivate1080I = {{ 'V', 'T', '1', '6', '2', 'x', 0, 0, 0, 0, 0, 0 }, TVTYPE_1080I,}; + +#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 +#define MODESUFFIX480P 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivate480P,0,0.0,0.0 +#define MODESUFFIX576P 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivate576P,0,0.0,0.0 +#define MODESUFFIX720P 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivate720P,0,0.0,0.0 +#define MODESUFFIX1080I 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\ + sizeof(struct VT162xModePrivate),(void *)&VT162xModePrivate1080I,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("720x480Noscale"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC }, + { 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, + }, + { "720x480Noscale", 720, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0, 0, 0, 0x03, 0, 0x10, 0x98, 0x98, 0x08, 0x5A, 0x17, 0x49, 0x41, 0, 0x89, + 0, 0, 0xA9, 0x19, 0xDC, 0x24, 0, 0, 0, 0, 0xEE, 0x03, 0x02, 0x80, 0, 0x04, + 0x11, 0x08, 0x04, 0x75, 0, 0x5A, 0x31, 0x95, 0x51, 0, 0, 0xAA, 0x2B, 0x7A, 0xDB, 0 }, + { 0xE4, 0x69, 0x04, 0, 0, 0x40, 0x77, 0xD0, 0x23, 0x0C, 0x02, 0x77, 0xD0, 0x80, 0x23, 0x88, + 0xC9, 0x30, 0xD0, 0x16, 0, 0, 0, 0, 0, 0x77, 0x03 }, + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, /* added later - untested */ + { 0x58, 0x48, 0x49 }, /* added later - untested */ + 0x20BA2E8B, 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("720x576Noscale"), 28000, 720, 736, 768, 896, 0, 576, 576, 579, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x480Noscale"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x480pal"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_NVSYNC, 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, + }, + { "720x576Noscale", 720, 576, TVTYPE_PAL, 0, 0, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x78, 0x78, 0x38, 0x5a, 0x00, 0x49, 0x2e, 0x00, 0x80, + 0x00, 0x00, 0x03, 0x0f, 0x16, 0x0c, 0x8d, 0x33, 0x89, 0x28, 0xee, 0x10, 0x02, 0x80, 0x00, 0x00, + 0x13, 0x0c, 0x04, 0x7b, 0x48, 0x64, 0x30, 0x93, 0x49, 0x5f, 0x15, 0xa5, 0x23, 0x77, 0xff, 0x00, + }, + { 0x00, 0x00, 0x04, 0x00, 0x00, 0x45, 0x7f, 0xd0, 0x23, 0x70, 0x02, 0x7f, 0xd0, 0x83, 0x23, 0x9c, + 0xdb, 0x08, 0xb7, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x03, }, + + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x49 }, + 0x2889338d, 0, + }, + + { "720x480Noscale", 720, 480, TVTYPE_NTSC, 0, 0, + { 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x78, 0x78, 0x06, 0x5a, 0x00, 0x49, 0x2f, 0x00, 0x80, + 0x00, 0x00, 0xed, 0x23, 0xde, 0x34, 0x97, 0xab, 0xca, 0x20, 0xee, 0x10, 0x02, 0x80, 0x00, 0x11, + 0x11, 0x08, 0x04, 0x76, 0x08, 0x5a, 0x31, 0x95, 0x51, 0x00, 0x00, 0xaa, 0x2b, 0x7a, 0xdb, 0x00, + }, + { 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x77, 0xd0, 0x23, 0x0c, 0x02, 0x77, 0xd0, 0x83, 0x23, 0x98, + 0xde, 0xe8, 0xc4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x03, }, + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x49 }, + 0x20caab97, 0, + }, + + { "720x480pal", 720, 480, TVTYPE_PAL, 0, 0, + { 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x74, 0x8c, 0x06, 0x50, 0x00, 0x4e, 0x2f, 0x00, 0x07, + 0x00, 0x00, 0xa9, 0x19, 0x6e, 0x24, 0xe3, 0x33, 0x89, 0x28, 0xee, 0x10, 0x02, 0x80, 0x00, 0x11, + 0x11, 0x08, 0x04, 0x76, 0x08, 0x5a, 0x31, 0x95, 0x51, 0x00, 0x00, 0xaa, 0x2b, 0x7a, 0xdb, 0x00, + }, + { 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x77, 0xd0, 0x23, 0x0c, 0x02, 0x77, 0xd0, 0xb0, 0x23, 0x88, + 0xc9, 0x30, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x03 }, + { 0xBA, 0xB8, 0xB8, 0x90, 0x99, 0 }, + { 0x58, 0x48, 0x49 }, + 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, + } +}; + +/* + * + * VT1625 modetables + * + */ + +static DisplayModeRec VT1625Modes[] = { +/* all available modes are: */ +/* { MODEPREFIX("640x480"), ... , MODESUFFIXNTSC }, + { MODEPREFIX("800x600"), ... , MODESUFFIXNTSC }, + { MODEPREFIX("1024x768"), ... , MODESUFFIXNTSC }, + + { MODEPREFIX("720x480"), ... , MODESUFFIX480P }, + + { MODEPREFIX("640x480"), ... , MODESUFFIX720P }, + { MODEPREFIX("800x600"), ... , MODESUFFIX720P }, + { MODEPREFIX("1024x768"), ... , MODESUFFIX720P }, + { MODEPREFIX("720x480"), ... , MODESUFFIX720P }, + { MODEPREFIX("720x576"), ... , MODESUFFIX720P }, + + { MODEPREFIX("640x480"), ... , MODESUFFIX1080I }, + { MODEPREFIX("800x600"), ... , MODESUFFIX1080I }, + { MODEPREFIX("1024x768"), ... , MODESUFFIX1080I }, + { MODEPREFIX("720x480"), ... , MODESUFFIX1080I }, + { MODEPREFIX("720x576"), ... , MODESUFFIX1080I }, + + { MODEPREFIX("640x480Over"), ... , MODESUFFIXNTSC }, + { MODEPREFIX("800x600Over"), ... , MODESUFFIXNTSC }, + { MODEPREFIX("1024x768Over"), ... , MODESUFFIXNTSC }, + { MODEPREFIX("720x480Over"), ... , MODESUFFIXNTSC }, + + { MODEPREFIX("640x480Over"), ... , MODESUFFIXPAL }, + { MODEPREFIX("800x600Over"), ... , MODESUFFIXPAL }, + { MODEPREFIX("1024x768Over"), ... , MODESUFFIXPAL }, + { MODEPREFIX("720x576Over"), ... , MODESUFFIXPAL },*/ +/* clock HR SH1 SH2 HFL VR SV1 SV2 VFL*/ + { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x576"), 34500, 720, 766, 800, 1000, 0, 576, 576, 579, 690, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + { MODEPREFIX("720x576Over"), 27000, 720, 768, 800, 864, 0, 576, 577, 579, 625, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL }, + + { MODEPREFIX("1280x720"), 74250, 1280, 1320, 1376, 1650, 0, 720, 722, 728, 750, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX720P }, + { MODEPREFIX("1920x1080"), 74250, 1920, 1960, 2016, 2200, 0, 1080, 1082, 1088, 1125, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX1080I }, + + { MODEPREFIX("640x480"), 24696, 640, 656, 744, 784, 0, 480, 482, 483, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x480Under"), 34000, 720, 728, 744, 784, 0, 480, 490, 496, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x480Fit"), 28980, 720, 728, 744, 784, 0, 480, 490, 496, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + { MODEPREFIX("720x480Over"), 27025, 720, 728, 744, 784, 0, 480, 490, 496, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC }, + + { MODEPREFIX("720x480Under"), 28224, 720, 728, 744, 784, 0, 480, 490, 496, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P }, + { MODEPREFIX("720x480Fit"), 28980, 720, 728, 776, 840, 0, 480, 484, 499, 575, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P }, + { MODEPREFIX("720x480Over"), 27027, 720, 784, 808, 858, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P }, + + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC }, +}; + +static struct VT162XTableRec +VT1625Table[] = { + { "640x480", 640, 480, TVTYPE_NTSC, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x40, 0x10, 0, 0, 0x28, 0x47, 0x15, 0x7B, 0, 0x50, 0x57, 0, 0x9E, + 0, 0x80, 0xFA, 0x21, 0xE0, 0x68, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x41, 0x80, 0, 0x10, + 0x1C, 0x2A, 0xCB, 0x77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0, 0, 0x01, 0x10, 0x4A, 0x0F, 0x83, 0x23, 0x57, 0x22, 0x59, 0x83, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0x13, 0x7C, 0x16, 0x49, 0, 0x92, 0x20, 0, 0x7F, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x56, 0x55 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F087BE, + }, + { "720x480Under", 720, 480, TVTYPE_NTSC, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x1F, 0x00, 0, 0, 0x2A, 0x41, 0x0A, 0x7B, 0x15, 0x50, 0x57, 0, 0xB7, + 0, 0x80, 0xAB, 0x27, 0x70, 0x2C, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x41, 0x80, 0, 0x10, + 0x1C, 0x08, 0xCB, 0x77, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x4A, 0x0F, 0xCF, 0x23, 0x57, 0x22, 0x59, 0x83, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0x13, 0x7A, 0x16, 0x49, 0xF1, 0x92, 0xA8, 0xFF, 0x7F, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F04CC3, + }, + { "720x480Fit", 720, 480, TVTYPE_NTSC, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x1F, 0x00, 0, 0, 0x41, 0x3B, 0x0B, 0x7B, 0x15, 0x50, 0x57, 0, 0xB7, + 0, 0x80, 0xCD, 0x21, 0x73, 0x34, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0, 0x10, + 0x1C, 0x08, 0xCA, 0x77, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0x10, 0x4A, 0x47, 0xCF, 0x23, 0x3E, 0x22, 0x59, 0x8B, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0x13, 0x7A, 0x16, 0x30, 0xD4, 0x8C, 0x28, 0xFF, 0x97, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F0EBE8, + }, + { "720x480Over", 720, 480, TVTYPE_NTSC, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x1F, 0x00, 0, 0, 0x33, 0x1C, 0x06, 0x7B, 0x15, 0x50, 0x57, 0, 0x9E, + 0, 0x80, 0x04, 0x08, 0x08, 0x10, 0xD6, 0x7B, 0xF0, 0x21, 0x00, 0x50, 0x43, 0x80, 0, 0x10, + 0x1C, 0x08, 0xDC, 0x77, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0x10, 0x4A, 0x59, 0xCF, 0x23, 0x0C, 0x22, 0x59, 0xCF, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0xE1, 0x7D, 0x06, 0, 0, 0x80, 0x28, 0xFF, 0x59, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F05C1E, + }, + { "720x480Under", 720, 480, TVTYPE_480P, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x40, 0x10, 0, 0, 0x2A, 0x41, 0x14, 0x7B, 0, 0x50, 0x57, 0, 0xB7, + 0, 0x80, 0xAB, 0x27, 0x70, 0x2C, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x41, 0x80, 0, 0x01, + 0x2F, 0x08, 0xCB, 0x7E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0, 0x4A, 0x0F, 0xCF, 0x23, 0x57, 0x22, 0x59, 0x83, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0x13, 0x7A, 0x16, 0x49, 0xF1, 0x92, 0xA8, 0, 0x7F, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F087BE, + }, + { "720x480Fit", 720, 480, TVTYPE_480P, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x40, 0x10, 0, 0, 0x41, 0x43, 0xFF, 0x7B, 0, 0x50, 0x57, 0, 0xB7, + 0, 0x80, 0xCD, 0x21, 0x73, 0x34, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0, 0x01, + 0x2F, 0x08, 0xCA, 0x7E, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0, 0x4A, 0x47, 0xCF, 0x23, 0x3E, 0x22, 0x59, 0x8B, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0x13, 0x7A, 0x16, 0x30, 0xD4, 0x8C, 0x28, 0, 0x97, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F087BE, + }, + { "720x480Over", 720, 480, TVTYPE_480P, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x40, 0x10, 0, 0, 0x33, 0x20, 0xFF, 0x7B, 0, 0x50, 0x57, 0, 0x9E, + 0, 0x80, 0x04, 0x08, 0x08, 0x10, 0xD6, 0x7B, 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0, 0x01, + 0x2F, 0x08, 0xDC, 0x7E, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0, 0x4A, 0x59, 0xCF, 0x23, 0x0C, 0x22, 0x59, 0xCF, 0x7F, 0x23, 0x91, + /* 5A 5F 60 64 */ + 0xD2, 0xE1, 0x7D, 0x06, 0, 0, 0x80, 0x28, 0, 0x59, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x37, 0x5C, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x54, 0x56 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x21F07BD6, 0x21F087BE, + }, + + { "1280x720", 1280, 720, TVTYPE_720P, 0, 0, + /* 00 0F */ + { 0x83, 0, 0x10, 0x40, 0x94, 0x00, 0, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, + 0x00, 0x80, 0x89, 0x10, 0x63, 0x24, 0x00, 0x00, 0x00, 0x00, 0, 0x50, 0x40, 0x80, 0x00, 0x03, + 0x25, 0x00, 0x00, 0x7E, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* hdtv - 4A 0x85, 4B 0x0A */ + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0, 0x00, 0x71, 0xFF, 0x46, 0xED, 0x12, 0x71, 0xFF, 0x50, 0x46, 0x30, + /* 5A 5F 60 64 */ + 0x30, 0x1C, 0x47, 0x96, 0x00, 0x00, 0x80, 0x28, 0x00, 0x71, 0x36 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x39, 0x66, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x56, 0x55 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x0, 0x0, + }, + + { "1920x1080", 1920, 540, TVTYPE_1080I, 0, 0, + /* 00 0F */ + { 0x83, 0, 0x10, 0x4A, 0x86, 0x39, 0, 0x8B, 0x3D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, + 0x00, 0x80, 0x4A, 0x08, 0x37, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x44, 0x80, 0x00, 0x03, + 0x25, 0x00, 0x00, 0x7E, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0, 0x00, 0x97, 0x7F, 0x78, 0x64, 0x14, 0x97, 0x7f, 0x59, 0x78, 0xb0, + /* 5A 5F 60 64 */ + 0x1a, 0xec, 0xfa, 0x08, 0x00, 0x00, 0x80, 0x20, 0xFF, 0x97, 0x28 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x55, 0x39, 0x66, 0, 0, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x55, 0x56, 0x55 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x0, 0x0, + }, + + { "720x576", 720, 576, TVTYPE_PAL, 0, 0, + /* 00 0F */ + { 0x03, 0x00, 0x10, 0x1f, 0x03, 0x00, 0x00, 0xc9, 0x4c, 0x11, 0x7c, 0x00, 0x56, 0x57, 0x07, 0xbf, + 0x00, 0x80, 0x09, 0x08, 0x17, 0x24, 0xcb, 0x8a, 0x09, 0x2a, 0x06, 0x50, 0x01, 0x80, 0x00, 0x10, + 0x14, 0x0c, 0x32, 0x7e, 0x00, 0x5f, 0x34, 0x8c, 0x4f, 0x5e, 0x15, 0xa2, 0x22, 0x80, 0xd3, 0x10 + }, + /* 4A 4F 50 59 */ + { 0xc5, 0x0f, 0x00, 0x01, 0x00, 0x4b, 0xe7, 0xd2, 0x23, 0xb1, 0x22, 0x5f, 0x61, 0x7f, 0x23, 0x90, + /* 5A 5F 60 64 */ + 0xcd, 0x35, 0x83, 0x16, 0x4F, 0x76, 0x8d, 0xa9, 0xff, 0x4f, 0x04 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x58, 0x48, 0x49 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x2A098ACB, 0, + }, + + { "720x576Over", 720, 576, TVTYPE_PAL, 0, 0, + /* 00 0F */ + { 0x03, 0, 0x10, 0x1F, 0x03, 0, 0, 0x39, 0x19, 0x01, 0x88, 0x00, 0x55, 0x5E, 0x00, 0x9E, + 0, 0x80, 0x04, 0x08, 0x08, 0x10, 0xCB, 0x8A, 0x09, 0x2A, 0x00, 0x50, 0x41, 0x80, 0, 0x10, + 0x17, 0x0C, 0x32, 0x7D, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 4A 4F 50 59 */ + { 0xC5, 0x0F, 0, 0x01, 0x10, 0x51, 0x5F, 0xCF, 0x23, 0x70, 0x22, 0x5F, 0xD0, 0x7F, 0x23, 0x92, + /* 5A 5F 60 64 */ + 0xCE, 0x0C, 0x8E, 0x16, 0, 0, 0x80, 0x20, 0xFF, 0x5F, 0x03 }, + /* RBG 65,66,67,27,2b,2c */ + { 0x6A, 0x62, 0x65, 0x90, 0x99, 0 }, + /* Y-Cb-Cr 65,66,67 */ + { 0x58, 0x48, 0x49 }, + /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */ + 0x2A098ACB, 0, + }, + +/* + { "1920x1080", 1920, 540, TVTYPE_NTSC, 0, 0, + { 0x83, 0, 0x10, 0x4A, 0x86, 0x39, 0, 0x8B, 0x3D, 0x32, 0, 0, 0, 0, 0, 0x9E, + 0, 0x80, 0x4A, 0x08, 0x37, 0x14, 0, 0, 0, 0, 0, 0x50, 0x44, 0x80, 0, 0x03, + 0x25, 0, 0, 0x7E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0xC5, 0x0F, 0, 0x01, 0, 0, 0x97, 0x7F, 0x78, 0x64, 0x14, 0x97, 0x7F, 0x59, 0x78, 0xB0, + 0x1A, 0xEC, 0xFA, 0x08, 0, 0, 0x80, 0x20, 0xFF, 0x97, 0x28 }, + { 0x55, 0x56, 0x55, 0x91, 0x9C, 0 }, + { 0x42, 0x49, 0x48 }, + 0x1E555518, 0x1E554CC3, + }, + { "960x540", 960, 540, TVTYPE_NTSC, 0, 0, + { 0x83, 0, 0x10, 0x4A, 0x86, 0x39, 0, 0x8B, 0x3D, 0x32, 0, 0, 0, 0, 0, 0x9E, + 0, 0x80, 0x4A, 0x08, 0x37, 0x14, 0, 0, 0, 0, 0, 0x50, 0x44, 0x80, 0, 0x03, + 0x25, 0, 0, 0x7E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0xC5, 0x0F, 0, 0x01, 0, 0, 0x97, 0x7F, 0x78, 0x64, 0x14, 0x97, 0x7F, 0x59, 0x78, 0xB0, + 0x1A, 0xEC, 0xFA, 0x08, 0, 0, 0x80, 0x20, 0xFF, 0x97, 0x28 }, + { 0x55, 0x56, 0x55, 0x91, 0x9C, 0 }, + { 0x42, 0x49, 0x48 }, + 0x1E555518, 0x1E554CC3, + }, +*/ + { 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/trunk/src/via_xvmc.c b/trunk/src/via_xvmc.c new file mode 100644 index 000000000000..310b24c1d708 --- /dev/null +++ b/trunk/src/via_xvmc.c @@ -0,0 +1,1018 @@ +/***************************************************************************** + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#ifdef XF86DRI + +#include "via.h" +#include "via_drm.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 <X11/extensions/Xv.h> +#include <X11/extensions/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, INT32 ** priv); +static void ViaXvMCDestroyContext(ScrnInfoPtr pScrn, XvMCContextPtr pContext); +static int ViaXvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, INT32 ** priv); +static void ViaXvMCDestroySurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf); +static int ViaXvMCCreateSubpicture(ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf, + int *num_priv, INT32 ** 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 +#ifdef USE_NEW_XVABI + , DrawablePtr +#endif +); +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, + 1024, + 1024, + 1024, + 1024, + XVMC_MPEG_2 | XVMC_VLD, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoRec Via_pga_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_mpg1_surface = { + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 1024, + 1024, + 1024, + 1024, + XVMC_MPEG_1 | XVMC_VLD, + XVMC_OVERLAID_SURFACE | XVMC_BACKEND_SUBPICTURE, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoRec Via_pga_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_pga[2] = { + (XF86MCSurfaceInfoPtr) & Via_pga_mpg2_surface, + (XF86MCSurfaceInfoPtr) & Via_pga_mpg1_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_pga = { + "XV_SWOV", /* name */ + 2, /* num_surfaces */ + ppSI_pga, /* 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_pga[1] = { (XF86MCAdaptorPtr) & pAdapt_pga }; + +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; + + pVia->XvMCEnabled = 0; + + if (!(pVia->Chipset == VIA_CLE266) && !(pVia->Chipset == VIA_K8M800) && + !(pVia->Chipset == VIA_PM800) && !(pVia->Chipset == VIA_VM800) && + !(pVia->Chipset == VIA_K8M890) && !(pVia->Chipset == VIA_P4M900) && + !(pVia->Chipset == VIA_P4M890)) { + 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 (((pVia->drmVerMajor <= 2) && (pVia->drmVerMinor < 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", + pVia->drmVerMajor, pVia->drmVerMinor, pVia->drmVerPL); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] Please update. Disabling XvMC.\n"); + return; + } + + 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_PM800) ? ppAdapt_pga : 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; + + if (pVia->ChipId != PCI_CHIP_VT3259 && pVia->ChipId != PCI_CHIP_VT3364) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[XvMC] Registering chromeXvMC.\n"); + xf86XvMCRegisterDRInfo(pScreen, "chromeXvMC", pDRIInfo->busIdString, + VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[XvMC] Registering chromeXvMCPro.\n"); + xf86XvMCRegisterDRInfo(pScreen, "chromeXvMCPro", + 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); + 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, INT32 ** 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; + + 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; + } + + /* + * 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->sAreaSize = pDRIInfo->SAREASize; + contextRec->sAreaPrivOffset = sizeof(XF86DRISAREARec); + contextRec->major = VIAXVMC_MAJOR; + contextRec->minor = VIAXVMC_MINOR; + contextRec->pl = VIAXVMC_PL; + contextRec->initAttrs = vx->xvAttr; + contextRec->useAGP = pViaDRI->ringBufActive && + ((pVia->Chipset == VIA_CLE266) || + (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_P4M900) || + (pVia->Chipset == VIA_PM800)); + contextRec->chipId = pVia->ChipId; + contextRec->screen = pScrn->pScreen->myNum; + contextRec->depth = pScrn->bitsPerPixel; + contextRec->stride = pVia->Bpp * pScrn->virtualX; + + vXvMC->nContexts++; + vXvMC->contexts[ctxNo] = pContext->context_id; + vXvMC->cPrivs[ctxNo] = cPriv; + + return Success; +} + +static int +ViaXvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, INT32 ** 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 = (INT32 *) xcalloc(*num_priv, sizeof(INT32)); + + 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, INT32 ** 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 = (INT32 *) xcalloc(3, sizeof(INT32)); + + 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; + viaPortPrivPtr pPriv; + XvPortRecPrivatePtr portPriv; + ViaXvMCXVPriv *vx; + + for (i = 0; i < VIA_XVMC_MAX_CONTEXTS; i++) { + if (vXvMC->contexts[i] == pContext->context_id) { + + 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; + } + + 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 +#ifdef USE_NEW_XVABI + , DrawablePtr pDraw +#endif + ) +{ + 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 +#ifdef USE_NEW_XVABI + , pDraw +#endif + ); +} + +unsigned long +viaXvMCPutImageSize(ScrnInfoPtr pScrn) +{ + if (VIAPTR(pScrn)->XvMCEnabled) + return sizeof(ViaXvMCCommandBuffer); + return 0; +} + +#endif diff --git a/trunk/src/via_xvmc.h b/trunk/src/via_xvmc.h new file mode 100644 index 000000000000..6bae5ba6eb9d --- /dev/null +++ b/trunk/src/via_xvmc.h @@ -0,0 +1,104 @@ +/***************************************************************************** + * 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 10 +#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 +{ + INT32 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 ctxNo; + unsigned int major, minor, pl; + unsigned xvmc_port; + unsigned int fbOffset; + unsigned int fbSize; + unsigned int mmioOffset; + unsigned int mmioSize; + unsigned int sAreaSize; + unsigned int sAreaPrivOffset; + ViaXvMCAttrHolder initAttrs; + int useAGP; + unsigned int chipId; + unsigned int screen; + unsigned int depth; + unsigned int stride; + unsigned int pad; +} ViaXvMCCreateContextRec; + +#endif diff --git a/trunk/src/via_xvpriv.h b/trunk/src/via_xvpriv.h new file mode 100644 index 000000000000..b6c796bf6689 --- /dev/null +++ b/trunk/src/via_xvpriv.h @@ -0,0 +1,90 @@ +/* + * 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 +}; + +typedef enum +{ + xve_none = 0, + xve_bandwidth, + xve_dmablit, + xve_mem, + xve_general, + xve_adaptor, + xve_numerr +} XvError; + +#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; + + /* + * For PCI DMA image transfer to frame-buffer memory. + */ + + unsigned char *dmaBounceBuffer; + unsigned dmaBounceStride; + unsigned dmaBounceLines; + XvError xvErr; + +} viaPortPrivRec, *viaPortPrivPtr; + +extern viaPortPrivPtr viaPortPriv[]; +extern unsigned viaNumXvPorts; + +#endif /* _VIA_XVPRIV_H_ */ |