diff options
Diffstat (limited to 'drivers/sound')
42 files changed, 18754 insertions, 1276 deletions
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in index 2be547953..e32181802 100644 --- a/drivers/sound/Config.in +++ b/drivers/sound/Config.in @@ -9,38 +9,40 @@ # Prompt user for primary drivers. -dep_tristate 'C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND -dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND -if [ "$CONFIG_SOUND_ES1370" = "y" ]; then - bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT +dep_tristate ' C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND +if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then + bool ' Enable legacy FM' CONFIG_SOUND_CMPCI_FM + bool ' Enable legacy MPU-401' CONFIG_SOUND_CMPCI_MIDI fi -dep_tristate 'Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND -if [ "$CONFIG_SOUND_ES1371" = "y" ]; then - bool 'Joystick support at boot time' CONFIG_SOUND_ES1371_JOYPORT_BOOT - if [ "$CONFIG_SOUND_ES1371_JOYPORT_BOOT" = "y" ]; then - hex 'Gameport I/O 200,208,210,218' CONFIG_SOUND_ES1371_GAMEPORT 200 - fi +dep_tristate ' Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND +dep_tristate ' Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND +dep_tristate ' ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' ESS Maestro, Maestro2, Maestro2E driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO $CONFIG_SOUND +fi +dep_tristate ' S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND +if [ "$CONFIG_VISWS" = "y" ]; then + dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND fi -dep_tristate 'S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND -dep_tristate 'Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND +dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then - comment 'Compiled-in MSND Classic support requires firmware during compilation.' + comment ' Compiled-in MSND Classic support requires firmware during compilation.' define_bool CONFIG_MSNDCLAS_HAVE_BOOT y else define_bool CONFIG_MSNDCLAS_HAVE_BOOT n fi - string ' Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" - string ' Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" + string 'Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" + string 'Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" fi if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then - int 'MSND Classic IRQ 5,7,9,10,11,12' CONFIG_MSNDCLAS_IRQ 5 - hex 'MSND Classic memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDCLAS_MEM D0000 - hex 'MSND Classic I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDCLAS_IO 290 + int ' MSND Classic IRQ 5, 7, 9, 10, 11, 12' CONFIG_MSNDCLAS_IRQ 5 + hex ' MSND Classic memory B0000, C8000, D0000, D8000, E0000, E8000' CONFIG_MSNDCLAS_MEM D0000 + hex ' MSND Classic I/O 210, 220, 230, 240, 250, 260, 290, 3E0' CONFIG_MSNDCLAS_IO 290 fi -dep_tristate 'Support for Turtle Beach MultiSound Pinnacle, Fiji' CONFIG_SOUND_MSNDPIN $CONFIG_SOUND +dep_tristate ' Support for Turtle Beach MultiSound Pinnacle, Fiji' CONFIG_SOUND_MSNDPIN $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDPIN" = "m" ]; then if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then comment 'Compiled-in MSND Pinnacle support requires firmware during compilation.' @@ -52,115 +54,94 @@ if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDPIN" = "m" ]; then string ' Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin" fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then - int 'MSND Pinnacle IRQ 5,7,9,10,11,12' CONFIG_MSNDPIN_IRQ 5 - hex 'MSND Pinnacle memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDPIN_MEM D0000 - hex 'MSND Pinnacle I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDPIN_IO 290 - bool 'MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL - bool 'MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP + int ' MSND Pinnacle IRQ 5, 7, 9, 10, 11, 12' CONFIG_MSNDPIN_IRQ 5 + hex ' MSND Pinnacle memory B0000, C8000, D0000, D8000, E0000, E8000' CONFIG_MSNDPIN_MEM D0000 + hex 'MSND Pinnacle I/O 210, 220, 230, 240, 250, 260, 290, 3E0' CONFIG_MSNDPIN_IO 290 + bool ' MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL + bool ' MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP if [ "$CONFIG_MSNDPIN_NONPNP" = "y" ]; then - comment 'MSND Pinnacle DSP section will be configured to above parameters.' - hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 - comment 'Pinnacle-specific Device Configuration (0 disables)' - hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0 - int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0 - hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0 - hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0 - int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0 - hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 + comment 'MSND Pinnacle DSP section will be configured to above parameters.' + hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 + comment 'Pinnacle-specific Device Configuration (0 disables)' + hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0 + int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0 + hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0 + hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0 + int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0 + hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 fi fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then int 'MSND buffer size (kB)' CONFIG_MSND_FIFOSIZE 128 fi -dep_tristate 'OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND +dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then - if [ "$CONFIG_SOUND_OSS" = "y" ]; then - bool 'Persistent DMA buffers' CONFIG_SOUND_DMAP - fi + if [ "$CONFIG_SOUND_OSS" = "y" ]; then + bool ' Persistent DMA buffers' CONFIG_SOUND_DMAP + fi - dep_tristate 'ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_PAS" = "y" ]; then - int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10 - int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3 - bool 'Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK - fi - - dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SB" = "y" ]; then - hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220 - int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7 - int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1 - int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5 - hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330 - comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.' - comment 'Enter -1 to the following question if you have something else such as SB16/32.' - int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1 - fi - - dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_SOUND_ADLIB $CONFIG_SOUND_OSS - - dep_tristate 'Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then - bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 - bool 'GUS MAX support' CONFIG_GUSMAX - fi - if [ "$CONFIG_SOUND_GUS" = "y" ]; then - hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220 - int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15 - int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6 - int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1 - if [ "$CONFIG_GUS16" = "y" ]; then - hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530 - int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7 - int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3 - fi - fi - - dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MPU401" = "y" ]; then - hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 - int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9 - fi - - dep_tristate 'PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_PSS" = "y" ]; then - hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220 - hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530 - int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11 - int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3 - hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330 - int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9 - bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT - if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then - string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND + if [ "$CONFIG_SOUND_AD1816" = "y" ]; then + hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530 + int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7 + int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0 + int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3 + int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000 fi - fi - if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then - bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER - fi - - dep_tristate 'Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MSS" = "y" ]; then - bool 'Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO - hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530 - int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11 - int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3 - int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1 - fi - - dep_tristate 'Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SSCAPE" = "y" ]; then + fi + + dep_tristate ' Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then + hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530 + int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11 + int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0 + int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3 + hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220 + fi + + dep_tristate ' Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_CS4232" = "y" ]; then + hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530 + int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11 + int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0 + int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3 + hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330 + int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9 + fi + + dep_tristate ' Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SSCAPE" = "y" ]; then hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' CONFIG_SSCAPE_BASE 330 int 'SoundScape MIDI IRQ ' CONFIG_SSCAPE_IRQ 9 int 'SoundScape initialization DMA 0, 1 or 3' CONFIG_SSCAPE_DMA 3 hex 'SoundScape audio I/O base 534, 608, E84 or F44' CONFIG_SSCAPE_MSS_BASE 534 int 'SoundScape audio IRQ 7, 9, 10 or 11' CONFIG_SSCAPE_MSS_IRQ 11 - fi - - dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_TRIX" = "y" ]; then + fi + + dep_tristate ' Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then + bool ' 16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 + bool ' GUS MAX support' CONFIG_GUSMAX + fi + if [ "$CONFIG_SOUND_GUS" = "y" ]; then + hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220 + int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15 + int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6 + int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1 + if [ "$CONFIG_GUS16" = "y" ]; then + hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530 + int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7 + int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3 + fi + fi + + dep_tristate ' Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS + + dep_tristate ' MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_TRIX" = "y" ]; then hex 'TRIX audio I/O base 530, 604, E80 or F40' CONFIG_TRIX_BASE 530 int 'TRIX audio IRQ 7, 9, 10 or 11' CONFIG_TRIX_IRQ 11 int 'TRIX audio DMA 0, 1 or 3' CONFIG_TRIX_DMA 0 @@ -170,131 +151,153 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then hex 'TRIX SB I/O base 220, 210, 230, 240, 250, 260 or 270' CONFIG_TRIX_SB_BASE 220 int 'TRIX SB IRQ 3, 4, 5 or 7' CONFIG_TRIX_SB_IRQ 7 int 'TRIX SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1 - bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT + bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then string ' Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE /etc/sound/trxpro.hex fi - fi + fi - dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then - bool 'Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD - fi - if [ "$CONFIG_SOUND_MAD16" = "y" ]; then + dep_tristate ' Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MSS" = "y" ]; then + bool ' Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO + hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530 + int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11 + int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3 + int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1 + fi + + dep_tristate ' MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MPU401" = "y" ]; then + hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 + int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9 + fi + + dep_tristate ' NM256AV/NM256ZX audio support' CONFIG_SOUND_NM256 $CONFIG_SOUND_OSS + + dep_tristate ' OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then + bool ' Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD + fi + if [ "$CONFIG_SOUND_MAD16" = "y" ]; then hex 'MAD16 audio I/O base 530, 604, E80 or F40' CONFIG_MAD16_BASE 530 int 'MAD16 audio IRQ 7, 9, 10 or 11' CONFIG_MAD16_IRQ 11 int 'MAD16 audio DMA 0, 1 or 3' CONFIG_MAD16_DMA 3 int 'MAD16 second (duplex) DMA 0, 1 or 3' CONFIG_MAD16_DMA2 0 hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' CONFIG_MAD16_MPU_BASE 330 int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9 - fi + fi + + dep_tristate ' ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_PAS" = "y" ]; then + int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10 + int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3 + bool ' Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK + fi + + dep_tristate ' PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_PSS" = "y" ]; then + hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220 + hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530 + int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11 + int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3 + hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330 + int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9 + bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT + if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then + string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld + fi + fi + if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then + bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER + fi + + dep_tristate ' SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then + int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050 + int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32 + fi - dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m - if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then + dep_tristate ' 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SB" = "y" ]; then + hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220 + int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7 + int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1 + int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5 + hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330 + comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.' + comment 'Enter -1 to the following question if you have something else such as SB16/32.' + int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1 + fi + + dep_tristate ' Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m + if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330 int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9 - fi - - dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_CS4232" = "y" ]; then - hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530 - int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11 - int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0 - int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3 - hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330 - int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9 - fi - - dep_tristate 'Support for Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then - int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1 - hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530 - int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9 - int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0 - int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1 - hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370 - hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330 - int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9 - fi + fi - dep_tristate 'Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MAUI" = "y" ]; then + dep_tristate ' Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MAUI" = "y" ]; then hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_MAUI_BASE 330 int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9 - bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT + bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then - string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot + string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot fi - fi + fi - - dep_tristate 'Support for Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then - hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530 - int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11 - int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0 - int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3 - hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220 - fi + dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_SOUND_OSS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'Support for AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND - if [ "$CONFIG_SOUND_AD1816" = "y" ]; then - hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530 - int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7 - int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0 - int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3 - int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000 - fi - fi - - dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_OPL3SA1" = "y" ]; then + dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS + + dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_OPL3SA1" = "y" ]; then hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA1_BASE 530 int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' CONFIG_OPL3SA1_IRQ 11 int 'OPL3-SA1 audio DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA 0 int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA2 3 hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA1_MPU_BASE 330 int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_OPL3SA1_MPU_IRQ 9 - fi - - dep_tristate 'SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then - int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050 - int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32 - fi + fi - dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS + dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then + int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1 + hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530 + int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9 + int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0 + int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1 + hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370 + hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330 + int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9 + fi - dep_tristate 'Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS - dep_tristate '6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_UART6850" = "y" ]; then + dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_UART6850" = "y" ]; then hex 'I/O base for UART 6850 MIDI port (Unknown)' CONFIG_U6850_BASE 0 int 'UART6850 IRQ (Unknown)' CONFIG_U6850_IRQ -1 - fi - - if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate 'VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS - dep_tristate 'Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then - hex ' WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250 - int ' WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 28 - int ' WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3 - int ' WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7 - fi - fi + fi + if [ "$CONFIG_ARM" = "y" ]; then + dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS + dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then + hex ' WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250 + int ' WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 12 + int ' WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3 + int ' WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7 + fi + fi - # Additional low level drivers. + # Additional low level drivers. - mainmenu_option next_comment - comment 'Additional low level sound drivers' - bool 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND_OSS - if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then + mainmenu_option next_comment + comment 'Additional low level sound drivers' + bool 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND_OSS + if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then source drivers/sound/lowlevel/Config.in - fi - endmenu + fi + endmenu fi diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index af3c37d31..0def3ddd1 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -24,7 +24,8 @@ endif export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \ msnd.o opl3.o sb_card.o sequencer_syms.o \ - sound_core.o sound_syms.o uart401.o ad1816.o + sound_core.o sound_syms.o uart401.o ad1816.o \ + nm256_audio.o @@ -42,7 +43,6 @@ obj- := obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_DMASOUND) += dmasound.o obj-$(CONFIG_SOUND_OSS) += sound.o -obj-$(CONFIG_SOUND_ADLIB) += adlib_card.o opl3.o obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o # In theory, there's probably no reason to include the uart401 code @@ -53,6 +53,7 @@ obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o obj-$(CONFIG_SOUND_CS4232) += uart401.o obj-$(CONFIG_SOUND_GUS) += gus.o ad1848.o obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb.o uart401.o +obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx.o sb.o uart401.o obj-$(CONFIG_SOUND_MAUI) += maui.o mpu401.o obj-$(CONFIG_SOUND_MPU401) += mpu401.o obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o @@ -64,7 +65,7 @@ obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o uart401.o obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_SB) += sb.o uart401.o obj-$(CONFIG_SOUND_SOFTOSS) += softoss2.o -obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o +obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o ad1848.o obj-$(CONFIG_SOUND_AD1816) += ad1816.o obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb.o uart401.o @@ -72,19 +73,22 @@ obj-$(CONFIG_SOUND_UART6850) += uart6850.o obj-$(CONFIG_SOUND_VMIDI) += v_midi.o obj-$(CONFIG_SOUND_YM3812) += adlib_card.o opl3.o obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o +obj-$(CONFIG_SOUND_VWSND) += vwsnd.o obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o +obj-$(CONFIG_SOUND_NM256) += nm256.o -#jnx +obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o obj-$(CONFIG_SOUND_CMPCI) += cmpci.o obj-$(CONFIG_SOUND_ES1370) += es1370.o obj-$(CONFIG_SOUND_ES1371) += es1371.o -obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o +obj-$(CONFIG_SOUND_ESSSOLO1) += esssolo1.o +obj-$(CONFIG_SOUND_MAESTRO) += maestro.o # Declare multi-part drivers. list-multi := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \ - soundcore.o wavefront.o + soundcore.o wavefront.o nm256.o sound-objs := \ dev_table.o soundcard.o sound_syms.o \ @@ -101,6 +105,7 @@ sb-objs := sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o \ softoss2-objs := softoss.o softoss_rs.o vidc_mod-objs := vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o wavefront-objs := wavfront.o wf_midi.o yss225.o +nm256-objs := nm256_audio.o ac97.o # Extract lists of the multi-part drivers. @@ -141,19 +146,19 @@ obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) # Translate to Rules.make lists. -L_TARGET := sound.a +O_TARGET := sounddrivers.o # This is a nice idea but needs depmod altering #MOD_LIST_NAME := SOUND_MODULES -L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y))) -LX_OBJS := $(sort $(filter $(export-objs), $(obj-y))) +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) ifeq ($(CONFIG_LOWLEVEL_SOUND),y) - L_OBJS += lowlevel/lowlevel.o + O_OBJS += lowlevel/lowlevel.o endif include $(TOPDIR)/Rules.make @@ -186,6 +191,9 @@ vidc_mod.o: $(vidc_mod-objs) wavefront.o: $(wavefront-objs) $(LD) -r -o $@ $(wavefront-objs) +nm256.o: $(nm256-objs) + $(LD) -r -o $@ $(nm256-objs) + # Firmware files that need translation # # The translated files are protected by a file that keeps track diff --git a/drivers/sound/ac97.c b/drivers/sound/ac97.c new file mode 100644 index 000000000..bc313134f --- /dev/null +++ b/drivers/sound/ac97.c @@ -0,0 +1,408 @@ +#include "ac97.h" + +/* Flag for mono controls. */ +#define MO 0 +/* And for stereo. */ +#define ST 1 + +static struct ac97_chn_desc { + int ac97_regnum; + int oss_channel; + int maxval; + int is_stereo; + int oss_mask; + int recordNum; + u16 regmask; +} mixerRegs[] = { + { AC97_MASTER_VOL_STEREO, SOUND_MIXER_VOLUME, 0x3f, ST, SOUND_MASK_VOLUME, 5, 0x0000 }, + { AC97_MASTER_VOL_MONO, SOUND_MIXER_PHONEOUT, 0x3f, MO, SOUND_MASK_PHONEOUT, 6, 0x0000 }, + { AC97_MASTER_TONE, SOUND_MIXER_TREBLE, 0x0f, MO, SOUND_MASK_TREBLE, -1, 0x00ff }, + { AC97_MASTER_TONE, SOUND_MIXER_BASS, 0x0f, MO, SOUND_MASK_BASS, -1, 0xff00 }, + { AC97_PCBEEP_VOL, SOUND_MIXER_SPEAKER, 0x0f, MO, SOUND_MASK_SPEAKER, -1, 0x001e }, + { AC97_PHONE_VOL, SOUND_MIXER_PHONEIN, 0x1f, MO, SOUND_MASK_PHONEIN, 7, 0x0000 }, + { AC97_MIC_VOL, SOUND_MIXER_MIC, 0x1f, MO, SOUND_MASK_MIC, 0, 0x0000 }, + { AC97_LINEIN_VOL, SOUND_MIXER_LINE, 0x1f, ST, SOUND_MASK_LINE, 4, 0x0000 }, + { AC97_CD_VOL, SOUND_MIXER_CD, 0x1f, ST, SOUND_MASK_CD, 1, 0x0000 }, + { AC97_VIDEO_VOL, SOUND_MIXER_VIDEO, 0x1f, ST, SOUND_MASK_VIDEO, 2, 0x0000 }, + { AC97_AUX_VOL, SOUND_MIXER_LINE1, 0x1f, ST, SOUND_MASK_LINE1, 3, 0x0000 }, + { AC97_PCMOUT_VOL, SOUND_MIXER_PCM, 0x1f, ST, SOUND_MASK_PCM, -1, 0x0000 }, + { AC97_RECORD_GAIN, SOUND_MIXER_IGAIN, 0x0f, ST, SOUND_MASK_IGAIN, -1, 0x0000 }, + { -1, -1, 0xff, 0, 0, -1, 0x0000 }, +}; + +static struct ac97_chn_desc * +ac97_find_chndesc (struct ac97_hwint *dev, int oss_channel) +{ + int x; + + for (x = 0; mixerRegs[x].oss_channel != -1; x++) { + if (mixerRegs[x].oss_channel == oss_channel) + return mixerRegs + x; + } + + return NULL; +} + +static inline int +ac97_is_valid_channel (struct ac97_hwint *dev, struct ac97_chn_desc *chn) +{ + return (dev->last_written_mixer_values[chn->ac97_regnum / 2] + != AC97_REG_UNSUPPORTED); +} + +int +ac97_init (struct ac97_hwint *dev) +{ + int x; + int reg0; + + /* Clear out the arrays of cached values. */ + for (x = 0; x < AC97_REG_CNT; x++) + dev->last_written_mixer_values[x] = AC97_REGVAL_UNKNOWN; + + for (x = 0; x < SOUND_MIXER_NRDEVICES; x++) + dev->last_written_OSS_values[x] = AC97_REGVAL_UNKNOWN; + + /* Clear the device masks. */ + dev->mixer_devmask = 0; + dev->mixer_stereomask = 0; + dev->mixer_recmask = 0; + + /* ??? Do a "standard reset" via register 0? */ + + /* Hardware-dependent reset. */ + if (dev->reset_device (dev)) + return -1; + + /* Check the mixer device capabilities. */ + reg0 = dev->read_reg (dev, AC97_RESET); + + if (reg0 < 0) + return -1; + + /* Check for support for treble/bass controls. */ + if (! (reg0 & 4)) { + dev->last_written_mixer_values[AC97_MASTER_TONE / 2] + = AC97_REG_UNSUPPORTED; + } + + /* ??? There may be other tests here? */ + + /* Fill in the device masks. */ + for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) { + if (ac97_is_valid_channel (dev, mixerRegs + x)) { + dev->mixer_devmask |= mixerRegs[x].oss_mask; + + if (mixerRegs[x].is_stereo) + dev->mixer_stereomask |= mixerRegs[x].oss_mask; + + if (mixerRegs[x].recordNum != -1) + dev->mixer_recmask |= mixerRegs[x].oss_mask; + } + } + + return 0; +} + +/* Return the contents of register REG; use the cache if the value in it + is valid. Returns a negative error code on failure. */ +int +ac97_get_register (struct ac97_hwint *dev, u8 reg) +{ + if (reg > 127 || (reg & 1)) + return -EINVAL; + + /* See if it's in the cache, or if it's just plain invalid. */ + switch (dev->last_written_mixer_values[reg / 2]) { + case AC97_REG_UNSUPPORTED: + return -EINVAL; + break; + case AC97_REGVAL_UNKNOWN: + dev->last_written_mixer_values[reg / 2] = dev->read_reg (dev, reg); + break; + default: + break; + } + return dev->last_written_mixer_values[reg / 2]; +} + +/* Write VALUE to AC97 register REG, and cache its value in the last-written + cache. Returns a negative error code on failure, or 0 on success. */ +int +ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value) +{ + if (reg > 127 || (reg & 1)) + return -EINVAL; + + if (dev->last_written_mixer_values[reg / 2] == AC97_REG_UNSUPPORTED) + return -EINVAL; + else { + int res = dev->write_reg (dev, reg, value); + if (res >= 0) { + dev->last_written_mixer_values[reg / 2] = value; + return 0; + } + else + return res; + } +} + +/* Scale VALUE (a value fro 0 to MAXVAL) to a value from 0-100. If + IS_STEREO is set, VALUE is a stereo value; the left channel value + is in the lower 8 bits, and the right channel value is in the upper + 8 bits. + + A negative error code is returned on failure, or the unsigned + scaled value on success. */ + +static int +ac97_scale_to_oss_val (int value, int maxval, int is_stereo) +{ + /* Muted? */ + if (value & AC97_MUTE) + return 0; + + if (is_stereo) + return (ac97_scale_to_oss_val (value & 255, maxval, 0) << 8) + | (ac97_scale_to_oss_val ((value >> 8) & 255, maxval, 0) << 0); + else { + int i; + + /* Inverted. */ + value = maxval - value; + + i = (value * 100 + (maxval / 2)) / maxval; + if (i > 100) + i = 100; + return i; + } +} + +static int +ac97_scale_from_oss_val (int value, int maxval, int is_stereo) +{ + if (is_stereo) + return (ac97_scale_from_oss_val (value & 255, maxval, 0) << 8) + | (ac97_scale_from_oss_val ((value >> 8) & 255, maxval, 0) << 0); + else { + int i = maxval - ((value & 255) * maxval + 50) / 100; + if (i < 0) + i = 0; + return i; + } +} + +int +ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, u16 oss_value) +{ + int scaled_value; + struct ac97_chn_desc *channel = ac97_find_chndesc (dev, oss_channel); + int result; + + if (channel == NULL) + return -ENODEV; + if (! ac97_is_valid_channel (dev, channel)) + return -ENODEV; + scaled_value = ac97_scale_from_oss_val (oss_value, channel->maxval, + channel->is_stereo); + if (scaled_value < 0) + return scaled_value; + + if (channel->regmask != 0) { + int mv; + + int oldval = ac97_get_register (dev, channel->ac97_regnum); + if (oldval < 0) + return oldval; + + for (mv = channel->regmask; ! (mv & 1); mv >>= 1) + scaled_value <<= 1; + + scaled_value &= channel->regmask; + scaled_value |= (oldval & ~channel->regmask); + } + result = ac97_put_register (dev, channel->ac97_regnum, scaled_value); + if (result == 0) + dev->last_written_OSS_values[oss_channel] = oss_value; + return result; +} + +int +ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel) +{ + struct ac97_chn_desc *channel = ac97_find_chndesc (dev, oss_channel); + int regval; + + if (channel == NULL) + return -ENODEV; + + if (! ac97_is_valid_channel (dev, channel)) + return -ENODEV; + + regval = ac97_get_register (dev, channel->ac97_regnum); + + if (regval < 0) + return regval; + + if (channel->regmask != 0) { + int mv; + + regval &= channel->regmask; + + for (mv = channel->regmask; ! (mv & 1); mv >>= 1) + regval >>= 1; + } + return ac97_scale_to_oss_val (regval, channel->maxval, + channel->is_stereo); +} + +int +ac97_get_recmask (struct ac97_hwint *dev) +{ + int recReg = ac97_get_register (dev, AC97_RECORD_SELECT); + + if (recReg < 0) + return recReg; + else { + int x; + for (x = 0; mixerRegs[x].ac97_regnum >= 0; x++) { + if (mixerRegs[x].recordNum == (recReg & 7)) + return mixerRegs[x].oss_mask; + } + return -ENODEV; + } +} + +int +ac97_set_recmask (struct ac97_hwint *dev, int oss_recmask) +{ + int x; + + if (oss_recmask == 0) + oss_recmask = SOUND_MIXER_MIC; + + for (x = 0; mixerRegs[x].ac97_regnum >= 0; x++) { + if ((mixerRegs[x].recordNum >= 0) + && (oss_recmask & mixerRegs[x].oss_mask)) + break; + } + if (mixerRegs[x].ac97_regnum < 0) + return -ENODEV; + else { + int regval = (mixerRegs[x].recordNum << 8) | mixerRegs[x].recordNum; + int res = ac97_put_register (dev, AC97_RECORD_SELECT, regval); + if (res == 0) + return ac97_get_recmask (dev); + else + return res; + } +} + +/* Set the mixer DEV to the list of values in VALUE_LIST. Return 0 on + success, or a negative error code. */ +int +ac97_set_values (struct ac97_hwint *dev, + struct ac97_mixer_value_list *value_list) +{ + int x; + + for (x = 0; value_list[x].oss_channel != -1; x++) { + int chnum = value_list[x].oss_channel; + struct ac97_chn_desc *chent = ac97_find_chndesc (dev, chnum); + if (chent != NULL) { + u16 val; + int res; + + if (chent->is_stereo) + val = (value_list[x].value.stereo.right << 8) + | value_list[x].value.stereo.left; + else { + /* We do this so the returned value looks OK in the + mixer app. It's not necessary otherwise. */ + val = (value_list[x].value.mono << 8) + | value_list[x].value.mono; + } + res = ac97_set_mixer (dev, chnum, val); + if (res < 0) + return res; + } + else + return -ENODEV; + } + return 0; +} + +int +ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, caddr_t arg) +{ + int ret; + + switch (cmd) { + case SOUND_MIXER_READ_RECSRC: + ret = ac97_get_recmask (dev); + break; + + case SOUND_MIXER_WRITE_RECSRC: + { + if (get_user (ret, (int *) arg)) + ret = -EFAULT; + else + ret = ac97_set_recmask (dev, ret); + } + break; + + case SOUND_MIXER_READ_CAPS: + ret = SOUND_CAP_EXCL_INPUT; + break; + + case SOUND_MIXER_READ_DEVMASK: + ret = dev->mixer_devmask; + break; + + case SOUND_MIXER_READ_RECMASK: + ret = dev->mixer_recmask; + break; + + case SOUND_MIXER_READ_STEREODEVS: + ret = dev->mixer_stereomask; + break; + + default: + /* Read or write request. */ + ret = -EINVAL; + if (_IOC_TYPE (cmd) == 'M') { + int dir = _IOC_DIR (cmd); + int channel = _IOC_NR (cmd); + + if (channel >= 0 && channel < SOUND_MIXER_NRDEVICES) { + ret = 0; + if (dir & _IOC_WRITE) { + int val; + if (get_user (val, (int *) arg) == 0) + ret = ac97_set_mixer (dev, channel, val); + else + ret = -EFAULT; + } + if (ret >= 0) { + if (dev->last_written_OSS_values[channel] == AC97_REGVAL_UNKNOWN) + dev->last_written_OSS_values[channel] + = ac97_get_mixer_scaled (dev, channel); + ret = dev->last_written_OSS_values[channel]; + } + } + } + break; + } + + if (ret < 0) + return ret; + else + return put_user(ret, (int *) arg); +} + + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/sound/ac97.h b/drivers/sound/ac97.h new file mode 100644 index 000000000..3269337d5 --- /dev/null +++ b/drivers/sound/ac97.h @@ -0,0 +1,203 @@ +/* + * ac97.h + * + * definitions for the AC97, Intel's Audio Codec 97 Spec + * also includes support for a generic AC97 interface + */ + +#ifndef _AC97_H_ +#define _AC97_H_ +#include "sound_config.h" +#include "sound_calls.h" + +#define AC97_RESET 0x0000 // */ +#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out +#define AC97_HEADPHONE_VOL 0x0004 // +#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output +#define AC97_MASTER_TONE 0x0008 // +#define AC97_PCBEEP_VOL 0x000a // none +#define AC97_PHONE_VOL 0x000c // TAD Input (mono) +#define AC97_MIC_VOL 0x000e // MIC Input (mono) +#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo) +#define AC97_CD_VOL 0x0012 // CD Input (stereo) +#define AC97_VIDEO_VOL 0x0014 // none +#define AC97_AUX_VOL 0x0016 // Aux Input (stereo) +#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo) +#define AC97_RECORD_SELECT 0x001a // +#define AC97_RECORD_GAIN 0x001c +#define AC97_RECORD_GAIN_MIC 0x001e +#define AC97_GENERAL_PURPOSE 0x0020 +#define AC97_3D_CONTROL 0x0022 +#define AC97_MODEM_RATE 0x0024 +#define AC97_POWER_CONTROL 0x0026 + +/* registers 0x0028 - 0x0058 are reserved */ + +/* registers 0x005a - 0x007a are vendor reserved */ + +#define AC97_VENDOR_ID1 0x007c +#define AC97_VENDOR_ID2 0x007e + +/* volume control bit defines */ + +#define AC97_MUTE 0x8000 +#define AC97_MICBOOST 0x0040 +#define AC97_LEFTVOL 0x3f00 +#define AC97_RIGHTVOL 0x003f + +/* record mux defines */ + +#define AC97_RECMUX_MIC 0x0000 +#define AC97_RECMUX_CD 0x0101 +#define AC97_RECMUX_VIDEO 0x0202 /* not used */ +#define AC97_RECMUX_AUX 0x0303 +#define AC97_RECMUX_LINE 0x0404 +#define AC97_RECMUX_STEREO_MIX 0x0505 +#define AC97_RECMUX_MONO_MIX 0x0606 +#define AC97_RECMUX_PHONE 0x0707 + + +/* general purpose register bit defines */ + +#define AC97_GP_LPBK 0x0080 /* Loopback mode */ +#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */ +#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */ +#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */ +#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */ +#define AC97_GP_LD 0x1000 /* Loudness 1=on */ +#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */ +#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */ +#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */ + + +/* powerdown control and status bit defines */ + +/* status */ +#define AC97_PWR_MDM 0x0010 /* Modem section ready */ +#define AC97_PWR_REF 0x0008 /* Vref nominal */ +#define AC97_PWR_ANL 0x0004 /* Analog section ready */ +#define AC97_PWR_DAC 0x0002 /* DAC section ready */ +#define AC97_PWR_ADC 0x0001 /* ADC section ready */ + +/* control */ +#define AC97_PWR_PR0 0x0100 /* ADC and Mux powerdown */ +#define AC97_PWR_PR1 0x0200 /* DAC powerdown */ +#define AC97_PWR_PR2 0x0400 /* Output mixer powerdown (Vref on) */ +#define AC97_PWR_PR3 0x0800 /* Output mixer powerdown (Vref off) */ +#define AC97_PWR_PR4 0x1000 /* AC-link powerdown */ +#define AC97_PWR_PR5 0x2000 /* Internal Clk disable */ +#define AC97_PWR_PR6 0x4000 /* HP amp powerdown */ +#define AC97_PWR_PR7 0x8000 /* Modem off - if supported */ + +/* useful power states */ +#define AC97_PWR_D0 0x0000 /* everything on */ +#define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4 +#define AC97_PWR_D2 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 +#define AC97_PWR_D3 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 +#define AC97_PWR_ANLOFF AC97_PWR_PR2|AC97_PWR_PR3 /* analog section off */ + +/* Total number of defined registers. */ +#define AC97_REG_CNT 64 + +/* Generic AC97 mixer interface. */ + +/* Structure describing access to the hardware. */ +struct ac97_hwint +{ + /* Perform any hardware-specific reset and initialization. Returns + 0 on success, or a negative error code. */ + int (*reset_device) (struct ac97_hwint *dev); + + /* Returns the contents of the specified register REG. The caller + should check to see if the desired contents are available in + the cache first, if applicable. Returns a positive unsigned value + representing the contents of the register, or a negative error + code. */ + int (*read_reg) (struct ac97_hwint *dev, u8 reg); + + /* Writes VALUE to register REG. Returns 0 on success, or a + negative error code. */ + int (*write_reg) (struct ac97_hwint *dev, u8 reg, u16 value); + + /* Hardware-specific information. */ + void *driver_private; + + /* Three OSS masks. */ + int mixer_devmask; + int mixer_stereomask; + int mixer_recmask; + + /* The mixer cache. The indices correspond to the AC97 hardware register + number / 2, since the register numbers are always an even number. + + Unknown values are set to -1; unsupported registers contain a + -2. */ + int last_written_mixer_values[AC97_REG_CNT]; + + /* A cache of values written via OSS; we need these so we can return + the values originally written by the user. + + Why the original user values? Because the real-world hardware + has less precision, and some existing applications assume that + they will get back the exact value that they wrote (aumix). + + A -1 value indicates that no value has been written to this mixer + channel via OSS. */ + int last_written_OSS_values[SOUND_MIXER_NRDEVICES]; +}; + +/* Values stored in the register cache. */ +#define AC97_REGVAL_UNKNOWN -1 +#define AC97_REG_UNSUPPORTED -2 + +struct ac97_mixer_value_list +{ + /* Mixer channel to set. List is terminated by a value of -1. */ + int oss_channel; + /* The scaled value to set it to; values generally range from 0-100. */ + union { + struct { + u8 left, right; + } stereo; + u8 mono; + } value; +}; + +/* Initialize the ac97 mixer by resetting it. */ +extern int ac97_init (struct ac97_hwint *dev); + +/* Sets the mixer DEV to the values in VALUE_LIST. Returns 0 on success, + or a negative error code. */ +extern int ac97_set_values (struct ac97_hwint *dev, + struct ac97_mixer_value_list *value_list); + +/* Sets one mixer channel OSS_CHANNEL to the scaled value OSS_VALUE. + Returns the resulting (rescaled) value, or a negative value + representing an error code. + + Stereo channels have two values in OSS_VALUE (the left value is in the + lower 8 bits, the right value is in the upper 8 bits). */ +extern int ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, + u16 oss_value); + +/* Return the contents of the specified AC97 register REG; it uses the + last-written value if it is available. */ +extern int ac97_get_register (struct ac97_hwint *dev, u8 reg); + +/* Writes the specified VALUE to the AC97 register REG in the mixer. + Takes care of setting the last-written cache as well. */ +extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value); + +/* Returns the last OSS value written to the OSS_CHANNEL mixer channel. */ +extern int ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel); + +/* Default ioctl. */ +extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, + caddr_t arg); +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c index baa090771..8de63a068 100644 --- a/drivers/sound/ad1848.c +++ b/drivers/sound/ad1848.c @@ -106,7 +106,7 @@ int soundpro = 1; int soundpro = 0; #endif -static volatile char irq2dev[17] = { +static volatile signed char irq2dev[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; @@ -2434,11 +2434,12 @@ int probe_ms_sound(struct address_info *hw_config) void attach_ms_sound(struct address_info *hw_config) { - static char interrupt_bits[12] = + static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 }; - char bits, dma2_bit = 0; + signed char bits; + char dma2_bit = 0; static char dma_bits[4] = { diff --git a/drivers/sound/adlib_card.c b/drivers/sound/adlib_card.c index b21d7316e..9bd6cc1c5 100644 --- a/drivers/sound/adlib_card.c +++ b/drivers/sound/adlib_card.c @@ -16,8 +16,6 @@ #include "sound_config.h" #include "soundmodule.h" -#ifdef CONFIG_YM3812 - void attach_adlib_card(struct address_info *hw_config) { hw_config->slots[0] = opl3_init(hw_config->io_base, hw_config->osp); @@ -70,4 +68,3 @@ void cleanup_module(void) } #endif -#endif diff --git a/drivers/sound/awacs_defs.h b/drivers/sound/awacs_defs.h index e30bb608c..2757347ad 100644 --- a/drivers/sound/awacs_defs.h +++ b/drivers/sound/awacs_defs.h @@ -70,8 +70,8 @@ struct awacs_regs { #define MASK_GAINMIC (0x0 << 8) /* Change Gain for Mic??? */ #define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */ -#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */ -#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */ +#define MASK_MUX_AUDIN (0x1 << 10) /* Select Audio In in MUX */ +#define MASK_MUX_MIC (0x1 << 11) /* Select Mic in MUX */ #define MASK_MUX_LINE MASK_MUX_AUDIN #define GAINRIGHT(x) ((x) & MASK_GAINRIGHT) diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c index d85429745..37103e857 100644 --- a/drivers/sound/cmpci.c +++ b/drivers/sound/cmpci.c @@ -57,7 +57,8 @@ * reported by Johan Maes <joma@telindus.be> * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK * read/write cannot be executed - * + * 20 09 99 0.13 merged the generic changes in sonicvibes since this + * diverged. */ /*****************************************************************************/ @@ -77,7 +78,7 @@ #include <asm/dma.h> #include <linux/init.h> #include <linux/poll.h> -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/hardirq.h> @@ -585,8 +586,9 @@ static int prog_dmabuf(struct cm_state *s, unsigned rec) db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; if (!db->rawbuf) { db->ready = db->mapped = 0; - for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER && !db->rawbuf; order--) - db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order); + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) + if ((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order))) + break; if (!db->rawbuf) return -ENOMEM; db->buforder = order; @@ -1152,9 +1154,9 @@ static int drain_dac(struct cm_state *s, int nonblock) current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->ratedac; + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "cm: dma timed out??\n"); } remove_wait_queue(&s->dma_dac.wait, &wait); @@ -1630,9 +1632,11 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un case SOUND_PCM_READ_BITS: return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg); + case SOUND_PCM_READ_FILTER: + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + case SOUND_PCM_WRITE_FILTER: case SNDCTL_DSP_SETSYNCRO: - case SOUND_PCM_READ_FILTER: return -EINVAL; } @@ -1732,6 +1736,7 @@ static /*const*/ struct file_operations cm_audio_fops = { static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct cm_state *s = (struct cm_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1742,7 +1747,10 @@ static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_ return -ESPIPE; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.iwait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.ird; @@ -1753,15 +1761,27 @@ static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_ if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.iwait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) + { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) + { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIINBUF; spin_lock_irqsave(&s->lock, flags); s->midi.ird = ptr; @@ -1770,13 +1790,17 @@ static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_ count -= cnt; buffer += cnt; ret += cnt; + break; } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); return ret; } static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct cm_state *s = (struct cm_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1787,7 +1811,10 @@ static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count return -ESPIPE; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.owait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.owr; @@ -1800,15 +1827,25 @@ static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.owait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIOUTBUF; spin_lock_irqsave(&s->lock, flags); s->midi.owr = ptr; @@ -1821,6 +1858,8 @@ static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count cm_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); return ret; } @@ -1915,7 +1954,7 @@ static int cm_midi_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1927,7 +1966,7 @@ static int cm_midi_release(struct inode *inode, struct file *file) break; if (file->f_flags & O_NONBLOCK) { remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } tmo = (count * HZ) / 3100; @@ -1935,7 +1974,7 @@ static int cm_midi_release(struct inode *inode, struct file *file) printk(KERN_DEBUG "cm: midi timed out??\n"); } remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); } down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); @@ -2176,9 +2215,9 @@ static struct initvol { }; #ifdef MODULE -__initfunc(int init_module(void)) +int __init init_module(void) #else -__initfunc(int init_cmpci(void)) +int __init init_cmpci(void) #endif { struct cm_state *s; @@ -2232,7 +2271,7 @@ __initfunc(int init_cmpci(void)) init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); s->magic = CM_MAGIC; - s->iobase = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + s->iobase = pcidev->resource[0].start; #ifdef CONFIG_SOUND_CMPCI_FM s->iosynth = 0x388; #endif @@ -2311,7 +2350,9 @@ __initfunc(int init_cmpci(void)) index++; continue; + err_dev4: unregister_sound_midi(s->dev_midi); + err_dev3: unregister_sound_mixer(s->dev_mixer); err_dev2: unregister_sound_dsp(s->dev_audio); @@ -2326,6 +2367,7 @@ __initfunc(int init_cmpci(void)) #ifdef CONFIG_SOUND_CMPCI_MIDI release_region(s->iomidi, CM_EXTENT_MIDI); #endif + err_region4: release_region(s->iobase, CM_EXTENT_CODEC); err_region5: kfree_s(s, sizeof(struct cm_state)); @@ -2342,11 +2384,6 @@ __initfunc(int init_cmpci(void)) #ifdef MODULE -#if 0 -MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); -#endif - MODULE_AUTHOR("ChenLi Tien, cltien@home.com"); MODULE_DESCRIPTION("CMPCI Audio Driver"); diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h index af72621c0..0ce2c49b0 100644 --- a/drivers/sound/dev_table.h +++ b/drivers/sound/dev_table.h @@ -33,7 +33,7 @@ #define SNDCARD_WAVEFRONT 41 #define SNDCARD_OPL3SA2 42 #define SNDCARD_OPL3SA2_MPU 43 -#define SNDCARD_WAVEARTIST 44 +#define SNDCARD_WAVEARTIST 44 /* Rebel Waveartist */ #define SNDCARD_OPL3SA2_MSS 45 /* Originally missed */ #define SNDCARD_AD1816 88 diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c index 85bde7d48..e70c10841 100644 --- a/drivers/sound/dmabuf.c +++ b/drivers/sound/dmabuf.c @@ -187,7 +187,7 @@ static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffpar printk(KERN_WARNING "Sound: DMA buffers not available\n"); return -ENOSPC; /* Memory allocation failed during boot */ } - if (sound_open_dma(dmap->dma, adev->name)) { + if (dmap->dma >= 0 && sound_open_dma(dmap->dma, adev->name)) { printk(KERN_WARNING "Unable to grab(2) DMA%d for the audio driver\n", dmap->dma); return -EBUSY; } @@ -209,15 +209,16 @@ static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap { unsigned long flags; - sound_close_dma(dmap->dma); + if (dmap->dma >= 0) { + sound_close_dma(dmap->dma); + flags=claim_dma_lock(); + disable_dma(dmap->dma); + release_dma_lock(flags); + } if (dmap->flags & DMA_BUSY) dmap->dma_mode = DMODE_NONE; dmap->flags &= ~DMA_BUSY; - flags=claim_dma_lock(); - disable_dma(dmap->dma); - release_dma_lock(flags); - if (sound_dmap_flag == DMAP_FREE_ON_CLOSE) sound_free_dmap(dmap); } diff --git a/drivers/sound/dmasound.c b/drivers/sound/dmasound.c index fe1cd95aa..341fb6f97 100644 --- a/drivers/sound/dmasound.c +++ b/drivers/sound/dmasound.c @@ -108,12 +108,13 @@ History: #include <asm/amigaints.h> #endif /* CONFIG_AMIGA */ #ifdef CONFIG_PPC +#include <linux/adb.h> +#include <linux/cuda.h> +#include <linux/pmu.h> #include <asm/prom.h> +#include <asm/machdep.h> #include <asm/io.h> #include <asm/dbdma.h> -#include <asm/adb.h> -#include <asm/cuda.h> -#include <asm/pmu.h> #include "awacs_defs.h" #include <linux/nvram.h> #include <linux/vt_kern.h> @@ -131,7 +132,9 @@ static int state_unit = -1; static int irq_installed = 0; #endif /* MODULE */ static char **sound_buffers = NULL; - +#ifdef CONFIG_PPC +static char **sound_read_buffers = NULL; +#endif #ifdef CONFIG_ATARI extern void atari_microwire_cmd(int cmd); @@ -184,6 +187,9 @@ static int awacs_revision; static void *awacs_tx_cmd_space; static volatile struct dbdma_cmd *awacs_tx_cmds; +static void *awacs_rx_cmd_space; +static volatile struct dbdma_cmd *awacs_rx_cmds; + /* * Cached values of AWACS registers (we can't read them). * Except on the burgundy. XXX @@ -239,9 +245,13 @@ static short beep_wform[256] = { static int beep_volume = BEEP_VOLUME; static int beep_playing = 0; +static int awacs_beep_state = 0; static short *beep_buf; static volatile struct dbdma_cmd *beep_dbdma_cmd; static void (*orig_mksound)(unsigned int, unsigned int); +static int is_pbook_3400; +static int is_pbook_G3; +static unsigned char *macio_base; /* Burgundy functions */ static void awacs_burgundy_wcw(unsigned addr,unsigned newval); @@ -255,9 +265,9 @@ static int awacs_burgundy_read_mvolume(unsigned address); /* * Stuff for restoring after a sleep. */ -static int awacs_sleep_notify(struct notifier_block *, unsigned long, void *); -struct notifier_block awacs_sleep_notifier = { - awacs_sleep_notify +static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when); +struct pmu_sleep_notifier awacs_sleep_notifier = { + awacs_sleep_notify, SLEEP_LEVEL_SOUND, }; #endif /* CONFIG_PMAC_PBOOK */ @@ -276,10 +286,17 @@ struct notifier_block awacs_sleep_notifier = { #define MIN_BUFSIZE 4 #define MAX_BUFSIZE 128 /* Limit for Amiga */ -static int catchRadius = 0, numBufs = 4, bufSize = 32; +static int catchRadius = 0; +static int numBufs = 4, bufSize = 32; +#ifdef CONFIG_PPC +static int numReadBufs = 4, readbufSize = 32; +#endif + MODULE_PARM(catchRadius, "i"); MODULE_PARM(numBufs, "i"); MODULE_PARM(bufSize, "i"); +MODULE_PARM(numreadBufs, "i"); +MODULE_PARM(readbufSize, "i"); #define arraysize(x) (sizeof(x)/sizeof(*(x))) #define min(x, y) ((x) < (y) ? (x) : (y)) @@ -630,6 +647,12 @@ static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount, static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); +static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); #endif /* CONFIG_PPC */ /*** Machine definitions *****************************************************/ @@ -681,6 +704,9 @@ struct sound_settings { SETTINGS soft; /* software settings */ SETTINGS dsp; /* /dev/dsp default settings */ TRANS *trans; /* supported translations */ +#if defined(CONFIG_PPC) + TRANS *read_trans; /* supported translations */ +#endif int volume_left; /* volume (range is machine dependent) */ int volume_right; int bass; /* tone (range is machine dependent) */ @@ -746,9 +772,11 @@ static void PMacIrqCleanup(void); static void PMacSilence(void); static void PMacInit(void); static void PMacPlay(void); +static void PMacRecord(void); static int PMacSetFormat(int format); static int PMacSetVolume(int volume); static void pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs); +static void pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs); static void pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs); static void awacs_write(int val); static int awacs_get_volume(int reg, int lshift); @@ -776,6 +804,12 @@ static ssize_t sound_copy_translate(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); +#ifdef CONFIG_PPC +static ssize_t sound_copy_translate_read(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +#endif /* @@ -809,8 +843,8 @@ struct sound_queue { * Amiga: Bit 0 is set: a frame is loaded * Bit 1 is set: a frame is playing */ - int playing; - wait_queue_head_t write_queue, open_queue, sync_queue; + int active; + wait_queue_head_t action_queue, open_queue, sync_queue; int open_mode; int busy, syncing; #ifdef CONFIG_ATARI @@ -822,6 +856,9 @@ struct sound_queue { }; static struct sound_queue sq; +#ifdef CONFIG_PPC +static struct sound_queue read_sq; +#endif #define sq_block_address(i) (sq.buffers[i]) #define SIGNAL_RECEIVED (signal_pending(current)) @@ -852,7 +889,7 @@ static inline int ioctl_return(int *addr, int value) if (value < 0) return(value); - return put_user(value, addr)? -EFAULT: 0; + return put_user(value, addr); } @@ -2172,6 +2209,135 @@ static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount, return stereo? utotal * 4: utotal * 2; } +static ssize_t pmac_ct_s8_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + data = val >> 8; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + data = val >> 8; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_u8_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + if (!stereo) { + short *up = (short *) userPtr; + while (count > 0) { + short data; + data = *fp; + if (put_user(data, up++)) + return -EFAULT; + fp+=2; + count--; + } + } else { + if (copy_to_user((u_char *)userPtr, fp, count * 4)) + return -EFAULT; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short *up = (short *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + while (count > 0) { + int data; + + data = *fp++; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + if (stereo) { + data = *fp; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + } + fp++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + + #endif /* CONFIG_PPC */ @@ -2212,6 +2378,11 @@ static TRANS transAwacsExpand = { pmac_ctx_law, pmac_ctx_law, pmac_ctx_s8, pmac_ctx_u8, pmac_ctx_s16, pmac_ctx_u16, pmac_ctx_s16, pmac_ctx_u16 }; + +static TRANS transAwacsNormalRead = { + NULL, NULL, pmac_ct_s8_read, pmac_ct_u8_read, + pmac_ct_s16_read, pmac_ct_u16_read, pmac_ct_s16_read, pmac_ct_u16_read +}; #endif /* CONFIG_PPC */ /*** Low level stuff *********************************************************/ @@ -2569,23 +2740,23 @@ static void ata_sq_play_next_frame(int index) start = sq_block_address(sq.front); end = start+((sq.count == index) ? sq.rear_size : sq.block_size); /* end might not be a legal virtual address. */ - DMASNDSetEnd(VTOP(end - 1) + 1); - DMASNDSetBase(VTOP(start)); + DMASNDSetEnd(virt_to_phys(end - 1) + 1); + DMASNDSetBase(virt_to_phys(start)); /* Since only an even number of samples per frame can be played, we might lose one byte here. (TO DO) */ sq.front = (sq.front+1) % sq.max_count; - sq.playing++; + sq.active++; tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT; } static void AtaPlay(void) { - /* ++TeSche: Note that sq.playing is no longer just a flag but holds + /* ++TeSche: Note that sq.active is no longer just a flag but holds * the number of frames the DMA is currently programmed for instead, * may be 0, 1 (currently being played) or 2 (pre-programmed). * - * Changes done to sq.count and sq.playing are a bit more subtle again + * Changes done to sq.count and sq.active are a bit more subtle again * so now I must admit I also prefer disabling the irq here rather * than considering all possible situations. But the point is that * disabling the irq doesn't have any bad influence on this version of @@ -2596,13 +2767,13 @@ static void AtaPlay(void) */ atari_disable_irq(IRQ_MFP_TIMA); - if (sq.playing == 2 || /* DMA is 'full' */ + if (sq.active == 2 || /* DMA is 'full' */ sq.count <= 0) { /* nothing to do */ atari_enable_irq(IRQ_MFP_TIMA); return; } - if (sq.playing == 0) { + if (sq.active == 0) { /* looks like there's nothing 'in' the DMA yet, so try * to put two frames into it (at least one is available). */ @@ -2650,7 +2821,7 @@ static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) #if 0 /* ++TeSche: if you should want to test this... */ static int cnt = 0; - if (sq.playing == 2) + if (sq.active == 2) if (++cnt == 10) { /* simulate losing an interrupt */ cnt = 0; @@ -2667,7 +2838,7 @@ static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) return; } - if (!sq.playing) { + if (!sq.active) { /* playing was interrupted and sq_reset() has already cleared * the sq variables, so better don't do anything here. */ @@ -2683,29 +2854,29 @@ static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) * as soon as the irq gets through. */ sq.count--; - sq.playing--; + sq.active--; - if (!sq.playing) { + if (!sq.active) { tt_dmasnd.ctrl = DMASND_CTRL_OFF; sq.ignore_int = 1; } - WAKE_UP(sq.write_queue); + WAKE_UP(sq.action_queue); /* At least one block of the queue is free now so wake up a writing process blocked because of a full queue. */ - if ((sq.playing != 1) || (sq.count != 1)) + if ((sq.active != 1) || (sq.count != 1)) /* We must be a bit carefully here: sq.count indicates the * number of buffers used and not the number of frames to - * be played. If sq.count==1 and sq.playing==1 that means + * be played. If sq.count==1 and sq.active==1 that means * the only remaining frame was already programmed earlier * (and is currently running) so we mustn't call AtaPlay() * here, otherwise we'll play one frame too much. */ AtaPlay(); - if (!sq.playing) WAKE_UP(sq.sync_queue); + if (!sq.active) WAKE_UP(sq.sync_queue); /* We are not playing after AtaPlay(), so there is nothing to play any more. Wake up a process waiting for audio output to drain. */ @@ -2902,7 +3073,7 @@ static void ami_sq_play_next_frame(int index) custom.dmacon = AMI_AUDIO_8; } sq.front = (sq.front+1) % sq.max_count; - sq.playing |= AMI_PLAY_LOADED; + sq.active |= AMI_PLAY_LOADED; } @@ -2912,13 +3083,13 @@ static void AmiPlay(void) custom.intena = IF_AUD0; - if (sq.playing & AMI_PLAY_LOADED) { + if (sq.active & AMI_PLAY_LOADED) { /* There's already a frame loaded */ custom.intena = IF_SETCLR | IF_AUD0; return; } - if (sq.playing & AMI_PLAY_PLAYING) + if (sq.active & AMI_PLAY_PLAYING) /* Increase threshold: frame 1 is already being played */ minframes = 2; @@ -2946,7 +3117,7 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) { int minframes = 1; - if (!sq.playing) { + if (!sq.active) { /* Playing was interrupted and sq_reset() has already cleared * the sq variables, so better don't do anything here. */ @@ -2954,20 +3125,20 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) return; } - if (sq.playing & AMI_PLAY_PLAYING) { + if (sq.active & AMI_PLAY_PLAYING) { /* We've just finished a frame */ sq.count--; - WAKE_UP(sq.write_queue); + WAKE_UP(sq.action_queue); } - if (sq.playing & AMI_PLAY_LOADED) + if (sq.active & AMI_PLAY_LOADED) /* Increase threshold: frame 1 is already being played */ minframes = 2; /* Shift the flags */ - sq.playing = (sq.playing<<1) & AMI_PLAY_MASK; + sq.active = (sq.active<<1) & AMI_PLAY_MASK; - if (!sq.playing) + if (!sq.active) /* No frame is playing, disable audio DMA */ custom.dmacon = AMI_AUDIO_OFF; @@ -2975,7 +3146,7 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) /* Try to play the next frame */ AmiPlay(); - if (!sq.playing) + if (!sq.active) /* Nothing to play anymore. Wake up a process waiting for audio output to drain. */ WAKE_UP(sq.sync_queue); @@ -3001,7 +3172,8 @@ static void PMacFree(void *ptr, unsigned int size) static int __init PMacIrqInit(void) { if (request_irq(awacs_irq, pmac_awacs_intr, 0, "AWACS", 0) - || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "AWACS out", 0)) + || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "AWACS out", 0) + || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "AWACS in", 0)) return 0; return 1; } @@ -3015,12 +3187,15 @@ static void PMacIrqCleanup(void) out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff); free_irq(awacs_irq, pmac_awacs_intr); free_irq(awacs_tx_irq, pmac_awacs_tx_intr); + free_irq(awacs_rx_irq, pmac_awacs_rx_intr); kfree(awacs_tx_cmd_space); + if (awacs_rx_cmd_space) + kfree(awacs_rx_cmd_space); if (beep_buf) kfree(beep_buf); kd_mksound = orig_mksound; #ifdef CONFIG_PMAC_PBOOK - notifier_chain_unregister(&sleep_notifier_list, &awacs_sleep_notifier); + pmu_unregister_sleep_notifier(&awacs_sleep_notifier); #endif } #endif /* MODULE */ @@ -3065,10 +3240,10 @@ static void PMacInit(void) sound.trans = &transAwacsNormal; else sound.trans = &transAwacsExpand; + sound.read_trans = &transAwacsNormalRead; sound.hard.speed = awacs_freqs[i]; awacs_rate_index = i; - PMacSilence(); /* XXX disable error interrupt on burgundy for now */ out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 | (awacs_revision < AWACS_BURGUNDY? MASK_IEE: 0)); @@ -3076,6 +3251,18 @@ static void PMacInit(void) awacs_write(awacs_reg[1] | MASK_ADDR1); out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE); + /* We really want to execute a DMA stop command, after the AWACS + * is initialized. + * For reasons I don't understand, it stops the hissing noise + * common to many PowerBook G3 systems (like mine :-). Maybe it + * is just the AWACS control register change...... + */ + out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); + st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); + out_le32(&awacs->control, (in_le32(&awacs->control) & ~0x1f00)); + out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + out_le32(&awacs_txdma->control, RUN | (RUN << 16)); + sound.bal = -sound.soft.speed; } @@ -3163,20 +3350,23 @@ static void PMacPlay(void) unsigned long flags; save_flags(flags); cli(); - if (beep_playing) { + if (awacs_beep_state) { /* sound takes precedence over beeps */ out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); out_le32(&awacs->control, (in_le32(&awacs->control) & ~0x1f00) - || (awacs_rate_index << 8)); + | (awacs_rate_index << 8)); out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE); + out_le32(&awacs_txdma->cmdptr, virt_to_bus(&(awacs_tx_cmds[(sq.front+sq.active) % sq.max_count]))); + beep_playing = 0; + awacs_beep_state = 0; } - i = sq.front + sq.playing; + i = sq.front + sq.active; if (i >= sq.max_count) i -= sq.max_count; - while (sq.playing < 2 && sq.playing < sq.count) { - count = (sq.count == sq.playing + 1)? sq.rear_size: sq.block_size; + while (sq.active < 2 && sq.active < sq.count) { + count = (sq.count == sq.active + 1)?sq.rear_size:sq.block_size; if (count < sq.block_size && !sq.syncing) /* last block not yet filled, and we're not syncing. */ break; @@ -3187,14 +3377,33 @@ static void PMacPlay(void) i = 0; out_le16(&awacs_tx_cmds[i].command, DBDMA_STOP); out_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS); - if (sq.playing == 0) + if (sq.active == 0) out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); - ++sq.playing; + ++sq.active; } restore_flags(flags); } + +static void PMacRecord(void) +{ + unsigned long flags; + + if (read_sq.active) + return; + + save_flags(flags); cli(); + + /* This is all we have to do......Just start it up. + */ + out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); + read_sq.active = 1; + + restore_flags(flags); +} + + static void pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs) { @@ -3202,26 +3411,78 @@ pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs) int stat; volatile struct dbdma_cmd *cp; - while (sq.playing > 0) { + while (sq.active > 0) { cp = &awacs_tx_cmds[i]; stat = ld_le16(&cp->xfer_status); if ((stat & ACTIVE) == 0) break; /* this frame is still going */ --sq.count; - --sq.playing; + --sq.active; if (++i >= sq.max_count) i = 0; } if (i != sq.front) - WAKE_UP(sq.write_queue); + WAKE_UP(sq.action_queue); sq.front = i; PMacPlay(); - if (!sq.playing) + if (!sq.active) WAKE_UP(sq.sync_queue); } + +static void +pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs) +{ + + /* For some reason on my PowerBook G3, I get one interrupt + * when the interrupt vector is installed (like something is + * pending). This happens before the dbdma is initialize by + * us, so I just check the command pointer and if it is zero, + * just blow it off. + */ + if (in_le32(&awacs_rxdma->cmdptr) == 0) + return; + + /* We also want to blow 'em off when shutting down. + */ + if (read_sq.active == 0) + return; + + /* Check multiple buffers in case we were held off from + * interrupt processing for a long time. Geeze, I really hope + * this doesn't happen. + */ + while (awacs_rx_cmds[read_sq.rear].xfer_status) { + + /* Clear status and move on to next buffer. + */ + awacs_rx_cmds[read_sq.rear].xfer_status = 0; + read_sq.rear++; + + /* Wrap the buffer ring. + */ + if (read_sq.rear >= read_sq.max_active) + read_sq.rear = 0; + + /* If we have caught up to the front buffer, bump it. + * This will cause weird (but not fatal) results if the + * read loop is currently using this buffer. The user is + * behind in this case anyway, so weird things are going + * to happen. + */ + if (read_sq.rear == read_sq.front) { + read_sq.front++; + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + + WAKE_UP(read_sq.action_queue); +} + + static void pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs) { @@ -3294,7 +3555,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) beep_timer.expires = jiffies + ticks; add_timer(&beep_timer); } - if (beep_playing || sq.playing || beep_buf == NULL) { + if (beep_playing || sq.active || beep_buf == NULL) { restore_flags(flags); return; /* too hard, sorry :-( */ } @@ -3324,6 +3585,7 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) st_le16(&beep_dbdma_cmd->xfer_status, 0); st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd)); st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf)); + awacs_beep_state = 1; save_flags(flags); cli(); if (beep_playing) { /* i.e. haven't been terminated already */ @@ -3342,14 +3604,15 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks) /* * Save state when going to sleep, restore it afterwards. */ -static int awacs_sleep_notify(struct notifier_block *this, - unsigned long code, void *x) +static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) { - switch (code) { - case PBOOK_SLEEP: + switch (when) { + case PBOOK_SLEEP_NOW: /* XXX we should stop any dma in progress when going to sleep and restart it when we wake. */ PMacSilence(); + disable_irq(awacs_irq); + disable_irq(awacs_tx_irq); break; case PBOOK_WAKE: out_le32(&awacs->control, MASK_IEPC @@ -3360,8 +3623,10 @@ static int awacs_sleep_notify(struct notifier_block *this, awacs_write(awacs_reg[2] | MASK_ADDR2); awacs_write(awacs_reg[4] | MASK_ADDR4); out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE); + enable_irq(awacs_irq); + enable_irq(awacs_tx_irq); } - return NOTIFY_DONE; + return PBOOK_SLEEP_OK; } #endif /* CONFIG_PMAC_PBOOK */ @@ -3586,7 +3851,7 @@ awacs_enable_amp(int spkr_vol) struct adb_request req; awacs_spkr_vol = spkr_vol; - if (adb_hardware != ADB_VIACUDA) + if (sys_ctrler != SYS_CTRLER_CUDA) return; /* turn on headphones */ @@ -3781,6 +4046,47 @@ static ssize_t sound_copy_translate(const u_char *userPtr, return 0; } +#ifdef CONFIG_PPC +static ssize_t sound_copy_translate_read(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL; + + switch (sound.soft.format) { + case AFMT_MU_LAW: + ct_func = sound.read_trans->ct_ulaw; + break; + case AFMT_A_LAW: + ct_func = sound.read_trans->ct_alaw; + break; + case AFMT_S8: + ct_func = sound.read_trans->ct_s8; + break; + case AFMT_U8: + ct_func = sound.read_trans->ct_u8; + break; + case AFMT_S16_BE: + ct_func = sound.read_trans->ct_s16be; + break; + case AFMT_U16_BE: + ct_func = sound.read_trans->ct_u16be; + break; + case AFMT_S16_LE: + ct_func = sound.read_trans->ct_s16le; + break; + case AFMT_U16_LE: + ct_func = sound.read_trans->ct_u16le; + break; + } + if (ct_func) + return ct_func(userPtr, userCount, frame, frameUsed, frameLeft); + else + return 0; +} +#endif + /* * /dev/mixer abstraction @@ -3983,7 +4289,8 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, #ifdef CONFIG_PPC case DMASND_AWACS: - if (awacs_revision<AWACS_BURGUNDY) { /* Different IOCTLS for burgundy*/ + /* Different IOCTLS for burgundy*/ + if (awacs_revision < AWACS_BURGUNDY) { switch (cmd) { case SOUND_MIXER_INFO: { mixer_info info; @@ -3999,7 +4306,8 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV - | SOUND_MASK_ALTPCM; + | SOUND_MASK_ALTPCM + | SOUND_MASK_MONITOR; return IOCTL_OUT(arg, data); case SOUND_MIXER_READ_RECMASK: data = SOUND_MASK_LINE | SOUND_MASK_MIC @@ -4013,20 +4321,27 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, data |= SOUND_MASK_MIC; if (awacs_reg[0] & MASK_MUX_CD) data |= SOUND_MASK_CD; + if (awacs_reg[1] & MASK_LOOPTHRU) + data |= SOUND_MASK_MONITOR; return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_RECSRC: IOCTL_IN(arg, data); data &= (SOUND_MASK_LINE - | SOUND_MASK_MIC | SOUND_MASK_CD); + | SOUND_MASK_MIC | SOUND_MASK_CD + | SOUND_MASK_MONITOR); awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC | MASK_MUX_AUDIN); + awacs_reg[1] &= ~MASK_LOOPTHRU; if (data & SOUND_MASK_LINE) awacs_reg[0] |= MASK_MUX_AUDIN; if (data & SOUND_MASK_MIC) awacs_reg[0] |= MASK_MUX_MIC; if (data & SOUND_MASK_CD) awacs_reg[0] |= MASK_MUX_CD; + if (data & SOUND_MASK_MONITOR) + awacs_reg[1] |= MASK_LOOPTHRU; awacs_write(awacs_reg[0] | MASK_ADDR0); + awacs_write(awacs_reg[1] | MASK_ADDR1); return IOCTL_OUT(arg, data); case SOUND_MIXER_READ_STEREODEVS: data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER @@ -4042,7 +4357,8 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_volume(data)); case SOUND_MIXER_READ_SPEAKER: - if (awacs_revision == 3 && adb_hardware == ADB_VIACUDA) + if (awacs_revision == 3 + && sys_ctrler == SYS_CTRLER_CUDA) data = awacs_spkr_vol; else data = (awacs_reg[1] & MASK_CMUTE)? 0: @@ -4050,7 +4366,8 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_SPEAKER: IOCTL_IN(arg, data); - if (awacs_revision == 3 && adb_hardware == ADB_VIACUDA) + if (awacs_revision == 3 + && sys_ctrler == SYS_CTRLER_CUDA) awacs_enable_amp(data); else data = awacs_volume_setter(data, 4, MASK_CMUTE, 6); @@ -4347,7 +4664,60 @@ static void sq_release_buffers(void) } -static void sq_setup(int numBufs, int bufSize, char **buffers) +#ifdef CONFIG_PPC +static int sq_allocate_read_buffers(void) +{ + int i; + int j; + + if (sound_read_buffers) + return 0; + sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL); + if (!sound_read_buffers) + return -ENOMEM; + for (i = 0; i < numBufs; i++) { + sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10, + GFP_KERNEL); + if (!sound_read_buffers[i]) { + while (i--) + sound.mach.dma_free (sound_read_buffers[i], + readbufSize << 10); + kfree (sound_read_buffers); + sound_read_buffers = 0; + return -ENOMEM; + } + /* XXXX debugging code */ + for (j=0; j<readbufSize; j++) { + sound_read_buffers[i][j] = 0xef; + } + } + return 0; +} + +static void sq_release_read_buffers(void) +{ + int i; + volatile struct dbdma_cmd *cp; + + + if (sound_read_buffers) { + cp = awacs_rx_cmds; + for (i = 0; i < numReadBufs; i++,cp++) { + st_le16(&cp->command, DBDMA_STOP); + } + /* We should probably wait for the thing to stop before we + release the memory */ + for (i = 0; i < numBufs; i++) + sound.mach.dma_free (sound_read_buffers[i], + bufSize << 10); + kfree (sound_read_buffers); + sound_read_buffers = 0; + } +} +#endif + + +static void sq_setup(int numBufs, int bufSize, char **write_buffers) { #ifdef CONFIG_PPC int i; @@ -4357,12 +4727,12 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) sq.max_count = numBufs; sq.max_active = numBufs; sq.block_size = bufSize; - sq.buffers = buffers; + sq.buffers = write_buffers; sq.front = sq.count = 0; sq.rear = -1; sq.syncing = 0; - sq.playing = 0; + sq.active = 0; #ifdef CONFIG_ATARI sq.ignore_int = 0; @@ -4375,7 +4745,7 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) cp = awacs_tx_cmds; memset((void *) cp, 0, (numBufs + 1) * sizeof(struct dbdma_cmd)); for (i = 0; i < numBufs; ++i, ++cp) { - st_le32(&cp->phy_addr, virt_to_bus(buffers[i])); + st_le32(&cp->phy_addr, virt_to_bus(write_buffers[i])); } st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds)); @@ -4384,6 +4754,50 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) #endif /* CONFIG_PPC */ } +#ifdef CONFIG_PPC +static void read_sq_setup(int numBufs, int bufSize, char **read_buffers) +{ + int i; + volatile struct dbdma_cmd *cp; + + read_sq.max_count = numBufs; + read_sq.max_active = numBufs; + read_sq.block_size = bufSize; + read_sq.buffers = read_buffers; + + read_sq.front = read_sq.count = 0; + read_sq.rear = 0; + read_sq.rear_size = 0; + read_sq.syncing = 0; + read_sq.active = 0; + + cp = awacs_rx_cmds; + memset((void *) cp, 0, (numBufs + 1) * sizeof(struct dbdma_cmd)); + + /* Set dma buffers up in a loop */ + for (i = 0; i < numBufs; i++,cp++) { + st_le32(&cp->phy_addr, virt_to_bus(read_buffers[i])); + st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS); + st_le16(&cp->req_count, read_sq.block_size); + st_le16(&cp->xfer_status, 0); + } + + /* The next two lines make the thing loop around. + */ + st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); + st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds)); + + /* Don't start until the first read is done. + * This will also abort any operations in progress if the DMA + * happens to be running (and it shouldn't). + */ + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds)); + +} +#endif /* CONFIG_PPC */ + + static void sq_play(void) { (*sound.mach.play)(); @@ -4428,7 +4842,7 @@ static ssize_t sq_write(struct file *file, const char *src, size_t uLeft, sq_play(); if (NON_BLOCKING(sq.open_mode)) return uWritten > 0 ? uWritten : -EAGAIN; - SLEEP(sq.write_queue, ONE_SECOND); + SLEEP(sq.action_queue, ONE_SECOND); if (SIGNAL_RECEIVED) return uWritten > 0 ? uWritten : -EINTR; } @@ -4462,29 +4876,122 @@ static ssize_t sq_write(struct file *file, const char *src, size_t uLeft, } +/***********/ + +#ifdef CONFIG_PPC + +/* Here is how the values are used for reading. + * The value 'active' simply indicates the DMA is running. This is + * done so the driver semantics are DMA starts when the first read is + * posted. The value 'front' indicates the buffer we should next + * send to the user. The value 'rear' indicates the buffer the DMA is + * currently filling. When 'front' == 'rear' the buffer "ring" is + * empty (we always have an empty available). The 'rear_size' is used + * to track partial offsets into the current buffer. Right now, I just keep + * the DMA running. If the reader can't keep up, the interrupt tosses + * the oldest buffer. We could also shut down the DMA in this case. + */ +static ssize_t sq_read(struct file *file, char *dst, size_t uLeft, + loff_t *ppos) +{ + + ssize_t uRead, bLeft, bUsed, uUsed; + + if (uLeft == 0) + return 0; + + if (!read_sq.active) + PMacRecord(); /* Kick off the record process. */ + + uRead = 0; + + /* Move what the user requests, depending upon other options. + */ + while (uLeft > 0) { + + /* When front == rear, the DMA is not done yet. + */ + while (read_sq.front == read_sq.rear) { + if (NON_BLOCKING(read_sq.open_mode)) { + return uRead > 0 ? uRead : -EAGAIN; + } + SLEEP(read_sq.action_queue, ONE_SECOND); + if (SIGNAL_RECEIVED) + return uRead > 0 ? uRead : -EINTR; + } + + /* The amount we move is either what is left in the + * current buffer or what the user wants. + */ + bLeft = read_sq.block_size - read_sq.rear_size; + bUsed = read_sq.rear_size; + uUsed = sound_copy_translate_read(dst, uLeft, + read_sq.buffers[read_sq.front], &bUsed, bLeft); + if (uUsed <= 0) + return uUsed; + dst += uUsed; + uRead += uUsed; + uLeft -= uUsed; + read_sq.rear_size += bUsed; + if (read_sq.rear_size >= read_sq.block_size) { + read_sq.rear_size = 0; + read_sq.front++; + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + return uRead; +} +#endif + static int sq_open(struct inode *inode, struct file *file) { int rc = 0; MOD_INC_USE_COUNT; - if (sq.busy) { - rc = -EBUSY; - if (NON_BLOCKING(file->f_flags)) - goto err_out; - rc = -EINTR; - while (sq.busy) { - SLEEP(sq.open_queue, ONE_SECOND); - if (SIGNAL_RECEIVED) + if (file->f_mode & FMODE_WRITE) { + if (sq.busy) { + rc = -EBUSY; + if (NON_BLOCKING(file->f_flags)) goto err_out; + rc = -EINTR; + while (sq.busy) { + SLEEP(sq.open_queue, ONE_SECOND); + if (SIGNAL_RECEIVED) + goto err_out; + } } - rc = 0; + sq.busy = 1; /* Let's play spot-the-race-condition */ + + if (sq_allocate_buffers()) goto err_out_nobusy; + + sq_setup(numBufs, bufSize<<10,sound_buffers); + sq.open_mode = file->f_mode; } - sq.busy = 1; - rc = sq_allocate_buffers(); - if (rc) - goto err_out_nobusy; - sq_setup(numBufs, bufSize << 10, sound_buffers); - sq.open_mode = file->f_flags; + + +#ifdef CONFIG_PPC + if (file->f_mode & FMODE_READ) { + if (read_sq.busy) { + rc = -EBUSY; + if (NON_BLOCKING(file->f_flags)) + goto err_out; + rc = -EINTR; + while (read_sq.busy) { + SLEEP(read_sq.open_queue, ONE_SECOND); + if (SIGNAL_RECEIVED) + goto err_out; + } + rc = 0; + } + read_sq.busy = 1; + if (sq_allocate_read_buffers()) goto err_out_nobusy; + + read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers); + read_sq.open_mode = file->f_mode; + } +#endif + #ifdef CONFIG_ATARI sq.ignore_int = 1; #endif /* CONFIG_ATARI */ @@ -4497,10 +5004,27 @@ static int sq_open(struct inode *inode, struct file *file) sound_set_stereo(0); sound_set_format(AFMT_MU_LAW); } + +#if 0 + if (file->f_mode == FMODE_READ) { + /* Start dma'ing straight away */ + PMacRecord(); + } +#endif + return 0; + err_out_nobusy: - sq.busy = 0; - WAKE_UP(sq.open_queue); + if (file->f_mode & FMODE_WRITE) { + sq.busy = 0; + WAKE_UP(sq.open_queue); + } +#ifdef CONFIG_PPC + if (file->f_mode & FMODE_READ) { + read_sq.busy = 0; + WAKE_UP(read_sq.open_queue); + } +#endif err_out: MOD_DEC_USE_COUNT; return rc; @@ -4510,7 +5034,7 @@ err_out: static void sq_reset(void) { sound_silence(); - sq.playing = 0; + sq.active = 0; sq.count = 0; sq.front = (sq.rear+1) % sq.max_count; } @@ -4523,7 +5047,7 @@ static int sq_fsync(struct file *filp, struct dentry *dentry) sq.syncing = 1; sq_play(); /* there may be an incomplete frame waiting */ - while (sq.playing) { + while (sq.active) { SLEEP(sq.sync_queue, ONE_SECOND); if (SIGNAL_RECEIVED) { /* While waiting for audio output to drain, an @@ -4548,11 +5072,27 @@ static int sq_release(struct inode *inode, struct file *file) sound.soft = sound.dsp; sound.hard = sound.dsp; sound_silence(); + +#ifdef CONFIG_PPC + sq_release_read_buffers(); +#endif sq_release_buffers(); MOD_DEC_USE_COUNT; - sq.busy = 0; - WAKE_UP(sq.open_queue); + /* There is probably a DOS atack here. They change the mode flag. */ + /* XXX add check here */ +#ifdef CONFIG_PPC + if (file->f_mode & FMODE_READ) { + read_sq.busy = 0; + WAKE_UP(read_sq.open_queue); + } +#endif + + if (file->f_mode & FMODE_WRITE) { + sq.busy = 0; + WAKE_UP(sq.open_queue); + } + /* Wake up a process waiting for the queue being released. * Note: There may be several processes waiting for a call * to open() returning. */ @@ -4624,14 +5164,14 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, case SNDCTL_DSP_SUBDIVIDE: break; case SNDCTL_DSP_SETFRAGMENT: - if (sq.count || sq.playing || sq.syncing) + if (sq.count || sq.active || sq.syncing) return -EINVAL; IOCTL_IN(arg, size); nbufs = size >> 16; if (nbufs < 2 || nbufs > numBufs) nbufs = numBufs; size &= 0xffff; - if (size >= 8 && size <= 30) { + if (size >= 8 && size <= 29) { size = 1 << size; size *= sound.hard.size * (sound.hard.stereo + 1); size /= sound.soft.size * (sound.soft.stereo + 1); @@ -4654,7 +5194,11 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, static struct file_operations sq_fops = { sound_lseek, +#ifdef CONFIG_PPC + sq_read, /* sq_read */ +#else NULL, /* sq_read */ +#endif sq_write, NULL, /* sq_readdir */ NULL, /* sq_poll */ @@ -4675,10 +5219,20 @@ static void __init sq_init(void) if (sq_unit < 0) return; - init_waitqueue_head(&sq.write_queue); + init_waitqueue_head(&sq.action_queue); init_waitqueue_head(&sq.open_queue); init_waitqueue_head(&sq.sync_queue); + +#ifdef CONFIG_PPC + init_waitqueue_head(&read_sq.action_queue); + init_waitqueue_head(&read_sq.open_queue); + init_waitqueue_head(&read_sq.sync_queue); +#endif + sq.busy = 0; +#ifdef CONFIG_PPC + read_sq.busy = 0; +#endif /* whatever you like as startup mode for /dev/dsp, * (/dev/audio hasn't got a startup mode). note that @@ -4727,6 +5281,9 @@ static void __init sq_init(void) static int state_open(struct inode *inode, struct file *file) { char *buffer = state.buf, *mach = ""; +#ifdef CONFIG_PPC + char awacs_buf[50]; +#endif int len = 0; if (state.busy) @@ -4750,7 +5307,8 @@ static int state_open(struct inode *inode, struct file *file) #endif /* CONFIG_AMIGA */ #ifdef CONFIG_PPC case DMASND_AWACS: - sprintf(mach, "PowerMac (AWACS rev %d) ", awacs_revision); + sprintf(awacs_buf, "PowerMac (AWACS rev %d) ", awacs_revision); + mach = awacs_buf; break; #endif /* CONFIG_PPC */ } @@ -4821,8 +5379,8 @@ static int state_open(struct inode *inode, struct file *file) sq.block_size, sq.max_count, sq.max_active); len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count, sq.rear_size); - len += sprintf(buffer+len, "\tsq.playing = %d sq.syncing = %d\n", - sq.playing, sq.syncing); + len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n", + sq.active, sq.syncing); state.len = len; return 0; } @@ -4951,15 +5509,18 @@ void __init dmasound_init(void) int vol; sound.mach = machPMac; has_sound = 1; + awacs = (volatile struct awacs_regs *) ioremap(np->addrs[0].address, 0x80); awacs_txdma = (volatile struct dbdma_regs *) ioremap(np->addrs[1].address, 0x100); awacs_rxdma = (volatile struct dbdma_regs *) ioremap(np->addrs[2].address, 0x100); + awacs_irq = np->intrs[0].line; awacs_tx_irq = np->intrs[1].line; awacs_rx_irq = np->intrs[2].line; + awacs_tx_cmd_space = kmalloc((numBufs + 4) * sizeof(struct dbdma_cmd), GFP_KERNEL); if (awacs_tx_cmd_space == NULL) { @@ -4968,6 +5529,18 @@ void __init dmasound_init(void) } awacs_tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(awacs_tx_cmd_space); + + + awacs_rx_cmd_space = kmalloc((numReadBufs + 4) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (awacs_rx_cmd_space == NULL) { + printk("DMA sound driver: No memory for input"); + } + awacs_rx_cmds = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(awacs_rx_cmd_space); + + + awacs_reg[0] = MASK_MUX_CD; awacs_reg[1] = MASK_LOOPTHRU | MASK_PAROUT; /* get default volume from nvram */ @@ -5001,9 +5574,33 @@ void __init dmasound_init(void) printk(KERN_WARNING "dmasound: no memory for " "beep buffer\n"); #ifdef CONFIG_PMAC_PBOOK - notifier_chain_register(&sleep_notifier_list, - &awacs_sleep_notifier); + pmu_register_sleep_notifier(&awacs_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ + + /* Powerbooks have odd ways of enabling inputs such as + an expansion-bay CD or sound from an internal modem + or a PC-card modem. */ + if (machine_is_compatible("AAPL,3400/2400")) { + is_pbook_3400 = 1; + /* + * Enable CD and PC-card sound inputs. + * This is done by reading from address + * f301a000, + 0x10 to enable the expansion-bay + * CD sound input, + 0x80 to enable the PC-card + * sound input. The 0x100 seems to enable the + * MESH and/or its SCSI bus drivers. + */ + in_8((unsigned char *)0xf301a190); + } else if (machine_is_compatible("PowerBook1,1")) { + np = find_devices("mac-io"); + if (np && np->n_addrs > 0) { + is_pbook_G3 = 1; + macio_base = (unsigned char *) + ioremap(np->addrs[0].address, 0x40); + /* enable CD sound input */ + out_8(macio_base + 0x37, 3); + } + } } #endif /* CONFIG_PPC */ @@ -5083,6 +5680,9 @@ void cleanup_module(void) sound.mach.irqcleanup(); } +#ifdef CONFIG_PPC + sq_release_read_buffers(); +#endif sq_release_buffers(); if (mixer_unit >= 0) diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c index 7c2093a43..08e819dce 100644 --- a/drivers/sound/es1370.c +++ b/drivers/sound/es1370.c @@ -100,6 +100,19 @@ * Guenter Geiger <geiger@epy.co.at> * 15.06.99 0.23 Fix bad allocation bug. * Thanks to Deti Fliegl <fliegl@in.tum.de> + * 28.06.99 0.24 Add pci_set_master + * 02.08.99 0.25 Added workaround for the "phantom write" bug first + * documented by Dave Sharpless from Anchor Games + * 03.08.99 0.26 adapt to Linus' new __setup/__initcall + * added kernel command line option "es1370=joystick[,lineout[,micbias]]" + * removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge + * 12.08.99 0.27 module_init/__setup fixes + * 19.08.99 0.28 SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it> + * 31.08.99 0.29 add spin_lock_init + * __initlocaldata to fix gcc 2.7.x problems + * replaced current->state = x with set_current_state(x) + * 03.09.99 0.30 change read semantics for MIDI to match + * OSS more closely; remove possible wakeup race * * some important things missing in Ensoniq documentation: * @@ -122,7 +135,6 @@ /*****************************************************************************/ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/string.h> @@ -137,7 +149,7 @@ #include <asm/dma.h> #include <linux/init.h> #include <linux/poll.h> -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/hardirq.h> @@ -174,12 +186,14 @@ #define ES1370_REG_DAC2_SCOUNT 0x28 #define ES1370_REG_ADC_SCOUNT 0x2c -#define ES1370_REG_DAC1_FRAMEADR 0xc30 -#define ES1370_REG_DAC1_FRAMECNT 0xc34 -#define ES1370_REG_DAC2_FRAMEADR 0xc38 -#define ES1370_REG_DAC2_FRAMECNT 0xc3c -#define ES1370_REG_ADC_FRAMEADR 0xd30 -#define ES1370_REG_ADC_FRAMECNT 0xd34 +#define ES1370_REG_DAC1_FRAMEADR 0xc30 +#define ES1370_REG_DAC1_FRAMECNT 0xc34 +#define ES1370_REG_DAC2_FRAMEADR 0xc38 +#define ES1370_REG_DAC2_FRAMECNT 0xc3c +#define ES1370_REG_ADC_FRAMEADR 0xd30 +#define ES1370_REG_ADC_FRAMECNT 0xd34 +#define ES1370_REG_PHANTOM_FRAMEADR 0xd38 +#define ES1370_REG_PHANTOM_FRAMECNT 0xd3c #define ES1370_FMT_U8_MONO 0 #define ES1370_FMT_U8_STEREO 1 @@ -359,6 +373,13 @@ struct es1370_state { static struct es1370_state *devs = NULL; +/* + * The following buffer is used to point the phantom write channel to, + * so that it cannot wreak havoc. The attribute makes sure it doesn't + * cross a page boundary and ensures dword alignment for the DMA engine + */ +static unsigned char bugbuf[16] __attribute__ ((aligned (16))); + /* --------------------------------------------------------------------- */ extern inline unsigned ld2(unsigned int x) @@ -778,10 +799,36 @@ static const struct { [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } /* mono out */ }; +static void set_recsrc(struct es1370_state *s, unsigned int val) +{ + unsigned int i, j; + + for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { + if (!(val & (1 << i))) + continue; + if (!mixtable[i].recmask) { + val &= ~(1 << i); + continue; + } + j |= mixtable[i].recmask; + } + s->mix.recsrc = val; + wrcodec(s, 0x12, j & 0xd5); + wrcodec(s, 0x13, j & 0xaa); + wrcodec(s, 0x14, (j >> 8) & 0x17); + wrcodec(s, 0x15, (j >> 8) & 0x0f); + i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60; + if (!s->mix.imix) { + i &= 0xff60; /* mute record and line monitor */ + } + wrcodec(s, 0x10, i); + wrcodec(s, 0x11, i >> 8); +} + static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long arg) { unsigned long flags; - int i, val, j; + int i, val; unsigned char l, r, rl, rr; VALIDATE_STATE(s); @@ -886,34 +933,13 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a switch (_IOC_NR(cmd)) { case SOUND_MIXER_IMIX: - if (arg == 0) - return -EFAULT; - get_user_ret(s->mix.imix,(int *)arg, -EFAULT); - val = s->mix.recsrc; - /* fall through */ + get_user_ret(s->mix.imix, (int *)arg, -EFAULT); + set_recsrc(s, s->mix.recsrc); + return 0; case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ get_user_ret(val, (int *)arg, -EFAULT); - for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { - if (!(val & (1 << i))) - continue; - if (!mixtable[i].recmask) { - val &= ~(1 << i); - continue; - } - j |= mixtable[i].recmask; - } - s->mix.recsrc = val; - wrcodec(s, 0x12, j & 0xd5); - wrcodec(s, 0x13, j & 0xaa); - wrcodec(s, 0x14, (j >> 8) & 0x17); - wrcodec(s, 0x15, (j >> 8) & 0x0f); - i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60; - if (!s->mix.imix) { - i &= 0xff60; /* mute record and line monitor */ - } - wrcodec(s, 0x10, i); - wrcodec(s, 0x11, i >> 8); + set_recsrc(s, val); return 0; default: @@ -1038,7 +1064,7 @@ static int drain_dac1(struct es1370_state *s, int nonblock) if (s->dma_dac1.mapped || !s->dma_dac1.ready) return 0; - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac1.wait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1050,16 +1076,17 @@ static int drain_dac1(struct es1370_state *s, int nonblock) break; if (nonblock) { remove_wait_queue(&s->dma_dac1.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } - tmo = (count * HZ) / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL]; + tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 + / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL]; tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) } remove_wait_queue(&s->dma_dac1.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; return 0; @@ -1073,7 +1100,7 @@ static int drain_dac2(struct es1370_state *s, int nonblock) if (s->dma_dac2.mapped || !s->dma_dac2.ready) return 0; - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac2.wait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1085,16 +1112,17 @@ static int drain_dac2(struct es1370_state *s, int nonblock) break; if (nonblock) { remove_wait_queue(&s->dma_dac2.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } - tmo = (count * HZ) / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV); + tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 + / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV); tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) } remove_wait_queue(&s->dma_dac2.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; return 0; @@ -2048,6 +2076,7 @@ static /*const*/ struct file_operations es1370_dac_fops = { static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct es1370_state *s = (struct es1370_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -2058,7 +2087,10 @@ static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, l return -ESPIPE; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.iwait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.ird; @@ -2069,15 +2101,25 @@ static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, l if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.iwait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIINBUF; spin_lock_irqsave(&s->lock, flags); s->midi.ird = ptr; @@ -2086,13 +2128,17 @@ static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, l count -= cnt; buffer += cnt; ret += cnt; + break; } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); return ret; } static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1370_state *s = (struct es1370_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -2103,7 +2149,10 @@ static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t c return -ESPIPE; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.owait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.owr; @@ -2116,15 +2165,25 @@ static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t c if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.owait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIOUTBUF; spin_lock_irqsave(&s->lock, flags); s->midi.owr = ptr; @@ -2137,6 +2196,8 @@ static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t c es1370_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); return ret; } @@ -2223,7 +2284,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -2235,7 +2296,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) break; if (file->f_flags & O_NONBLOCK) { remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } tmo = (count * HZ) / 3100; @@ -2243,7 +2304,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");) } remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); } down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); @@ -2281,14 +2342,21 @@ static /*const*/ struct file_operations es1370_midi_fops = { /* maximum number of devices */ #define NR_DEVICE 5 -#ifdef CONFIG_SOUND_ES1370_JOYPORT_BOOT -static int joystick[NR_DEVICE] = { 1, 0, }; -#else + static int joystick[NR_DEVICE] = { 0, }; -#endif static int lineout[NR_DEVICE] = { 0, }; static int micbias[NR_DEVICE] = { 0, }; +MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate driver)"); +MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); +MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); + /* --------------------------------------------------------------------- */ static struct initvol { @@ -2307,11 +2375,12 @@ static struct initvol { { SOUND_MIXER_WRITE_OGAIN, 0x4040 } }; -#ifdef MODULE -int __init init_module(void) -#else -int __init init_es1370(void) -#endif +#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \ + ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) +#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) + + +static int __init init_es1370(void) { struct es1370_state *s; struct pci_dev *pcidev = NULL; @@ -2320,11 +2389,10 @@ int __init init_es1370(void) if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1370: version v0.23 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1370: version v0.29 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) { - if (pcidev->base_address[0] == 0 || - (pcidev->base_address[0] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + if (!RSRCISIOREGION(pcidev, 0)) continue; if (pcidev->irq == 0) continue; @@ -2340,8 +2408,9 @@ int __init init_es1370(void) init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); s->magic = ES1370_MAGIC; - s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + s->io = RSRCADDRESS(pcidev, 0); s->irq = pcidev->irq; if (check_region(s->io, ES1370_EXTENT)) { printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1); @@ -2384,6 +2453,11 @@ int __init init_es1370(void) /* initialize the chips */ outl(s->ctrl, s->io+ES1370_REG_CONTROL); outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); + /* point phantom write channel to "bugbuf" */ + outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE); + outl(virt_to_bus(bugbuf), s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff)); + outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff)); + pci_set_master(pcidev); /* enable bus mastering */ wrcodec(s, 0x16, 3); /* no RST, PD */ wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!! */ wrcodec(s, 0x18, 0); /* recording source is mixer */ @@ -2423,21 +2497,7 @@ int __init init_es1370(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate driver)"); -MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); -MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); - -void cleanup_module(void) +static void __exit cleanup_es1370(void) { struct es1370_state *s; @@ -2457,4 +2517,32 @@ void cleanup_module(void) printk(KERN_INFO "es1370: unloading\n"); } +module_init(init_es1370); +module_exit(cleanup_es1370); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE + +/* format is: es1370=[joystick[,lineout[,micbias]]] */ + +static int __init es1370_setup(char *str) +{ + static unsigned __initlocaldata nr_dev = 0; + + if (nr_dev >= NR_DEVICE) + return 0; + + (void) + ( (get_option(&str,&joystick[nr_dev]) == 2) + && (get_option(&str,&lineout [nr_dev]) == 2) + && get_option(&str,&micbias [nr_dev]) + ); + + nr_dev++; + return 1; +} + +__setup("es1370=", es1370_setup); + #endif /* MODULE */ diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c index 80812de15..bf5048fe2 100644 --- a/drivers/sound/es1371.c +++ b/drivers/sound/es1371.c @@ -3,7 +3,7 @@ /* * es1371.c -- Creative Ensoniq ES1371. * - * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,12 +67,30 @@ * other than i386 * 15.06.99 0.12 Fix bad allocation bug. * Thanks to Deti Fliegl <fliegl@in.tum.de> + * 28.06.99 0.13 Add pci_set_master + * 03.08.99 0.14 adapt to Linus' new __setup/__initcall + * added kernel command line option "es1371=joystickaddr" + * removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge + * 10.08.99 0.15 (Re)added S/PDIF module option for cards revision >= 4. + * Initial version by Dave Platt <dplatt@snulbug.mtview.ca.us>. + * module_init/__setup fixes + * 08.16.99 0.16 Joe Cotellese <joec@ensoniq.com> + * Added detection for ES1371 revision ID so that we can + * detect the ES1373 and later parts. + * added AC97 #defines for readability + * added a /proc file system for dumping hardware state + * updated SRC and CODEC w/r functions to accomodate bugs + * in some versions of the ES137x chips. + * 31.08.99 0.17 add spin_lock_init + * __initlocaldata to fix gcc 2.7.x problems + * replaced current->state = x with set_current_state(x) + * 03.09.99 0.18 change read semantics for MIDI to match + * OSS more closely; remove possible wakeup race * */ /*****************************************************************************/ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/string.h> @@ -83,17 +101,21 @@ #include <linux/malloc.h> #include <linux/soundcard.h> #include <linux/pci.h> -#include <asm/io.h> -#include <asm/dma.h> #include <linux/init.h> #include <linux/poll.h> -#include <asm/spinlock.h> +#include <linux/bitops.h> +#include <linux/proc_fs.h> +#include <linux/spinlock.h> +#include <asm/io.h> +#include <asm/dma.h> #include <asm/uaccess.h> #include <asm/hardirq.h> +#include "ac97.h" /* --------------------------------------------------------------------- */ #undef OSS_DOCUMENTED_MIXER_SEMANTICS +#define ES1371_DEBUG /* --------------------------------------------------------------------- */ @@ -104,6 +126,18 @@ #define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 #endif +/* ES1371 chip ID */ +/* This is a little confusing because all ES1371 compatible chips have the + same DEVICE_ID, the only thing differentiating them is the REV_ID field. + This is only significant if you want to enable features on the later parts. + Yes, I know it's stupid and why didn't we use the sub IDs? +*/ +#define ES1371REV_ES1373_A 0x04 +#define ES1371REV_ES1373_B 0x06 +#define ES1371REV_CT5880_A 0x07 +#define ES1371REV_ES1371_B 0x09 + + #define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371) #define ES1371_EXTENT 0x40 @@ -142,6 +176,7 @@ static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; +#define CTRL_SPDIFEN_B 0x04000000 #define CTRL_JOY_SHIFT 24 #define CTRL_JOY_MASK 3 #define CTRL_JOY_200 0x00000000 /* joystick base address */ @@ -177,6 +212,9 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 }; #define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ +#define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */ +#define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */ +#define STAT_TESTMODE 0x00010000 /* test ASIC */ #define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */ #define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */ #define STAT_SH_VC 6 @@ -199,14 +237,22 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 }; #define UCTRL_CNTRL_SWR 0x03 /* software reset command */ /* sample rate converter */ +#define SRC_OKSTATE 1 + #define SRC_RAMADDR_MASK 0xfe000000 #define SRC_RAMADDR_SHIFT 25 +#define SRC_DAC1FREEZE (1UL << 21) +#define SRC_DAC2FREEZE (1UL << 20) +#define SRC_ADCFREEZE (1UL << 19) + + #define SRC_WE 0x01000000 /* read/write control for SRC RAM */ #define SRC_BUSY 0x00800000 /* SRC busy */ #define SRC_DIS 0x00400000 /* 1 = disable SRC */ #define SRC_DDAC1 0x00200000 /* 1 = disable accum update for DAC1 */ #define SRC_DDAC2 0x00100000 /* 1 = disable accum update for DAC2 */ #define SRC_DADC 0x00080000 /* 1 = disable accum update for ADC2 */ +#define SRC_CTLMASK 0x00780000 #define SRC_RAMDATA_MASK 0x0000ffff #define SRC_RAMDATA_SHIFT 0 @@ -286,7 +332,7 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 }; /* misc stuff */ - +#define POLL_COUNT 0x1000 #define FMODE_DAC 4 /* slight misuse of mode_t */ /* MIDI buffer sizes */ @@ -345,8 +391,13 @@ struct es1371_state { /* hardware resources */ unsigned long io; /* long for SPARC */ unsigned int irq; - - /* mixer registers; there is no HW readback */ + u8 rev; /* the chip revision */ + +#ifdef ES1371_DEBUG + /* debug /proc entry */ + struct proc_dir_entry *ps; +#endif /* ES1371_DEBUG */ + /* mixer registers; there is no HW readback */ struct { unsigned short codec_id; unsigned int modcnt; @@ -431,31 +482,12 @@ extern inline unsigned ld2(unsigned int x) } /* --------------------------------------------------------------------- */ -/* - * hweightN: returns the hamming weight (i.e. the number - * of bits set) of a N-bit word - */ - -#ifdef hweight32 -#undef hweight32 -#endif - -extern __inline__ unsigned int hweight32(unsigned int w) -{ - unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); - res = (res & 0x33333333) + ((res >> 2) & 0x33333333); - res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); - res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); - return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); -} - -/* --------------------------------------------------------------------- */ static unsigned wait_src_ready(struct es1371_state *s) { unsigned int t, r; - for (t = 0; t < 1000; t++) { + for (t = 0; t < POLL_COUNT; t++) { if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY)) return r; udelay(1); @@ -466,29 +498,53 @@ static unsigned wait_src_ready(struct es1371_state *s) static unsigned src_read(struct es1371_state *s, unsigned reg) { - unsigned int r; + unsigned int temp,i,orig; + + /* wait for ready */ + temp = wait_src_ready (s); + + /* we can only access the SRC at certain times, make sure + we're allowed to before we read */ + + orig = temp; + /* expose the SRC state bits */ + outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL, + s->io + ES1371_REG_SRCONV); + + /* now, wait for busy and the correct time to read */ + temp = wait_src_ready (s); + + if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){ + /* wait for the right state */ + for (i=0; i<POLL_COUNT; i++){ + temp = inl (s->io + ES1371_REG_SRCONV); + if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 )) + break; + } + } - r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC); - r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK; - outl(r, s->io + ES1371_REG_SRCONV); - return (wait_src_ready(s) & SRC_RAMDATA_MASK) >> SRC_RAMDATA_SHIFT; + /* hide the state bits */ + outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV); + return temp; + + } - static void src_write(struct es1371_state *s, unsigned reg, unsigned data) { + unsigned int r; r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC); r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK; r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK; outl(r | SRC_WE, s->io + ES1371_REG_SRCONV); + } /* --------------------------------------------------------------------- */ /* most of the following here is black magic */ - static void set_adc_rate(struct es1371_state *s, unsigned rate) { unsigned long flags; @@ -525,6 +581,7 @@ static void set_adc_rate(struct es1371_state *s, unsigned rate) spin_unlock_irqrestore(&s->lock, flags); } + static void set_dac1_rate(struct es1371_state *s, unsigned rate) { unsigned long flags; @@ -559,6 +616,7 @@ static void set_dac2_rate(struct es1371_state *s, unsigned rate) rate = 4000; freq = (rate << 15) / 3000; s->dac2rate = (freq * 3000) >> 15; + printk (KERN_DEBUG "dac2 freq: %d\n", freq); spin_lock_irqsave(&s->lock, flags); r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2; outl(r, s->io + ES1371_REG_SRCONV); @@ -573,26 +631,80 @@ static void set_dac2_rate(struct es1371_state *s, unsigned rate) /* --------------------------------------------------------------------- */ +static void __init src_init(struct es1371_state *s) +{ + unsigned int i; + + /* before we enable or disable the SRC we need + to wait for it to become ready */ + wait_src_ready(s); + + outl(SRC_DIS, s->io + ES1371_REG_SRCONV); + + for (i = 0; i < 0x80; i++) + src_write(s, i, 0); + + src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4); + src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10); + src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4); + src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10); + src_write(s, SRCREG_VOL_ADC, 1 << 12); + src_write(s, SRCREG_VOL_ADC+1, 1 << 12); + src_write(s, SRCREG_VOL_DAC1, 1 << 12); + src_write(s, SRCREG_VOL_DAC1+1, 1 << 12); + src_write(s, SRCREG_VOL_DAC2, 1 << 12); + src_write(s, SRCREG_VOL_DAC2+1, 1 << 12); + set_adc_rate(s, 22050); + set_dac1_rate(s, 22050); + set_dac2_rate(s, 22050); + + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) + */ + wait_src_ready(s); + outl(0, s->io+ES1371_REG_SRCONV); +} + +/* --------------------------------------------------------------------- */ + static void wrcodec(struct es1371_state *s, unsigned addr, unsigned data) { unsigned long flags; unsigned t, x; - - for (t = 0; t < 0x1000; t++) + + for (t = 0; t < POLL_COUNT; t++) if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) break; spin_lock_irqsave(&s->lock, flags); - /* save the current state for later */ - x = inl(s->io+ES1371_REG_SRCONV); - /* enable SRC state data in SRC mux */ - outl((wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000, + + /* save the current state for later */ + x = wait_src_ready(s); + + /* enable SRC state data in SRC mux */ + outl(( x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000, s->io+ES1371_REG_SRCONV); - /* wait for a SAFE time to write addr/data and then do it, dammit */ - for (t = 0; t < 0x1000; t++) - if ((inl(s->io+ES1371_REG_SRCONV) & 0x00070000) == 0x00010000) - break; + + /* wait for not busy (state 0) first to avoid + transition states */ + for (t=0; t<POLL_COUNT; t++){ + if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 ) + break; + udelay(1); + } + + /* wait for a SAFE time to write addr/data and then do it, dammit */ + for (t=0; t<POLL_COUNT; t++){ + if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) + break; + udelay(1); + } + outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC); + /* restore SRC reg */ wait_src_ready(s); outl(x, s->io+ES1371_REG_SRCONV); @@ -604,28 +716,50 @@ static unsigned rdcodec(struct es1371_state *s, unsigned addr) unsigned long flags; unsigned t, x; + /* wait for WIP to go away */ for (t = 0; t < 0x1000; t++) if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) break; spin_lock_irqsave(&s->lock, flags); + /* save the current state for later */ - x = inl(s->io+ES1371_REG_SRCONV); + x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)); + /* enable SRC state data in SRC mux */ - outl((wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000, - s->io+ES1371_REG_SRCONV); - /* wait for a SAFE time to write addr/data and then do it, dammit */ - for (t = 0; t < 0x1000; t++) - if ((inl(s->io+ES1371_REG_SRCONV) & 0x00070000) == 0x00010000) - break; + outl( x | 0x00010000, + s->io+ES1371_REG_SRCONV); + + /* wait for not busy (state 0) first to avoid + transition states */ + for (t=0; t<POLL_COUNT; t++){ + if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 ) + break; + udelay(1); + } + + /* wait for a SAFE time to write addr/data and then do it, dammit */ + for (t=0; t<POLL_COUNT; t++){ + if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) + break; + udelay(1); + } + outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC); /* restore SRC reg */ wait_src_ready(s); outl(x, s->io+ES1371_REG_SRCONV); spin_unlock_irqrestore(&s->lock, flags); - /* now wait for the stinkin' data (RDY) */ + + /* wait for WIP again */ for (t = 0; t < 0x1000; t++) + if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) + break; + + /* now wait for the stinkin' data (RDY) */ + for (t = 0; t < POLL_COUNT; t++) if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY) break; + return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); } @@ -986,6 +1120,21 @@ static const char invalid_magic[] = KERN_CRIT "es1371: invalid magic value\n"; /* --------------------------------------------------------------------- */ +/* + * AC97 Mixer Register to Connections mapping of the Concert 97 board + * + * AC97_MASTER_VOL_STEREO Line Out + * AC97_MASTER_VOL_MONO TAD Output + * AC97_PCBEEP_VOL none + * AC97_PHONE_VOL TAD Input (mono) + * AC97_MIC_VOL MIC Input (mono) + * AC97_LINEIN_VOL Line Input (stereo) + * AC97_CD_VOL CD Input (stereo) + * AC97_VIDEO_VOL none + * AC97_AUX_VOL Aux Input (stereo) + * AC97_PCMOUT_VOL Wave Output (stereo) + */ + #define AC97_PESSIMISTIC /* @@ -1011,25 +1160,25 @@ static const unsigned int recsrc[8] = static const unsigned char volreg[SOUND_MIXER_NRDEVICES] = { /* 5 bit stereo */ - [SOUND_MIXER_LINE] = 0x10, - [SOUND_MIXER_CD] = 0x12, - [SOUND_MIXER_VIDEO] = 0x14, - [SOUND_MIXER_LINE1] = 0x16, - [SOUND_MIXER_PCM] = 0x18, + [SOUND_MIXER_LINE] = AC97_LINEIN_VOL, + [SOUND_MIXER_CD] = AC97_CD_VOL, + [SOUND_MIXER_VIDEO] = AC97_VIDEO_VOL, + [SOUND_MIXER_LINE1] = AC97_AUX_VOL, + [SOUND_MIXER_PCM] = AC97_PCMOUT_VOL, /* 6 bit stereo */ - [SOUND_MIXER_VOLUME] = 0x02, - [SOUND_MIXER_PHONEOUT] = 0x04, + [SOUND_MIXER_VOLUME] = AC97_MASTER_VOL_STEREO, + [SOUND_MIXER_PHONEOUT] = AC97_HEADPHONE_VOL, /* 6 bit mono */ - [SOUND_MIXER_OGAIN] = 0x06, - [SOUND_MIXER_PHONEIN] = 0x0c, + [SOUND_MIXER_OGAIN] = AC97_MASTER_VOL_MONO, + [SOUND_MIXER_PHONEIN] = AC97_PHONE_VOL, /* 4 bit mono but shifted by 1 */ - [SOUND_MIXER_SPEAKER] = 0x08, + [SOUND_MIXER_SPEAKER] = AC97_MASTER_TONE, /* 6 bit mono + preamp */ - [SOUND_MIXER_MIC] = 0x0e, + [SOUND_MIXER_MIC] = AC97_MIC_VOL, /* 4 bit stereo */ - [SOUND_MIXER_RECLEV] = 0x1c, + [SOUND_MIXER_RECLEV] = AC97_RECORD_GAIN, /* 4 bit mono */ - [SOUND_MIXER_IGAIN] = 0x1e + [SOUND_MIXER_IGAIN] = AC97_RECORD_GAIN_MIC }; #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS @@ -1042,8 +1191,8 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) switch (ch) { case SOUND_MIXER_MIC: - j = rdcodec(s, 0x0e); - if (j & 0x8000) + j = rdcodec(s, AC97_MIC_VOL); + if (j & AC97_MUTE) return put_user(0, (int *)arg); #ifdef AC97_PESSIMISTIC return put_user(0x4949 - 0x202 * (j & 0x1f) + ((j & 0x40) ? 0x1b1b : 0), (int *)arg); @@ -1054,7 +1203,7 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) case SOUND_MIXER_OGAIN: case SOUND_MIXER_PHONEIN: j = rdcodec(s, volreg[ch]); - if (j & 0x8000) + if (j & AC97_MUTE) return put_user(0, (int *)arg); #ifdef AC97_PESSIMISTIC return put_user(0x6464 - 0x303 * (j & 0x1f), (int *)arg); @@ -1068,7 +1217,7 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) /* fall through */ case SOUND_MIXER_VOLUME: j = rdcodec(s, volreg[ch]); - if (j & 0x8000) + if (j & AC97_MUTE) return put_user(0, (int *)arg); #ifdef AC97_PESSIMISTIC return put_user(0x6464 - (swab(j) & 0x1f1f) * 3, (int *)arg); @@ -1077,8 +1226,8 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) #endif /* AC97_PESSIMISTIC */ case SOUND_MIXER_SPEAKER: - j = rdcodec(s, 0x0a); - if (j & 0x8000) + j = rdcodec(s, AC97_PCBEEP_VOL); + if (j & AC97_MUTE return put_user(0, (int *)arg); return put_user(0x6464 - ((j >> 1) & 0xf) * 0x606, (int *)arg); @@ -1088,7 +1237,7 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) case SOUND_MIXER_LINE1: case SOUND_MIXER_PCM: j = rdcodec(s, volreg[ch]); - if (j & 0x8000) + if (j & AC97_MUTE) return put_user(0, (int *)arg); return put_user(0x6464 - (swab(j) & 0x1f1f) * 3, (int *)arg); @@ -1096,23 +1245,23 @@ static int mixer_rdch(struct es1371_state *s, unsigned int ch, int *arg) case SOUND_MIXER_TREBLE: if (!(s->mix.codec_id & CODEC_ID_BASSTREBLE)) return -EINVAL; - j = rdcodec(s, 0x08); + j = rdcodec(s, AC97_MASTER_TONE); if (ch == SOUND_MIXER_BASS) j >>= 8; return put_user((((j & 15) * 100) / 15) * 0x101, (int *)arg); /* SOUND_MIXER_RECLEV and SOUND_MIXER_IGAIN specify gain */ case SOUND_MIXER_RECLEV: - j = rdcodec(s, 0x1c); - if (j & 0x8000) + j = rdcodec(s, AC97_RECORD_GAIN); + if (j & AC97_MUTE) return put_user(0, (int *)arg); return put_user((swab(j) & 0xf0f) * 6 + 0xa0a, (int *)arg); case SOUND_MIXER_IGAIN: if (!(s->mix.codec_id & CODEC_ID_DEDICATEDMIC)) return -EINVAL; - j = rdcodec(s, 0x1e); - if (j & 0x8000) + j = rdcodec(s, AC97_RECORD_GAIN_MIC); + if (j & AC97_MUTE) return put_user(0, (int *)arg); return put_user((j & 0xf) * 0x606 + 0xa0a, (int *)arg); @@ -1167,7 +1316,7 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) case SOUND_MIXER_LINE1: case SOUND_MIXER_PCM: if (l1 < 7 && r1 < 7) { - wrcodec(s, volreg[ch], 0x8000); + wrcodec(s, volreg[ch], AC97_MUTE); return 0; } if (l1 < 7) @@ -1184,7 +1333,7 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) case SOUND_MIXER_VOLUME: #ifdef AC97_PESSIMISTIC if (l1 < 7 && r1 < 7) { - wrcodec(s, volreg[ch], 0x8000); + wrcodec(s, volreg[ch], AC97_MUTE); return 0; } if (l1 < 7) @@ -1195,7 +1344,7 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) return 0; #else /* AC97_PESSIMISTIC */ if (l1 < 4 && r1 < 4) { - wrcodec(s, volreg[ch], 0x8000); + wrcodec(s, volreg[ch], AC97_MUTE); return 0; } if (l1 < 4) @@ -1209,21 +1358,21 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) case SOUND_MIXER_OGAIN: case SOUND_MIXER_PHONEIN: #ifdef AC97_PESSIMISTIC - wrcodec(s, volreg[ch], (l1 < 7) ? 0x8000 : (100 - l1) / 3); + wrcodec(s, volreg[ch], (l1 < 7) ? AC97_MUTE : (100 - l1) / 3); return 0; #else /* AC97_PESSIMISTIC */ - wrcodec(s, volreg[ch], (l1 < 4) ? 0x8000 : (2 * (100 - l1) / 3)); + wrcodec(s, volreg[ch], (l1 < 4) ? AC97_MUTE : (2 * (100 - l1) / 3)); return 0; #endif /* AC97_PESSIMISTIC */ case SOUND_MIXER_SPEAKER: - wrcodec(s, 0x0a, (l1 < 10) ? 0x8000 : ((100 - l1) / 6) << 1); + wrcodec(s, AC97_PCBEEP_VOL, (l1 < 10) ? AC97_MUTE : ((100 - l1) / 6) << 1); return 0; case SOUND_MIXER_MIC: #ifdef AC97_PESSIMISTIC if (l1 < 11) { - wrcodec(s, 0x0e, 0x8000); + wrcodec(s, AC97_MIC_VOL, AC97_MUTE); return 0; } i = 0; @@ -1233,11 +1382,11 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) } if (l1 < 11) l1 = 11; - wrcodec(s, 0x0e, ((73 - l1) / 2) | i); + wrcodec(s, AC97_MIC_VOL, ((73 - l1) / 2) | i); return 0; #else /* AC97_PESSIMISTIC */ if (l1 < 9) { - wrcodec(s, 0x0e, 0x8000); + wrcodec(s, AC97_MIC_VOL, AC97_MUTE); return 0; } i = 0; @@ -1247,37 +1396,37 @@ static int mixer_wrch(struct es1371_state *s, unsigned int ch, int val) } if (l1 < 9) l1 = 9; - wrcodec(s, 0x0e, (((87 - l1) * 4) / 5) | i); + wrcodec(s, AC97_MIC_VOL, (((87 - l1) * 4) / 5) | i); return 0; #endif /* AC97_PESSIMISTIC */ case SOUND_MIXER_BASS: val = ((l1 * 15) / 100) & 0xf; - wrcodec(s, 0x08, (rdcodec(s, 0x08) & 0x00ff) | (val << 8)); + wrcodec(s, AC97_MASTER_TONE, (rdcodec(s, AC97_MASTER_TONE) & 0x00ff) | (val << 8)); return 0; case SOUND_MIXER_TREBLE: val = ((l1 * 15) / 100) & 0xf; - wrcodec(s, 0x08, (rdcodec(s, 0x08) & 0xff00) | val); + wrcodec(s, AC97_MASTER_TONE, (rdcodec(s, AC97_MASTER_TONE) & 0xff00) | val); return 0; /* SOUND_MIXER_RECLEV and SOUND_MIXER_IGAIN specify gain */ case SOUND_MIXER_RECLEV: if (l1 < 10 || r1 < 10) { - wrcodec(s, 0x1c, 0x8000); + wrcodec(s, AC97_RECORD_GAIN, AC97_MUTE); return 0; } if (l1 < 10) l1 = 10; if (r1 < 10) r1 = 10; - wrcodec(s, 0x1c, (((l1 - 10) / 6) << 8) | ((r1 - 10) / 6)); + wrcodec(s, AC97_RECORD_GAIN, (((l1 - 10) / 6) << 8) | ((r1 - 10) / 6)); return 0; case SOUND_MIXER_IGAIN: if (!(s->mix.codec_id & CODEC_ID_DEDICATEDMIC)) return -EINVAL; - wrcodec(s, 0x1e, (l1 < 10) ? 0x8000 : ((l1 - 10) / 6) & 0xf); + wrcodec(s, AC97_RECORD_GAIN_MIC, (l1 < 10) ? AC97_MUTE : ((l1 - 10) / 6) & 0xf); return 0; default: @@ -1295,8 +1444,8 @@ static int mixer_ioctl(struct es1371_state *s, unsigned int cmd, unsigned long a return -EINVAL; get_user_ret(val, (int *)arg, -EFAULT); if (val & 1) - wrcodec(s, 0x22, ((val << 3) & 0xf00) | ((val >> 1) & 0xf)); - val = rdcodec(s, 0x22); + wrcodec(s, AC97_3D_CONTROL, ((val << 3) & 0xf00) | ((val >> 1) & 0xf)); + val = rdcodec(s, AC97_3D_CONTROL); return put_user(((val & 0xf) << 1) | ((val & 0xf00) >> 3), (int *)arg); } if (cmd == SOUND_MIXER_INFO) { @@ -1323,7 +1472,7 @@ static int mixer_ioctl(struct es1371_state *s, unsigned int cmd, unsigned long a if (_IOC_DIR(cmd) == _IOC_READ) { switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ - return put_user(recsrc[rdcodec(s, 0x1a) & 7], (int *)arg); + return put_user(recsrc[rdcodec(s, AC97_RECORD_SELECT) & 7], (int *)arg); case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ return put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_VIDEO | @@ -1370,10 +1519,10 @@ static int mixer_ioctl(struct es1371_state *s, unsigned int cmd, unsigned long a if (i == 0) return 0; /*val = mixer_recmask(s);*/ else if (i > 1) - val &= ~recsrc[rdcodec(s, 0x1a) & 7]; + val &= ~recsrc[rdcodec(s, AC97_RECORD_SELECT) & 7]; for (i = 0; i < 8; i++) { if (val & recsrc[i]) { - wrcodec(s, 0x1a, 0x101 * i); + wrcodec(s, AC97_RECORD_SELECT, 0x101 * i); return 0; } } @@ -1463,7 +1612,8 @@ static int drain_dac1(struct es1371_state *s, int nonblock) if (s->dma_dac1.mapped || !s->dma_dac1.ready) return 0; - current->state = TASK_INTERRUPTIBLE; + + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac1.wait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1475,16 +1625,16 @@ static int drain_dac1(struct es1371_state *s, int nonblock) break; if (nonblock) { remove_wait_queue(&s->dma_dac1.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } - tmo = (count * HZ) / s->dac1rate; + tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) - printk(KERN_DEBUG "es1371: dma timed out??\n"); + if (!schedule_timeout(tmo + 1)) + printk(KERN_DEBUG "es1371: dac1 dma timed out??\n"); } remove_wait_queue(&s->dma_dac1.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; return 0; @@ -1498,7 +1648,8 @@ static int drain_dac2(struct es1371_state *s, int nonblock) if (s->dma_dac2.mapped || !s->dma_dac2.ready) return 0; - current->state = TASK_INTERRUPTIBLE; + + __set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&s->dma_dac2.wait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1510,16 +1661,16 @@ static int drain_dac2(struct es1371_state *s, int nonblock) break; if (nonblock) { remove_wait_queue(&s->dma_dac2.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } - tmo = (count * HZ) / s->dac2rate; + tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) - printk(KERN_DEBUG "es1371: dma timed out??\n"); + if (!schedule_timeout(tmo + 1)) + printk(KERN_DEBUG "es1371: dac2 dma timed out??\n"); } remove_wait_queue(&s->dma_dac2.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; return 0; @@ -1743,6 +1894,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd if (file->f_mode & FMODE_WRITE) { stop_dac2(s); s->dma_dac2.ready = 0; + printk (KERN_DEBUG "es137x: setting DAC2 rate: %d\n", val); set_dac2_rate(s, val); } } @@ -2460,6 +2612,7 @@ static /*const*/ struct file_operations es1371_dac_fops = { static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -2470,7 +2623,10 @@ static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, l return -ESPIPE; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.iwait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.ird; @@ -2481,15 +2637,25 @@ static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, l if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.iwait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIINBUF; spin_lock_irqsave(&s->lock, flags); s->midi.ird = ptr; @@ -2498,13 +2664,17 @@ static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, l count -= cnt; buffer += cnt; ret += cnt; + break; } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); return ret; } static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -2515,7 +2685,10 @@ static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t c return -ESPIPE; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.owait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.owr; @@ -2528,15 +2701,25 @@ static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t c if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.owait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIOUTBUF; spin_lock_irqsave(&s->lock, flags); s->midi.owr = ptr; @@ -2549,6 +2732,8 @@ static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t c es1371_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); return ret; } @@ -2634,7 +2819,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -2646,7 +2831,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) break; if (file->f_flags & O_NONBLOCK) { remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } tmo = (count * HZ) / 3100; @@ -2654,7 +2839,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) printk(KERN_DEBUG "es1371: midi timed out??\n"); } remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); } down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); @@ -2690,16 +2875,57 @@ static /*const*/ struct file_operations es1371_midi_fops = { /* --------------------------------------------------------------------- */ +/* + * for debugging purposes, we'll create a proc device that dumps the + * CODEC chipstate + */ + +#ifdef ES1371_DEBUG +static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data) +{ + int len = 0; + + struct es1371_state *s = devs; + int cnt; + + /* print out header */ + len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n"); + + /* print out CODEC state */ + len += sprintf (buf + len, "AC97 CODEC state\n"); + + for (cnt=0; cnt <= 0x7e; cnt = cnt +2) + len+= sprintf (buf + len, "reg:0x%02x val:0x%04x\n", cnt, rdcodec(s , cnt)); + + if (fpos >=len){ + *start = buf; + *eof =1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof =1; + return len; + +} +#endif /* ES1371_DEBUG */ + +/* --------------------------------------------------------------------- */ + /* maximum number of devices */ #define NR_DEVICE 5 -#if CONFIG_SOUND_ES1371_JOYPORT_BOOT -static int joystick[NR_DEVICE] = { -CONFIG_SOUND_ES1371_GAMEPORT -, 0, }; -#else static int joystick[NR_DEVICE] = { 0, }; -#endif +static int spdif[NR_DEVICE] = { 0, }; + +MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)"); +MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); /* --------------------------------------------------------------------- */ @@ -2722,24 +2948,25 @@ static struct initvol { { SOUND_MIXER_WRITE_IGAIN, 0x4040 } }; -#ifdef MODULE -int __init init_module(void) -#else -int __init init_es1371(void) -#endif +#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \ + ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) +#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) + + +static int __init init_es1371(void) { struct es1371_state *s; struct pci_dev *pcidev = NULL; mm_segment_t fs; int i, val, val2, index = 0; + unsigned cssr; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1371: version v0.12 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1371: version v0.17 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) { - if (pcidev->base_address[0] == 0 || - (pcidev->base_address[0] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + if (!RSRCISIOREGION(pcidev, 0)) continue; if (pcidev->irq == 0) continue; @@ -2755,9 +2982,11 @@ int __init init_es1371(void) init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); s->magic = ES1371_MAGIC; - s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + s->io = RSRCADDRESS(pcidev, 0); s->irq = pcidev->irq; + pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev); if (check_region(s->io, ES1371_EXTENT)) { printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); goto err_region; @@ -2767,8 +2996,8 @@ int __init init_es1371(void) printk(KERN_ERR "es1371: irq %u in use\n", s->irq); goto err_irq; } - printk(KERN_INFO "es1371: found adapter at io %#lx irq %u\n" - KERN_INFO "es1371: features: joystick 0x%x\n", s->io, s->irq, joystick[index]); + printk(KERN_INFO "es1371: found es1371 rev %d at io %#lx irq %u\n" + KERN_INFO "es1371: features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[index]); /* register devices */ if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0) goto err_dev1; @@ -2778,6 +3007,13 @@ int __init init_es1371(void) goto err_dev3; if ((s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)) < 0) goto err_dev4; +#ifdef ES1371_DEBUG + /* intialize the debug proc device */ + s->ps = create_proc_entry("es1371", S_IFREG | S_IRUGO, NULL); + if (s->ps) + s->ps->read_proc = proc_es1371_dump; +#endif /* ES1371_DEBUG */ + /* initialize codec registers */ s->ctrl = 0; if ((joystick[index] & ~0x18) == 0x200) { @@ -2788,44 +3024,33 @@ int __init init_es1371(void) } } s->sctrl = 0; + cssr = 0; + /* check to see if s/pdif mode is being requested */ + if (spdif[index]) { + if (s->rev >= 4) { + printk(KERN_INFO "es1371: enabling S/PDIF output\n"); + cssr |= STAT_EN_SPDIF; + s->ctrl |= CTRL_SPDIFEN_B; + } else { + printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", s->rev); + } + } /* initialize the chips */ outl(s->ctrl, s->io+ES1371_REG_CONTROL); outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); outl(0, s->io+ES1371_REG_LEGACY); + pci_set_master(pcidev); /* enable bus mastering */ /* AC97 warm reset to start the bitclk */ outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL); udelay(2); outl(s->ctrl, s->io+ES1371_REG_CONTROL); /* init the sample rate converter */ - outl(SRC_DIS, s->io + ES1371_REG_SRCONV); - for (val = 0; val < 0x80; val++) - src_write(s, val, 0); - src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4); - src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10); - src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4); - src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10); - src_write(s, SRCREG_VOL_ADC, 1 << 12); - src_write(s, SRCREG_VOL_ADC+1, 1 << 12); - src_write(s, SRCREG_VOL_DAC1, 1 << 12); - src_write(s, SRCREG_VOL_DAC1+1, 1 << 12); - src_write(s, SRCREG_VOL_DAC2, 1 << 12); - src_write(s, SRCREG_VOL_DAC2+1, 1 << 12); - set_adc_rate(s, 22050); - set_dac1_rate(s, 22050); - set_dac2_rate(s, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - */ - wait_src_ready(s); - outl(0, s->io+ES1371_REG_SRCONV); + src_init(s); /* codec init */ - wrcodec(s, 0x00, 0); /* reset codec */ - s->mix.codec_id = rdcodec(s, 0x00); /* get codec ID */ - val = rdcodec(s, 0x7c); - val2 = rdcodec(s, 0x7e); + wrcodec(s, AC97_RESET, 0); /* reset codec */ + s->mix.codec_id = rdcodec(s, AC97_RESET); /* get codec ID */ + val = rdcodec(s, AC97_VENDOR_ID1); + val2 = rdcodec(s, AC97_VENDOR_ID2); printk(KERN_INFO "es1371: codec vendor %c%c%c revision %d\n", (val >> 8) & 0xff, val & 0xff, (val2 >> 8) & 0xff, val2 & 0xff); printk(KERN_INFO "es1371: codec features"); @@ -2852,6 +3077,7 @@ int __init init_es1371(void) printk("%s\n", (s->mix.codec_id & 0x3ff) ? "" : " none"); val = (s->mix.codec_id >> CODEC_ID_SESHIFT) & CODEC_ID_SEMASK; printk(KERN_INFO "es1371: stereo enhancement: %s\n", (val <= 20) ? stereo_enhancement[val] : "unknown"); + fs = get_fs(); set_fs(KERNEL_DS); val = SOUND_MASK_LINE; @@ -2861,6 +3087,8 @@ int __init init_es1371(void) mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); } set_fs(fs); + /* turn on S/PDIF output driver if requested */ + outl(cssr, s->io+ES1371_REG_STATUS); /* queue it for later freeing */ s->next = devs; devs = s; @@ -2886,22 +3114,16 @@ int __init init_es1371(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); - -void cleanup_module(void) +static void __exit cleanup_es1371(void) { struct es1371_state *s; while ((s = devs)) { devs = devs->next; +#ifdef ES1371_DEBUG + if (s->ps) + remove_proc_entry("es1371", NULL); +#endif /* ES1371_DEBUG */ outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */ outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */ synchronize_irq(); @@ -2916,4 +3138,27 @@ void cleanup_module(void) printk(KERN_INFO "es1371: unloading\n"); } +module_init(init_es1371); +module_exit(cleanup_es1371); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE + +/* format is: es1371=[joystick] */ + +static int __init es1371_setup(char *str) +{ + static unsigned __initlocaldata nr_dev = 0; + + if (nr_dev >= NR_DEVICE) + return 0; + if (get_option(&str, &joystick[nr_dev]) == 2) + (void)get_option(&str, &spdif[nr_dev]); + nr_dev++; + return 1; +} + +__setup("es1371=", es1371_setup); + #endif /* MODULE */ diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c new file mode 100644 index 000000000..90ccaf342 --- /dev/null +++ b/drivers/sound/esssolo1.c @@ -0,0 +1,2241 @@ +/*****************************************************************************/ + +/* + * esssolo1.c -- ESS Technology Solo1 (ES1946) audio driver. + * + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module command line parameters: + * none so far + * + * Supported devices: + * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible + * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible + * /dev/midi simple MIDI UART interface, no ioctl + * + * Revision history + * 10.11.98 0.1 Initial release (without any hardware) + * 22.03.99 0.2 cinfo.blocks should be reset after GETxPTR ioctl. + * reported by Johan Maes <joma@telindus.be> + * return EAGAIN instead of EBUSY when O_NONBLOCK + * read/write cannot be executed + * 07.04.99 0.3 implemented the following ioctl's: SOUND_PCM_READ_RATE, + * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; + * Alpha fixes reported by Peter Jones <pjones@redhat.com> + * 15.06.99 0.4 Fix bad allocation bug. + * Thanks to Deti Fliegl <fliegl@in.tum.de> + * 28.06.99 0.5 Add pci_set_master + * 12.08.99 0.6 Fix MIDI UART crashing the driver + * Changed mixer semantics from OSS documented + * behaviour to OSS "code behaviour". + * Recording might actually work now. + * The real DDMA controller address register is at PCI config + * 0x60, while the register at 0x18 is used as a placeholder + * register for BIOS address allocation. This register + * is supposed to be copied into 0x60, according + * to the Solo1 datasheet. When I do that, I can access + * the DDMA registers except the mask bit, which + * is stuck at 1. When I copy the contents of 0x18 +0x10 + * to the DDMA base register, everything seems to work. + * The fun part is that the Windows Solo1 driver doesn't + * seem to do these tricks. + * Bugs remaining: plops and clicks when starting/stopping playback + * 31.08.99 0.7 add spin_lock_init + * replaced current->state = x with set_current_state(x) + * 03.09.99 0.8 change read semantics for MIDI to match + * OSS more closely; remove possible wakeup race + * + */ + +/*****************************************************************************/ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/sound.h> +#include <linux/malloc.h> +#include <linux/soundcard.h> +#include <linux/pci.h> +#include <linux/bitops.h> +#include <asm/io.h> +#include <asm/dma.h> +#include <linux/init.h> +#include <linux/poll.h> +#include <linux/spinlock.h> +#include <asm/uaccess.h> +#include <asm/hardirq.h> + +#include "dm.h" + +/* --------------------------------------------------------------------- */ + +#undef OSS_DOCUMENTED_MIXER_SEMANTICS + +/* --------------------------------------------------------------------- */ + +#ifndef PCI_VENDOR_ID_ESS +#define PCI_VENDOR_ID_ESS 0x125d +#endif +#ifndef PCI_DEVICE_ID_ESS_SOLO1 +#define PCI_DEVICE_ID_ESS_SOLO1 0x1969 +#endif + +#define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1) + +#define DDMABASE_OFFSET 0x10 /* chip bug workaround kludge */ +#define DDMABASE_EXTENT 16 + +#define IOBASE_EXTENT 16 +#define SBBASE_EXTENT 16 +#define VCBASE_EXTENT (DDMABASE_EXTENT+DDMABASE_OFFSET) +#define MPUBASE_EXTENT 4 +#define GPBASE_EXTENT 4 + + +/* MIDI buffer sizes */ + +#define MIDIINBUF 256 +#define MIDIOUTBUF 256 + +#define FMODE_MIDI_SHIFT 3 +#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) +#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) + +#define FMODE_DMFM 0x10 + +/* --------------------------------------------------------------------- */ + +struct solo1_state { + /* magic */ + unsigned int magic; + + /* we keep the cards in a linked list */ + struct solo1_state *next; + + /* pcidev is needed to turn off the DDMA controller at driver shutdown */ + struct pci_dev *pcidev; + + /* soundcore stuff */ + int dev_audio; + int dev_mixer; + int dev_midi; + int dev_dmfm; + + /* hardware resources */ + unsigned long iobase, sbbase, vcbase, ddmabase, mpubase, gpbase; /* long for SPARC */ + unsigned int irq; + + /* mixer registers */ + struct { + unsigned short vol[10]; + unsigned int recsrc; + unsigned int modcnt; + unsigned short micpreamp; + } mix; + + /* wave stuff */ + unsigned fmt; + unsigned channels; + unsigned rate; + unsigned char clkdiv; + unsigned ena; + + spinlock_t lock; + struct semaphore open_sem; + mode_t open_mode; + wait_queue_head_t open_wait; + + struct dmabuf { + void *rawbuf; + unsigned buforder; + unsigned numfrag; + unsigned fragshift; + unsigned hwptr, swptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + wait_queue_head_t wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + unsigned fragsamples; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned endcleared:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; + } dma_dac, dma_adc; + + /* midi stuff */ + struct { + unsigned ird, iwr, icnt; + unsigned ord, owr, ocnt; + wait_queue_head_t iwait; + wait_queue_head_t owait; + struct timer_list timer; + unsigned char ibuf[MIDIINBUF]; + unsigned char obuf[MIDIOUTBUF]; + } midi; +}; + +/* --------------------------------------------------------------------- */ + +struct solo1_state *devs = NULL; + +/* --------------------------------------------------------------------- */ + +extern inline void write_seq(struct solo1_state *s, unsigned char data) +{ + int i; + unsigned long flags; + + /* the __cli stunt is to send the data within the command window */ + for (i = 0; i < 0xffff; i++) { + __save_flags(flags); + __cli(); + if (!(inb(s->sbbase+0xc) & 0x80)) { + outb(data, s->sbbase+0xc); + __restore_flags(flags); + return; + } + __restore_flags(flags); + } +} + +extern inline int read_seq(struct solo1_state *s, unsigned char *data) +{ + int i; + + if (!data) + return 0; + for (i = 0; i < 0xffff; i++) + if (inb(s->sbbase+0xe) & 0x80) { + *data = inb(s->sbbase+0xa); + return 1; + } + return 0; +} + +static int inline reset_ctrl(struct solo1_state *s) +{ + int i; + + outb(3, s->sbbase+6); /* clear sequencer and FIFO */ + udelay(10); + outb(0, s->sbbase+6); + for (i = 0; i < 0xffff; i++) + if (inb(s->sbbase+0xe) & 0x80) + if (inb(s->sbbase+0xa) == 0xaa) { + write_seq(s, 0xc6); /* enter enhanced mode */ + return 1; + } + return 0; +} + +static void write_ctrl(struct solo1_state *s, unsigned char reg, unsigned char data) +{ + write_seq(s, reg); + write_seq(s, data); +} + +static unsigned char read_ctrl(struct solo1_state *s, unsigned char reg) +{ + unsigned char r; + + write_seq(s, 0xc0); + write_seq(s, reg); + read_seq(s, &r); + return r; +} + +static void write_mixer(struct solo1_state *s, unsigned char reg, unsigned char data) +{ + outb(reg, s->sbbase+4); + outb(data, s->sbbase+5); +} + +static unsigned char read_mixer(struct solo1_state *s, unsigned char reg) +{ + outb(reg, s->sbbase+4); + return inb(s->sbbase+5); +} + +/* --------------------------------------------------------------------- */ + +extern inline unsigned ld2(unsigned int x) +{ + unsigned r = 0; + + if (x >= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + +/* --------------------------------------------------------------------- */ + +extern inline void stop_dac(struct solo1_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->ena &= ~FMODE_WRITE; + write_mixer(s, 0x78, 0x10); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_dac(struct solo1_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { + s->ena |= FMODE_WRITE; + write_mixer(s, 0x78, 0x12); + udelay(10); + write_mixer(s, 0x78, 0x13); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +extern inline void stop_adc(struct solo1_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->ena &= ~FMODE_READ; + write_ctrl(s, 0xb8, 0xe); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_adc(struct solo1_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) + && s->dma_adc.ready) { + s->ena |= FMODE_READ; + write_ctrl(s, 0xb8, 0xf); +#if 0 + printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf); + printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", + inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8)); +#endif + outb(0, s->ddmabase+0xd); /* master reset */ + outb(1, s->ddmabase+0xf); /* mask */ + outb(0x54/*0x14*/, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ + outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase); + outw(s->dma_adc.dmasize-1, s->ddmabase+4); + outb(0, s->ddmabase+0xf); + } + spin_unlock_irqrestore(&s->lock, flags); +#if 0 + printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x SBstat: 0x%02x\n" + KERN_DEBUG "solo1: DMA: stat: 0x%02x cnt: 0x%04x mask: 0x%02x\n", + read_ctrl(s, 0xb8), inb(s->sbbase+0xc), + inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf)); + printk(KERN_DEBUG "solo1: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" + KERN_DEBUG "solo1: B1: 0x%02x B2: 0x%02x B4: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n", + read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), + read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb4), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), + read_ctrl(s, 0xb9)); +#endif +} + +/* --------------------------------------------------------------------- */ + +#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) +#define DMABUF_MINORDER 1 + +extern inline void dealloc_dmabuf(struct dmabuf *db) +{ + unsigned long map, mapend; + + if (db->rawbuf) { + /* undo marking the pages as reserved */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + clear_bit(PG_reserved, &mem_map[map].flags); + free_pages((unsigned long)db->rawbuf, db->buforder); + } + db->rawbuf = NULL; + db->mapped = db->ready = 0; +} + +static int prog_dmabuf(struct solo1_state *s, struct dmabuf *db, int gfp_mask) +{ + int order; + unsigned bytespersec; + unsigned bufs, sample_shift = 0; + unsigned long map, mapend; + + db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; + if (!db->rawbuf) { + db->ready = db->mapped = 0; + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) + if ((db->rawbuf = (void *)__get_free_pages(gfp_mask, order))) + break; + if (!db->rawbuf) + return -ENOMEM; + db->buforder = order; + /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + set_bit(PG_reserved, &mem_map[map].flags); + } + if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) + sample_shift++; + if (s->channels > 1) + sample_shift++; + bytespersec = s->rate << sample_shift; + bufs = PAGE_SIZE << db->buforder; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytespersec) + db->fragshift = ld2(bytespersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + db->fragshift = ld2(bytespersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->fragsamples = db->fragsize >> sample_shift; + db->dmasize = db->numfrag << db->fragshift; + return 0; +} + +extern inline int prog_dmabuf_adc(struct solo1_state *s) +{ + unsigned long va; + int c; + + stop_adc(s); + if ((c = prog_dmabuf(s, &s->dma_adc, GFP_KERNEL | GFP_DMA))) + return c; + va = virt_to_bus(s->dma_adc.rawbuf); + if ((va & ~((1<<24)-1))) + panic("solo1: buffer above 16M boundary"); + outb(0, s->ddmabase+0xd); /* clear */ + outb(1, s->ddmabase+0xf); /* mask */ + /*outb(0, s->ddmabase+8);*/ /* enable (enable is active low!) */ + outb(0x54, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ + outl(va, s->ddmabase); + outw(s->dma_adc.dmasize-1, s->ddmabase+4); + c = - s->dma_adc.fragsamples; + write_ctrl(s, 0xa4, c); + write_ctrl(s, 0xa5, c >> 8); + outb(0, s->ddmabase+0xf); + s->dma_adc.ready = 1; + return 0; +} + +extern inline int prog_dmabuf_dac(struct solo1_state *s) +{ + unsigned long va; + int c; + + stop_dac(s); + if ((c = prog_dmabuf(s, &s->dma_dac, GFP_KERNEL))) + return c; + memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80, s->dma_dac.dmasize); /* almost correct for U16 */ + va = virt_to_bus(s->dma_dac.rawbuf); + if ((va ^ (va + s->dma_dac.dmasize - 1)) & ~((1<<20)-1)) + panic("solo1: buffer crosses 1M boundary"); + outl(va, s->iobase); + /* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */ + outw(s->dma_dac.dmasize, s->iobase+4); + c = - s->dma_dac.fragsamples; + write_mixer(s, 0x74, c); + write_mixer(s, 0x76, c >> 8); + outb(0xa, s->iobase+6); + s->dma_dac.ready = 1; + return 0; +} + +extern inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c) +{ + if (bptr + len > bsize) { + unsigned x = bsize - bptr; + memset(((char *)buf) + bptr, c, x); + bptr = 0; + len -= x; + } + memset(((char *)buf) + bptr, c, len); +} + +/* call with spinlock held! */ + +static void solo1_update_ptr(struct solo1_state *s) +{ + int diff; + unsigned hwptr; + + /* update ADC pointer */ + if (s->ena & FMODE_READ) { + hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize; + diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; + s->dma_adc.hwptr = hwptr; + s->dma_adc.total_bytes += diff; + s->dma_adc.count += diff; +#if 0 + printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n", + s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count); +#endif + if (s->dma_adc.mapped) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + } else { + if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { + s->ena &= ~FMODE_READ; + write_ctrl(s, 0xb8, 0xe); + s->dma_adc.error++; + } + if (s->dma_adc.count > 0) + wake_up(&s->dma_adc.wait); + } + } + /* update DAC pointer */ + if (s->ena & FMODE_WRITE) { + hwptr = (s->dma_dac.dmasize - inw(s->iobase+4)) % s->dma_dac.dmasize; + diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; + s->dma_dac.hwptr = hwptr; + s->dma_dac.total_bytes += diff; +#if 0 + printk(KERN_DEBUG "solo1: wr: hwptr %u swptr %u dmasize %u count %u\n", + s->dma_dac.hwptr, s->dma_dac.swptr, s->dma_dac.dmasize, s->dma_dac.count); +#endif + if (s->dma_dac.mapped) { + s->dma_dac.count += diff; + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + wake_up(&s->dma_dac.wait); + } else { + s->dma_dac.count -= diff; + if (s->dma_dac.count <= 0) { + s->ena &= ~FMODE_WRITE; + write_mixer(s, 0x78, 0x12); + s->dma_dac.error++; + } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { + clear_advance(s->dma_dac.rawbuf, s->dma_dac.dmasize, s->dma_dac.swptr, + s->dma_dac.fragsize, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80); + s->dma_dac.endcleared = 1; + } + if (s->dma_dac.count < (signed)s->dma_dac.dmasize) + wake_up(&s->dma_dac.wait); + } + } +} + +/* --------------------------------------------------------------------- */ + +static void prog_codec(struct solo1_state *s) +{ + unsigned long flags; + int fdiv, filter; + unsigned char c; + + reset_ctrl(s); + write_seq(s, 0xd3); + /* program sampling rates */ + filter = s->rate * 9 / 20; /* Set filter roll-off to 90% of rate/2 */ + fdiv = 256 - 7160000 / (filter * 82); + spin_lock_irqsave(&s->lock, flags); + write_ctrl(s, 0xa1, s->clkdiv); + write_ctrl(s, 0xa2, fdiv); + write_mixer(s, 0x70, s->clkdiv); + write_mixer(s, 0x72, fdiv); + /* program ADC parameters */ + write_ctrl(s, 0xb8, 0xe); + write_ctrl(s, 0xb9, /*0x1*/0); + write_ctrl(s, 0xa8, (s->channels > 1) ? 0x11 : 0x12); + c = 0xd0; + if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) + c |= 0x04; + if (s->fmt & (AFMT_S16_LE | AFMT_S8)) + c |= 0x20; + if (s->channels > 1) + c ^= 0x48; + write_ctrl(s, 0xb7, (c & 0x70) | 1); + write_ctrl(s, 0xb7, c); + write_ctrl(s, 0xb1, 0x50); + write_ctrl(s, 0xb2, 0x50); + /* program DAC parameters */ + c = 0x40; + if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) + c |= 1; + if (s->fmt & (AFMT_S16_LE | AFMT_S8)) + c |= 4; + if (s->channels > 1) + c |= 2; + write_mixer(s, 0x7a, c); + write_mixer(s, 0x78, 0x10); + s->ena = 0; + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +static const char invalid_magic[] = KERN_CRIT "solo1: invalid magic value\n"; + +#define VALIDATE_STATE(s) \ +({ \ + if (!(s) || (s)->magic != SOLO1_MAGIC) { \ + printk(invalid_magic); \ + return -ENXIO; \ + } \ +}) + +/* --------------------------------------------------------------------- */ + +static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long arg) +{ + static const unsigned int mixer_src[8] = { + SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME, + SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0 + }; + static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = { + [SOUND_MIXER_PCM] = 1, /* voice */ + [SOUND_MIXER_SYNTH] = 2, /* FM */ + [SOUND_MIXER_CD] = 3, /* CD */ + [SOUND_MIXER_LINE] = 4, /* Line */ + [SOUND_MIXER_LINE1] = 5, /* AUX */ + [SOUND_MIXER_MIC] = 6, /* Mic */ + [SOUND_MIXER_LINE2] = 7, /* Mono in */ + [SOUND_MIXER_SPEAKER] = 8, /* Speaker */ + [SOUND_MIXER_RECLEV] = 9, /* Recording level */ + [SOUND_MIXER_VOLUME] = 10 /* Master Volume */ + }; + static const unsigned char mixreg[] = { + 0x7c, /* voice */ + 0x36, /* FM */ + 0x38, /* CD */ + 0x3e, /* Line */ + 0x3a, /* AUX */ + 0x1a, /* Mic */ + 0x6d /* Mono in */ + }; + unsigned char l, r, rl, rr, vidx; + int i, val; + + VALIDATE_STATE(s); + + if (cmd == SOUND_MIXER_PRIVATE1) { + /* enable/disable/query mixer preamp */ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != -1) { + val = val ? 0xff : 0xf7; + write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val); + } + val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0; + return put_user(val, (int *)arg); + } + if (cmd == SOUND_MIXER_PRIVATE2) { + /* enable/disable/query spatializer */ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != -1) { + val &= 0x3f; + write_mixer(s, 0x52, val); + write_mixer(s, 0x50, val ? 0x08 : 0); + } + return put_user(read_mixer(s, 0x52), (int *)arg); + } + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "Solo1", sizeof(info.id)); + strncpy(info.name, "ESS Solo1", sizeof(info.name)); + info.modify_counter = s->mix.modcnt; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "Solo1", sizeof(info.id)); + strncpy(info.name, "ESS Solo1", sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) + return -EINVAL; + if (_IOC_DIR(cmd) == _IOC_READ) { + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + return put_user(mixer_src[read_mixer(s, 0x1c) & 7], (int *)arg); + + case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ + return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD | + SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC | + SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV | + SOUND_MASK_SPEAKER, (int *)arg); + + case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ + return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, (int *)arg); + + case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ + return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD | + SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC | + SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, (int *)arg); + + case SOUND_MIXER_CAPS: + return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) + return -EINVAL; + return put_user(s->mix.vol[vidx-1], (int *)arg); + } + } + if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) + return -EINVAL; + s->mix.modcnt++; + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ +#if 0 + { + static const unsigned char regs[] = { + 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c + }; + int i; + + for (i = 0; i < sizeof(regs); i++) + printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n", + regs[i], read_mixer(s, regs[i])); + printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n", + 0xb4, read_ctrl(s, 0xb4)); + } +#endif + get_user_ret(val, (int *)arg, -EFAULT); + i = hweight32(val); + if (i == 0) + return 0; + else if (i > 1) + val &= ~mixer_src[read_mixer(s, 0x1c) & 7]; + for (i = 0; i < 8; i++) { + if (mixer_src[i] & val) + break; + } + if (i > 7) + return 0; + write_mixer(s, 0x1c, i); + return 0; + + case SOUND_MIXER_VOLUME: + get_user_ret(val, (int *)arg, -EFAULT); + l = val & 0xff; + if (l > 100) + l = 100; + r = (val >> 8) & 0xff; + if (r > 100) + r = 100; + if (l < 6) { + rl = 0x40; + l = 0; + } else { + rl = (l * 2 - 11) / 3; + l = (rl * 3 + 11) / 2; + } + if (r < 6) { + rr = 0x40; + r = 0; + } else { + rr = (r * 2 - 11) / 3; + r = (rr * 3 + 11) / 2; + } + write_mixer(s, 0x60, rl); + write_mixer(s, 0x62, rr); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[9] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[9] = val; +#endif + return put_user(s->mix.vol[9], (int *)arg); + + case SOUND_MIXER_SPEAKER: + get_user_ret(val, (int *)arg, -EFAULT); + l = val & 0xff; + if (l > 100) + l = 100; + else if (l < 2) + l = 2; + rl = (l - 2) / 14; + l = rl * 14 + 2; + write_mixer(s, 0x3c, rl); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[7] = l * 0x101; +#else + s->mix.vol[7] = val; +#endif + return put_user(s->mix.vol[7], (int *)arg); + + case SOUND_MIXER_RECLEV: + get_user_ret(val, (int *)arg, -EFAULT); + l = (val << 1) & 0x1fe; + if (l > 200) + l = 200; + else if (l < 5) + l = 5; + r = (val >> 7) & 0x1fe; + if (r > 200) + r = 200; + else if (r < 5) + r = 5; + rl = (l - 5) / 13; + rr = (r - 5) / 13; + r = (rl * 13 + 5) / 2; + l = (rr * 13 + 5) / 2; + write_ctrl(s, 0xb4, (rl << 4) | rr); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[8] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[8] = val; +#endif + return put_user(s->mix.vol[8], (int *)arg); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + l = (val << 1) & 0x1fe; + if (l > 200) + l = 200; + else if (l < 5) + l = 5; + r = (val >> 7) & 0x1fe; + if (r > 200) + r = 200; + else if (r < 5) + r = 5; + rl = (l - 5) / 13; + rr = (r - 5) / 13; + r = (rl * 13 + 5) / 2; + l = (rr * 13 + 5) / 2; + write_mixer(s, mixreg[vidx-1], (rl << 4) | rr); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[vidx-1] = val; +#endif + return put_user(s->mix.vol[vidx-1], (int *)arg); + } +} + +/* --------------------------------------------------------------------- */ + +static loff_t solo1_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* --------------------------------------------------------------------- */ + +static int solo1_open_mixdev(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct solo1_state *s = devs; + + while (s && s->dev_mixer != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + MOD_INC_USE_COUNT; + return 0; +} + +static int solo1_release_mixdev(struct inode *inode, struct file *file) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + + VALIDATE_STATE(s); + MOD_DEC_USE_COUNT; + return 0; +} + +static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + return mixer_ioctl((struct solo1_state *)file->private_data, cmd, arg); +} + +static /*const*/ struct file_operations solo1_mixer_fops = { + &solo1_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &solo1_ioctl_mixdev, + NULL, /* mmap */ + &solo1_open_mixdev, + NULL, /* flush */ + &solo1_release_mixdev, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int drain_dac(struct solo1_state *s, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count; + unsigned tmo; + + if (s->dma_dac.mapped) + return 0; + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&s->dma_dac.wait, &wait); + for (;;) { + spin_lock_irqsave(&s->lock, flags); + count = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&s->dma_dac.wait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate; + if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) + tmo >>= 1; + if (s->channels > 1) + tmo >>= 1; + if (!schedule_timeout(tmo + 1)) + printk(KERN_DEBUG "solo1: dma timed out??\n"); + } + remove_wait_queue(&s->dma_dac.wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static ssize_t solo1_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_adc.mapped) + return -ENXIO; + if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) + return ret; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + ret = 0; + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + swptr = s->dma_adc.swptr; + cnt = s->dma_adc.dmasize-swptr; + if (s->dma_adc.count < cnt) + cnt = s->dma_adc.count; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; +#ifdef DEBUGREC + printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x cnt: %u\n", + read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt); +#endif + if (cnt <= 0) { + start_adc(s); +#ifdef DEBUGREC + printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" + KERN_DEBUG "solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" + KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" + KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", + read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), + read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), + inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); +#endif + if (inb(s->ddmabase+15) & 1) + printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->dma_adc.wait); +#ifdef DEBUGREC + printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" + KERN_DEBUG "solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" + KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" + KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", + read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), + read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), + inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); +#endif + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) + return ret ? ret : -EFAULT; + swptr = (swptr + cnt) % s->dma_adc.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_adc.swptr = swptr; + s->dma_adc.count -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_adc(s); +#ifdef DEBUGREC + printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x\n", + read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc)); +#endif + } + return ret; +} + +static ssize_t solo1_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_dac.mapped) + return -ENXIO; + if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; +#if 0 + printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x 71: 0x%02x 72: 0x%02x 74: 0x%02x 76: 0x%02x 78: 0x%02x 7A: 0x%02x\n" + KERN_DEBUG "solo1_write: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x SBstat: 0x%02x\n", + read_mixer(s, 0x70), read_mixer(s, 0x71), read_mixer(s, 0x72), read_mixer(s, 0x74), read_mixer(s, 0x76), + read_mixer(s, 0x78), read_mixer(s, 0x7a), inl(s->iobase), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc)); + printk(KERN_DEBUG "solo1_write: reg 78: 0x%02x reg 7A: 0x%02x DMAcnt: 0x%04x DMAstat: 0x%02x SBstat: 0x%02x\n", + read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc)); +#endif + ret = 0; + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + if (s->dma_dac.count < 0) { + s->dma_dac.count = 0; + s->dma_dac.swptr = s->dma_dac.hwptr; + } + swptr = s->dma_dac.swptr; + cnt = s->dma_dac.dmasize-swptr; + if (s->dma_dac.count + cnt > s->dma_dac.dmasize) + cnt = s->dma_dac.dmasize - s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + start_dac(s); + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->dma_dac.wait); + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) + return ret ? ret : -EFAULT; + swptr = (swptr + cnt) % s->dma_dac.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_dac.swptr = swptr; + s->dma_dac.count += cnt; + s->dma_dac.endcleared = 0; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_dac(s); + } + return ret; +} + +static unsigned int solo1_poll(struct file *file, struct poll_table_struct *wait) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + poll_wait(file, &s->dma_dac.wait, wait); + if (file->f_mode & FMODE_READ) + poll_wait(file, &s->dma_adc.wait, wait); + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + if (file->f_mode & FMODE_READ) { + if (s->dma_adc.mapped) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; + } else { + if (s->dma_adc.count > 0) + mask |= POLLIN | POLLRDNORM; + } + } + if (file->f_mode & FMODE_WRITE) { + if (s->dma_dac.mapped) { + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)s->dma_dac.dmasize > s->dma_dac.count) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + + +static int solo1_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + struct dmabuf *db; + int ret; + unsigned long size; + + VALIDATE_STATE(s); + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf_dac(s)) != 0) + return ret; + db = &s->dma_dac; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf_adc(s)) != 0) + return ret; + db = &s->dma_adc; + } else + return -EINVAL; + if (vma->vm_offset != 0) + return -EINVAL; + size = vma->vm_end - vma->vm_start; + if (size > (PAGE_SIZE << db->buforder)) + return -EINVAL; + if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) + return -EAGAIN; + db->mapped = 1; + return 0; +} + +static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int val, mapped, ret; + int div1, div2; + unsigned rate1, rate2; + + VALIDATE_STATE(s); + mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || + ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + synchronize_irq(); + s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + synchronize_irq(); + s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; + } + prog_codec(s); + return 0; + + case SNDCTL_DSP_SPEED: + get_user_ret(val, (int *)arg, -EFAULT); + if (val >= 0) { + stop_adc(s); + stop_dac(s); + s->dma_adc.ready = s->dma_dac.ready = 0; + /* program sampling rates */ + if (val > 48000) + val = 48000; + if (val < 6300) + val = 6300; + div1 = (768000 + val / 2) / val; + rate1 = (768000 + div1 / 2) / div1; + div1 = -div1; + div2 = (793800 + val / 2) / val; + rate2 = (793800 + div2 / 2) / div2; + div2 = (-div2) & 0x7f; + if (abs(val - rate2) < abs(val - rate1)) { + rate1 = rate2; + div1 = div2; + } + s->rate = rate1; + s->clkdiv = div1; + prog_codec(s); + } + return put_user(s->rate, (int *)arg); + + case SNDCTL_DSP_STEREO: + get_user_ret(val, (int *)arg, -EFAULT); + stop_adc(s); + stop_dac(s); + s->dma_adc.ready = s->dma_dac.ready = 0; + /* program channels */ + s->channels = val ? 2 : 1; + prog_codec(s); + return 0; + + case SNDCTL_DSP_CHANNELS: + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 0) { + stop_adc(s); + stop_dac(s); + s->dma_adc.ready = s->dma_dac.ready = 0; + /* program channels */ + s->channels = val ? 2 : 1; + prog_codec(s); + } + return put_user(s->channels, (int *)arg); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != AFMT_QUERY) { + stop_adc(s); + stop_dac(s); + s->dma_adc.ready = s->dma_dac.ready = 0; + /* program format */ + if (val != AFMT_S16_LE && val != AFMT_U16_LE && + val != AFMT_S8 && val != AFMT_U8) + val = AFMT_U8; + s->fmt = val; + prog_codec(s); + } + return put_user(s->fmt, (int *)arg); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & s->ena & FMODE_READ) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & s->ena & FMODE_WRITE) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) + return ret; + start_adc(s); + if (inb(s->ddmabase+15) & 1) + printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); + } else + stop_adc(s); + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s))) + return ret; + start_dac(s); + } else + stop_dac(s); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!(s->ena & FMODE_WRITE) && (val = prog_dmabuf_dac(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + abinfo.fragsize = s->dma_dac.fragsize; + abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; + abinfo.fragstotal = s->dma_dac.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!(s->ena & FMODE_READ) && (val = prog_dmabuf_adc(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + abinfo.fragsize = s->dma_adc.fragsize; + abinfo.bytes = s->dma_adc.count; + abinfo.fragstotal = s->dma_adc.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + val = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + return put_user(val, (int *)arg); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + cinfo.bytes = s->dma_adc.total_bytes; + cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; + cinfo.ptr = s->dma_adc.hwptr; + if (s->dma_adc.mapped) + s->dma_adc.count &= s->dma_adc.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + solo1_update_ptr(s); + cinfo.bytes = s->dma_dac.total_bytes; + cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; + cinfo.ptr = s->dma_dac.hwptr; + if (s->dma_dac.mapped) + s->dma_dac.count &= s->dma_dac.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf_dac(s))) + return val; + return put_user(s->dma_dac.fragsize, (int *)arg); + } + if ((val = prog_dmabuf_adc(s))) + return val; + return put_user(s->dma_adc.fragsize, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + s->dma_adc.ossfragshift = val & 0xffff; + s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_adc.ossfragshift < 4) + s->dma_adc.ossfragshift = 4; + if (s->dma_adc.ossfragshift > 15) + s->dma_adc.ossfragshift = 15; + if (s->dma_adc.ossmaxfrags < 4) + s->dma_adc.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + s->dma_dac.ossfragshift = val & 0xffff; + s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_dac.ossfragshift < 4) + s->dma_dac.ossfragshift = 4; + if (s->dma_dac.ossfragshift > 15) + s->dma_dac.ossfragshift = 15; + if (s->dma_dac.ossmaxfrags < 4) + s->dma_dac.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || + (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + s->dma_adc.subdivision = val; + if (file->f_mode & FMODE_WRITE) + s->dma_dac.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user(s->rate, (int *)arg); + + case SOUND_PCM_READ_CHANNELS: + return put_user(s->channels, (int *)arg); + + case SOUND_PCM_READ_BITS: + return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + + } + return mixer_ioctl(s, cmd, arg); +} + +static int solo1_release(struct inode *inode, struct file *file) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + drain_dac(s, file->f_flags & O_NONBLOCK); + down(&s->open_sem); + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + outb(0, s->iobase+6); /* disable DMA */ + dealloc_dmabuf(&s->dma_dac); + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + outb(1, s->ddmabase+0xf); /* mask DMA channel */ + outb(0, s->ddmabase+0xd); /* DMA master clear */ + dealloc_dmabuf(&s->dma_adc); + } + s->open_mode &= ~(FMODE_READ | FMODE_WRITE); + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static int solo1_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct solo1_state *s = devs; + + while (s && ((s->dev_audio ^ minor) & ~0xf)) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & (FMODE_READ | FMODE_WRITE)) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + s->fmt = AFMT_U8; + s->channels = 1; + s->rate = 8000; + s->clkdiv = 96 | 0x80; + s->ena = 0; + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; + s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; + s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + up(&s->open_sem); + MOD_INC_USE_COUNT; + if (prog_dmabuf_dac(s) || prog_dmabuf_adc(s)) { + solo1_release(inode, file); + return -ENOMEM; + } + prog_codec(s); + return 0; +} + +static /*const*/ struct file_operations solo1_audio_fops = { + &solo1_llseek, + &solo1_read, + &solo1_write, + NULL, /* readdir */ + &solo1_poll, + &solo1_ioctl, + &solo1_mmap, + &solo1_open, + NULL, /* flush */ + &solo1_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +/* hold spinlock for the following! */ +static void solo1_handle_midi(struct solo1_state *s) +{ + unsigned char ch; + int wake; + + if (!(s->mpubase)) + return; + wake = 0; + while (!(inb(s->mpubase+1) & 0x80)) { + ch = inb(s->mpubase); + if (s->midi.icnt < MIDIINBUF) { + s->midi.ibuf[s->midi.iwr] = ch; + s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; + s->midi.icnt++; + } + wake = 1; + } + if (wake) + wake_up(&s->midi.iwait); + wake = 0; + while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) { + outb(s->midi.obuf[s->midi.ord], s->mpubase); + s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; + s->midi.ocnt--; + if (s->midi.ocnt < MIDIOUTBUF-16) + wake = 1; + } + if (wake) + wake_up(&s->midi.owait); +} + +static void solo1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct solo1_state *s = (struct solo1_state *)dev_id; + unsigned int intsrc; + + /* fastpath out, to ease interrupt sharing */ + intsrc = inb(s->iobase+7); /* get interrupt source(s) */ + if (!intsrc) + return; + (void)inb(s->sbbase+0xe); /* clear interrupt */ + spin_lock(&s->lock); + /* clear audio interrupts first */ + if (intsrc & 0x20) + write_mixer(s, 0x7a, read_mixer(s, 0x7a) & 0x7f); + solo1_update_ptr(s); + solo1_handle_midi(s); + spin_unlock(&s->lock); +} + +static void solo1_midi_timer(unsigned long data) +{ + struct solo1_state *s = (struct solo1_state *)data; + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + solo1_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + s->midi.timer.expires = jiffies+1; + add_timer(&s->midi.timer); +} + +/* --------------------------------------------------------------------- */ + +static ssize_t solo1_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + if (count == 0) + return 0; + ret = 0; + add_wait_queue(&s->midi.iwait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.ird; + cnt = MIDIINBUF - ptr; + if (s->midi.icnt < cnt) + cnt = s->midi.icnt; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } + ptr = (ptr + cnt) % MIDIINBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.ird = ptr; + s->midi.icnt -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); + return ret; +} + +static ssize_t solo1_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + if (count == 0) + return 0; + ret = 0; + add_wait_queue(&s->midi.owait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.owr; + cnt = MIDIOUTBUF - ptr; + if (s->midi.ocnt + cnt > MIDIOUTBUF) + cnt = MIDIOUTBUF - s->midi.ocnt; + if (cnt <= 0) + solo1_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } + ptr = (ptr + cnt) % MIDIOUTBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.owr = ptr; + s->midi.ocnt += cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + spin_lock_irqsave(&s->lock, flags); + solo1_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); + return ret; +} + +static unsigned int solo1_midi_poll(struct file *file, struct poll_table_struct *wait) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_flags & FMODE_WRITE) + poll_wait(file, &s->midi.owait, wait); + if (file->f_flags & FMODE_READ) + poll_wait(file, &s->midi.iwait, wait); + spin_lock_irqsave(&s->lock, flags); + if (file->f_flags & FMODE_READ) { + if (s->midi.icnt > 0) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_flags & FMODE_WRITE) { + if (s->midi.ocnt < MIDIOUTBUF) + mask |= POLLOUT | POLLWRNORM; + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int solo1_midi_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct solo1_state *s = devs; + unsigned long flags; + + while (s && s->dev_midi != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + outb(0xff, s->mpubase+1); /* reset command */ + outb(0x3f, s->mpubase+1); /* uart command */ + if (!(inb(s->mpubase+1) & 0x80)) + inb(s->mpubase); + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + outb(0xb0, s->iobase + 7); /* enable A1, A2, MPU irq's */ + init_timer(&s->midi.timer); + s->midi.timer.expires = jiffies+1; + s->midi.timer.data = (unsigned long)s; + s->midi.timer.function = solo1_midi_timer; + add_timer(&s->midi.timer); + } + if (file->f_mode & FMODE_READ) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + } + if (file->f_mode & FMODE_WRITE) { + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + } + spin_unlock_irqrestore(&s->lock, flags); + s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int solo1_midi_release(struct inode *inode, struct file *file) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + unsigned count, tmo; + + VALIDATE_STATE(s); + + if (file->f_mode & FMODE_WRITE) { + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&s->midi.owait, &wait); + for (;;) { + spin_lock_irqsave(&s->lock, flags); + count = s->midi.ocnt; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (file->f_flags & O_NONBLOCK) { + remove_wait_queue(&s->midi.owait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = (count * HZ) / 3100; + if (!schedule_timeout(tmo ? : 1) && tmo) + printk(KERN_DEBUG "solo1: midi timed out??\n"); + } + remove_wait_queue(&s->midi.owait, &wait); + set_current_state(TASK_RUNNING); + } + down(&s->open_sem); + s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + outb(0x30, s->iobase + 7); /* enable A1, A2 irq's */ + del_timer(&s->midi.timer); + } + spin_unlock_irqrestore(&s->lock, flags); + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations solo1_midi_fops = { + &solo1_llseek, + &solo1_midi_read, + &solo1_midi_write, + NULL, /* readdir */ + &solo1_midi_poll, + NULL, /* ioctl */ + NULL, /* mmap */ + &solo1_midi_open, + NULL, /* flush */ + &solo1_midi_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + static const unsigned char op_offset[18] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 + }; + struct solo1_state *s = (struct solo1_state *)file->private_data; + struct dm_fm_voice v; + struct dm_fm_note n; + struct dm_fm_params p; + unsigned int io; + unsigned int regb; + + switch (cmd) { + case FM_IOCTL_RESET: + for (regb = 0xb0; regb < 0xb9; regb++) { + outb(regb, s->sbbase); + outb(0, s->sbbase+1); + outb(regb, s->sbbase+2); + outb(0, s->sbbase+3); + } + return 0; + + case FM_IOCTL_PLAY_NOTE: + if (copy_from_user(&n, (void *)arg, sizeof(n))) + return -EFAULT; + if (n.voice >= 18) + return -EINVAL; + if (n.voice >= 9) { + regb = n.voice - 9; + io = s->sbbase+2; + } else { + regb = n.voice; + io = s->sbbase; + } + outb(0xa0 + regb, io); + outb(n.fnum & 0xff, io+1); + outb(0xb0 + regb, io); + outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1); + return 0; + + case FM_IOCTL_SET_VOICE: + if (copy_from_user(&v, (void *)arg, sizeof(v))) + return -EFAULT; + if (v.voice >= 18) + return -EINVAL; + regb = op_offset[v.voice]; + io = s->sbbase + ((v.op & 1) << 1); + outb(0x20 + regb, io); + outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | + ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1); + outb(0x40 + regb, io); + outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1); + outb(0x60 + regb, io); + outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1); + outb(0x80 + regb, io); + outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1); + outb(0xe0 + regb, io); + outb(v.waveform & 0x7, io+1); + if (n.voice >= 9) { + regb = n.voice - 9; + io = s->sbbase+2; + } else { + regb = n.voice; + io = s->sbbase; + } + outb(0xc0 + regb, io); + outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) | + (v.connection & 1), io+1); + return 0; + + case FM_IOCTL_SET_PARAMS: + if (copy_from_user(&p, (void *)arg, sizeof(p))) + return -EFAULT; + outb(0x08, s->sbbase); + outb((p.kbd_split & 1) << 6, s->sbbase+1); + outb(0xbd, s->sbbase); + outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) | + ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->sbbase+1); + return 0; + + case FM_IOCTL_SET_OPL: + outb(4, s->sbbase+2); + outb(arg, s->sbbase+3); + return 0; + + case FM_IOCTL_SET_MODE: + outb(5, s->sbbase+2); + outb(arg & 1, s->sbbase+3); + return 0; + + default: + return -EINVAL; + } +} + +static int solo1_dmfm_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct solo1_state *s = devs; + + while (s && s->dev_dmfm != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & FMODE_DMFM) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + /* init the stuff */ + outb(1, s->sbbase); + outb(0x20, s->sbbase+1); /* enable waveforms */ + outb(4, s->sbbase+2); + outb(0, s->sbbase+3); /* no 4op enabled */ + outb(5, s->sbbase+2); + outb(1, s->sbbase+3); /* enable OPL3 */ + s->open_mode |= FMODE_DMFM; + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int solo1_dmfm_release(struct inode *inode, struct file *file) +{ + struct solo1_state *s = (struct solo1_state *)file->private_data; + unsigned int regb; + + VALIDATE_STATE(s); + down(&s->open_sem); + s->open_mode &= ~FMODE_DMFM; + for (regb = 0xb0; regb < 0xb9; regb++) { + outb(regb, s->sbbase); + outb(0, s->sbbase+1); + outb(regb, s->sbbase+2); + outb(0, s->sbbase+3); + } + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations solo1_dmfm_fops = { + &solo1_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &solo1_dmfm_ioctl, + NULL, /* mmap */ + &solo1_dmfm_open, + NULL, /* flush */ + &solo1_dmfm_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +/* maximum number of devices */ +#define NR_DEVICE 5 + +/* --------------------------------------------------------------------- */ + +static struct initvol { + int mixch; + int vol; +} initvol[] __initdata = { + { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, + { SOUND_MIXER_WRITE_PCM, 0x4040 }, + { SOUND_MIXER_WRITE_SYNTH, 0x4040 }, + { SOUND_MIXER_WRITE_CD, 0x4040 }, + { SOUND_MIXER_WRITE_LINE, 0x4040 }, + { SOUND_MIXER_WRITE_LINE1, 0x4040 }, + { SOUND_MIXER_WRITE_LINE2, 0x4040 }, + { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, + { SOUND_MIXER_WRITE_SPEAKER, 0x4040 }, + { SOUND_MIXER_WRITE_MIC, 0x4040 } +}; + +#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \ + ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) +#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) + + +static int __init init_solo1(void) +{ + struct solo1_state *s; + struct pci_dev *pcidev = NULL; + mm_segment_t fs; + int i, val, index = 0; + + if (!pci_present()) /* No PCI bus in this machine! */ + return -ENODEV; + printk(KERN_INFO "solo1: version v0.7 time " __TIME__ " " __DATE__ "\n"); + while (index < NR_DEVICE && + (pcidev = pci_find_device(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, pcidev))) { + if (!RSRCISIOREGION(pcidev, 0) || + !RSRCISIOREGION(pcidev, 1) || + !RSRCISIOREGION(pcidev, 2) || + !RSRCISIOREGION(pcidev, 3)) + continue; + if (pcidev->irq == 0) + continue; + if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) { + printk(KERN_WARNING "solo1: out of memory\n"); + continue; + } + memset(s, 0, sizeof(struct solo1_state)); + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); + s->magic = SOLO1_MAGIC; + s->pcidev = pcidev; + s->iobase = RSRCADDRESS(pcidev, 0); + s->sbbase = RSRCADDRESS(pcidev, 1); + s->vcbase = RSRCADDRESS(pcidev, 2); + s->ddmabase = s->vcbase + DDMABASE_OFFSET; + s->mpubase = RSRCADDRESS(pcidev, 3); + s->gpbase = RSRCADDRESS(pcidev, 4); + s->irq = pcidev->irq; + if (check_region(s->iobase, IOBASE_EXTENT) || + check_region(s->sbbase+4, SBBASE_EXTENT-4) || + check_region(s->ddmabase, DDMABASE_EXTENT) || + check_region(s->mpubase, MPUBASE_EXTENT)) { + printk(KERN_ERR "solo1: io ports in use\n"); + goto err_region; + } + request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1"); + request_region(s->sbbase+4, SBBASE_EXTENT-4, "ESS Solo1"); /* allow OPL3 synth module */ + request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1"); + request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1"); + if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) { + printk(KERN_ERR "solo1: irq %u in use\n", s->irq); + goto err_irq; + } + /* initialize DDMA base address */ + printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase); + pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1); + /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */ + pci_write_config_dword(pcidev, 0x50, 0); + /* disable legacy audio address decode */ + pci_write_config_word(pcidev, 0x40, 0x907f); + + printk(KERN_INFO "solo1: joystick port at %#lx\n", s->gpbase+1); + + /* register devices */ + if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) + goto err_dev1; + if ((s->dev_mixer = register_sound_mixer(&solo1_mixer_fops, -1)) < 0) + goto err_dev2; + if ((s->dev_midi = register_sound_midi(&solo1_midi_fops, -1)) < 0) + goto err_dev3; + if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0) + goto err_dev4; + /* initialize the chips */ + outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */ + + /* initialize mixer regs */ + write_mixer(s, 0x7f, 0); /* disable music digital recording */ + write_mixer(s, 0x7d, 0x0c); /* enable mic preamp, MONO_OUT is 2nd DAC right channel */ + write_mixer(s, 0x64, 0x45); /* volume control */ + write_mixer(s, 0x48, 0x10); /* enable music DAC/ES6xx interface */ + write_mixer(s, 0x50, 0); /* disable spatializer */ + write_mixer(s, 0x52, 0); + write_mixer(s, 0x14, 0); /* DAC1 minimum volume */ + write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */ + outb(0, s->ddmabase+0xd); /* DMA master clear */ + outb(1, s->ddmabase+0xf); /* mask channel */ + /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */ + + pci_set_master(pcidev); /* enable bus mastering */ + + fs = get_fs(); + set_fs(KERNEL_DS); + val = SOUND_MASK_LINE; + mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); + for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { + val = initvol[i].vol; + mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); + } + val = 1; /* enable mic preamp */ + mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val); + set_fs(fs); + /* queue it for later freeing */ + s->next = devs; + devs = s; + index++; + continue; + + err_dev4: + unregister_sound_dsp(s->dev_midi); + err_dev3: + unregister_sound_mixer(s->dev_mixer); + err_dev2: + unregister_sound_dsp(s->dev_audio); + err_dev1: + printk(KERN_ERR "solo1: cannot register misc device\n"); + free_irq(s->irq, s); + err_irq: + release_region(s->iobase, IOBASE_EXTENT); + release_region(s->sbbase+4, SBBASE_EXTENT-4); + release_region(s->ddmabase, DDMABASE_EXTENT); + release_region(s->mpubase, MPUBASE_EXTENT); + err_region: + kfree_s(s, sizeof(struct solo1_state)); + } + if (!devs) + return -ENODEV; + return 0; +} + +/* --------------------------------------------------------------------- */ + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ESS Solo1 Driver"); + +static void __exit cleanup_solo1(void) +{ + struct solo1_state *s; + + while ((s = devs)) { + devs = devs->next; + /* stop DMA controller */ + outb(0, s->iobase+6); + outb(0, s->ddmabase+0xd); /* DMA master clear */ + outb(3, s->sbbase+6); /* reset sequencer and FIFO */ + synchronize_irq(); + pci_write_config_word(s->pcidev, 0x60, 0); /* turn off DDMA controller address space */ + free_irq(s->irq, s); + release_region(s->iobase, IOBASE_EXTENT); + release_region(s->sbbase+4, SBBASE_EXTENT-4); + release_region(s->ddmabase, DDMABASE_EXTENT); + release_region(s->mpubase, MPUBASE_EXTENT); + unregister_sound_dsp(s->dev_audio); + unregister_sound_mixer(s->dev_mixer); + unregister_sound_midi(s->dev_midi); + unregister_sound_special(s->dev_dmfm); + kfree_s(s, sizeof(struct solo1_state)); + } + printk(KERN_INFO "solo1: unloading\n"); +} + +/* --------------------------------------------------------------------- */ + +module_init(init_solo1); +module_exit(cleanup_solo1); + diff --git a/drivers/sound/lowlevel/Config.in b/drivers/sound/lowlevel/Config.in index 09a9f7249..30f1713f9 100644 --- a/drivers/sound/lowlevel/Config.in +++ b/drivers/sound/lowlevel/Config.in @@ -1,57 +1,57 @@ -dep_tristate 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND_OSS +dep_tristate ' ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND_OSS -dep_tristate 'AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND_OSS +dep_tristate ' AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND_OSS if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then - dep_tristate 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS - if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then - hex ' I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 - fi + dep_tristate ' Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS + if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 + hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 + fi - if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then - comment 'SC-6600 Audio Cards have no jumper switches at all' - bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 - if [ "$CONFIG_SC6600" = "y" ]; then - comment 'SC-6600 specific configuration' - bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY - int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' CONFIG_SC6600_CDROM 4 - hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 - fi + if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then + comment 'SC-6600 Audio Cards have no jumper switches at all' + bool ' SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 + if [ "$CONFIG_SC6600" = "y" ]; then + comment 'SC-6600 specific configuration' + bool ' Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY + int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' CONFIG_SC6600_CDROM 4 + hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 + fi - if [ "$CONFIG_SOUND_SB" = "y" -o "$CONFIG_SOUND_SB" = "m" ]; then - if [ "$CONFIG_AEDSP16_MSS" != "y" ]; then - bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO - if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then - comment 'Audio Excel DSP 16 [Sound Blaster Pro]' - hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5 - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0 - fi + if [ "$CONFIG_SOUND_SB" = "y" -o "$CONFIG_SOUND_SB" = "m" ]; then + if [ "$CONFIG_AEDSP16_MSS" != "y" ]; then + bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO + if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then + comment 'Audio Excel DSP 16 [Sound Blaster Pro]' + hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0 fi - fi + fi + fi - if [ "$CONFIG_SOUND_MSS" = "y" -o "$CONFIG_SOUND_MSS" = "m" ]; then - if [ "$CONFIG_AEDSP16_SBPRO" != "y" ]; then - bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS - if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then - comment 'Audio Excel DSP 16 [Microsoft Sound System]' - hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5 - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1 - fi + if [ "$CONFIG_SOUND_MSS" = "y" -o "$CONFIG_SOUND_MSS" = "m" ]; then + if [ "$CONFIG_AEDSP16_SBPRO" != "y" ]; then + bool ' Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS + if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then + comment 'Audio Excel DSP 16 [Microsoft Sound System]' + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1 fi - fi + fi + fi - if [ "$CONFIG_SOUND_MPU401" = "y" -o "$CONFIG_SOUND_MPU401" = "m" ]; then - bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 - if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then - comment 'Audio Excel DSP 16 [MPU-401]' - if [ "$CONFIG_AEDSP16_SBPRO" != "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then - hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - fi - int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ + if [ "$CONFIG_SOUND_MPU401" = "y" -o "$CONFIG_SOUND_MPU401" = "m" ]; then + bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 + if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then + comment 'Audio Excel DSP 16 [MPU-401]' + if [ "$CONFIG_AEDSP16_SBPRO" != "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 fi - fi - fi + int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ + fi + fi + fi fi diff --git a/drivers/sound/lowlevel/aci.c b/drivers/sound/lowlevel/aci.c index c65fbd84a..fc71be47d 100644 --- a/drivers/sound/lowlevel/aci.c +++ b/drivers/sound/lowlevel/aci.c @@ -676,4 +676,4 @@ void cleanup_module(void) { } #endif /* MODULE */ - +
\ No newline at end of file diff --git a/drivers/sound/lowlevel/awe_compat-fbsd.h b/drivers/sound/lowlevel/awe_compat-fbsd.h deleted file mode 100644 index 9b00cc6f9..000000000 --- a/drivers/sound/lowlevel/awe_compat-fbsd.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * sound/awe_compat.h - * - * Compat defines for the AWE32/SB32/AWE64 wave table synth driver. - * version 0.4.3; Nov. 1, 1998 - * - * Copyright (C) 1996-1998 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef AWE_COMPAT_H_DEF -#define AWE_COMPAT_H_DEF - -/*================================================================ - * version check - *================================================================*/ - -/* FreeBSD version check */ -#include <i386/isa/sound/awe_config.h> - -#define AWE_OBSOLETE_VOXWARE -#if __FreeBSD__ >= 2 -# include <osreldate.h> -# if __FreeBSD_version >= 300000 -# undef AWE_OBSOLETE_VOXWARE -# endif -#endif -#ifdef __linux__ -# include <linux/config.h> -#endif - - -/*================================================================ - * INCLUDE OTHER HEADER FILES - *================================================================*/ - -/* reading configuration of sound driver */ - -#ifdef AWE_OBSOLETE_VOXWARE - -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32) -#define CONFIG_AWE32_SYNTH -#endif - -#else /* AWE_OBSOLETE_VOXWARE */ - -#ifdef HAS_LOWLEVEL_H -#include "lowlevel.h" -#endif - -#include <i386/isa/sound/sound_config.h> -#if defined(CONFIGURE_SOUNDCARD) && defined(CONFIG_AWE32) -# define CONFIG_AWE32_SYNTH -#endif - -#endif /* AWE_OBSOLETE_VOXWARE */ - - -/*================================================================ - * include AWE header files - *================================================================*/ - -#if defined(CONFIG_AWE32_SYNTH) || defined(CONFIG_AWE32_SYNTH_MODULE) - -#include <i386/isa/sound/awe_hw.h> -#include <i386/isa/sound/awe_version.h> -#include <i386/isa/sound/awe_voice.h> - -#ifdef AWE_HAS_GUS_COMPATIBILITY -/* include finetune table */ -#ifdef AWE_OBSOLETE_VOXWARE -# define SEQUENCER_C -#endif -#include <i386/isa/sound/tuning.h> -#include <machine/ultrasound.h> -#endif /* AWE_HAS_GUS_COMPATIBILITY */ - - -/*---------------------------------------------------------------- - * compatibility macros for AWE32 driver - *----------------------------------------------------------------*/ - -/* redefine following macros */ -#undef IOCTL_IN -#undef IOCTL_OUT -#undef OUTW -#undef COPY_FROM_USER -#undef COPY_TO_USER -#undef GET_BYTE_FROM_USER -#undef GET_SHORT_FROM_USER -#undef IOCTL_TO_USER - -/* inline is not checked yet.. maybe it'll work */ -#define INLINE /*inline*/ - -#define KERN_WARNING /**/ - -/*---------------------------------------------------------------- - * memory management for freebsd - *----------------------------------------------------------------*/ - -/* i/o requests; nothing */ -#define awe_check_port() 0 /* always false */ -#define awe_request_region() /* nothing */ -#define awe_release_region() /* nothing */ - -#define AWE_DYNAMIC_BUFFER - -#define my_malloc_init(ptr) /* nothing */ -#define my_malloc_memptr() 0 -#define my_malloc(size) malloc(size, M_TEMP, M_WAITOK) -#define my_free(ptr) if (ptr) {free(ptr, M_TEMP);} - -#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;} - -/*---------------------------------------------------------------- - * i/o interfaces for freebsd - *----------------------------------------------------------------*/ - -/* according to linux rule; the arguments are swapped */ -#define OUTW(data,addr) outw(addr, data) - -#define COPY_FROM_USER(target,source,offs,count) \ - uiomove(((caddr_t)(target)),(count),((struct uio *)(source))) -#define COPY_TO_USER(target,source,offs,count) \ - uiomove(((caddr_t)(source)),(count),((struct uio *)(target))) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - uiomove(((char*)&(target)), 1, ((struct uio *)(addr))) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - uiomove(((char*)&(target)), 2, ((struct uio *)(addr))) -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(&((target)[offs]), (source), (count)) -#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN) -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) -#define BZERO(target,len) bzero((caddr_t)target, len) -#define MEMCPY(dst,src,len) bcopy((caddr_t)src, (caddr_t)dst, len) - -#ifndef AWE_OBSOLETE_VOXWARE -# define printk printf -# define RET_ERROR(err) -err -#endif - - -/* old style device tables (not modulized) */ -#define sound_alloc_synthdev() \ - (num_synths >= MAX_SYNTH_DEV ? -1 : num_synths++) -#define sound_alloc_mixerdev() \ - (num_mixers >= MAX_MIXER_DEV ? -1 : num_mixers++) -#define sound_alloc_mididev() \ - (num_midis >= MAX_MIXER_DEV ? -1 : num_midis++) -#define sound_unload_synthdev(dev) /**/ -#define sound_unload_mixerdev(dev) /**/ -#define sound_unload_mididev(dev) /**/ - - -#endif /* CONFIG_AWE32_SYNTH */ - -#endif /* AWE_COMPAT_H_DEF */ diff --git a/drivers/sound/lowlevel/awe_compat-linux.h b/drivers/sound/lowlevel/awe_compat-linux.h deleted file mode 100644 index 6ab482ac4..000000000 --- a/drivers/sound/lowlevel/awe_compat-linux.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * sound/awe_compat.h - * - * Compat defines for the AWE32/SB32/AWE64 wave table synth driver. - * version 0.4.3; Oct. 1, 1998 - * - * Copyright (C) 1996-1998 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef AWE_COMPAT_H_DEF -#define AWE_COMPAT_H_DEF - -/*================================================================ - * version check - *================================================================*/ - -#include "awe_config.h" - -#define ASC_LINUX_VERSION(V,P,S) (((V) * 65536) + ((P) * 256) + (S)) - -#ifndef LINUX_VERSION_CODE -#include <linux/version.h> -#endif - -/* linux version check */ -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) -#define AWE_OBSOLETE_VOXWARE -#endif - -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0) -#define AWE_NEW_KERNEL_INTERFACE -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,80) -#define AWE_MODULE_SUPPORT -#endif -#endif - -#ifdef AWE_OBSOLETE_VOXWARE -#include "soundvers.h" -#else -#include "../soundvers.h" -#endif - -#if defined(SOUND_INTERNAL_VERSION) && SOUND_INTERNAL_VERSION >= 0x30803 -/* OSS/Free-3.8 */ -#define AWE_NO_PATCHMGR -#define AWE_OSS38 -#define HAS_LOWLEVEL_H -#endif - -/*================================================================ - * INCLUDE OTHER HEADER FILES - *================================================================*/ - -/* set up module */ - -#if defined(AWE_MODULE_SUPPORT) && defined(MODULE) -#include <linux/config.h> -#include <linux/string.h> -#include <linux/module.h> -#include "../soundmodule.h" -#endif - - -/* reading configuration of sound driver */ - -#ifdef AWE_OBSOLETE_VOXWARE - -#include "sound_config.h" -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32) -#define CONFIG_AWE32_SYNTH -#endif - -#else /* AWE_OBSOLETE_VOXWARE */ - -#ifdef HAS_LOWLEVEL_H -#include "lowlevel.h" -#endif - -#include "../sound_config.h" - -#endif /* AWE_OBSOLETE_VOXWARE */ - - -/*================================================================ - * include AWE header files - *================================================================*/ - -#if defined(CONFIG_AWE32_SYNTH) || defined(CONFIG_AWE32_SYNTH_MODULE) - -#include "awe_hw.h" -#include "awe_version.h" -#include <linux/awe_voice.h> - -#ifdef AWE_HAS_GUS_COMPATIBILITY -/* include finetune table */ -#ifdef AWE_OBSOLETE_VOXWARE -# include "tuning.h" -#else -# include "../tuning.h" -#endif -#include <linux/ultrasound.h> -#endif /* AWE_HAS_GUS_COMPATIBILITY */ - - -/*---------------------------------------------------------------- - * compatibility macros for AWE32 driver - *----------------------------------------------------------------*/ - -/* redefine following macros */ -#undef IOCTL_IN -#undef IOCTL_OUT -#undef OUTW -#undef COPY_FROM_USER -#undef COPY_TO_USER -#undef GET_BYTE_FROM_USER -#undef GET_SHORT_FROM_USER -#undef IOCTL_TO_USER - -/* use inline prefix */ -#define INLINE inline - -/*---------------------------------------------------------------- - * memory management for linux - *----------------------------------------------------------------*/ - -#ifdef AWE_OBSOLETE_VOXWARE -/* old type linux system */ - -/* i/o requests; nothing */ -#define awe_check_port() 0 /* always false */ -#define awe_request_region() /* nothing */ -#define awe_release_region() /* nothing */ - -static int _mem_start; /* memory pointer for permanent buffers */ - -#define my_malloc_init(memptr) _mem_start = (memptr) -#define my_malloc_memptr() _mem_start -#define my_free(ptr) /* do nothing */ - -/* allocate buffer only once */ -#define INIT_TABLE(buffer,index,nums,type) {\ -PERMANENT_MALLOC(buffer, char*, size, _mem_start); index = (nums);\ -} - -#else - -#define AWE_DYNAMIC_BUFFER - -#define my_malloc_init(ptr) /* nothing */ -#define my_malloc_memptr() 0 -#define my_malloc(size) vmalloc(size) -#define my_free(ptr) if (ptr) {vfree(ptr);} - -/* do not allocate buffer at beginning */ -#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;} - -/* old type macro */ -#define RET_ERROR(err) -err - -#endif - -/*---------------------------------------------------------------- - * i/o interfaces for linux - *----------------------------------------------------------------*/ - -#define OUTW(data,addr) outw(data, addr) - -#ifdef AWE_NEW_KERNEL_INTERFACE -#define COPY_FROM_USER(target,source,offs,count) \ - copy_from_user(target, (source)+(offs), count) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - get_user(target, (unsigned char*)&((addr)[offs])) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - get_user(target, (unsigned short*)&((addr)[offs])) -#ifdef AWE_OSS38 -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(target, (source)+(offs), count) -#define IO_WRITE_CHECK(cmd) (_SIOC_DIR(cmd) & _IOC_WRITE) -#else -#define IOCTL_TO_USER(target,offs,source,count) \ - copy_to_user(target, (source)+(offs), count) -#define IO_WRITE_CHECK(cmd) (_IOC_DIR(cmd) & _IOC_WRITE) -#endif /* AWE_OSS38 */ -#define COPY_TO_USER IOCTL_TO_USER -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) - -#else /* old type i/o */ -#define COPY_FROM_USER(target,source,offs,count) \ - memcpy_fromfs(target, (source)+(offs), (count)) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - *((char *)&(target)) = get_fs_byte((addr)+(offs)) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - *((short *)&(target)) = get_fs_word((addr)+(offs)) -#ifdef AWE_OSS38 -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(target, (source)+(offs), count) -#define COPY_TO_USER(target,offs,source,count) \ - memcpy_tofs(target, (source)+(offs), (count)) -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) -#define IO_WRITE_CHECK(cmd) (_SIOC_DIR(cmd) & _IOC_WRITE) -#else /* AWE_OSS38 */ -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy_tofs(target, (source)+(offs), (count)) -#define COPY_TO_USER IOCTL_TO_USER -#define IOCTL_IN(arg) get_fs_long((long *)(arg)) -#define IOCTL_OUT(arg,ret) snd_ioctl_return((int *)arg, ret) -#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN) -#endif /* AWE_OSS38 */ - -#endif /* AWE_NEW_KERNEL_INTERFACE */ - -#define BZERO(target,len) memset(target, 0, len) -#define MEMCPY(dst,src,len) memcpy(dst, src, len) - -/* old style device tables (not modulized) */ -#ifndef AWE_MODULE_SUPPORT - -#define sound_alloc_synthdev() \ - (num_synths >= MAX_SYNTH_DEV ? -1 : num_synths++) -#define sound_alloc_mixerdev() \ - (num_mixers >= MAX_MIXER_DEV ? -1 : num_mixers++) -#define sound_alloc_mididev() \ - (num_midis >= MAX_MIXER_DEV ? -1 : num_midis++) -#define sound_unload_synthdev(dev) /**/ -#define sound_unload_mixerdev(dev) /**/ -#define sound_unload_mididev(dev) /**/ - -#endif /* AWE_MODULE_SUPPORT */ - -#endif /* CONFIG_AWE32_SYNTH */ - -#endif /* AWE_COMPAT_H_DEF */ diff --git a/drivers/sound/lowlevel/miroaci.h b/drivers/sound/lowlevel/miroaci.h index 9d64eaa1e..e8ed6ceb5 100644 --- a/drivers/sound/lowlevel/miroaci.h +++ b/drivers/sound/lowlevel/miroaci.h @@ -1,6 +1,12 @@ +#if defined(CONFIG_ACI_MIXER) || defined(CONFIG_ACI_MIXER_MODULE) extern int aci_implied_cmd(unsigned char opcode); extern int aci_write_cmd(unsigned char opcode, unsigned char parameter); extern int aci_write_cmd_d(unsigned char opcode, unsigned char parameter, unsigned char parameter2); extern int aci_read_cmd(unsigned char opcode, int length, unsigned char *parameter); extern int aci_indexed_cmd(unsigned char opcode, unsigned char index, unsigned char *parameter); +#else + +#error Compiling a driver that needs the ACI-mixer but ACI-mixer support is not configured + +#endif diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c index 649c9861f..6b1b2d13f 100644 --- a/drivers/sound/mad16.c +++ b/drivers/sound/mad16.c @@ -668,7 +668,7 @@ void attach_mad16(struct address_info *hw_config) * Set the IRQ and DMA addresses. */ - if (board_type == C930) + if (board_type == C930 || c924pnp) interrupt_bits[5] = 0x28; /* Also IRQ5 is possible on C930 */ bits = interrupt_bits[hw_config->irq]; @@ -889,7 +889,7 @@ int irq = -1; int cdtype = 0; int cdirq = 0; int cdport = 0x340; -int cddma = 3; +int cddma = -1; int opl4 = 0; int joystick = 0; @@ -949,23 +949,28 @@ int init_module(void) break; case 0x02: printk("Sony CDU31A"); - dmatype = 2; + dmatype = 1; + if(cddma == -1) cddma = 3; break; case 0x04: printk("Mitsumi"); - dmatype = 1; + dmatype = 0; + if(cddma == -1) cddma = 5; break; case 0x06: printk("Panasonic Lasermate"); - dmatype = 2; + dmatype = 1; + if(cddma == -1) cddma = 3; break; case 0x08: printk("Secondary IDE"); - dmatype = 1; + dmatype = 0; + if(cddma == -1) cddma = 5; break; case 0x0A: printk("Primary IDE"); - dmatype = 1; + dmatype = 0; + if(cddma == -1) cddma = 5; break; default: printk("\n"); @@ -973,8 +978,16 @@ int init_module(void) return -EINVAL; } - if (dmatype) - { + /* + * Build the config words + */ + + mad16_conf = (joystick ^ 1) | cdtype; + mad16_cdsel = 0; + if (opl4) + mad16_cdsel |= 0x20; + + if(cdtype){ if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1) { printk("\n"); @@ -985,58 +998,51 @@ int init_module(void) printk(", DMA %d", cddma); else printk(", no DMA"); - } - if (cdtype && !cdirq) - printk(", no IRQ"); - else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1) - { - printk(", invalid IRQ (disabling)"); - cdirq = 0; - } - else printk(", IRQ %d", cdirq); - - printk(".\n"); - printk(KERN_INFO "Joystick port "); - if (joystick == 1) - printk("enabled.\n"); - else - { - joystick = 0; - printk("disabled.\n"); - } - /* - * Build the config words - */ + if (!cdirq) + printk(", no IRQ"); + else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1) + { + printk(", invalid IRQ (disabling)"); + cdirq = 0; + } + else printk(", IRQ %d", cdirq); - mad16_conf = (joystick ^ 1) | cdtype; - mad16_cdsel = 0; - if (opl4) - mad16_cdsel |= 0x20; - mad16_cdsel |= dma_map[dmatype][cddma]; + mad16_cdsel |= dma_map[dmatype][cddma]; - if (cdtype < 0x08) - { - switch (cdport) + if (cdtype < 0x08) { - case 0x340: - mad16_cdsel |= 0x00; - break; - case 0x330: - mad16_cdsel |= 0x40; - break; - case 0x360: - mad16_cdsel |= 0x80; - break; - case 0x320: - mad16_cdsel |= 0xC0; - break; - default: - printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport); - return -EINVAL; + switch (cdport) + { + case 0x340: + mad16_cdsel |= 0x00; + break; + case 0x330: + mad16_cdsel |= 0x40; + break; + case 0x360: + mad16_cdsel |= 0x80; + break; + case 0x320: + mad16_cdsel |= 0xC0; + break; + default: + printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport); + return -EINVAL; + } } + mad16_cdsel |= irq_map[cdirq]; } - mad16_cdsel |= irq_map[cdirq]; + + printk(".\n"); + printk(KERN_INFO "Joystick port "); + if (joystick == 1) + printk("enabled.\n"); + else + { + joystick = 0; + printk("disabled.\n"); + } config.io_base = io; config.irq = irq; diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c new file mode 100644 index 000000000..e0ed9e33a --- /dev/null +++ b/drivers/sound/maestro.c @@ -0,0 +1,3425 @@ +/***************************************************************************** + * + * ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.2.x + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * (c) Copyright 1999 Alan Cox <alan.cox@linux.org> + * + * Based heavily on SonicVibes.c: + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * Heavily modified by Zach Brown <zab@redhat.com> based on lunch + * with ESS engineers. Many thanks to Howard Kim for providing + * contacts and hardware. Honorable mention goes to Eric + * Brombaugh for the BOB routines and great record code hacking. + * Best regards to the proprietors of Hack Central for fine + * lodging. + * + * Supported devices: + * /dev/dsp0-7 standard /dev/dsp device, (mostly) OSS compatible + * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible + * + * Hardware Description + * + * A working Maestro setup contains the Maestro chip wired to a + * codec or 2. In the Maestro we have the APUs, the ASP, and the + * Wavecache. The APUs can be though of as virtual audio routing + * channels. They can take data from a number of sources and perform + * basic encodings of the data. The wavecache is a storehouse for + * PCM data. Typically it deals with PCI and interracts with the + * APUs. The ASP is a wacky DSP like device that ESS is loathe + * to release docs on. Thankfully it isn't required on the Maestro + * until you start doing insane things like FM emulation and surround + * encoding. The codecs are almost always AC-97 compliant codecs, + * but it appears that early Maestros may have had PT101 (an ESS + * part?) wired to them. The only real difference in the Maestro + * families is external goop like docking capability, memory for + * the ASP, and trivial initialization differences. + * + * Driver Operation + * + * We only drive the APU/Wavecache as typical DACs and drive the + * mixers in the codecs. There are 64 APUs. We assign 6 to each + * /dev/dsp? device. 2 channels for output, and 4 channels for + * input. + * + * For output we maintain a ring buffer of data that we are DMAing + * to the card. In mono operation this is nice and easy. When + * we receive data we tack it onto the ring buffer and make sure + * the APU assigned to it is playing over the data. When we fill + * the ring buffer we put the client to sleep until there is + * room again. Easy. + * + * However, this starts to stink when we use stereo. The APUs + * supposedly can decode LRLR packed stereo data, but it + * doesn't work. So we're forced to use dual mono APUs walking over + * mono encoded data. This requires us to split the input from + * the client and complicates the buffer maths tremendously. Ick. + * + * This also pollutes the recording paths as well. We have to use + * 2 l/r incoming APUs that are fixed at 16bit/48khz. We then pipe + * these through 2 rate converion apus that mix them down to the + * requested frequency and write them to memory through the wavecache. + * We also apparently need a 512byte region thats used as temp space + * between the incoming APUs and the rate converters. + * + * The wavecache makes our life even more fun. First off, it can + * only address the first 28 bits of PCI address space, making it + * useless on quite a few architectures. Secondly, its insane. + * It can only fetch from 4 regions of PCI space, each 2 meg in length + * and 4k aligned. It then uses high bits of the address in the APU + * to decide which buffer to use, but as far as I can tell can only + * choose between 2 of the 4 available when you really want to hit + * PCI space. So all the memory we're touching has to fit in 2 regions + * of 4 meg under 256meg. So much for dynamic allocation of multiple + * /dev/dsps. So we force only 1 /dev/dsp, allocate both its read + * and write buffers contiguously at open(), and allocate the weird + * mixbuf input APU buffers on another page. The first 2meg region + * goes to the input/output buffers, and the second region goes to + * the weird mixbuf. Long term fixes? Get an allocator that lets + * us try and allocate from zones. Alleviate pain by putting the mixbuf + * in onboard ram rather than in system memory. Buy a real sound card. + * + * History + * v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com> + * fix wavecache thinkos. limit to 1 /dev/dsp. + * eric is wearing his thinking toque this week. + * spotted apu mode bugs and gain ramping problem + * don't touch weird mixer regs, make recmask optional + * fixed igain inversion, defaults for mixers, clean up rec_start + * make mono recording work. + * report subsystem stuff, please send reports. + * littles: parallel out, amp now + * v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com> + * merged and fixed up Eric's initial recording code + * munged format handling to catch misuse, needs rewrite. + * revert ring bus init, fixup shared int, add pci busmaster setting + * fix mixer oss interface, fix mic mute and recmask + * mask off unsupported mixers, reset with all 1s, modularize defaults + * make sure bob is running while we need it + * got rid of device limit, initial minimal apm hooks + * pull out dead code/includes, only allow multimedia/audio maestros + * v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com> + * copied memory leak fix from sonicvibes driver + * different ac97 reset, play with 2.0 ac97, simplify ring bus setup + * bob freq code, region sanity, jitter sync fix; all from Eric + * + * TODO + * some people get indir reg timeouts? + * anyone have a pt101 codec? + * mmap(), but beware stereo encoding nastiness. + * actually post pci writes + * look really hard at the apu/bob/dma buffer code paths. + * fix bob frequency + * do smart things with ac97 2.0 bits. + * fix wavecache so multiple /dev/dsps work + * test different sized writes + * fixup latencies ? + * get apm save/restore working? + * allocate dma bounce page + * start_adc is called way too often + * sort out 0x34->0x36 crap in init + * wavecache needs to be looked at, multiple + * dsps and recording seem confused + * + * the entire issue of smp safety needs to be looked at. cli() needs + * to be replaced with spinlock_irqsave, being very careful of call + * paths avoiding deadlock. if lock hold times are quick just + * use one big ass per device spinlock.. + * + * apm is kind of a mess. I doubt we can rely on the machine keeping + * power to the maestro/codecs when we suspend. This means we have + * to keep full mixer/wavecache/apu state. bother. if we could rely + * on the chips being powered we would simply turn down the apus and + * bob and it would all just work out. That last bit I've implemented + * before I realized how much it was all going to suck :). + * + * it also would be fun to have a mode that would not use pci dma at all + * but would copy into the wavecache on board memory and use that + * on architectures that don't like the maestro's pci dma ickiness + * throughout. + */ + +/*****************************************************************************/ + + +#include <linux/module.h> +#include <linux/version.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/sound.h> +#include <linux/malloc.h> +#include <linux/soundcard.h> +#include <linux/pci.h> +#include <asm/io.h> +#include <asm/dma.h> +#include <linux/init.h> +#include <linux/poll.h> +#include <linux/spinlock.h> +#include <asm/uaccess.h> +#include <asm/hardirq.h> + +#ifdef CONFIG_APM +#include <linux/apm_bios.h> +#endif + +#include "maestro.h" + +/* --------------------------------------------------------------------- */ + +#define M_DEBUG 1 + +#ifdef M_DEBUG +static int debug=0; +#define M_printk(args...) {if (debug) printk(args);} +#else +#define M_printk(x) +#endif + +/* --------------------------------------------------------------------- */ +#define DRIVER_VERSION "0.06" + +#ifndef PCI_VENDOR_ESS +#define PCI_VENDOR_ESS 0x125D +#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */ +#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */ + +#define PCI_VENDOR_ESS_OLD 0x1285 /* Platform Tech, + the people the maestro + was bought from */ +#define PCI_DEVICE_ID_ESS_ESS0100 0x0100 /* maestro 1 */ +#endif /* PCI_VENDOR_ESS */ + +#define ESS_CHAN_HARD 0x100 + +#undef CONFIG_APM /* see notes above */ + +/* changed so that I could actually find all the + references and fix them up. its a little more readable now. */ +#define ESS_FMT_STEREO 0x01 +#define ESS_FMT_16BIT 0x02 +#define ESS_FMT_MASK 0x03 +#define ESS_DAC_SHIFT 0 +#define ESS_ADC_SHIFT 4 + +#define ESS_ENABLE_PE 1 +#define ESS_ENABLE_RE 2 + +#define ESS_STATE_MAGIC 0x125D1968 +#define ESS_CARD_MAGIC 0x19283746 + +#define DAC_RUNNING 1 +#define ADC_RUNNING 2 + +#define NR_DSPS 1 /* our wavecache setup demands this. */ + +#define SND_DEV_DSP16 5 + +static const unsigned sample_size[] = { 1, 2, 2, 4 }; +static const unsigned sample_shift[] = { 0, 1, 1, 2 }; + +enum card_types_t { + TYPE_MAESTRO, + TYPE_MAESTRO2, + TYPE_MAESTRO2E +}; + +static const char *card_names[]={ + [TYPE_MAESTRO] = "ESS Maestro", + [TYPE_MAESTRO2] = "ESS Maestro 2", + [TYPE_MAESTRO2E] = "ESS Maestro 2E" +}; + + +/* --------------------------------------------------------------------- */ + +struct ess_state { + unsigned int magic; + /* FIXME: we probably want submixers in here, but only one record pair */ + u8 apu[6]; /* l/r output, l/r intput converters, l/r input apus */ + u8 apu_mode[6]; /* Running mode for this APU */ + u8 apu_pan[6]; /* Panning setup for this APU */ + struct ess_card *card; /* Card info */ + /* wave stuff */ + unsigned int rateadc, ratedac; + unsigned char fmt, enable; + + spinlock_t lock; + struct semaphore open_sem; + mode_t open_mode; + wait_queue_head_t open_wait; + + /* soundcore stuff */ + int dev_audio; + + struct dmabuf { + void *rawbuf; + unsigned buforder; + unsigned numfrag; + unsigned fragshift; + /* XXX zab - swptr only in here so that it can be referenced by + clear_advance, as far as I can tell :( */ + unsigned hwptr, swptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + wait_queue_head_t wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + unsigned fragsamples; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned endcleared:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; + u16 base; /* Offset for ptr */ + } dma_dac, dma_adc; + + + /* pointer to each dsp?s piece of the apu->src buffer page */ + void *mixbuf; +}; + +struct ess_card { + unsigned int magic; + + /* We keep maestro cards in a linked list */ + struct ess_card *next; + + int dev_mixer; + + int card_type; + + /* as most of this is static, + perhaps it should be a pointer to a global struct */ + struct mixer_goo { + int modcnt; + int supported_mixers; + int stereo_mixers; + int record_sources; + /* the caller must guarantee arg sanity before calling these */ +/* int (*read_mixer)(struct ess_card *card, int index);*/ + void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right); + int (*recmask_io)(struct ess_card *card,int rw,int mask); + unsigned int mixer_state[SOUND_MIXER_NRDEVICES]; + } mix; + + struct ess_state channels[NR_DSPS]; + u16 maestro_map[32]; /* Register map */ +#ifdef CONFIG_APM + /* we have to store this junk so that we can come back from a + suspend */ + u16 apu_map[64][16]; /* contents of apu regs */ +#endif + + /* 1 page of DMA-able memory for mixer apu buffers, + shared amongst dsp?s. */ + void *mixpage; + + /* hardware resources */ + u32 iobase; + u32 irq; + + int bob_freq; + char bob_running; +}; + +extern __inline__ unsigned ld2(unsigned int x) +{ + unsigned r = 0; + + if (x >= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + + +/* --------------------------------------------------------------------- */ + +static struct ess_card *devs = NULL; + +/* --------------------------------------------------------------------- */ + + +/* + * ESS Maestro AC97 codec programming interface. + */ + +static void maestro_ac97_set(int io, u8 cmd, u16 val) +{ + int i; + /* + * Wait for the codec bus to be free + */ + + for(i=0;i<10000;i++) + { + if(!(inb(io+ESS_AC97_INDEX)&1)) + break; + } + /* + * Write the bus + */ + outw(val, io+ESS_AC97_DATA); + mdelay(1); + outb(cmd, io+ESS_AC97_INDEX); + mdelay(1); +} + +static u16 maestro_ac97_get(int io, u8 cmd) +{ + int sanity=10000; + u16 data; + int i; + + /* + * Wait for the codec bus to be free + */ + + for(i=0;i<10000;i++) + { + if(!(inb(io+ESS_AC97_INDEX)&1)) + break; + } + + outb(cmd|0x80, io+ESS_AC97_INDEX); + mdelay(1); + + while(inb(io+ESS_AC97_INDEX)&1) + { + sanity--; + if(!sanity) + { + printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd); + return 0; + } + } + data=inw(io+ESS_AC97_DATA); + mdelay(1); + return data; +} + +/* OSS interface to the ac97s.. */ + +#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\ + SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\ + SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN) + +#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ + SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\ + SOUND_MASK_SPEAKER) + +#define AC97_RECORD_MASK (SOUND_MASK_MIC|\ + SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\ + SOUND_MASK_PHONEIN) + +#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) ) + +/* this table has default mixer values for all OSS mixers. + be sure to fill it in if you add oss mixers + to anyone's supported mixer defines */ + +/* possible __init */ +static struct mixer_defaults { + int mixer; + unsigned int value; +} mixer_defaults[SOUND_MIXER_NRDEVICES] = { + /* all values 0 -> 100 in bytes */ + {SOUND_MIXER_VOLUME, 0x3232}, + {SOUND_MIXER_BASS, 0x3232}, + {SOUND_MIXER_TREBLE, 0x3232}, + {SOUND_MIXER_SPEAKER, 0x3232}, + {SOUND_MIXER_MIC, 0x3232}, + {SOUND_MIXER_LINE, 0x3232}, + {SOUND_MIXER_CD, 0x3232}, + {SOUND_MIXER_VIDEO, 0x3232}, + {SOUND_MIXER_LINE1, 0x3232}, + {SOUND_MIXER_PCM, 0x3232}, + {SOUND_MIXER_IGAIN, 0x3232}, + {-1,0} +}; + +static struct ac97_mixer_hw { + unsigned char offset; + int scale; +} ac97_hw[SOUND_MIXER_NRDEVICES]= { + [SOUND_MIXER_VOLUME] = {0x02,63}, + [SOUND_MIXER_BASS] = {0x08,15}, + [SOUND_MIXER_TREBLE] = {0x08,15}, + [SOUND_MIXER_SPEAKER] = {0x0a,15}, + [SOUND_MIXER_MIC] = {0x0e,31}, + [SOUND_MIXER_LINE] = {0x10,31}, + [SOUND_MIXER_CD] = {0x12,31}, + [SOUND_MIXER_VIDEO] = {0x14,31}, + [SOUND_MIXER_LINE1] = {0x16,31}, + [SOUND_MIXER_PCM] = {0x18,31}, + [SOUND_MIXER_IGAIN] = {0x1c,31} +}; + +#if 0 /* *shrug* removed simply because we never used it. + feel free to implement again if needed */ + +/* reads the given OSS mixer from the ac97 + the caller must have insured that the ac97 knows + about that given mixer, and should be holding a + spinlock for the card */ +static int ac97_read_mixer(struct ess_card *card, int mixer) +{ + u16 val; + int ret=0; + struct ac97_mixer_hw *mh = &ac97_hw[mixer]; + + val = maestro_ac97_get(card->iobase , mh->offset); + + if(AC97_STEREO_MASK & (1<<mixer)) { + /* nice stereo mixers .. */ + int left,right; + + left = (val >> 8) & 0x7f; + right = val & 0x7f; + + if (mixer == SOUND_MIXER_IGAIN) { + right = (right * 100) / mh->scale; + left = (left * 100) / mh->scale; + else { + right = 100 - ((right * 100) / mh->scale); + left = 100 - ((left * 100) / mh->scale); + } + + ret = left | (right << 8); + } else if (mixer == SOUND_MIXER_SPEAKER) { + ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale); + } else if (mixer == SOUND_MIXER_MIC) { + ret = 100 - (((val & 0x1f) * 100) / mh->scale); + /* the low bit is optional in the tone sliders and masking + it lets is avoid the 0xf 'bypass'.. */ + } else if (mixer == SOUND_MIXER_BASS) { + ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale); + } else if (mixer == SOUND_MIXER_TREBLE) { + ret = 100 - (((val & 0xe) * 100) / mh->scale); + } + + M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret); + + return ret; +} +#endif + +/* write the OSS encoded volume to the given OSS encoded mixer, + again caller's job to make sure all is well in arg land, + call with spinlock held */ +static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right) +{ + u16 val=0; + struct ac97_mixer_hw *mh = &ac97_hw[mixer]; + + M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right); + + if(AC97_STEREO_MASK & (1<<mixer)) { + /* stereo mixers */ + + + if (mixer == SOUND_MIXER_IGAIN) { + right = (right * mh->scale) / 100; + left = (left * mh->scale) / 100; + } else { + right = ((100 - right) * mh->scale) / 100; + left = ((100 - left) * mh->scale) / 100; + } + + val = (left << 8) | right; + + } else if (mixer == SOUND_MIXER_SPEAKER) { + val = (((100 - left) * mh->scale) / 100) << 1; + } else if (mixer == SOUND_MIXER_MIC) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x801f; + val |= (((100 - left) * mh->scale) / 100); + /* the low bit is optional in the tone sliders and masking + it lets is avoid the 0xf 'bypass'.. */ + } else if (mixer == SOUND_MIXER_BASS) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x0f00; + val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00; + } else if (mixer == SOUND_MIXER_TREBLE) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x000f; + val |= (((100 - left) * mh->scale) / 100) & 0x000e; + } + + maestro_ac97_set(card->iobase , mh->offset, val); + + M_printk(" -> %x\n",val); +} + +/* the following tables allow us to go from + OSS <-> ac97 quickly. */ + +enum ac97_recsettings { + AC97_REC_MIC=0, + AC97_REC_CD, + AC97_REC_VIDEO, + AC97_REC_AUX, + AC97_REC_LINE, + AC97_REC_STEREO, /* combination of all enabled outputs.. */ + AC97_REC_MONO, /*.. or the mono equivalent */ + AC97_REC_PHONE +}; + +static unsigned int ac97_rm2oss[] = { + [AC97_REC_MIC] = SOUND_MIXER_MIC, + [AC97_REC_CD] = SOUND_MIXER_CD, + [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO, + [AC97_REC_AUX] = SOUND_MIXER_LINE1, + [AC97_REC_LINE] = SOUND_MIXER_LINE, + [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN +}; + +/* indexed by bit position */ +static unsigned int ac97_oss_rm[] = { + [SOUND_MIXER_MIC] = AC97_REC_MIC, + [SOUND_MIXER_CD] = AC97_REC_CD, + [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, + [SOUND_MIXER_LINE1] = AC97_REC_AUX, + [SOUND_MIXER_LINE] = AC97_REC_LINE, + [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE +}; + +/* read or write the recmask + the ac97 can really have left and right recording + inputs independantly set, but OSS doesn't seem to + want us to express that to the user. + the caller guarantees that we have a supported bit set, + and they must be holding the card's spinlock */ +static int ac97_recmask_io(struct ess_card *card, int rw, int mask) +{ + unsigned int val; + + if (rw) { + /* read it from the card */ + val = maestro_ac97_get(card->iobase, 0x1a) & 0x7; + return ac97_rm2oss[val]; + } + + /* else, write the first set in the mask as the + output */ + + val = ffs(mask); + val = ac97_oss_rm[val-1]; + val |= val << 8; /* set both channels */ + + M_printk("maestro: setting ac97 recmask to 0x%x\n",val); + + maestro_ac97_set(card->iobase,0x1a,val); + + return 0; +}; + +/* + * The Maestro can be wired to a standard AC97 compliant codec + * (see www.intel.com for the pdf's on this), or to a PT101 codec + * which appears to be the ES1918 (data sheet on the esstech.com.tw site) + * + * The PT101 setup is untested. + */ + +static u16 maestro_ac97_init(struct ess_card *card, int iobase) +{ + u16 vend1, vend2, caps; + + card->mix.supported_mixers = AC97_SUPPORTED_MASK; + card->mix.stereo_mixers = AC97_STEREO_MASK; + card->mix.record_sources = AC97_RECORD_MASK; +/* card->mix.read_mixer = ac97_read_mixer;*/ + card->mix.write_mixer = ac97_write_mixer; + card->mix.recmask_io = ac97_recmask_io; + +#if 0 /* this needs to be thought about harder */ + /* aim at the second codec */ + outw(0x21, iobase+0x38); + outw(0x5555, iobase+0x3a); + outw(0x5555, iobase+0x3c); + udelay(1); + vend1 = maestro_ac97_get(iobase, 0x7c); + vend2 = maestro_ac97_get(iobase, 0x7e); + if(vend1 != 0xffff || vend2 != 0xffff) { + printk("maestro: second codec 0x%4x%4x found, enabling both. please report this.\n", + vend1,vend2); + /* enable them both */ + outw(0x00, iobase+0x38); + outw(0xFFFC, iobase+0x3a); + outw(0x000C, iobase+0x3c); + } else { + /* back to the first only */ + outw(0x0, iobase+0x38); + outw(0x0, iobase+0x3a); + outw(0x0, iobase+0x3c); + } + udelay(1); +#endif + + /* perform codec reset */ + maestro_ac97_set(iobase, 0x00, 0xFFFF); + + vend1 = maestro_ac97_get(iobase, 0x7c); + vend2 = maestro_ac97_get(iobase, 0x7e); + + caps = maestro_ac97_get(iobase, 0x00); + + printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n", + vend1,vend2,caps,maestro_ac97_get(iobase,0x26) & 0xf); + + if (! (caps & 0x4) ) { + /* no bass/treble nobs */ + card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE); + } + + /* XXX endianness, dork head. */ + /* vendor specifc bits.. */ + switch ((long)(vend1 << 16) | vend2) { + case 0x545200ff: /* TriTech */ + /* no idea what this does */ + maestro_ac97_set(iobase,0x2a,0x0001); + maestro_ac97_set(iobase,0x2c,0x0000); + maestro_ac97_set(iobase,0x2c,0xffff); + break; + case 0x83847609: /* ESS 1921 */ + /* writing to 0xe (mic) or 0x1a (recmask) seems + to hang this codec */ + card->mix.supported_mixers &= ~(SOUND_MASK_MIC); + card->mix.record_sources = 0; + card->mix.recmask_io = NULL; + /* no idea what these do */ + maestro_ac97_set(iobase,0x76,0xABBA); /* o/~ Take a chance on me o/~ */ + udelay(20); + maestro_ac97_set(iobase,0x78,0x3002); + udelay(20); + maestro_ac97_set(iobase,0x78,0x3802); + udelay(20); + break; + default: break; + } + +#if 0 /* used to be set, lets try using the codec defaults */ + /* always set headphones to max unmuted, OSS won't + let us change it :( */ + maestro_ac97_set(iobase, 0x04, 0x0000); + maestro_ac97_set(iobase, 0x06, 0x0000); + maestro_ac97_set(iobase, 0x0C, 0x1F1F); + /* null record select */ + maestro_ac97_set(iobase, 0x1A, 0x0000); +#endif + maestro_ac97_set(iobase, 0x1E, 0x0404); + /* null misc stuff */ + maestro_ac97_set(iobase, 0x20, 0x0000); + /* the regs are read only, duh :) */ +/* maestro_ac97_set(iobase, 0x26, 0x000F);*/ + +#if 0 /* this is a really good way to hang + codecs. we need a better way. */ + if(maestro_ac97_get(iobase,0x36) ==0x8080) { + int reg; + printk("maestro: your ac97 might be 2.0, see if this makes sense:\n"); + for(reg = 0x28; reg <= 0x58 ; reg += 2) { + printk(" 0x%2x: %4x\n",reg,maestro_ac97_get(iobase,reg)); + } + } +#endif + + return 0; +} + +static u16 maestro_pt101_init(struct ess_card *card,int iobase) +{ + printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n"); + /* who knows.. */ + maestro_ac97_set(iobase, 0x2A, 0x0001); + maestro_ac97_set(iobase, 0x2C, 0x0000); + maestro_ac97_set(iobase, 0x2C, 0xFFFF); + maestro_ac97_set(iobase, 0x10, 0x9F1F); + maestro_ac97_set(iobase, 0x12, 0x0808); + maestro_ac97_set(iobase, 0x14, 0x9F1F); + maestro_ac97_set(iobase, 0x16, 0x9F1F); + maestro_ac97_set(iobase, 0x18, 0x0404); + maestro_ac97_set(iobase, 0x1A, 0x0000); + maestro_ac97_set(iobase, 0x1C, 0x0000); + maestro_ac97_set(iobase, 0x02, 0x0404); + maestro_ac97_set(iobase, 0x04, 0x0808); + maestro_ac97_set(iobase, 0x0C, 0x801F); + maestro_ac97_set(iobase, 0x0E, 0x801F); + return 0; +} + +static void maestro_ac97_reset(int ioaddr) +{ +/* outw(0x2000, ioaddr+0x36); + inb(ioaddr); + mdelay(1); + outw(0x0000, ioaddr+0x36); + inb(ioaddr); + mdelay(1);*/ + + /* well this seems to work a little + better on my pci board.. probably + because gpio is wired to ac97 reset */ + + /* this screws around with the gpio + mask/input/direction.. */ + outw(0x0000, ioaddr+0x36); + udelay(20); + outw(0xFFFE, ioaddr+0x64); + outw(0x1, ioaddr+0x68); + outw(0x0, ioaddr+0x60); + udelay(20); + outw(0x1, ioaddr+0x60); + udelay(20); /* other source says 500ms.. INSANE */ + outw(0x2000, ioaddr+0x36); + udelay(20); + outw(0x3000, ioaddr+0x36); + udelay(200); + outw(0x0001, ioaddr+0x68); + outw(0xFFFF, ioaddr+0x64); + + /* strange strange reset tickling the ring bus */ + outw(0x0, ioaddr+0x36); + udelay(20); + outw(0x200, ioaddr+0x36); /* first codec only */ + udelay(20); + outw(0x0, ioaddr+0x36); + udelay(20); + outw(0x2000, ioaddr+0x36); + udelay(20); + outw(0x3000, ioaddr+0x36); + udelay(20); +} + +/* + * Indirect register access. Not all registers are readable so we + * need to keep register state ourselves + */ + +#define WRITEABLE_MAP 0xEFFFFF +#define READABLE_MAP 0x64003F + +/* + * The Maestro engineers were a little indirection happy. These indirected + * registers themselves include indirect registers at another layer + */ + +static void maestro_write(struct ess_state *ess, u16 reg, u16 data) +{ + long ioaddr = ess->card->iobase; + unsigned long flags; + save_flags(flags); + cli(); + outw(reg, ioaddr+0x02); + outw(data, ioaddr+0x00); + ess->card->maestro_map[reg]=data; + restore_flags(flags); +} + +static u16 maestro_read(struct ess_state *ess, u16 reg) +{ + long ioaddr = ess->card->iobase; + if(READABLE_MAP & (1<<reg)) + { + unsigned long flags; + save_flags(flags); + cli(); + outw(reg, ioaddr+0x02); + ess->card->maestro_map[reg]=inw(ioaddr+0x00); + restore_flags(flags); + } + return ess->card->maestro_map[reg]; +} + +/* + * These routines handle accessing the second level indirections to the + * wave ram. + */ + +/* + * The register names are the ones ESS uses (see 104T31.ZIP) + */ + +#define IDR0_DATA_PORT 0x00 +#define IDR1_CRAM_POINTER 0x01 +#define IDR2_CRAM_DATA 0x02 +#define IDR3_WAVE_DATA 0x03 +#define IDR4_WAVE_PTR_LOW 0x04 +#define IDR5_WAVE_PTR_HI 0x05 +#define IDR6_TIMER_CTRL 0x06 +#define IDR7_WAVE_ROMRAM 0x07 + +static void apu_index_set(struct ess_state *ess, u16 index) +{ + int i; + maestro_write(ess, IDR1_CRAM_POINTER, index); + for(i=0;i<1000;i++) + if(maestro_read(ess, IDR1_CRAM_POINTER)==index) + return; + printk(KERN_WARNING "maestro: APU register select failed.\n"); +} + +static void apu_data_set(struct ess_state *ess, u16 data) +{ + int i; + for(i=0;i<1000;i++) + { + if(maestro_read(ess, IDR0_DATA_PORT)==data) + return; + maestro_write(ess, IDR0_DATA_PORT, data); + } +} + +/* + * This is the public interface for APU manipulation. It handles the + * interlock to avoid two APU writes in parallel etc. Don't diddle + * directly with the stuff above. + */ + +static void apu_set_register(struct ess_state *ess, u16 channel, u8 reg, u16 data) +{ + unsigned long flags; + + if(channel&ESS_CHAN_HARD) + channel&=~ESS_CHAN_HARD; + else + { + if(channel>5) + printk("BAD CHANNEL %d.\n",channel); + else + channel = ess->apu[channel]; + } +#ifdef CONFIG_APM + /* store based on real hardware apu/reg */ + ess->card->apu_map[channel][reg]=data; +#endif + reg|=(channel<<4); + + save_flags(flags); + cli(); + apu_index_set(ess, reg); + apu_data_set(ess, data); + restore_flags(flags); +} + +static u16 apu_get_register(struct ess_state *ess, u16 channel, u8 reg) +{ + unsigned long flags; + u16 v; + + if(channel&ESS_CHAN_HARD) + channel&=~ESS_CHAN_HARD; + else + channel = ess->apu[channel]; + + reg|=(channel<<4); + + save_flags(flags); + cli(); + apu_index_set(ess, reg); + v=maestro_read(ess, IDR0_DATA_PORT); + restore_flags(flags); + return v; +} + + +/* + * The wavecache buffers between the APUs and + * pci bus mastering + */ + +static void wave_set_register(struct ess_state *ess, u16 reg, u16 value) +{ + long ioaddr = ess->card->iobase; + unsigned long flags; + + save_flags(flags); + cli(); + outw(reg, ioaddr+0x10); + outw(value, ioaddr+0x12); + restore_flags(flags); +} + +static u16 wave_get_register(struct ess_state *ess, u16 reg) +{ + long ioaddr = ess->card->iobase; + unsigned long flags; + u16 value; + + save_flags(flags); + cli(); + outw(reg, ioaddr+0x10); + value=inw(ioaddr+0x12); + restore_flags(flags); + + return value; +} + +static void sound_reset(int ioaddr) +{ + outw(0x2000, 0x18+ioaddr); + udelay(1); + outw(0x0000, 0x18+ioaddr); + udelay(1); +} + +/* sets the play formats of these apus, should be passed the already shifted format */ +static void set_apu_fmt(struct ess_state *s, int apu, int mode) +{ + if(mode&ESS_FMT_16BIT) { + s->apu_mode[apu] = 0x10; + s->apu_mode[apu+1] = 0x10; + } else { + s->apu_mode[apu] = 0x30; + s->apu_mode[apu+1] = 0x30; + } +} + +/* this only fixes the output apu mode to be later set by start_dac and + company. output apu modes are set in ess_rec_setup */ +static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data) +{ + s->fmt = (s->fmt & mask) | data; + set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK); +} + +static u16 compute_rate(u32 freq) +{ + if(freq==48000) + return 0xFFFF; + freq<<=16; + freq/=48000; + return freq; +} + +static void set_dac_rate(struct ess_state *s, unsigned rate) +{ + u32 freq; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + + s->ratedac = rate; + + if(!((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT)) + rate >>= 1; /* who knows */ + +/* M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/ + + freq = compute_rate(rate); + + /* Load the frequency, turn on 6dB */ + apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 0, 3, freq>>8); + apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 1, 3, freq>>8); +} + +static void set_adc_rate(struct ess_state *s, unsigned rate) +{ + u32 freq; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + + s->rateadc = rate; + + freq = compute_rate(rate); + + /* Load the frequency, turn on 6dB */ + apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 2, 3, freq>>8); + apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 3, 3, freq>>8); + + /* fix mixer rate at 48khz. and its _must_ be 0x10000. */ + freq = 0x10000; + + apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 4, 3, freq>>8); + apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 5, 3, freq>>8); +} + + +/* + * Native play back driver + */ + +/* the mode passed should be already shifted and masked */ +static void ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) +{ + u32 pa; + u32 tmpval; + int high_apu = 0; + int channel; + + M_printk("mode=%d rate=%d buf=%p len=%d.\n", + mode, rate, buffer, size); + + /* all maestro sizes are in 16bit words */ + size >>=1; + + /* we're given the full size of the buffer, but + in stereo each channel will only play its half */ + if(mode&ESS_FMT_STEREO) { + size >>=1; + high_apu++; + } + + for(channel=0; channel <= high_apu; channel++) + { + int i; + + /* + * To understand this it helps to know how the + * wave cache works. There are 4 DSP wavecache + * blocks which are 0x1FC->0x1FF. They are selected + * by setting bits 22,21,20 of the address to + * 1 X Y where X Y select the block. + * + * In addition stereo pairing is supported. This is + * set in the wave cache control for the channel as is + * 8bit unsigned. + * + * Note that this causes a problem. With our limit of + * about 12 full duplex pairs (48 channels active) we + * will need to do a lot of juggling to get all the + * memory we want sufficiently close together. + * + * Even with 64K blocks that means + * 24 channel pairs + * 6 pairs/block + * + * 10K per channel pair = 5000 samples. + */ + + if(!channel) + pa = virt_to_bus(buffer); + else + /* right channel plays its split half. + *2 accomodates for rampant shifting earlier */ + pa = virt_to_bus(buffer + size*2); + + /* play bufs are in the same first region as record bufs */ + wave_set_register(ess, 0x01FC , (pa&0xFFE00000)>>12); + + /* set the wavecache control reg */ + tmpval = (pa - 0x10) & 0xFFF8; +#if 0 + if(mode & 1) tmpval |= 2; /* stereo */ +#endif + if(!(mode & 2)) tmpval |= 4; /* 8bit */ + wave_set_register(ess, ess->apu[channel]<<3, tmpval); + + pa&=0x1FFFFF; /* Low 21 bits */ + pa>>=1; /* words */ + + /* base offset of dma calcs when reading the pointer + on this left one */ + if(!channel) ess->dma_dac.base = pa&0xFFFF; + +#if 0 + if(mode&ESS_FMT_STEREO) /* Enable stereo */ + pa|=0x00800000; +#endif + pa|=0x00400000; /* System RAM */ + + /* Begin loading the APU */ + for(i=0;i<15;i++) /* clear all PBRs */ + apu_set_register(ess, channel, i, 0x0000); + +/* XXX think about endianess when writing these registers */ + M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa); + /* Load the buffer into the wave engine */ + apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); + apu_set_register(ess, channel, 5, pa&0xFFFF); + apu_set_register(ess, channel, 6, (pa+size)&0xFFFF); + /* setting loop == sample len */ + apu_set_register(ess, channel, 7, size); + + /* clear effects/env.. */ + apu_set_register(ess, channel, 8, 0x0000); + /* aplitudeNow to 0xd0? */ + apu_set_register(ess, channel, 9, 0xD000); + + /* set the panning reg of the apu to left/right/mid.. */ + + /* clear routing stuff */ + apu_set_register(ess, channel, 11, 0x0000); + /* mark dma and turn on filter stuff? */ + apu_set_register(ess, channel, 0, 0x400F); + + if(mode&ESS_FMT_STEREO) + /* set panning: left or right */ + apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0x10 : 0)); + else + apu_set_register(ess, channel, 10, 0x8F08); + + } + + /* clear WP interupts */ + outw(1, ess->card->iobase+0x04); + /* enable WP ints */ + outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18); + + set_dac_rate(ess,rate); + + for(channel=0; channel<=high_apu; channel++) + { + /* Turn on the DMA */ + if(mode&ESS_FMT_16BIT) + { + apu_set_register(ess, channel, 0, + (apu_get_register(ess, channel, 0)&0xFF0F)|0x10); + ess->apu_mode[channel]=0x10; + } + else + { + apu_set_register(ess, channel, 0, + (apu_get_register(ess, channel, 0)&0xFF0F)|0x30); + ess->apu_mode[channel]=0x30; + } + } +} + +/* + * Native record driver + */ + +/* again, passed mode is alrady shifted/masked */ +static void ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) +{ + int apu_step = 2; + int channel; + u8 apu_type; + + M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n", + mode, rate, buffer, size); + + /* all maestro sizes are in 16bit words */ + size >>=1; + + /* we're given the full size of the buffer, but + in stereo each channel will only use its half */ + if(mode&ESS_FMT_STEREO) { + size >>=1; + apu_step = 1; + } + + /* APU assignments: 2 = mono/left SRC + 3 = right SRC + 4 = mono/left Input Mixer + 5 = right Input Mixer */ + for(channel=2;channel<6;channel+=apu_step) + { + int i; + int bsize, route; + u32 pa; + u32 tmpval; + + /* data seems to flow from the codec, through an apu into + the 'mixbuf' bit of page, then through the SRC apu + and out to the real 'buffer'. ok. sure. */ + + if(channel & 0x04) { + /* ok, we're an input mixer going from adc + through the mixbuf to the other apus */ + + if(!(channel & 0x01)) { + pa = virt_to_bus(ess->mixbuf); + } else { + pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4)); + } + + /* we source from a 'magic' apu */ + bsize = PAGE_SIZE >> 5; /* half of this channels alloc, in words */ + route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */ + + } else { + /* we're a rate converter taking + input from the input apus and outputing it to + system memory */ + if(!(channel & 0x01)) { + pa = virt_to_bus(buffer); + } else { + /* right channel records its split half. + *2 accomodates for rampant shifting earlier */ + pa = virt_to_bus(buffer + size*2); + } + + bsize = size; + /* get input from inputing apu */ + route = channel + 2; + } + + M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel); + + /* put our base address in the right region */ + wave_set_register(ess, 0x01FC + (channel >> 2), (pa&0xFFE00000)>>12); + + /* set the wavecache control reg */ + tmpval = (pa - 0x10) & 0xFFF8; + wave_set_register(ess, ess->apu[channel]<<3, tmpval); + + pa&=0x1FFFFF; /* Low 21 bits*/ + pa>>=1; /* words */ + + /* base offset of dma calcs when reading the pointer + on this left one */ + if(channel==2) ess->dma_adc.base = pa&0xFFFF; + + pa|=0x00400000; /* bit 22 -> System RAM */ + + if ( channel & 4) + pa|=0x00200000; /* bit 21 -> second region for mixbuf */ + + M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", + ess->apu[channel], pa, bsize, route); + + /* Begin loading the APU */ + for(i=0;i<15;i++) /* clear all PBRs */ + apu_set_register(ess, channel, i, 0x0000); + + apu_set_register(ess, channel, 0, 0x400F); + + /* need to enable subgroups.. and we should probably + have different groups for different /dev/dsps.. */ + apu_set_register(ess, channel, 2, 0x8); + + /* Load the buffer into the wave engine */ + apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); + /* XXX reg is little endian.. */ + apu_set_register(ess, channel, 5, pa&0xFFFF); + apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF); + apu_set_register(ess, channel, 7, bsize); + + /* clear effects/env.. */ + apu_set_register(ess, channel, 8, 0x00F0); + + /* amplitude now? sure. why not. */ + apu_set_register(ess, channel, 9, 0x0000); + + /* set filter tune, radius, polar pan */ + apu_set_register(ess, channel, 10, 0x8F08); + + /* route input */ + apu_set_register(ess, channel, 11, route); + } + + /* clear WP interupts */ + outw(1, ess->card->iobase+0x04); + /* enable WP ints */ + outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18); + + set_adc_rate(ess,rate); + + for(channel=2; channel<6; channel+=apu_step) + { + if(channel & 0x04) { + apu_type = 0x90; /* Input Mixer */ + } else { + apu_type = 0xB0; /* Sample Rate Converter */ + } + + apu_set_register(ess, channel, 0, + (apu_get_register(ess, channel, 0)&0xFF0F) | apu_type); + ess->apu_mode[channel] = apu_type; + } +} +/* --------------------------------------------------------------------- */ + +static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count) +{ + M_printk("set_dmaa??\n"); +} + +static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count) +{ + M_printk("set_dmac??\n"); +} + +/* Playback pointer */ +extern __inline__ unsigned get_dmaa(struct ess_state *s) +{ + long ioport = s->card->iobase; + int offset; + + outw(1, ioport+2); + outw(s->apu[0]<<4|5, ioport); + outw(0, ioport+2); + offset=inw(ioport); + +/* M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */ + + offset-=s->dma_dac.base; + + return (offset&0xFFFE)<<1; /* hardware is in words */ +} + +/* Record pointer */ +extern __inline__ unsigned get_dmac(struct ess_state *s) +{ + long ioport = s->card->iobase; + int offset; + + outw(1, ioport+2); + outw(s->apu[2]<<4|5, ioport); + outw(0, ioport+2); + offset=inw(ioport); + +/* M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */ + + /* The offset is an address not a position relative to base */ + offset-=s->dma_adc.base; + + return (offset&0xFFFE)<<1; /* hardware is in words */ +} + +/* + * Meet Bob, the timer... + */ + +static void ess_interrupt(int irq, void *dev_id, struct pt_regs *regs); + +static void stop_bob(struct ess_state *s) +{ + /* Mask IDR 11,17 */ + maestro_write(s, 0x11, maestro_read(s, 0x11)&~1); + maestro_write(s, 0x17, maestro_read(s, 0x17)&~1); +} + +/* eventually we could be clever and limit bob ints + to the frequency at which our smallest duration + chunks may expire */ +#define ESS_SYSCLK 50000000 +static void start_bob(struct ess_state *s) +{ + int prescale; + int divide; + + /* XXX make freq selector much smarter, see calc_bob_rate */ + int freq = 150; /* requested frequency - calculate what we want here. */ + + /* compute ideal interrupt frequency for buffer size & play rate */ + /* first, find best prescaler value to match freq */ + for(prescale=5;prescale<12;prescale++) + if(freq > (ESS_SYSCLK>>(prescale+9))) + break; + + /* next, back off prescaler whilst getting divider into optimum range */ + divide=1; + while((prescale > 5) && (divide<32)) + { + prescale--; + divide <<=1; + } + divide>>=1; + + /* now fine-tune the divider for best match */ + for(;divide<31;divide++) + if(freq >= ((ESS_SYSCLK>>(prescale+9))/(divide+1))) + break; + + /* divide = 0 is illegal, but don't let prescale = 4! */ + if(divide == 0) + { + divide++; + if(prescale>5) + prescale--; + } + + maestro_write(s, 6, 0x9000 | (prescale<<5) | divide); /* set reg */ + + /* Now set IDR 11/17 */ + maestro_write(s, 0x11, maestro_read(s, 0x11)|1); + maestro_write(s, 0x17, maestro_read(s, 0x17)|1); +} +/* --------------------------------------------------------------------- */ + +/* this quickly calculates the frequency needed for bob + and sets it if its different than what bob is + currently running at. its called often so + needs to be fairly quick. */ +#define BOB_MIN 50 +#define BOB_MAX 400 +static void calc_bob_rate(struct ess_state *s) { +#if 0 /* this thing tries to set the frequency of bob such that + there are 2 interrupts / buffer walked by the dac/adc. That + is probably very wrong for people who actually care about + mid buffer positioning. it should be calculated as bytes/interrupt + and that needs to be decided :) so for now just use the static 150 + in start_bob.*/ + + unsigned int dac_rate=2,adc_rate=1,newrate; + static int israte=-1; + + if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN; + else { + dac_rate = (2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / + (s->dma_dac.fragsize) ; + } + + if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN; + else { + adc_rate = (2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / + (s->dma_adc.fragsize) ; + } + + if(dac_rate > adc_rate) newrate = adc_rate; + else newrate=dac_rate; + + if(newrate > BOB_MAX) newrate = BOB_MAX; + else { + if(newrate < BOB_MIN) + newrate = BOB_MIN; + } + + if( israte != newrate) { + printk("dac: %d adc: %d rate: %d\n",dac_rate,adc_rate,israte); + israte=newrate; + } +#endif + +} + +/* Stop our host of recording apus */ +extern inline void stop_adc(struct ess_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->enable &= ~ADC_RUNNING; + apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F); + apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F); + apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F); + apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F); + spin_unlock_irqrestore(&s->lock, flags); +} + +/* stop output apus */ +extern inline void stop_dac(struct ess_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->enable &= ~DAC_RUNNING; + apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F); + apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_dac(struct ess_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { + s->enable |= DAC_RUNNING; + + apu_set_register(s, 0, 0, + (apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]); + + if((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_STEREO) + apu_set_register(s, 1, 0, + (apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_adc(struct ess_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) + && s->dma_adc.ready) { + s->enable |= ADC_RUNNING; + apu_set_register(s, 2, 0, + (apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]); + apu_set_register(s, 4, 0, + (apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]); + if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + apu_set_register(s, 3, 0, + (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]); + apu_set_register(s, 5, 0, + (apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]); + } + + } + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +/* we allocate both buffers at once */ +#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) +#define DMABUF_MINORDER 2 + +static void dealloc_dmabuf(struct dmabuf *db) +{ + unsigned long map, mapend; + + if (db->rawbuf) { + M_printk("maestro: freeing %p\n",db->rawbuf); + /* undo marking the pages as reserved */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + clear_bit(PG_reserved, &mem_map[map].flags); + free_pages((unsigned long)db->rawbuf, db->buforder); + } + db->rawbuf = NULL; + db->mapped = db->ready = 0; +} + +static int prog_dmabuf(struct ess_state *s, unsigned rec) +{ + struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; + unsigned rate = rec ? s->rateadc : s->ratedac; + int order; + unsigned bytepersec; + unsigned bufs; + unsigned long map, mapend; + unsigned char fmt; + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + fmt = s->fmt; + if (rec) { + s->enable &= ~ESS_ENABLE_RE; + fmt >>= ESS_ADC_SHIFT; + } else { + s->enable &= ~ESS_ENABLE_PE; + fmt >>= ESS_DAC_SHIFT; + } + spin_unlock_irqrestore(&s->lock, flags); + fmt &= ESS_FMT_MASK; + + db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; + + if (!db->rawbuf) { + void *rawbuf; + /* haha, this thing is hacked to hell and back. + this is so ugly. */ + s->dma_dac.ready = s->dma_dac.mapped = 0; + s->dma_adc.ready = s->dma_adc.mapped = 0; + + /* alloc as big a chunk as we can */ + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) + if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order))) + + break; + + if (!rawbuf) + return -ENOMEM; + + + /* we allocated both buffers */ + s->dma_adc.rawbuf = rawbuf; + s->dma_dac.rawbuf = rawbuf + ( PAGE_SIZE << (order - 1) ); + + M_printk("maestro: allocated %ld bytes at %p\n",PAGE_SIZE<<order, db->rawbuf); + + s->dma_adc.buforder = s->dma_dac.buforder = order - 1; + + /* XXX these checks are silly now */ +#if 0 + if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1)) & ~0xffff) + printk(KERN_DEBUG "maestro: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n", + virt_to_bus(db->rawbuf), PAGE_SIZE << order); + +#endif + if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1) & ~0xffffff) + printk(KERN_DEBUG "maestro: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n", + virt_to_bus(db->rawbuf), PAGE_SIZE << order); + + /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << order) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + set_bit(PG_reserved, &mem_map[map].flags); + } + bytepersec = rate << sample_shift[fmt]; + bufs = PAGE_SIZE << db->buforder; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytepersec) + db->fragshift = ld2(bytepersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + /* lets hand out reasonable big ass buffers by default */ + db->fragshift = (db->buforder + PAGE_SHIFT -2); +#if 0 + db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; +#endif + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->fragsamples = db->fragsize >> sample_shift[fmt]; + db->dmasize = db->numfrag << db->fragshift; + + memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize); + + spin_lock_irqsave(&s->lock, flags); + if (rec) { + ess_rec_setup(s, fmt, s->rateadc, + db->rawbuf, db->numfrag << db->fragshift); + } else { + ess_play_setup(s, fmt, s->ratedac, + db->rawbuf, db->numfrag << db->fragshift); + } + spin_unlock_irqrestore(&s->lock, flags); + db->ready = 1; + + return 0; +} + +/* XXX haha, way broken with our split stereo setup. giggle. */ +/* only called by ess_write (dac ness ) */ +extern __inline__ void clear_advance(struct ess_state *s) +{ + unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80; + unsigned char *buf = s->dma_dac.rawbuf; + unsigned bsize = s->dma_dac.dmasize; + unsigned bptr = s->dma_dac.swptr; + unsigned len = s->dma_dac.fragsize; + + if (bptr + len > bsize) { + unsigned x = bsize - bptr; + memset(buf + bptr, c, x); + /* account for wrapping? */ + bptr = 0; + len -= x; + } + memset(buf + bptr, c, len); +} + +/* call with spinlock held! */ +static void ess_update_ptr(struct ess_state *s) +{ + unsigned hwptr; + int diff; + + /* update ADC pointer */ + if (s->dma_adc.ready) { + /* oh boy should this all be re-written. everything in the current code paths think + that the various counters/pointers are expressed in bytes to the user but we have + two apus doing stereo stuff so we fix it up here.. it propogates to all the various + counters from here. Notice that this means that mono recording is very very + broken right now. */ + if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize; + } else { + hwptr = get_dmac(s) % s->dma_adc.dmasize; + } + diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; + s->dma_adc.hwptr = hwptr; + s->dma_adc.total_bytes += diff; + s->dma_adc.count += diff; + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { + if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { + s->enable &= ~ESS_ENABLE_RE; + /* FILL ME + wrindir(s, SV_CIENABLE, s->enable); */ + stop_adc(s); + s->dma_adc.error++; + } + } + } + /* update DAC pointer */ + if (s->dma_dac.ready) { + /* this is so gross. */ + hwptr = (/*s->dma_dac.dmasize -*/ get_dmaa(s)) % s->dma_dac.dmasize; + diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; +/* M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/ + s->dma_dac.hwptr = hwptr; + s->dma_dac.total_bytes += diff; + if (s->dma_dac.mapped) { + s->dma_dac.count += diff; + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) { + wake_up(&s->dma_dac.wait); + } + } else { + s->dma_dac.count -= diff; +/* M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */ + if (s->dma_dac.count <= 0) { + s->enable &= ~ESS_ENABLE_PE; + /* FILL ME + wrindir(s, SV_CIENABLE, s->enable); */ + /* XXX how on earth can calling this with the lock held work.. */ + stop_dac(s); + /* brute force everyone back in sync, sigh */ + s->dma_dac.count = 0; + s->dma_dac.swptr = 0; + s->dma_dac.hwptr = 0; + s->dma_dac.error++; + } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { + clear_advance(s); + s->dma_dac.endcleared = 1; + } + if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) { + wake_up(&s->dma_dac.wait); + } + } + } +} + +static void ess_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ess_state *s; + struct ess_card *c = (struct ess_card *)dev_id; + int i; + u32 event; + + if ( ! (event = inb(c->iobase+0x1A)) ) return; + + outw(inw(c->iobase+4)&1, c->iobase+4); + +/* M_printk("maestro int: %x\n",event);*/ + + if(event&(1<<6)) + { + /* XXX if we have a hw volume control int enable + all the ints? doesn't make sense.. */ + event = inw(c->iobase+0x18); + outb(0xFF, c->iobase+0x1A); + } + else + { + /* else ack 'em all, i imagine */ + outb(0xFF, c->iobase+0x1A); + } + + /* + * Update the pointers for all APU's we are running. + */ + for(i=0;i<NR_DSPS;i++) + { + s=&c->channels[i]; + if(s->dev_audio == -1) + break; + spin_lock(&s->lock); + ess_update_ptr(s); + spin_unlock(&s->lock); + } +} + + +/* --------------------------------------------------------------------- */ + +static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n"; + +#define VALIDATE_MAGIC(FOO,MAG) \ +({ \ + if (!(FOO) || (FOO)->magic != MAG) { \ + printk(invalid_magic,__FUNCTION__); \ + return -ENXIO; \ + } \ +}) + +#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC) +#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC) + +static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) +{ + unsigned int left,right; + /* cleanse input a little */ + right = ((val >> 8) & 0xff) ; + left = (val & 0xff) ; + + if(right > 100) right = 100; + if(left > 100) left = 100; + + card->mix.mixer_state[mixer]=(right << 8) | left; + card->mix.write_mixer(card,mixer,left,right); +} + +static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg) +{ + unsigned long flags; + int i, val=0; + struct ess_state *s = &card->channels[0]; + + VALIDATE_CARD(card); + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, card_names[card->card_type], sizeof(info.id)); + strncpy(info.name,card_names[card->card_type],sizeof(info.name)); + info.modify_counter = card->mix.modcnt; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, card_names[card->card_type], sizeof(info.id)); + strncpy(info.name,card_names[card->card_type],sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + + if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) + return -EINVAL; + + if (_IOC_DIR(cmd) == _IOC_READ) { + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* give them the current record source */ + + if(!card->mix.recmask_io) { + val = 0; + } else { + spin_lock_irqsave(&s->lock, flags); + val = card->mix.recmask_io(card,1,0); + spin_unlock_irqrestore(&s->lock, flags); + } + break; + + case SOUND_MIXER_DEVMASK: /* give them the supported mixers */ + val = card->mix.supported_mixers; + break; + + case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ + val = card->mix.record_sources; + break; + + case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ + val = card->mix.stereo_mixers; + break; + + case SOUND_MIXER_CAPS: + val = SOUND_CAP_EXCL_INPUT; + break; + + default: /* read a specific mixer */ + i = _IOC_NR(cmd); + + if ( ! supported_mixer(card,i)) + return -EINVAL; + + /* do we ever want to touch the hardware? */ +/* spin_lock_irqsave(&s->lock, flags); + val = card->mix.read_mixer(card,i); + spin_unlock_irqrestore(&s->lock, flags);*/ + + val = card->mix.mixer_state[i]; +/* M_printk("returned 0x%x for mixer %d\n",val,i);*/ + + break; + } + return put_user(val,(int *)arg); + } + + if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ)) + return -EINVAL; + + card->mix.modcnt++; + + get_user_ret(val, (int *)arg, -EFAULT); + + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + + if (!card->mix.recmask_io) return -EINVAL; + if(! (val &= card->mix.record_sources)) return -EINVAL; + + spin_lock_irqsave(&s->lock, flags); + card->mix.recmask_io(card,0,val); + spin_unlock_irqrestore(&s->lock, flags); + return 0; + + default: + i = _IOC_NR(cmd); + + if ( ! supported_mixer(card,i)) + return -EINVAL; + + spin_lock_irqsave(&s->lock, flags); + set_mixer(card,i,val); + spin_unlock_irqrestore(&s->lock, flags); + + return 0; + } +} + +/* --------------------------------------------------------------------- */ + +static loff_t ess_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* --------------------------------------------------------------------- */ + +static int ess_open_mixdev(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct ess_card *card = devs; + + while (card && card->dev_mixer != minor) + card = card->next; + if (!card) + return -ENODEV; + + file->private_data = card; + MOD_INC_USE_COUNT; + return 0; +} + +static int ess_release_mixdev(struct inode *inode, struct file *file) +{ + struct ess_card *card = (struct ess_card *)file->private_data; + + VALIDATE_CARD(card); + + MOD_DEC_USE_COUNT; + return 0; +} + +static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ess_card *card = (struct ess_card *)file->private_data; + + VALIDATE_CARD(card); + + return mixer_ioctl(card, cmd, arg); +} + +static /*const*/ struct file_operations ess_mixer_fops = { + &ess_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &ess_ioctl_mixdev, + NULL, /* mmap */ + &ess_open_mixdev, + NULL, /* flush */ + &ess_release_mixdev, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int drain_dac(struct ess_state *s, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count; + signed long tmo; + + if (s->dma_dac.mapped || !s->dma_dac.ready) + return 0; + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&s->dma_dac.wait, &wait); + for (;;) { + spin_lock_irqsave(&s->lock, flags); + count = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&s->dma_dac.wait, &wait); + current->state = TASK_RUNNING; + return -EBUSY; + } + tmo = (count * HZ) / s->ratedac; + tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]; + /* XXX this is just broken. someone is waking us up alot, or schedule_timeout is broken. + or something. who cares. - zach */ + if (!schedule_timeout(tmo ? tmo : 1) && tmo) + M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies); + } + remove_wait_queue(&s->dma_dac.wait, &wait); + current->state = TASK_RUNNING; + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ +/* Zach sez: "god this is gross.." */ +int comb_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset, + int count, int bufsize) +{ + /* No such thing as stereo recording, so we + use dual input mixers. which means we have to + combine mono to stereo buffer. yuck. + + but we don't have to be able to work a byte at a time..*/ + + unsigned char *so,*left,*right; + int i; + + so = tmp_buffer; + left = real_buffer + offset; + right = real_buffer + bufsize/2 + offset; + +/* M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/ + + for(i=count/4; i ; i--) { + (*(so+2)) = *(right++); + (*(so+3)) = *(right++); + (*so) = *(left++); + (*(so+1)) = *(left++); + so+=4; + } + + return 0; +} + +/* in this loop, dma_adc.count signifies the amount of data thats waiting + to be copied to the user's buffer. it is filled by the interrupt + handler and drained by this loop. */ +static ssize_t ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + unsigned char *combbuf = NULL; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_adc.mapped) + return -ENXIO; + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + return ret; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + if(!(combbuf = kmalloc(count,GFP_KERNEL))) + return -ENOMEM; + ret = 0; + + calc_bob_rate(s); + + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + /* remember, all these things are expressed in bytes to be + sent to the user.. hence the evil / 2 down below */ + swptr = s->dma_adc.swptr; + cnt = s->dma_adc.dmasize-swptr; + if (s->dma_adc.count < cnt) + cnt = s->dma_adc.count; + spin_unlock_irqrestore(&s->lock, flags); + + if (cnt > count) + cnt = count; + + if ( cnt > 0 ) cnt &= ~3; + + if (cnt <= 0) { + start_adc(s); + if (file->f_flags & O_NONBLOCK) + { + ret = ret ? ret : -EAGAIN; + goto rec_return_free; + } + if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { + printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", + s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, + s->dma_adc.hwptr, s->dma_adc.swptr); + stop_adc(s); + spin_lock_irqsave(&s->lock, flags); + set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift); + /* program enhanced mode registers */ + /* FILL ME */ +/* wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8); + wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */ + s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; + spin_unlock_irqrestore(&s->lock, flags); + } + if (signal_pending(current)) + { + ret = ret ? ret : -ERESTARTSYS; + goto rec_return_free; + } + continue; + } + + if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + /* swptr/2 so that we know the real offset in each apu's buffer */ + comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize); + if (copy_to_user(buffer, combbuf, cnt)) { + ret = ret ? ret : -EFAULT; + goto rec_return_free; + } + } else { + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + ret = ret ? ret : -EFAULT; + goto rec_return_free; + } + } + + swptr = (swptr + cnt) % s->dma_adc.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_adc.swptr = swptr; + s->dma_adc.count -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_adc(s); + } + +rec_return_free: + if(combbuf) kfree(combbuf); + return ret; +} + +/* god this is gross..*/ +/* again, the mode passed is shifted/masked */ +int split_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset, + int count, int bufsize, int mode) +{ + /* oh, bother. stereo decoding APU's don't work in 16bit so we + use dual linear decoders. which means we have to hack up stereo + buffer's we're given. yuck. */ + + unsigned char *so,*left,*right; + int i; + + so = tmp_buffer; + left = real_buffer + offset; + right = real_buffer + bufsize/2 + offset; + +/* M_printk("writing %d to %p and %p from %p:%d bufs: %d\n",count/2, left,right,real_buffer,offset,bufsize);*/ + + if(mode & ESS_FMT_16BIT) { + for(i=count/4; i ; i--) { + *(right++) = (*(so+2)); + *(right++) = (*(so+3)); + *(left++) = (*so); + *(left++) = (*(so+1)); + so+=4; + } + } else { + for(i=count/2; i ; i--) { + *(right++) = (*(so+1)); + *(left++) = (*so); + so+=2; + } + } + + return 0; +} + +static ssize_t ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + unsigned char *splitbuf = NULL; + int cnt; + int mode = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK; + +/* printk("maestro: ess_write: count %d\n", count);*/ + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_dac.mapped) + return -ENXIO; + if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + /* XXX be more clever than this.. */ + if (!(splitbuf = kmalloc(count,GFP_KERNEL))) + return -ENOMEM; + ret = 0; + + calc_bob_rate(s); + + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + + if (s->dma_dac.count < 0) { + s->dma_dac.count = 0; + s->dma_dac.swptr = s->dma_dac.hwptr; + } + swptr = s->dma_dac.swptr; + + if(mode & ESS_FMT_STEREO) { + /* in stereo we have the 'dual' buffers.. */ + cnt = ((s->dma_dac.dmasize/2)-swptr)*2; + } else { + cnt = s->dma_dac.dmasize-swptr; + } + if (s->dma_dac.count + cnt > s->dma_dac.dmasize) + cnt = s->dma_dac.dmasize - s->dma_dac.count; + + spin_unlock_irqrestore(&s->lock, flags); + + if (cnt > count) + cnt = count; + + /* our goofball stereo splitter can only deal in mults of 4 */ + if (cnt > 0) + cnt &= ~3; + + if (cnt <= 0) { + /* buffer is full, wait for it to be played */ + start_dac(s); + if (file->f_flags & O_NONBLOCK) { + if(!ret) ret = -EAGAIN; + goto return_free; + } + if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) { + printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", + s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, + s->dma_dac.hwptr, s->dma_dac.swptr); + stop_dac(s); + spin_lock_irqsave(&s->lock, flags); + set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift); + /* program enhanced mode registers */ +/* wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8); + wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); */ + /* FILL ME */ + s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; + spin_unlock_irqrestore(&s->lock, flags); + } + if (signal_pending(current)) { + if (!ret) ret = -ERESTARTSYS; + goto return_free; + } + continue; + } + if(mode & ESS_FMT_STEREO) { + if (copy_from_user(splitbuf, buffer, cnt)) { + if (!ret) ret = -EFAULT; + goto return_free; + } + split_stereo(s->dma_dac.rawbuf,splitbuf,swptr,cnt,s->dma_dac.dmasize, + mode); + } else { + if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { + if (!ret) ret = -EFAULT; + goto return_free; + } + } + + if(mode & ESS_FMT_STEREO) { + /* again with the weird pointer magic*/ + swptr = (swptr + (cnt/2)) % (s->dma_dac.dmasize/2); + } else { + swptr = (swptr + cnt) % s->dma_dac.dmasize; + } + spin_lock_irqsave(&s->lock, flags); + s->dma_dac.swptr = swptr; + s->dma_dac.count += cnt; + s->dma_dac.endcleared = 0; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_dac(s); + } +return_free: + if (splitbuf) kfree(splitbuf); + return ret; +} + +static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + poll_wait(file, &s->dma_dac.wait, wait); + if (file->f_mode & FMODE_READ) + poll_wait(file, &s->dma_adc.wait, wait); + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + if (file->f_mode & FMODE_READ) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (s->dma_dac.mapped) { + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +/* this needs to be fixed to deal with the dual apus/buffers */ +#if 0 +static int ess_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + struct dmabuf *db; + int ret; + unsigned long size; + + VALIDATE_STATE(s); + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf(s, 1)) != 0) + return ret; + db = &s->dma_dac; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf(s, 0)) != 0) + return ret; + db = &s->dma_adc; + } else + return -EINVAL; + if (vma->vm_offset != 0) + return -EINVAL; + size = vma->vm_end - vma->vm_start; + if (size > (PAGE_SIZE << db->buforder)) + return -EINVAL; + if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) + return -EAGAIN; + db->mapped = 1; + return 0; +} +#endif + +static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int val, mapped, ret; + unsigned char fmtm, fmtd; + +/* printk("maestro: ess_ioctl: cmd %d\n", cmd);*/ + + VALIDATE_STATE(s); + mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || + ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_dac(s, file->f_flags & O_NONBLOCK); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + /* XXX fix */ + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(0/*DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP*/, (int *)arg); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + synchronize_irq(); + s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + synchronize_irq(); + s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; + } + return 0; + + case SNDCTL_DSP_SPEED: + get_user_ret(val, (int *)arg, -EFAULT); + if (val >= 0) { + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + set_adc_rate(s, val); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + set_dac_rate(s, val); + } + } + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + + case SNDCTL_DSP_STEREO: + get_user_ret(val, (int *)arg, -EFAULT); + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + if (val) + fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; + else + fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val) + fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; + else + fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); + } + set_fmt(s, fmtm, fmtd); + return 0; + + case SNDCTL_DSP_CHANNELS: + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 0) { + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + if (val >= 2) + fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; + else + fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val >= 2) + fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; + else + fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); + } + set_fmt(s, fmtm, fmtd); + } + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) + : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_S8|AFMT_S16_LE, (int *)arg); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != AFMT_QUERY) { + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + /* fixed at 16bit for now */ + fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; +#if 0 + if (val == AFMT_S16_LE) + fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; + else + fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT); +#endif + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val == AFMT_S16_LE) + fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT; + else + fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT); + } + set_fmt(s, fmtm, fmtd); + } + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? + (ESS_FMT_16BIT << ESS_ADC_SHIFT) + : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? + AFMT_S16_LE : + AFMT_S8, + (int *)arg); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && s->enable & ESS_ENABLE_RE) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && s->enable & ESS_ENABLE_PE) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + return ret; + start_adc(s); + } else + stop_adc(s); + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) + return ret; + start_dac(s); + } else + stop_dac(s); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!(s->enable & ESS_ENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + abinfo.fragsize = s->dma_dac.fragsize; + abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; + abinfo.fragstotal = s->dma_dac.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!(s->enable & ESS_ENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + abinfo.fragsize = s->dma_adc.fragsize; + abinfo.bytes = s->dma_adc.count; + abinfo.fragstotal = s->dma_adc.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + val = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + return put_user(val, (int *)arg); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + cinfo.bytes = s->dma_adc.total_bytes; + cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; + cinfo.ptr = s->dma_adc.hwptr; + if (s->dma_adc.mapped) + s->dma_adc.count &= s->dma_adc.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + ess_update_ptr(s); + cinfo.bytes = s->dma_dac.total_bytes; + cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; + cinfo.ptr = s->dma_dac.hwptr; + if (s->dma_dac.mapped) + s->dma_dac.count &= s->dma_dac.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf(s, 0))) + return val; + return put_user(s->dma_dac.fragsize, (int *)arg); + } + if ((val = prog_dmabuf(s, 1))) + return val; + return put_user(s->dma_adc.fragsize, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + s->dma_adc.ossfragshift = val & 0xffff; + s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_adc.ossfragshift < 4) + s->dma_adc.ossfragshift = 4; + if (s->dma_adc.ossfragshift > 15) + s->dma_adc.ossfragshift = 15; + if (s->dma_adc.ossmaxfrags < 4) + s->dma_adc.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + s->dma_dac.ossfragshift = val & 0xffff; + s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_dac.ossfragshift < 4) + s->dma_dac.ossfragshift = 4; + if (s->dma_dac.ossfragshift > 15) + s->dma_dac.ossfragshift = 15; + if (s->dma_dac.ossmaxfrags < 4) + s->dma_dac.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || + (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + s->dma_adc.subdivision = val; + if (file->f_mode & FMODE_WRITE) + s->dma_dac.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + + case SOUND_PCM_READ_CHANNELS: + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) + : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg); + + case SOUND_PCM_READ_BITS: + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) + : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + + } + return -EINVAL; +} + +static int ess_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct ess_card *c = devs; + struct ess_state *s = NULL, *sp; + int i; + unsigned char fmtm = ~0, fmts = 0; + + /* + * Scan the cards and find the channel. We only + * do this at open time so it is ok + */ + + while (c!=NULL) + { + for(i=0;i<NR_DSPS;i++) + { + sp=&c->channels[i]; + if(sp->dev_audio < 0) + continue; + if((sp->dev_audio ^ minor) & ~0xf) + continue; + s=sp; + } + c=c->next; + } + + if (!s) + return -ENODEV; + + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & file->f_mode) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EWOULDBLOCK; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + if (file->f_mode & FMODE_READ) { +/* + fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT); + if ((minor & 0xf) == SND_DEV_DSP16) + fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */ + + fmtm = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT; + + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; + set_adc_rate(s, 8000); + } + if (file->f_mode & FMODE_WRITE) { + fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT); + if ((minor & 0xf) == SND_DEV_DSP16) + fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT; + s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; + set_dac_rate(s, 8000); + } + set_fmt(s, fmtm, fmts); + s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + + /* we're covered by the open_sem */ + if( ! s->card->bob_running ) + start_bob(s); + s->card->bob_running++; + M_printk("maestro: open, %d bobs now\n",s->card->bob_running); + + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int ess_release(struct inode *inode, struct file *file) +{ + struct ess_state *s = (struct ess_state *)file->private_data; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + drain_dac(s, file->f_flags & O_NONBLOCK); + down(&s->open_sem); + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + } + + /* free our shared dma buffers */ + dealloc_dmabuf(&s->dma_adc); + dealloc_dmabuf(&s->dma_dac); + + s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); + /* we're covered by the open_sem */ + M_printk("maestro: %d -1 bob clients\n",s->card->bob_running); + if( --s->card->bob_running <= 0) { + stop_bob(s); + } + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations ess_audio_fops = { + &ess_llseek, + &ess_read, + &ess_write, + NULL, /* readdir */ + &ess_poll, + &ess_ioctl, + NULL, /* XXX &ess_mmap, */ + &ess_open, + NULL, /* flush */ + &ess_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +#ifdef CONFIG_APM +int maestro_apm_callback(apm_event_t ae) { + + struct ess_card *s; + + if(ae != APM_USER_SUSPEND) + return 0; + + printk("suspending.. blowing away apus\n"); + + while ((s = devs)) { + int i; + devs = devs->next; + + for(i=0;i<NR_DSPS;i++) { + struct ess_state *ess = &s->channels[i]; + int j; + + if(ess->dev_audio == -1) + continue; + + for(j=0;j<6;j++) { + apu_set_register(ess, ess->apu[j], 0, + (apu_get_register(ess, ess->apu[j], 0)&0xFF0F)); + } + + } + } + if(devs) { + printk("suspending.. stopping bob\n"); + stop_bob(devs); + } + + return 0; +} +#endif + +void free_mixpage(struct ess_card *card) { + if (card->mixpage) { + /* undo marking the page as reserved */ + clear_bit(PG_reserved, &mem_map[MAP_NR(card->mixpage)].flags); + /* free mixpage */ + free_pages((unsigned long)card->mixpage, 1); + } +} +/* --------------------------------------------------------------------- */ + +static int maestro_install(struct pci_dev *pcidev, int card_type) +{ + u16 w; + u32 n; + int iobase; + int i; + struct ess_card *card; + struct ess_state *ess; + int apu; + int num = 0; + + /* don't pick up weird modem maestros */ + if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) + return 0; + + iobase = pcidev->resource[0].start; + + if(check_region(iobase, 256)) + { + printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase); + return 0; + } + + /* this was tripping up some machines */ + if(pcidev->irq == 0) + { + printk(KERN_WARNING "maestro: pci subsystem reports irq 0, this might not be correct.\n"); + } + + /* just to be sure */ + pci_set_master(pcidev); + + card = kmalloc(sizeof(struct ess_card), GFP_KERNEL); + if(card == NULL) + { + printk(KERN_WARNING "maestro: out of memory\n"); + return 0; + } + + memset(card, 0, sizeof(*card)); + + /* allocate a page for the input mixer APUs + 512 * NR_DSPS must fit in here !!*/ + if(!(card->mixpage = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, 1))) + { + printk(KERN_WARNING "maestro: can't allocate mixer page.\n"); + kfree(card); + return 0; + } + +#ifdef CONFIG_APM + printk("reg_callback: %d\n",apm_register_callback(maestro_apm_callback)); +#endif + /* mark the page reserved */ + set_bit(PG_reserved, &mem_map[MAP_NR(card->mixpage)].flags); + + card->iobase = iobase; + card->card_type = card_type; + card->irq = pcidev->irq; + card->next = devs; + card->magic = ESS_CARD_MAGIC; + devs = card; + + /* init our groups of 6 apus */ + for(i=0;i<NR_DSPS;i++) + { + struct ess_state *s=&card->channels[i]; + + s->card = card; + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac.wait); + init_waitqueue_head(&s->open_wait); + init_MUTEX(&s->open_sem); + s->magic = ESS_STATE_MAGIC; + + s->apu[0] = 6*i; + s->apu[1] = (6*i)+1; + s->apu[2] = (6*i)+2; + s->apu[3] = (6*i)+3; + s->apu[4] = (6*i)+4; + s->apu[5] = (6*i)+5; + + if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf) + printk("maestro: BOTCH!\n"); + /* register devices */ + if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0) + break; + /* divide the page into smaller chunks */ + s->mixbuf = card->mixpage + (i * 512); + } + + num = i; + + /* clear the rest if we ran out of slots to register */ + for(;i<NR_DSPS;i++) + { + struct ess_state *s=&card->channels[i]; + s->dev_audio = -1; + } + + ess = &card->channels[0]; + + /* + * Ok card ready. Begin setup proper + */ + + printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", + card_names[card_type],iobase,card->irq); + pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n); + printk(KERN_INFO "maestro: subvendor id: 0x%08x\n",n); + + /* + * Disable ACPI + */ + + pci_write_config_dword(pcidev, 0x54, 0x00000000); + pci_write_config_dword(pcidev, 0x56, 0x00000000); + + /* + * Use TDMA for now. TDMA works on all boards, so while its + * not the most efficient its the simplest. + */ + + pci_read_config_word(pcidev, 0x50, &w); + + /* Clear DMA bits */ + w&=~(1<<10|1<<9|1<<8); + + /* TDMA on */ + w|=(1<<8); + +/* XXX do we care about these two ? */ + /* + * MPU at 330 + */ + + w&=~((1<<4)|(1<<3)); + + /* + * SB at 0x220 + */ + + w&=~(1<<2); + +#if 0 /* huh? its sub decode.. */ + + /* + * Reserved write as 0 + */ + + w&=~(1<<1); +#endif + + /* + * Some of these are undocumented bits + */ + + w&=~(1<<13)|(1<<14); /* PIC Snoop mode bits */ + w&=~(1<<11); /* Safeguard off */ + w|= (1<<7); /* Posted write */ + w|= (1<<6); /* ISA timing on */ + w&=~(1<<1); /* Subtractive decode off */ + /* XXX huh? claims to be reserved.. */ + w&=~(1<<5); /* Don't swap left/right */ + + pci_write_config_word(pcidev, 0x50, w); + + pci_read_config_word(pcidev, 0x52, &w); + w&=~(1<<15); /* Turn off internal clock multiplier */ + /* XXX how do we know which to use? */ + w&=~(1<<14); /* External clock */ + + w&=~(1<<7); /* HWV off */ + w&=~(1<<6); /* Debounce off */ + w&=~(1<<5); /* GPIO 4:5 */ + w&=~(1<<4); /* Disconnect from the CHI */ + w&=~(1<<3); /* IDMA off (undocumented) */ + w&=~(1<<2); /* MIDI fix off (undoc) */ + w&=~(1<<1); /* reserved, always write 0 */ + w&=~(1<<0); /* IRQ to ISA off (undoc) */ + pci_write_config_word(pcidev, 0x52, w); + + /* + * DDMA off + */ + + pci_read_config_word(pcidev, 0x60, &w); + w&=~(1<<0); + pci_write_config_word(pcidev, 0x60, w); + + /* + * Legacy mode + */ + + pci_read_config_word(pcidev, 0x40, &w); + w|=(1<<15); /* legacy decode off */ + w&=~(1<<14); /* Disable SIRQ */ + w&=~(0x1f); /* disable mpu irq/io, game port, fm, SB */ + + pci_write_config_word(pcidev, 0x40, w); + + /* stake our claim on the iospace */ + request_region(iobase, 256, card_names[card_type]); + + sound_reset(iobase); + + /* + * Ring Bus Setup + */ + + /* setup usual 0x34 stuff.. 0x36 may be chip specific */ + outw(0xC090, iobase+0x34); /* direct sound, stereo */ + udelay(20); + outw(0x3000, iobase+0x36); /* direct sound, stereo */ + udelay(20); + + + /* + * Reset the CODEC + */ + + maestro_ac97_reset(iobase); + + /* + * Ring Bus Setup + */ + + n=inl(iobase+0x34); + n&=~0xF000; + n|=12<<12; /* Direct Sound, Stereo */ + outl(n, iobase+0x34); + + n=inl(iobase+0x34); + n&=~0x0F00; /* Modem off */ + outl(n, iobase+0x34); + + n=inl(iobase+0x34); + n&=~0x00F0; + n|=9<<4; /* DAC, Stereo */ + outl(n, iobase+0x34); + + n=inl(iobase+0x34); + n&=~0x000F; /* ASSP off */ + outl(n, iobase+0x34); + + + n=inl(iobase+0x34); + n|=(1<<29); /* Enable ring bus */ + outl(n, iobase+0x34); + + + n=inl(iobase+0x34); + n|=(1<<28); /* Enable serial bus */ + outl(n, iobase+0x34); + + n=inl(iobase+0x34); + n&=~0x00F00000; /* MIC off */ + outl(n, iobase+0x34); + + n=inl(iobase+0x34); + n&=~0x000F0000; /* I2S off */ + outl(n, iobase+0x34); + + w=inw(iobase+0x18); + w&=~(1<<7); /* ClkRun off */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w&=~(1<<6); /* Harpo off */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w&=~(1<<4); /* ASSP irq off */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w&=~(1<<3); /* ISDN irq off */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w|=(1<<2); /* Direct Sound IRQ on */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w&=~(1<<1); /* MPU401 IRQ off */ + outw(w, iobase+0x18); + + w=inw(iobase+0x18); + w|=(1<<0); /* SB IRQ on */ + outw(w, iobase+0x18); + + +#if 0 /* asp crap */ + outb(0, iobase+0xA4); + outb(3, iobase+0xA2); + outb(0, iobase+0xA6); +#endif + + for(apu=0;apu<16;apu++) + { + /* Write 0 into the buffer area 0x1E0->1EF */ + outw(0x01E0+apu, 0x10+iobase); + outw(0x0000, 0x12+iobase); + + /* + * The 1.10 test program seem to write 0 into the buffer area + * 0x1D0-0x1DF too. + */ + outw(0x01D0+apu, 0x10+iobase); + outw(0x0000, 0x12+iobase); + } + +#if 1 + wave_set_register(ess, IDR7_WAVE_ROMRAM, + (wave_get_register(ess, IDR7_WAVE_ROMRAM)&0xFF00)); + wave_set_register(ess, IDR7_WAVE_ROMRAM, + wave_get_register(ess, IDR7_WAVE_ROMRAM)|0x100); + wave_set_register(ess, IDR7_WAVE_ROMRAM, + wave_get_register(ess, IDR7_WAVE_ROMRAM)&~0x200); + wave_set_register(ess, IDR7_WAVE_ROMRAM, + wave_get_register(ess, IDR7_WAVE_ROMRAM)|~0x400); +#else + maestro_write(ess, IDR7_WAVE_ROMRAM, + (maestro_read(ess, IDR7_WAVE_ROMRAM)&0xFF00)); + maestro_write(ess, IDR7_WAVE_ROMRAM, + maestro_read(ess, IDR7_WAVE_ROMRAM)|0x100); + maestro_write(ess, IDR7_WAVE_ROMRAM, + maestro_read(ess, IDR7_WAVE_ROMRAM)&~0x200); + maestro_write(ess, IDR7_WAVE_ROMRAM, + maestro_read(ess, IDR7_WAVE_ROMRAM)|0x400); +#endif + + maestro_write(ess, IDR2_CRAM_DATA, 0x0000); + maestro_write(ess, 0x08, 0xB004); + /* Now back to the DirectSound stuff */ + maestro_write(ess, 0x09, 0x001B); + maestro_write(ess, 0x0A, 0x8000); + maestro_write(ess, 0x0B, 0x3F37); + maestro_write(ess, 0x0C, 0x0098); + + /* parallel out ?? */ + maestro_write(ess, 0x0C, + (maestro_read(ess, 0x0C)&~0xF000)|0x8000); + /* parallel in, has something to do with recording :) */ + maestro_write(ess, 0x0C, + (maestro_read(ess, 0x0C)&~0x0F00)|0x0500); + + maestro_write(ess, 0x0D, 0x7632); + + /* Wave cache control on - test off, sg off, + enable, enable extra chans 1Mb */ + + outw(inw(0x14+iobase)|(1<<8),0x14+iobase); + outw(inw(0x14+iobase)&0xFE03,0x14+iobase); + outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase); + outw(inw(0x14+iobase)|(1<<7),0x14+iobase); + + outw(0xA1A0, 0x14+iobase); /* 0300 ? */ + + if(maestro_ac97_get(iobase, 0x00)==0x0080) { + maestro_pt101_init(card,iobase); + } else { + maestro_ac97_init(card,iobase); + } + + if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) { + printk("maestro: couldn't register mixer!\n"); + } else { + int i; + for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) { + struct mixer_defaults *md = &mixer_defaults[i]; + + if(md->mixer == -1) break; + if( ! supported_mixer(card,md->mixer)) continue; + set_mixer(card,md->mixer,md->value); + } + } + + /* Now clear the channel data */ + for(apu=0;apu<64;apu++) + { + for(w=0;w<0x0E;w++) + apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0); + } + + if(request_irq(card->irq, ess_interrupt, SA_SHIRQ, card_names[card_type], card)) + { + printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq); + unregister_sound_mixer(card->dev_mixer); + for(i=0;i<NR_DSPS;i++) + { + struct ess_state *s = &card->channels[i]; + if(s->dev_audio != -1) + unregister_sound_dsp(s->dev_audio); + } + free_mixpage(card); + release_region(card->iobase, 256); + kfree(card); + return 0; + } + + printk("maestro: %d channels configured.\n", num); + return 1; +} + +#ifdef MODULE +int init_module(void) +#else +int __init init_maestro(void) +#endif +{ + struct pci_dev *pcidev = NULL; + int foundone = 0; + + if (!pci_present()) /* No PCI bus in this machine! */ + return -ENODEV; + printk(KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n"); + + pcidev = NULL; + + /* + * Find the ESS Maestro 2. + */ + + while( (pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO2) )) { + foundone=1; + } + + /* + * Find the ESS Maestro 2E + */ + + while((pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO2E) )) { + foundone=1; + } + + /* + * ESS Maestro 1 + */ + + while((pcidev = pci_find_device(PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO) )) { + foundone=1; + } + if( ! foundone ) + return -ENODEV; + return 0; +} + +/* --------------------------------------------------------------------- */ + +#ifdef MODULE + +MODULE_AUTHOR("Zach Brown <zab@redhat.com>, Alan Cox <alan@redhat.com>"); +MODULE_DESCRIPTION("ESS Maestro Driver"); +#ifdef M_DEBUG +MODULE_PARM(debug,"i"); +#endif + +void cleanup_module(void) +{ + struct ess_card *s; + +#ifdef CONFIG_APM + apm_unregister_callback(maestro_apm_callback); +#endif + while ((s = devs)) { + int i; + devs = devs->next; + + /* XXX maybe should force stop bob, but should be all + stopped by _release by now */ + free_irq(s->irq, s); + unregister_sound_mixer(s->dev_mixer); + for(i=0;i<NR_DSPS;i++) + { + struct ess_state *ess = &s->channels[i]; + if(ess->dev_audio != -1) + unregister_sound_dsp(ess->dev_audio); + } + free_mixpage(s); + release_region(s->iobase, 256); + kfree(s); + } + M_printk("maestro: unloading\n"); +} + +#endif /* MODULE */ + diff --git a/drivers/sound/maestro.h b/drivers/sound/maestro.h new file mode 100644 index 000000000..023ec7f96 --- /dev/null +++ b/drivers/sound/maestro.h @@ -0,0 +1,60 @@ +/* + * Registers for the ESS PCI cards + */ + +/* + * Memory access + */ + +#define ESS_MEM_DATA 0x00 +#define ESS_MEM_INDEX 0x02 + +/* + * AC-97 Codec port. Delay 1uS after each write. This is used to + * talk AC-97 (see intel.com). Write data then register. + */ + +#define ESS_AC97_INDEX 0x30 /* byte wide */ +#define ESS_AC97_DATA 0x32 + +/* + * Reading is a bit different. You write register|0x80 to ubdex + * delay 1uS poll the low bit of index, when it clears read the + * data value. + */ + +/* + * Control port. Not yet fully understood + * The value 0xC090 gets loaded to it then 0x0000 and 0x2800 + * to the data port. Then after 4uS the value 0x300 is written + */ + +#define RING_BUS_CTRL_L 0x34 +#define RING_BUS_CTRL_H 0x36 + +/* + * This is also used during setup. The value 0x17 is written to it + */ + +#define ESS_SETUP_18 0x18 + +/* + * And this one gets 0x000b + */ + +#define ESS_SETUP_A2 0xA2 + +/* + * And this 0x0000 + */ + +#define ESS_SETUP_A4 0xA4 +#define ESS_SETUP_A6 0xA6 + +/* + * Stuff to do with Harpo - the wave stuff + */ + +#define ESS_WAVETABLE_SIZE 0x14 +#define ESS_WAVETABLE_2M 0xA180 + diff --git a/drivers/sound/maestro_tables.h b/drivers/sound/maestro_tables.h new file mode 100644 index 000000000..1edf1850a --- /dev/null +++ b/drivers/sound/maestro_tables.h @@ -0,0 +1,333 @@ +/* + * Set up data block for the ESS soundblaster emulation. This is like + * the example code from ftp.esstech.com.tw (104T31.ZIP) + */ + +u16 asp_block_0[]= { + 0x7980, 0x003a, 0x7980, 0x007d, 0xbe3a, 0x8b00, 0xbe3a, 0x8b00, + 0xbe3a, 0x8b00, 0xbe3a, 0x8b00, 0xbe3a, 0x8b00, 0xbe3a, 0x8b00, + 0x7980, 0x0be6, 0x7980, 0x0069, 0xbe3a, 0x8b00, 0x8048, 0x6945, + 0xb801, 0x9045, 0x6941, 0xe388, 0x0031, 0x6944, 0xba50, 0xe38c, + 0x0031, 0x8b88, 0x6942, 0x304a, 0xe308, 0x0028, 0x6949, 0x9042, + 0x0042, 0xafa0, 0x8000, 0xafa0, 0x8000, 0x8042, 0x6944, 0xb801, + 0x9044, 0x0048, 0xbe3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xbe41, 0xbf80, 0x0101, 0x8806, 0x8804, 0xb912, + 0x8807, 0xbc26, 0xbe40, 0xb92f, 0x9001, 0x9002, 0x003b, 0x0122, + 0x7a88, 0x0055, 0x003a, 0x013c, 0x7a88, 0x0055, 0x4902, 0xe100, + 0x0800, 0x0c02, 0xa000, 0x7980, 0x004e, 0xb908, 0x8809, 0xbec6, + 0x0067, 0x4a80, 0xe200, 0x0065, 0x4880, 0xe200, 0x0063, 0xb97f, + 0x6e80, 0x7980, 0x0066, 0x1089, 0x9088, 0xb900, 0x90a9, 0x8ba8, + 0xef00, 0x803d, 0x0003, 0x1007, 0x881f, 0x8b88, 0xbb0f, 0xada0, + 0x0810, 0x9003, 0x4903, 0xe200, 0x007b, 0x9002, 0x6a05, 0x6d04, + 0x9803, 0x9804, 0x9005, 0x003d, 0xbe3a, 0xaf06, 0x0000, 0x803d, + 0x8b88, 0x6906, 0x8810, 0xaf06, 0x0001, 0xbfb0, 0x00ff, 0xbaf5, + 0xe3cc, 0x009a, 0x5e06, 0x003f, 0xbf80, 0x0080, 0x4a06, 0xe200, + 0x0095, 0x6e80, 0x6d06, 0x7980, 0x009b, 0x9080, 0x0810, 0xba46, + 0x8810, 0x8b00, 0x1006, 0x9080, 0x003d, 0xbe3a, 0x1024, 0x2009, + 0x8810, 0x8b88, 0x8b00, 0x1089, 0xbfb0, 0x000e, 0xbe0a, 0x880d, + 0x903e, 0x1038, 0x2008, 0x8810, 0x1037, 0x2008, 0x8811, 0x5f3e, + 0x0000, 0x8b00, 0xf500, 0x5e80, 0xfffe, 0x1039, 0x2008, 0x8815, + 0x8b8d, 0x0231, 0x0333, 0x108a, 0x90ad, 0x1025, 0x200a, 0x8815, + 0x0605, 0xb91f, 0x8809, 0x4f16, 0x1080, 0xf600, 0xbfb0, + 0x0003, 0xbfb0, 0x0007, 0x9089, 0xbe47, 0xbe43, 0xbec6, + 0x00f6, 0x4f8b, 0x14a8, 0xe500, 0x6380, 0x8b89, 0x4e8a, + 0xbfe3, 0xe500, 0x2480, 0xbe46, 0x8b9d, 0xbfe7, 0xbfb0, + 0x00ff, 0x288c, 0x2026, 0x8814, 0xbe47, 0x8b00, 0x738f, + 0x54aa, 0xbe03, 0xbe0a, 0x2fa8, 0x988a, 0x8da9, 0xbe03, + 0x4d8e, 0xbfe1, 0xf500, 0x6180, 0x9880, 0x8ba9, 0xbe03, + 0x4c8e, 0xbfe1, 0xf500, 0x6180, 0x9880, 0x8ba9, 0xbe42, + 0x1039, 0x2008, 0x8815, 0x8b8d, 0x8b00, 0x8d8a, 0x7980, + 0x0bcf}; + +u16 asp_block_1[]={ + 0x0005, 0xb900, 0x9008, 0x9009, 0x900a, 0xbb3f, 0x90a0, + 0x001a, 0x011b, 0x021c, 0x0323, 0x1089, 0x9015, 0x108a, + 0x9016, 0x108b, 0x9017, 0x1088, 0x9018, 0x0137, 0x0524, + 0x8b8d, 0x4f16, 0xe200, 0x0827, 0x4f15, 0xe200, 0x0827, + 0x7a80, 0x08e6, 0x102c, 0xb802, 0x8813, 0x8b8b, 0xb900, + 0x90a0, 0x908d, 0x7980, 0x0833, 0x7a80, 0x0913, 0x7803, + 0x7a80, 0x0913, 0x102c, 0xb802, 0x8813, 0x8b8b, 0xb903, + 0x90a0, 0x908d, 0x7c02, 0x4f16, 0xe200, 0x0845, 0x4e15, + 0xe200, 0x0845, 0x7a80, 0x08e6, 0x102c, 0xb806, 0x8813, + 0x8b8b, 0xb901, 0x90a0, 0x908d, 0x7980, 0x0851, 0x7a80, + 0x0913, 0x7803, 0x7a80, 0x0913, 0x102c, 0xb806, 0x8813, + 0x8b8b, 0xb904, 0x90a0, 0x908d, 0x7c02, 0x4f16, 0xe200, + 0x0863, 0x4d15, 0xe200, 0x0863, 0x7a80, 0x08e6, 0x102c, + 0xb80a, 0x8813, 0x8b8b, 0xb902, 0x90a0, 0x908d, 0x7980, + 0x086f, 0x7a80, 0x0913, 0x7803, 0x7a80, 0x0913, 0x102c, + 0xb80a, 0x8813, 0x8b8b, 0xb905, 0x90a0, 0x908d, 0x7801, + 0x7a80, 0x0913, 0x7801, 0x7a80, 0x0913, 0x7801, 0x7a80, + 0x0913, 0x1024, 0xbf90, 0x0100, 0x8815, 0x4f16, 0xe200, + 0x088e, 0x4c15, 0xe200, 0x088e, 0x7a80, 0x08e6, 0x102c, + 0xb814, 0x8813, 0x8b8b, 0xbf80, 0x0100, 0x90a0, 0x908d, + 0x7980, 0x089b, 0x7a80, 0x0913, 0x7803, 0x7a80, 0x0913, + 0x102c, 0xb814, 0x8813, 0x8b8b, 0xbf80, 0x0103, 0x90a0, + 0x908d, 0x7c02, 0x4f16, 0xe200, 0x08ae, 0x4b15, 0xe200, + 0x08ae, 0x7a80, 0x08e6, 0x102c, 0xb818, 0x8813, 0x8b8b, + 0xbf80, 0x0101, 0x90a0, 0x908d, 0x7980, 0x08bb, 0x7a80, + 0x0913, 0x7803, 0x7a80, 0x0913, 0x102c, 0xb818, 0x8813, + 0x8b8b, 0xbf80, 0x0104, 0x90a0, 0x908d, 0x7c02, 0x4f16, + 0xe200, 0x08ce, 0x4a15, 0xe200, 0x08ce, 0x7a80, 0x08e6, + 0x102c, 0xb81c, 0x8813, 0x8b8b, 0xbf80, 0x0102, 0x90a0, + 0x908d, 0x7980, 0x08db, 0x7a80, 0x0913, 0x7803, 0x7a80, + 0x0913, 0x102c, 0xb81c, 0x8813, 0x8b8b, 0xbf80, 0x0105, + 0x90a0, 0x908d, 0x7801, 0x7a80, 0x0913, 0x7801, 0x7a80, + 0x0913, 0x7801, 0x7a80, 0x0913, 0x7980, 0x0920, 0x4f80, + 0x7803, 0xe100, 0x08fe, 0x4f89, 0xe100, 0x08f5, 0xb901, + 0x90a0, 0xb902, 0x90a0, 0x90a0, 0xb906, 0x90ad, 0xef00, + 0xb901, 0x90a0, 0xb906, 0x90a0, 0xb900, 0x90a0, 0xb906, + 0x90ad, 0xef00, 0x4f89, 0xe100, 0x090a, 0xb905, 0x90a0, + 0xb900, 0x90a0, 0xb902, 0x90a0, 0xb906, 0x90ad, 0xef00, + 0xb905, 0x90a0, 0xb900, 0x90a0, 0xb906, 0x90a0, 0xb904, + 0x90ad, 0xef00, 0x4f89, 0xe100, 0x091b, 0xb901, 0x90a0, + 0xb906, 0x90ad, 0xef00, 0xb905, 0x90a0, 0xb904, 0x90ad, + 0xef00, 0xb91f, 0x8809, 0x0034, 0x8b88, 0xbec6, 0x0932, + 0x1313, 0xbe1e, 0x1014, 0xbe1a, 0xbe01, 0xbfe8, 0xbe17, + 0x6a13, 0x6214, 0xbe14, 0x9813, 0x9014, 0x98a0, 0xbe47, + 0x5f0f, 0x002e, 0xe200, 0x093d, 0xbf80, 0xffd2, 0x900f, + 0x7980, 0x0940, 0x100f, 0xb801, 0x900f, 0x400f, 0x8b00, + 0xe500, 0xbe01, 0xbe09, 0x9010, 0xbe46, 0x5f11, 0x003f, + 0xe200, 0x094f, 0xb900, 0x9011, 0x7980, 0x0952, 0x1011, + 0xb801, 0x9011, 0x1001, 0xe388, 0x0bcf, 0x1021, 0x2009, + 0x8813, 0x8b8b, 0x8b00, 0x1080, 0xbfe6, 0x7810, 0x8b00, + 0x8b00, 0x2180, 0xbfb0, 0x0007, 0x4c11, 0x8b00, 0xe100, + 0x096c, 0x4b11, 0x8b00, 0xe600, 0xb900, 0x7980, 0x096d, + 0xbe0a, 0x4a11, 0x8b00, 0xe500, 0xbe01, 0x9012, 0x1037, + 0x2008, 0x8811, 0x102e, 0x2008, 0x8812, 0x4a89, 0xb901, + 0xe500, 0x9019, 0xe100, 0x09c9, 0xb900, 0x9019, 0x4a18, + 0xe200, 0x09c9, 0x5f0a, 0x0010, 0xe200, 0x098d, 0x4b18, + 0xb901, 0xe500, 0x9019, 0x7980, 0x09c9, 0x5f0a, 0x0013, + 0xe200, 0x0997, 0x4b18, 0xb901, 0xe500, 0x9019, 0x7980, + 0x09c9, 0x5f0a, 0x0011, 0xe200, 0x09a4, 0x4f18, 0xb905, + 0xe500, 0x9080, 0xb901, 0xe500, 0x9019, 0x7980, 0x09c9, + 0x5f0a, 0x0014, 0xe200, 0x09b1, 0x4c18, 0xb904, 0xe500, + 0x9080, 0xb901, 0xe500, 0x9019, 0x7980, 0x09c9, 0x5f0a, + 0x0012, 0xe200, 0x09be, 0x4d18, 0xb905, 0xe500, 0x9080, + 0xb901, 0xe500, 0x9019, 0x7980, 0x09c9, 0x5f0a, 0x0015, + 0xe200, 0x09c9, 0x4e18, 0xb904, 0xe500, 0x9080, 0xb901, + 0xe500, 0x9019, 0x8b8a, 0x4f19, 0xe200, 0x09d4, 0x4b80, + 0xe200, 0x09d6, 0x5d80, 0x0020, 0x7980, 0x09d9, 0x5d80, + 0x0010, 0x4a80, 0xe200, 0x0bca, 0x1001, 0xba01, 0x9001, + 0x1024, 0x2009, 0x8815, 0x8b89, 0x4d8d, 0xe200, 0x09f8, + 0x4f16, 0xe100, 0x09ed, 0x8b89, 0x1080, 0xbfc0, 0x000c, + 0x908c, 0x7980, 0x09f8, 0x4b89, 0x108d, 0xf600, 0xbfb0, + 0x0003, 0x4a89, 0x8b00, 0xf500, 0xbfc0, 0x0008, 0x908c, + 0x1022, 0x2009, 0x8811, 0x102e, 0x2008, 0x8812, 0x102f, + 0x2008, 0x8813, 0x1020, 0x200a, 0x8814, 0x101d, 0x200a, + 0x8815, 0x8b8a, 0x4f19, 0xe100, 0x0a11, 0x5e80, 0x0020, + 0x5d80, 0x0018, 0x7980, 0x0a3e, 0x4f80, 0xe200, 0x0a1e, + 0x8b8b, 0x108a, 0xbfa0, 0x7fc0, 0x8b00, 0xf704, 0x5c80, + 0x0003, 0x7980, 0x0a3e, 0x4e80, 0xe200, 0x0a36, 0x8b8c, + 0x178b, 0xbe01, 0xbfb7, 0x00f0, 0x308a, 0xe344, 0x0a3e, + 0x8b8d, 0x4a8a, 0x8b00, 0xe200, 0x0a32, 0x5c80, 0x0006, + 0x7980, 0x0a3e, 0x5c80, 0x000a, 0x7980, 0x0a3e, 0x4c80, + 0xe200, 0x0a3e, 0x4b80, 0x8b00, 0xf500, 0x5c80, 0x0019, + 0x4f80, 0xe200, 0x0a4d, 0x101f, 0x200a, 0x8816, 0x8b00, + 0x8b00, 0x8b8e, 0x1780, 0xbfb7, 0x00f0, 0x900b, 0x7980, + 0x0a64, 0x4e80, 0xe200, 0x0a5c, 0x101f, 0x200a, 0x8816, + 0x8b00, 0x8b00, 0x8b8e, 0x1b80, 0xbfbb, 0x000f, 0x900b, + 0x7980, 0x0a64, 0x4c80, 0xe200, 0x0a64, 0x8b8c, 0x1b80, + 0xbfbb, 0x000f, 0x900b, 0x8b89, 0x1880, 0xbfb8, 0x001c, + 0x4917, 0xe100, 0x0a6e, 0x4f80, 0x7980, 0x0a70, 0x4e80, + 0x8b00, 0xf500, 0xbf98, 0x0002, 0x8b8d, 0x4b89, 0x8b00, + 0xe600, 0xbfe1, 0x903e, 0xbe43, 0x6a0b, 0x613e, 0xbfe8, + 0x980c, 0xbe42, 0x7c10, 0x1080, 0xbfe5, 0xbe1e, 0x7810, + 0x1280, 0xbfb2, 0x001f, 0xbe11, 0x2027, 0x8811, 0x101e, + 0x200a, 0x8816, 0x8b00, 0x128e, 0x4980, 0xe100, 0x0a9b, + 0x4880, 0xe100, 0x0a98, 0xb900, 0x7980, 0x0a9f, 0xbe0a, + 0x7980, 0x0a9f, 0x4880, 0xe200, 0x0a9f, 0xbe09, 0xbe1e, + 0x158d, 0xbfb5, 0x003f, 0xbe11, 0x4889, 0xe200, 0x0aae, + 0xbe1e, 0x1010, 0x4818, 0x8b00, 0xe600, 0xbfe1, 0xbe11, + 0xbfe1, 0x8811, 0xbe1e, 0xb9ff, 0x8819, 0x8b00, 0x8b00, + 0xbf46, 0x8b00, 0xe600, 0xbe1f, 0xbe01, 0xbfb0, 0x00ff, + 0x202a, 0x8811, 0x8b00, 0x8b00, 0x108a, 0x900d, 0xb91f, + 0x8809, 0x0732, 0x730d, 0x4f80, 0xe200, 0x0ad8, 0x1028, + 0x200c, 0x8815, 0xbe43, 0x8b8b, 0x6a8d, 0xbec6, 0x0ad4, + 0x618b, 0x9880, 0x548f, 0x8dad, 0xbe42, 0x7980, 0x0b24, + 0x4e80, 0xe200, 0x0af9, 0x8b8c, 0x178b, 0xbe01, 0xbfb7, + 0x00f0, 0x903e, 0x1029, 0x200c, 0x8815, 0x108d, 0xbec6, + 0x0af6, 0x308b, 0xbe1e, 0x303e, 0x903f, 0x403f, 0xbe1f, + 0xe500, 0x103e, 0x9080, 0xbfe6, 0x202a, 0x8811, 0x8b00, + 0x1089, 0x548f, 0x8dad, 0x7980, 0x0b24, 0x4c8b, 0xe200, + 0x0b1b, 0x1029, 0x200c, 0x8815, 0xbf80, 0x007f, 0x903e, + 0x108d, 0xbec6, 0x0b14, 0x308b, 0xbe1e, 0x303e, 0x903f, + 0x403f, 0xbe1f, 0xe500, 0xb900, 0x9080, 0xbfe6, 0x202a, + 0x8811, 0x8b00, 0x1089, 0x548f, 0x8dad, 0x8b8a, 0xf500, + 0x5e80, 0xffdf, 0x7980, 0x0b24, 0x1089, 0xbfe6, 0x202a, + 0x8811, 0x8b00, 0x8b00, 0x548f, 0xbb1f, 0x8da0, 0x8b8f, + 0x0732, 0x1021, 0x2009, 0x8811, 0x8b89, 0x101d, 0x200a, + 0x8812, 0x1080, 0x7810, 0x8b00, 0xbe47, 0x288a, 0xbfb0, + 0x03ff, 0x4989, 0xe200, 0x0b3e, 0xbe1e, 0x1012, 0x4918, + 0x8b00, 0xe600, 0xbe0a, 0xbe11, 0x900e, 0xbe46, 0x108a, + 0xbfb0, 0x001c, 0xbfe1, 0x880d, 0x8b00, 0x6b0e, 0xbe0a, + 0x880c, 0x108c, 0xbfb0, 0x000f, 0x202d, 0x8814, 0x8b00, + 0x8b00, 0x5589, 0xbf03, 0x8c0e, 0xbf00, 0x1030, 0x2008, + 0x8811, 0xb91f, 0x8809, 0x108b, 0x0333, 0xbec6, 0x0b5f, + 0x200e, 0x90a0, 0x8b00, 0x8b89, 0x9080, 0x4a18, 0xe200, + 0x0b7a, 0x5f0a, 0x0011, 0xe200, 0x0b6c, 0x4f18, 0xe900, + 0x0b7c, 0x5f0a, 0x0014, 0xe200, 0x0b73, 0x4c18, 0xe900, + 0x0b9b, 0x5f0a, 0x0015, 0xe200, 0x0b7a, 0x4e18, 0xe900, + 0x0bb2, 0x7980, 0x009e, 0x0034, 0xb91f, 0x8809, 0x0333, + 0x8b8b, 0xbec6, 0x0b99, 0x1280, 0x6c80, 0xbfea, 0xbe1e, + 0x1580, 0x6c88, 0xbfec, 0xbe13, 0x903e, 0x6cab, 0x903f, + 0x4f3e, 0xb900, 0xf500, 0xbf80, 0x8000, 0x4f3f, 0xbf90, + 0x0d00, 0xf500, 0xbf90, 0x2700, 0x90a0, 0xef00, 0x0034, + 0xb91f, 0x8809, 0x0333, 0x8b88, 0xbec6, 0x0bb0, 0x1eab, + 0x6c80, 0xbfed, 0x903e, 0x4180, 0xb900, 0xf500, 0xbf80, + 0x8000, 0x4f3e, 0x8b00, 0xf500, 0xbf90, 0x4000, 0x90a8, + 0xef00, 0x0034, 0xb91f, 0x8809, 0x0333, 0x8b8b, 0xbec6, + 0x0bc8, 0x1280, 0x6c8b, 0xbfea, 0xbe1e, 0x1580, 0x6c80, + 0xbfec, 0xbe13, 0x903e, 0x4f3e, 0xbf80, 0x4000, 0xf500, + 0xbf90, 0x8000, 0x90a0, 0xef00, 0x0231, 0x8b8a, 0xb900, + 0xbb20, 0x90a0, 0x5f08, 0x0023, 0xe100, 0x0043, 0x1008, + 0xb801, 0x9008, 0x102b, 0x2008, 0x8812, 0x8b00, 0x8b00, + 0x1080, 0x900a, 0x102c, 0x2008, 0x8812, 0x8b00, 0x8b00, + 0x1080, 0x9009, 0x7980, 0x0952, 0x8148, 0x6946, 0xb801, + 0x9046, 0xb901, 0x9041, 0x6944, 0xba08, 0xe344, 0x0bfe, + 0x9044, 0x8b89, 0x0143, 0x694b, 0x881f, 0xbb0f, 0xada0, + 0x8143, 0x0811, 0x304a, 0xe308, 0x0bfe, 0x6949, 0x9043, + 0x0148, 0xbe3a +}; + +u16 asp_block_2[]={ + 0x0000, 0x0000, 0x0003, 0x0003, 0x0001, 0x0001, + 0x0004, 0x0004, 0x0002, 0x0002, 0x0005, 0x0005, + 0x0006, 0x0006, 0x0007, 0x0007, 0x0008, 0x0008, + 0x0100, 0x0100, 0x0103, 0x0103, 0x0101, 0x0101, + 0x0104, 0x0104, 0x0102, 0x0102, 0x0105, 0x0105, + 0x0106, 0x0106, 0x0107, 0x0107, 0x0108, 0x0108 +}; + +u16 asp_block_3[]={ + 0x0000, 0x0000, 0x0000, 0x1200, 0x1200, 0x1280, 0x0000, 0x05d0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1104, 0x1105, 0x1008, 0x1020, 0x1040, 0x1060, + 0x1080, 0x10a0, 0x10b0, 0x100d, 0x1010, 0x10e0, 0x2000, 0x2980, + 0x2b00, 0x2b40, 0x2a00, 0x2b90, 0x13dc, 0x2b80, 0x11bc, 0x134c, + 0x1370, 0x12e0, 0x1240, 0x1260, 0x12c0, 0x009e, 0x0045, 0x10bc, + 0x1394, 0x13b8, 0x11f6, 0x10f6, 0x11b0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0815, 0x0956, 0x09df, 0x0be5, 0x0a19, 0x0a48, 0x0b37, + 0x0b5d, 0x0a8b, 0x0aae, 0x0ad2 }; + + +u16 asp_block_4[] = { + 0x0192, 0x04b6, 0x07d9, 0x0afb, 0x0e1c, 0x113a, 0x1455, 0x176e, + 0x1a83, 0x1d93, 0x209f, 0x23a7, 0x26a8, 0x29a4, 0x2c99, 0x2f87, + 0x326e, 0x354e, 0x3825, 0x3af3, 0x3db8, 0x4074, 0x4326, 0x45cd, + 0x486a, 0x4afb, 0x4d81, 0x4ffb, 0x5269, 0x54ca, 0x571e, 0x5964, + 0x5b9d, 0x5dc8, 0x5fe4, 0x61f1, 0x63ef, 0x65de, 0x67bd, 0x698c, + 0x6b4b, 0x6cf9, 0x6e97, 0x7023, 0x719e, 0x7308, 0x7460, 0x75a6, + 0x76d9, 0x77fb, 0x790a, 0x7a06, 0x7aef, 0x7bc6, 0x7c89, 0x7d3a, + 0x7dd6, 0x7e60, 0x7ed6, 0x7f38, 0x7f87, 0x7fc2, 0x7fea, 0x7ffe, + 0x7ffe, 0x7fea, 0x7fc2, 0x7f87, 0x7f38, 0x7ed6, 0x7e60, 0x7dd6, + 0x7d3a, 0x7c89, 0x7bc6, 0x7aef, 0x7a06, 0x790a, 0x77fb, 0x76d9, + 0x75a6, 0x7460, 0x7308, 0x719e, 0x7023, 0x6e97, 0x6cf9, 0x6b4b, + 0x698c, 0x67bd, 0x65de, 0x63ef, 0x61f1, 0x5fe4, 0x5dc8, 0x5b9d, + 0x5964, 0x571e, 0x54ca, 0x5269, 0x4ffb, 0x4d81, 0x4afb, 0x486a, + 0x45cd, 0x4326, 0x4074, 0x3db8, 0x3af3, 0x3825, 0x354e, 0x326e, + 0x2f87, 0x2c99, 0x29a4, 0x26a8, 0x23a7, 0x209f, 0x1d93, 0x1a83, + 0x176e, 0x1455, 0x113a, 0x0e1c, 0x0afb, 0x07d9, 0x04b6, 0x0192, + 0xfe6f, 0xfb4b, 0xf828, 0xf506, 0xf1e5, 0xeec7, 0xebac, 0xe893, + 0xe57e, 0xe26e, 0xdf62, 0xdc5a, 0xd959, 0xd65d, 0xd368, 0xd07a, + 0xcd93, 0xcab3, 0xc7dc, 0xc50e, 0xc249, 0xbf8d, 0xbcdb, 0xba34, + 0xb797, 0xb506, 0xb280, 0xb006, 0xad98, 0xab37, 0xa8e3, 0xa69d, + 0xa464, 0xa239, 0xa01d, 0x9e10, 0x9c12, 0x9a23, 0x9844, 0x9675, + 0x94b6, 0x9308, 0x916a, 0x8fde, 0x8e63, 0x8cf9, 0x8ba1, 0x8a5b, + 0x8928, 0x8806, 0x86f7, 0x85fb, 0x8512, 0x843b, 0x8378, 0x82c7, + 0x822b, 0x81a1, 0x812b, 0x80c9, 0x807a, 0x803f, 0x8017, 0x8003, + 0x8003, 0x8017, 0x803f, 0x807a, 0x80c9, 0x812b, 0x81a1, 0x822b, + 0x82c7, 0x8378, 0x843b, 0x8512, 0x85fb, 0x86f7, 0x8806, 0x8928, + 0x8a5b, 0x8ba1, 0x8cf9, 0x8e63, 0x8fde, 0x916a, 0x9308, 0x94b6, + 0x9675, 0x9844, 0x9a23, 0x9c12, 0x9e10, 0xa01d, 0xa239, 0xa464, + 0xa69d, 0xa8e3, 0xab37, 0xad98, 0xb006, 0xb280, 0xb506, 0xb797, + 0xba34, 0xbcdb, 0xbf8d, 0xc249, 0xc50e, 0xc7dc, 0xcab3, 0xcd93, + 0xd07a, 0xd368, 0xd65d, 0xd959, 0xdc5a, 0xdf62, 0xe26e, 0xe57e, + 0xe893, 0xebac, 0xeec7, 0xf1e5, 0xf506, 0xf828, 0xfb4b, 0xfe6f, + 0x7cc3, 0x725e, 0x68d5, 0x6017, 0x5813, 0x50b9, 0x49fb, 0x43cd, + 0x3e22, 0x38ef, 0x342b, 0x2fcc, 0x2bc9, 0x281c, 0x24be, 0x21a6, + 0x1ed1, 0x1c37, 0x19d5, 0x17a6, 0x15a5, 0x13ce, 0x121f, 0x1093, + 0x0f28, 0x0ddc, 0x0cab, 0x0b93, 0x0a92, 0x09a7, 0x08cf, 0x080a, + 0x0754, 0x06ae, 0x0615, 0x0589, 0x0509, 0x0494, 0x0428, 0x03c5, + 0x036a, 0x0317, 0x02cb, 0x0285, 0x0245, 0x020a, 0x01d4, 0x01a2, + 0x0175, 0x014b, 0x0125, 0x0102, 0x00e2, 0x00c5, 0x00aa, 0x0091, + 0x007b, 0x0066, 0x0053, 0x0041, 0x0031, 0x0022, 0x0015, 0x0009, + 0xfffe, 0xfff2, 0xffe5, 0xffd7, 0xffc8, 0xffb7, 0xffa5, 0xff91, + 0xff7b, 0xff64, 0xff4a, 0xff2e, 0xff0f, 0xfeee, 0xfec9, 0xfea1, + 0xfe76, 0xfe46, 0xfe13, 0xfdda, 0xfd9d, 0xfd5a, 0xfd11, 0xfcc1, + 0xfc6b, 0xfc0c, 0xfba5, 0xfb34, 0xfab9, 0xfa33, 0xf9a1, 0xf902, + 0xf854, 0xf797, 0xf6c8, 0xf5e7, 0xf4f1, 0xf3e5, 0xf2c1, 0xf183, + 0xf027, 0xeeac, 0xed0f, 0xeb4d, 0xe961, 0xe74a, 0xe501, 0xe284, + 0xdfcd, 0xdcd8, 0xd99d, 0xd618, 0xd242, 0xce12, 0xc982, 0xc487, + 0xbf1a, 0xb92e, 0xb2ba, 0xabaf, 0xa402, 0x9ba3, 0x9282, 0x888d, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 0x0010, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x000a, 0x000e, + 0x0010, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020, + 0x0000, 0x0000, 0x0000, 0x000a, 0x0010, 0x0016, 0x001a, 0x001e, + 0x0020, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, + 0x0000, 0x0000, 0x0010, 0x001a, 0x0020, 0x0026, 0x002a, 0x002e, + 0x0030, 0x0034, 0x0036, 0x0038, 0x003a, 0x003c, 0x003e, 0x0040, + 0x0000, 0x0010, 0x0020, 0x002a, 0x0030, 0x0036, 0x003a, 0x003e, + 0x0040, 0x0044, 0x0046, 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, + 0x0000, 0x0020, 0x0030, 0x003a, 0x0040, 0x0046, 0x004a, 0x004e, + 0x0050, 0x0054, 0x0056, 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, + 0x0000, 0x0030, 0x0040, 0x004a, 0x0050, 0x0056, 0x005a, 0x005e, + 0x0060, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, 0x0070, + 0x0008, 0x0021, 0x0042, 0x0064, 0x0086, 0x00a8, 0x00cb, 0x00ee, + 0x0111, 0x0135, 0x0158, 0x017d, 0x01a1, 0x01c6, 0x01eb, 0x0211, + 0x0236, 0x025d, 0x0283, 0x02aa, 0x02d1, 0x02f9, 0x0321, 0x0349, + 0x0372, 0x039b, 0x03c4, 0x03ee, 0x0418, 0x0442, 0x046d, 0x0499, + 0x04c4, 0x04f0, 0x051d, 0x054a, 0x0577, 0x05a5, 0x05d3, 0x0601, + 0x0630, 0x0660, 0x0690, 0x06c0, 0x06f1, 0x0722, 0x0753, 0x0785, + 0x07b8, 0x07eb, 0x081e, 0x0852, 0x0886, 0x08bb, 0x08f0, 0x0926, + 0x095c, 0x0993, 0x09ca, 0x0a02, 0x0a3a, 0x0a73, 0x0aac, 0x0ae6, + 0x0b20, 0x0b5b, 0x0b96, 0x0bd2, 0x0c0e, 0x0c4b, 0x0c89, 0x0cc7, + 0x0d05, 0x0d44, 0x0d84, 0x0dc5, 0x0e05, 0x0e47, 0x0e89, 0x0ecc, + 0x0f0f, 0x0f53, 0x0f97, 0x0fdd, 0x1022, 0x1069, 0x10b0, 0x10f7, + 0x1140, 0x1189, 0x11d2, 0x121c, 0x1267, 0x12b3, 0x12ff, 0x134c, + 0x139a, 0x13e8, 0x1438, 0x1487, 0x14d8, 0x1529, 0x157b, 0x15ce, + 0x1621, 0x1676, 0x16cb, 0x1720, 0x1777, 0x17ce, 0x1826, 0x187f, + 0x18d9, 0x1934, 0x198f, 0x19eb, 0x1a48, 0x1aa6, 0x1b05, 0x1b64, + 0x1bc5, 0x1c26, 0x1c88, 0x1ceb, 0x1d4f, 0x1db4, 0x1e1a, 0x1e80, + 0x1ee8, 0x1f51, 0x1fba, 0x2025, 0x2090, 0x20fc, 0x216a, 0x21d8, + 0x2247, 0x22b8, 0x2329, 0x239b, 0x240f, 0x2483, 0x24f9, 0x256f, + 0x25e7, 0x2660, 0x26da, 0x2755, 0x27d1, 0x284e, 0x28cc, 0x294b, + 0x29cc, 0x2a4e, 0x2ad1, 0x2b55, 0x2bda, 0x2c61, 0x2ce8, 0x2d71, + 0x2dfb, 0x2e87, 0x2f13, 0x2fa1, 0x3031, 0x30c1, 0x3153, 0x31e6, + 0x327b, 0x3310, 0x33a8, 0x3440, 0x34da, 0x3575, 0x3612, 0x36b0, + 0x3750, 0x37f1, 0x3893, 0x3937, 0x39dc, 0x3a83, 0x3b2c, 0x3bd6, + 0x3c81, 0x3d2e, 0x3ddd, 0x3e8d, 0x3f3f, 0x3ff2, 0x40a7, 0x415d, + 0x4216, 0x42d0, 0x438b, 0x4448, 0x4507, 0x45c8, 0x468b, 0x474f, + 0x4815, 0x48dd, 0x49a6, 0x4a72, 0x4b3f, 0x4c0e, 0x4cdf, 0x4db2, + 0x4e87, 0x4f5d, 0x5036, 0x5111, 0x51ed, 0x52cc, 0x53ac, 0x548f, + 0x5573, 0x565a, 0x5743, 0x582e, 0x591b, 0x5a0a, 0x5afb, 0x5bef, + 0x5ce4, 0x5ddc, 0x5ed7, 0x5fd3, 0x60d2, 0x61d3, 0x62d6, 0x63dc, + 0x64e4, 0x65ee, 0x66fb, 0x680a, 0x691c, 0x6a30, 0x6b47, 0x6c60, + 0x6d7c, 0x6e9a, 0x6fbb, 0x70de, 0x7204, 0x732d, 0x7459, 0x7587, + 0x76b8, 0x77eb, 0x7922, 0x7a5b, 0x7b97, 0x7cd6, 0x7e18, 0x7f5d, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0003, + 0x0003, 0x0004, 0x0004, 0x0005, 0x0006, 0x0008, 0x0009, 0x000a, + 0x000c, 0x0010, 0x0012, 0x0015, 0x0019, 0x0022, 0x0024, 0x002a, + 0x0031, 0x003e, 0x0049, 0x0055, 0x0062, 0x007c, 0x0092, 0x00a9, + 0x00c4, 0x00fc, 0x0125, 0x0152, 0x0187, 0x01f2, 0x024a, 0x02a4, + 0x030d, 0x03e3, 0x0492, 0x0547, 0x061b, 0x07c7, 0x0923, 0x0a8d, + 0x0c19, 0x0eb3, 0x1228, 0x14c1, 0x17fb, 0x1d17, 0x22f2, 0x2835, + 0x2dd4, 0x3cd0, 0x4cf5, 0x51cc, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0005, 0x0007, 0x0008, 0x000a, + 0x000b, 0x000e, 0x0011, 0x0014, 0x0017, 0x001c, 0x0022, 0x0028, + 0x002e, 0x0039, 0x0045, 0x0050, 0x005c, 0x0073, 0x008a, 0x00a0, + 0x00b9, 0x00e7, 0x0114, 0x0141, 0x0172, 0x01ce, 0x0228, 0x0283, + 0x02e3, 0x039b, 0x0454, 0x0501, 0x05bf, 0x072a, 0x0899, 0x0a18, + 0x0b7e, 0x0e55, 0x10d3, 0x1404, 0x16c3, 0x16c3, 0x16c3, 0x16c3, + 0x0012, 0x0024, 0x0048, 0x006c, 0x0090, 0x00b4, 0x00d8, 0x00fc, + 0x0120, 0x0144, 0x0168, 0x0168, 0x01b0, 0x01b0, 0x021c, 0x021c, + 0x0000, 0x0003, 0x0008, 0x000b, 0x0001, 0x0004, 0x0009, 0x000c, + 0x0002, 0x0005, 0x000a, 0x000d, 0x0010, 0x0013, 0x0011, 0x0014, + 0x0012, 0x0015, 0x0100, 0x0103, 0x0108, 0x010b, 0x0101, 0x0104, + 0x0109, 0x010c, 0x0102, 0x0105, 0x010a, 0x010d, 0x0110, 0x0113, + 0x0111, 0x0114, 0x0112, 0x0115 }; diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c index 531957453..75ea6c118 100644 --- a/drivers/sound/maui.c +++ b/drivers/sound/maui.c @@ -23,7 +23,7 @@ #include <linux/config.h> #include <linux/module.h> -#include <asm/init.h> +#include <linux/init.h> #define USE_SEQ_MACROS #define USE_SIMPLE_MACROS diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c index c73366b10..17089b0ad 100644 --- a/drivers/sound/mpu401.c +++ b/drivers/sound/mpu401.c @@ -437,6 +437,15 @@ static void mpu401_input_loop(struct mpu_config *devc) devc->m_busy = 0; } +int intchk_mpu401(void *dev_id) +{ + struct mpu_config *devc; + int dev = (int) dev_id; + + devc = &dev_conf[dev]; + return input_avail(devc); +} + void mpuintr(int irq, void *dev_id, struct pt_regs *dummy) { struct mpu_config *devc; @@ -1715,6 +1724,7 @@ static int mpu_timer_init(int midi_dev) EXPORT_SYMBOL(probe_mpu401); EXPORT_SYMBOL(attach_mpu401); EXPORT_SYMBOL(unload_mpu401); +EXPORT_SYMBOL(intchk_mpu401); EXPORT_SYMBOL(mpuintr); #ifdef MODULE diff --git a/drivers/sound/msnd.c b/drivers/sound/msnd.c index a3f73eded..4bfca0875 100644 --- a/drivers/sound/msnd.c +++ b/drivers/sound/msnd.c @@ -44,7 +44,7 @@ # include <linux/init.h> # include <asm/io.h> # include <asm/uaccess.h> -# include <asm/spinlock.h> +# include <linux/spinlock.h> #endif #include <asm/irq.h> #include "msnd.h" diff --git a/drivers/sound/nm256.h b/drivers/sound/nm256.h new file mode 100644 index 000000000..4cc720ab9 --- /dev/null +++ b/drivers/sound/nm256.h @@ -0,0 +1,254 @@ +#ifndef _NM256_H_ +#define _NM256_H_ + +#include "ac97.h" + +enum nm256rev { + REV_NM256AV, REV_NM256ZX +}; + +struct nm256_info +{ + /* Magic number used to verify that this struct is valid. */ +#define NM_MAGIC_SIG 0x55aa00ff + int magsig; + + /* Revision number */ + enum nm256rev rev; + + struct ac97_hwint mdev; + + /* Our audio device numbers. */ + int dev[2]; + + /* The # of times each device has been opened. (Should only be + 0 or 1). */ + int opencnt[2]; + + /* We use two devices, because we can do simultaneous play and record. + This keeps track of which device is being used for what purpose; + these are the actual device numbers. */ + int dev_for_play; + int dev_for_record; + + /* The mixer device. */ + int mixer_oss_dev; + + /* Can only be opened once for each operation. These aren't set + until an actual I/O operation is performed; this allows one + device to be open for read/write without inhibiting I/O to + the other device. */ + int is_open_play; + int is_open_record; + + /* Non-zero if we're currently playing a sample. */ + int playing; + /* Ditto for recording a sample. */ + int recording; + + /* The two memory ports. */ + char *ports[2]; + + /* Starting offset of the port1 area mapped into memory. */ + u32 port1_start; + /* Ending offset. */ + u32 port1_end; + /* The offset of the end of the actual buffer area. */ + u32 bufend; + + /* The following are offsets within memory port 1. */ + u32 coeffBuf; + u32 allCoeffBuf; + /* Record and playback buffers. */ + u32 abuf1, abuf2; + + /* Offset of the AC97 mixer in memory port 2. */ + u32 mixer; + + /* The sizes of the playback and record ring buffers. */ + u32 playbackBufferSize; + u32 recordBufferSize; + + /* Are the coefficient values in the memory cache current? */ + u8 coeffsCurrent; + + /* For writes, the amount we last wrote. */ + u32 requested_amt; + /* The start of the block currently playing. */ + u32 curPlayPos; + + /* The amount of data we requested to record. */ + u32 requestedRecAmt; + /* The offset of the currently-recording block. */ + u32 curRecPos; + /* The destination buffer. */ + char *recBuf; + + /* Our IRQ number. */ + int irq; + + /* A flag indicating how many times we've grabbed the IRQ. */ + int has_irq; + + /* The card interrupt service routine. */ + void (*introutine) (int, void *, struct pt_regs *); + + /* Current audio config, cached. */ + struct sinfo { + u32 samplerate; + u8 bits; + u8 stereo; + } sinfo[2]; /* goes with each device */ + + /* The cards are stored in a chain; this is the next card. */ + struct nm256_info *next_card; +}; + +/* Debug flag--bigger numbers mean more output. */ +extern int nm256_debug; + +/* Size of the second memory port. */ +#define NM_PORT2_SIZE 4096 +/* The location of the mixer. */ +#define NM_MIXER_BASE 0x600 +/* The maximum size of a coefficient entry. */ +#define NM_MAX_COEFFICIENT 0x5000 + +/* The interrupt register. */ +#define NM_INT_REG 0xa04 +/* And its bits. */ +#define NM_PLAYBACK_INT 0x40 +#define NM_RECORD_INT 0x100 +#define NM_MISC_INT_1 0x4000 +#define NM_MISC_INT_2 0x1 +#define NM_ACK_INT(CARD, X) nm256_writePort16((CARD), 2, NM_INT_REG, (X) << 1) + +/* For the second revision. It uses the same interrupt register, but it + holds 32 bits instead of 16. */ +#define NM2_PLAYBACK_INT 0x10000 +#define NM2_RECORD_INT 0x80000 +#define NM2_MISC_INT_1 0x8 +#define NM2_MISC_INT_2 0x2 +#define NM2_ACK_INT(CARD, X) nm256_writePort32((CARD), 2, NM_INT_REG, (X)) + +/* The playback registers start from here. */ +#define NM_PLAYBACK_REG_OFFSET 0x0 +/* The record registers start from here. */ +#define NM_RECORD_REG_OFFSET 0x200 + +/* The rate register is located 2 bytes from the start of the register + area. */ +#define NM_RATE_REG_OFFSET 2 + +/* Mono/stereo flag, number of bits on playback, and rate mask. */ +#define NM_RATE_STEREO 1 +#define NM_RATE_BITS_16 2 +#define NM_RATE_MASK 0xf0 + +/* Playback enable register. */ +#define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1) +#define NM_PLAYBACK_ENABLE_FLAG 1 +#define NM_PLAYBACK_ONESHOT 2 +#define NM_PLAYBACK_FREERUN 4 + +/* Mutes the audio output. */ +#define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18) +#define NM_AUDIO_MUTE_LEFT 0x8000 +#define NM_AUDIO_MUTE_RIGHT 0x0080 + +/* Recording enable register */ +#define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0) +#define NM_RECORD_ENABLE_FLAG 1 +#define NM_RECORD_FREERUN 2 + +#define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4) +#define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10) +#define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc) +#define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8) + +#define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4) +#define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14) +#define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc) +#define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8) + +/* A few trivial routines to make it easier to work with the registers + on the chip. */ + +/* This is a common code portion used to fix up the port offsets. */ +#define NM_FIX_PORT \ + if (port < 1 || port > 2 || card == NULL) \ + return -1; \ +\ + if (port == 1) { \ + if (offset < card->port1_start || offset >= card->port1_end) { \ + printk (KERN_ERR "Bad port request port 1:0x%x\n", offset); \ + return -1; \ + } \ + offset -= card->port1_start; \ + } else if (offset < 0 || offset > 4096) { \ + printk (KERN_ERR "Bad port request port 2: 0x%x\n", offset); \ + return -1; \ + } + +#define DEFwritePortX(X, func) \ +static inline int nm256_writePort##X (struct nm256_info *card,\ + int port, int offset, int value)\ +{\ + u##X *addr;\ +\ + NM_FIX_PORT;\ +\ + addr = (u##X *)(card->ports[port - 1] + offset);\ + func (value, addr);\ + return 0;\ +} + +DEFwritePortX (8, writeb) +DEFwritePortX (16, writew) +DEFwritePortX (32, writel) + +#define DEFreadPortX(X) \ +static inline u##X nm256_readPort##X (struct nm256_info *card,\ + int port, int offset)\ +{\ + u##X *addr, res;\ +\ + NM_FIX_PORT\ +\ + addr = (u##X *)(card->ports[port - 1] + offset);\ + memcpy_fromio (&res, addr, sizeof (res));\ + return res;\ +} + +DEFreadPortX (8) +DEFreadPortX (16) +DEFreadPortX (32) + +static inline int +nm256_writeBuffer8 (struct nm256_info *card, u8 *src, int port, int offset, + int amt) +{ + NM_FIX_PORT; + memcpy_toio (card->ports[port - 1] + offset, src, amt); + return 0; +} + +static inline int +nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, + int amt) +{ + NM_FIX_PORT; + memcpy_fromio (dst, card->ports[port - 1] + offset, amt); + return 0; +} + +/* Returns a non-zero value if we should use the coefficient cache. */ +extern int nm256_cachedCoefficients (struct nm256_info *card); + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c new file mode 100644 index 000000000..0c3ee7b37 --- /dev/null +++ b/drivers/sound/nm256_audio.c @@ -0,0 +1,1393 @@ +/* Audio driver for the NeoMagic 256AV and 256ZX chipsets in native + mode, with AC97 mixer support. + + Overall design and parts of this code stolen from vidc_*.c and + skeleton.c. + + Yeah, there are a lot of magic constants in here. You tell ME what + they are. I just get this stuff psychically, remember? + + This driver was written by someone who wishes to remain anonymous. + It is in the public domain, so share and enjoy. Try to make a profit + off of it; go on, I dare you. */ + +#include <linux/config.h> +#include <linux/pci.h> +#include <linux/module.h> +#include "sound_config.h" +#include "soundmodule.h" +#include "nm256.h" +#include "nm256_coeff.h" + +int nm256_debug = 0; + +/* The size of the playback reserve. */ +#define NM256_PLAY_WMARK_SIZE 512 + +static struct audio_driver nm256_audio_driver; + +static int nm256_grabInterrupt (struct nm256_info *card); +static int nm256_releaseInterrupt (struct nm256_info *card); +static void nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy); +static void nm256_interrupt_zx (int irq, void *dev_id, + struct pt_regs *dummy); + +/* These belong in linux/pci.h. */ +#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 +#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 + +/* List of cards. */ +static struct nm256_info *nmcard_list; + +/* Locate the card in our list. */ +static struct nm256_info * +nm256_find_card (int dev) +{ + struct nm256_info *card; + + for (card = nmcard_list; card != NULL; card = card->next_card) + if (card->dev[0] == dev || card->dev[1] == dev) + return card; + + return NULL; +} + +/* Ditto, but find the card struct corresponding to the mixer device DEV + instead. */ +static struct nm256_info * +nm256_find_card_for_mixer (int dev) +{ + struct nm256_info *card; + + for (card = nmcard_list; card != NULL; card = card->next_card) + if (card->mixer_oss_dev == dev) + return card; + + return NULL; +} + +static int usecache = 0; +static int buffertop = 0; + +/* Check to see if we're using the bank of cached coefficients. */ +int +nm256_cachedCoefficients (struct nm256_info *card) +{ + return usecache; +} + +/* The actual rates supported by the card. */ +static int samplerates[9] = { + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 +}; + +/* Set the card samplerate, word size and stereo mode to correspond to + the settings in the CARD struct for the specified device in DEV. + We keep two separate sets of information, one for each device; the + hardware is not actually configured until a read or write is + attempted. */ + +int +nm256_setInfo (int dev, struct nm256_info *card) +{ + int x; + int w; + int targetrate; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return -ENODEV; + + targetrate = card->sinfo[w].samplerate; + + if ((card->sinfo[w].bits != 8 && card->sinfo[w].bits != 16) + || targetrate < samplerates[0] + || targetrate > samplerates[7]) + return -EINVAL; + + for (x = 0; x < 8; x++) + if (targetrate < ((samplerates[x] + samplerates[x + 1]) / 2)) + break; + + if (x < 8) { + u8 speedbits = ((x << 4) & NM_RATE_MASK) + | (card->sinfo[w].bits == 16 ? NM_RATE_BITS_16: 0) + | (card->sinfo[w].stereo ? NM_RATE_STEREO : 0); + + card->sinfo[w].samplerate = samplerates[x]; + + if (card->dev_for_play == dev && card->playing) { + nm256_loadCoefficient (card, 0, x); + nm256_writePort8 (card, 2, + NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET, + speedbits); + } + + if (card->dev_for_record == dev && card->recording) { + nm256_loadCoefficient (card, 1, x); + nm256_writePort8 (card, 2, + NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET, + speedbits); + } + return 0; + } + else + return -EINVAL; +} + +/* Start the play process going. */ +static void +startPlay (struct nm256_info *card) +{ + if (! card->playing) { + card->playing = 1; + if (nm256_grabInterrupt (card) == 0) { + nm256_setInfo (card->dev_for_play, card); + + /* Enable playback engine and interrupts. */ + nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, + NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN); + + /* Enable both channels. */ + nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, 0x0); + } + } +} + +/* Request one chunk of AMT bytes from the recording device. When the + operation is complete, the data will be copied into BUFFER and the + function DMAbuf_inputintr will be invoked. */ + +static void +nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) +{ + u32 endpos; + int enableEngine = 0; + u32 ringsize = card->recordBufferSize; + + if (amt > (ringsize / 2)) { + /* Of course this won't actually work right, because the + caller is going to assume we will give what we got asked + for. */ + printk (KERN_ERR "NM256: Read request too large: %d\n", amt); + amt = ringsize / 2; + } + + if (amt < 8) { + printk (KERN_ERR "NM256: Read request too small; %d\n", amt); + return; + } + + /* If we're not currently recording, set up the start and end registers + for the recording engine. */ + if (! card->recording) { + card->recording = 1; + if (nm256_grabInterrupt (card) == 0) { + card->curRecPos = 0; + nm256_setInfo (card->dev_for_record, card); + nm256_writePort32 (card, 2, NM_RBUFFER_START, card->abuf2); + nm256_writePort32 (card, 2, NM_RBUFFER_END, + card->abuf2 + ringsize); + + nm256_writePort32 (card, 2, NM_RBUFFER_CURRP, + card->abuf2 + card->curRecPos); + enableEngine = 1; + } + else { + /* Not sure what else to do here. */ + return; + } + } + + endpos = card->abuf2 + ((card->curRecPos + amt) % ringsize); + + card->recBuf = buffer; + card->requestedRecAmt = amt; + nm256_writePort32 (card, 2, NM_RBUFFER_WMARK, endpos); + /* Enable recording engine and interrupts. */ + if (enableEngine) + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, + NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN); +} + +/* Stop the play engine. */ +static void +stopPlay (struct nm256_info *card) +{ + /* Shut off sound from both channels. */ + nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, + NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT); + /* Disable play engine. */ + nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, 0); + if (card->playing) { + nm256_releaseInterrupt (card); + + /* Reset the relevant state bits. */ + card->playing = 0; + card->curPlayPos = 0; + } +} + +/* Stop recording. */ +static void +stopRecord (struct nm256_info *card) +{ + /* Disable recording engine. */ + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0); + + if (card->recording) { + nm256_releaseInterrupt (card); + + card->recording = 0; + card->curRecPos = 0; + } +} + +/* Ring buffers, man. That's where the hip-hop, wild-n-wooly action's at. + 1972? + + Write AMT bytes of BUFFER to the playback ring buffer, and start the + playback engine running. It will only accept up to 1/2 of the total + size of the ring buffer. */ + +static void +nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) +{ + u32 ringsize = card->playbackBufferSize; + u32 endstop; + + if (amt > (ringsize / 2)) { + printk (KERN_ERR "NM256: Write request too large: %d\n", amt); + amt = (ringsize / 2); + } + + if (amt < NM256_PLAY_WMARK_SIZE) { + printk (KERN_ERR "NM256: Write request too small: %d\n", amt); + return; + } + + card->curPlayPos %= ringsize; + + card->requested_amt = amt; + + if ((card->curPlayPos + amt) >= ringsize) { + u32 rem = ringsize - card->curPlayPos; + + nm256_writeBuffer8 (card, buffer, 1, + card->abuf1 + card->curPlayPos, + rem); + if (amt > rem) + nm256_writeBuffer8 (card, buffer, 1, card->abuf1, + amt - rem); + } + else + nm256_writeBuffer8 (card, buffer, 1, + card->abuf1 + card->curPlayPos, + amt); + + /* Setup the start-n-stop-n-limit registers, and start that engine + goin'. + + Normally we just let it wrap around to avoid the click-click + action scene. */ + if (! card->playing) { + /* The PBUFFER_END register in this case points to one "word" + before the end of the buffer. */ + int w = (card->dev_for_play == card->dev[0] ? 0 : 1); + int wordsize = (card->sinfo[w].bits == 16 ? 2 : 1) + * (card->sinfo[w].stereo ? 2 : 1); + + /* Need to set the not-normally-changing-registers up. */ + nm256_writePort32 (card, 2, NM_PBUFFER_START, + card->abuf1 + card->curPlayPos); + nm256_writePort32 (card, 2, NM_PBUFFER_END, + card->abuf1 + ringsize - wordsize); + nm256_writePort32 (card, 2, NM_PBUFFER_CURRP, + card->abuf1 + card->curPlayPos); + } + endstop = (card->curPlayPos + amt - NM256_PLAY_WMARK_SIZE) % ringsize; + nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); + if (! card->playing) + startPlay (card); +} + +/* We just got a card playback interrupt; process it. */ +static void +nm256_get_new_block (struct nm256_info *card) +{ + /* Check to see how much got played so far. */ + u32 amt = nm256_readPort32 (card, 2, NM_PBUFFER_CURRP) - card->abuf1; + + if (amt >= card->playbackBufferSize) { + printk (KERN_ERR "NM256: Sound playback pointer invalid!\n"); + amt = 0; + } + + if (amt < card->curPlayPos) + amt = (card->playbackBufferSize - card->curPlayPos) + amt; + else + amt -= card->curPlayPos; + + if (card->requested_amt > (amt + NM256_PLAY_WMARK_SIZE)) { + u32 endstop = + card->curPlayPos + card->requested_amt - NM256_PLAY_WMARK_SIZE; + nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); + } else { + card->curPlayPos += card->requested_amt; + /* Get a new block to write. This will eventually invoke + nm256_write_block (). */ + DMAbuf_outputintr (card->dev_for_play, 1); + } +} + +/* Ultra cheez-whiz. But I'm too lazy to grep headers. */ +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + +/* Read the last-recorded block from the ring buffer, copy it into the + saved buffer pointer, and invoke DMAuf_inputintr() with the recording + device. */ + +static void +nm256_read_block (struct nm256_info *card) +{ + /* Grab the current position of the recording pointer. */ + u32 currptr = nm256_readPort32 (card, 2, NM_RBUFFER_CURRP) - card->abuf2; + u32 amtToRead = card->requestedRecAmt; + u32 ringsize = card->recordBufferSize; + + if (currptr >= card->recordBufferSize) { + printk (KERN_ERR "NM256: Sound buffer record pointer invalid!\n"); + currptr = 0; + } + + /* This test is probably redundant; we shouldn't be here unless + it's true. */ + if (card->recording) { + /* If we wrapped around, copy everything from the start of our + recording buffer to the end of the buffer. */ + if (currptr < card->curRecPos) { + u32 amt = MIN (ringsize - card->curRecPos, amtToRead); + + nm256_readBuffer8 (card, card->recBuf, 1, + card->abuf2 + card->curRecPos, + amt); + amtToRead -= amt; + card->curRecPos += amt; + card->recBuf += amt; + if (card->curRecPos == ringsize) + card->curRecPos = 0; + } + + if ((card->curRecPos < currptr) && (amtToRead > 0)) { + u32 amt = MIN (currptr - card->curRecPos, amtToRead); + nm256_readBuffer8 (card, card->recBuf, 1, + card->abuf2 + card->curRecPos, amt); + card->curRecPos = ((card->curRecPos + amt) % ringsize); + } + card->recBuf = NULL; + card->requestedRecAmt = 0; + DMAbuf_inputintr (card->dev_for_record); + } +} +#undef MIN + +/* Initialize the hardware and various other card data we'll need + later. */ +static void +nm256_initHw (struct nm256_info *card) +{ + int x; + + card->playbackBufferSize = 16384; + card->recordBufferSize = 16384; + + card->coeffBuf = card->bufend - NM_MAX_COEFFICIENT; + card->abuf2 = card->coeffBuf - card->recordBufferSize; + card->abuf1 = card->abuf2 - card->playbackBufferSize; + card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4); + + /* Fixed setting. */ + card->mixer = NM_MIXER_BASE; + + card->playing = 0; + card->is_open_play = 0; + card->curPlayPos = 0; + + card->recording = 0; + card->is_open_record = 0; + card->curRecPos = 0; + + card->coeffsCurrent = 0; + + card->opencnt[0] = 0; card->opencnt[1] = 0; + + /* Reset everything. */ + nm256_writePort8 (card, 2, 0, 0x11); + + /* Disable recording. */ + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0); + nm256_writePort16 (card, 2, 0x214, 0); + + /* Reasonable default settings, but largely unnecessary. */ + for (x = 0; x < 2; x++) { + card->sinfo[x].bits = 8; + card->sinfo[x].stereo = 0; + card->sinfo[x].samplerate = 8000; + } +} + +/* Handle a potential interrupt for the device referred to by DEV_ID. */ + +static void +nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) +{ + struct nm256_info *card = (struct nm256_info *)dev_id; + u16 status; + static int badintrcount = 0; + + if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { + printk (KERN_ERR "NM256: Bad card pointer\n"); + return; + } + + status = nm256_readPort16 (card, 2, NM_INT_REG); + + /* Not ours. */ + if (status == 0) { + if (badintrcount++ > 1000) { + printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); + nm256_releaseInterrupt (card); + } + return; + } + + badintrcount = 0; + + if (status & NM_PLAYBACK_INT) { + status &= ~NM_PLAYBACK_INT; + NM_ACK_INT (card, NM_PLAYBACK_INT); + + if (card->playing) + nm256_get_new_block (card); + } + + if (status & NM_RECORD_INT) { + status &= ~NM_RECORD_INT; + NM_ACK_INT (card, NM_RECORD_INT); + + if (card->recording) + nm256_read_block (card); + } + + if (status & NM_MISC_INT_1) { + u8 cbyte; + + status &= ~NM_MISC_INT_1; + printk (KERN_ERR "NM256: Got misc interrupt #1\n"); + NM_ACK_INT (card, NM_MISC_INT_1); + nm256_writePort16 (card, 2, NM_INT_REG, 0x8000); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte | 2); + } + + if (status & NM_MISC_INT_2) { + u8 cbyte; + + status &= ~NM_MISC_INT_2; + printk (KERN_ERR "NM256: Got misc interrupt #2\n"); + NM_ACK_INT (card, NM_MISC_INT_2); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte & ~2); + } + + if (status) { + printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", + status); + /* Pray. */ + NM_ACK_INT (card, status); + } +} + +/* Handle a potential interrupt for the device referred to by DEV_ID. + This handler is for the 256ZX. */ + +static void +nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) +{ + struct nm256_info *card = (struct nm256_info *)dev_id; + u32 status; + static int badintrcount = 0; + + if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { + printk (KERN_ERR "NM256: Bad card pointer\n"); + return; + } + + status = nm256_readPort32 (card, 2, NM_INT_REG); + + /* Not ours. */ + if (status == 0) { + if (badintrcount++ > 1000) { + printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); + nm256_releaseInterrupt (card); + } + return; + } + + badintrcount = 0; + + if (status & NM2_PLAYBACK_INT) { + status &= ~NM2_PLAYBACK_INT; + NM2_ACK_INT (card, NM2_PLAYBACK_INT); + + if (card->playing) + nm256_get_new_block (card); + } + + if (status & NM2_RECORD_INT) { + status &= ~NM2_RECORD_INT; + NM2_ACK_INT (card, NM2_RECORD_INT); + + if (card->recording) + nm256_read_block (card); + } + + if (status & NM2_MISC_INT_1) { + u8 cbyte; + + status &= ~NM2_MISC_INT_1; + printk (KERN_ERR "NM256: Got misc interrupt #1\n"); + NM2_ACK_INT (card, NM2_MISC_INT_1); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte | 2); + } + + if (status & NM2_MISC_INT_2) { + u8 cbyte; + + status &= ~NM2_MISC_INT_2; + printk (KERN_ERR "NM256: Got misc interrupt #2\n"); + NM2_ACK_INT (card, NM2_MISC_INT_2); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte & ~2); + } + + if (status) { + printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", + status); + /* Pray. */ + NM2_ACK_INT (card, status); + } +} + +/* Request our interrupt. */ +static int +nm256_grabInterrupt (struct nm256_info *card) +{ + if (card->has_irq++ == 0) { + if (request_irq (card->irq, card->introutine, SA_SHIRQ, + "NM256_audio", card) < 0) { + printk (KERN_ERR "NM256: can't obtain IRQ %d\n", card->irq); + return -1; + } + } + return 0; +} + +/* Release our interrupt. */ +static int +nm256_releaseInterrupt (struct nm256_info *card) +{ + if (card->has_irq <= 0) { + printk (KERN_ERR "nm256: too many calls to releaseInterrupt\n"); + return -1; + } + card->has_irq--; + if (card->has_irq == 0) { + free_irq (card->irq, card); + } + return 0; +} + +static int +nm256_isReady (struct ac97_hwint *dev) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + int t2 = 10; + u32 testaddr; + u16 testb; + int done = 0; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in isReady!\n"); + return 0; + } + + if (card->rev == REV_NM256AV) { + testaddr = 0xa06; + testb = 0x0100; + } else if (card->rev == REV_NM256ZX) { + testaddr = 0xa08; + testb = 0x0800; + } else { + return -1; + } + + while (t2-- > 0) { + if ((nm256_readPort16 (card, 2, testaddr) & testb) == 0) { + done = 1; + break; + } + udelay (100); + } + return done; +} + +static int +nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in readAC97Reg!\n"); + return -EINVAL; + } + + if (reg < 128) { + int res; + + nm256_isReady (dev); + res = nm256_readPort16 (card, 2, card->mixer + reg); + udelay (1000); + return res; + } + else + return -EINVAL; +} + +static int +nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) +{ + unsigned long flags; + int tries = 2; + int done = 0; + u32 base; + + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in writeAC97Reg!\n"); + return -EINVAL; + } + + base = card->mixer; + + save_flags (flags); + cli (); + + nm256_isReady (dev); + + /* Wait for the write to take, too. */ + while ((tries-- > 0) && !done) { + nm256_writePort16 (card, 2, base + reg, value); + if (nm256_isReady (dev)) { + done = 1; + break; + } + + } + + restore_flags (flags); + udelay (1000); + + return ! done; +} + +struct initialValues +{ + unsigned short port; + unsigned short value; +}; + +static struct initialValues nm256_ac97_initial_values[] = +{ + { 0x0002, 0x8000 }, + { 0x0004, 0x0000 }, + { 0x0006, 0x0000 }, + { 0x000A, 0x0000 }, + { 0x000C, 0x0008 }, + { 0x000E, 0x8008 }, + { 0x0010, 0x8808 }, + { 0x0012, 0x8808 }, + { 0x0014, 0x8808 }, + { 0x0016, 0x8808 }, + { 0x0018, 0x0808 }, + { 0x001A, 0x0000 }, + { 0x001C, 0x0B0B }, + { 0x0020, 0x0000 }, + { 0xffff, 0xffff } +}; + +static int +nm256_resetAC97 (struct ac97_hwint *dev) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + int x; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in resetAC97!\n"); + return -EINVAL; + } + + /* Reset the card. 'Tis magic! */ + nm256_writePort8 (card, 2, 0x6c0, 1); + nm256_writePort8 (card, 2, 0x6cc, 0x87); + nm256_writePort8 (card, 2, 0x6cc, 0x80); + nm256_writePort8 (card, 2, 0x6cc, 0x0); + + for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) { + ac97_put_register (dev, + nm256_ac97_initial_values[x].port, + nm256_ac97_initial_values[x].value); + } + + return 0; +} + +/* We don't do anything special here. */ +static int +nm256_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg) +{ + struct nm256_info *card = nm256_find_card_for_mixer (dev); + if (card != NULL) + return ac97_mixer_ioctl (&(card->mdev), cmd, arg); + else + return -ENODEV; +} + +static struct mixer_operations nm256_mixer_operations = { + "NeoMagic", + "NM256AC97Mixer", + nm256_default_mixer_ioctl +}; + +/* I "love" C sometimes. Got braces? */ +static struct ac97_mixer_value_list mixer_defaults[] = { + { SOUND_MIXER_VOLUME, { { 85, 85 } } }, + { SOUND_MIXER_SPEAKER, { { 100 } } }, + { SOUND_MIXER_PCM, { { 65, 65 } } }, + { SOUND_MIXER_CD, { { 65, 65 } } }, + { -1, { { 0, 0 } } } +}; + +static int +nm256_install_mixer (struct nm256_info *card) +{ + int mixer; + + card->mdev.reset_device = nm256_resetAC97; + card->mdev.read_reg = nm256_readAC97Reg; + card->mdev.write_reg = nm256_writeAC97Reg; + card->mdev.driver_private = (void *)card; + + if (ac97_init (&(card->mdev))) + return -1; + + mixer = sound_alloc_mixerdev(); + if (num_mixers >= MAX_MIXER_DEV) { + printk ("NM256 mixer: Unable to alloc mixerdev\n"); + return -1; + } + + mixer_devs[mixer] = &nm256_mixer_operations; + card->mixer_oss_dev = mixer; + + /* Some reasonable default values. */ + ac97_set_values (&(card->mdev), mixer_defaults); + + printk(KERN_INFO "Initialized AC97 mixer\n"); + return 0; +} + +/* See if the signature left by the NM256 BIOS is intact; if so, we use + the associated address as the end of our buffer. */ +static void +nm256_peek_for_sig (struct nm256_info *card, u32 port1addr) +{ + char *temp = ioremap_nocache (port1addr + card->port1_end - 0x0400, 16); + u32 sig; + + if (temp == NULL) { + printk (KERN_ERR "NM256: Unable to scan for card signature in video RAM\n"); + return; + } + memcpy_fromio (&sig, temp, sizeof (u32)); + if ((sig & 0xffff0000) == 0x4e4d0000) { + memcpy_fromio (&(card->bufend), temp + 4, sizeof (u32)); + printk (KERN_INFO "NM256: Found card signature in video RAM: 0x%x\n", + card->bufend); + } + + release_region ((unsigned long) temp, 16); +} + +/* Install a driver for the soundcard referenced by PCIDEV. */ + +static int +nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) +{ + struct nm256_info *card; + u32 port1addr = pcidev->resource[0].start; + u32 port2addr = pcidev->resource[1].start; + int x; + + card = kmalloc (sizeof (struct nm256_info), GFP_KERNEL); + if (card == NULL) { + printk (KERN_ERR "NM256: out of memory!\n"); + return 0; + } + + card->magsig = NM_MAGIC_SIG; + card->playing = 0; + card->recording = 0; + card->rev = rev; + + /* The NM256 has two memory ports. The first port is nothing + more than a chunk of video RAM, which is used as the I/O ring + buffer. The second port has the actual juicy stuff (like the + mixer and the playback engine control registers). */ + + card->ports[1] = ioremap_nocache (port2addr, NM_PORT2_SIZE); + + if (card->ports[1] == NULL) { + printk (KERN_ERR "NM256: Unable to remap port 2\n"); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + if (card->rev == REV_NM256AV) { + card->port1_end = 2560 * 1024; + card->introutine = nm256_interrupt; + } + else { + if (nm256_readPort8 (card, 2, 0xa0b) != 0) + card->port1_end = 6144 * 1024; + else + card->port1_end = 4096 * 1024; + + card->introutine = nm256_interrupt_zx; + } + + /* Default value. */ + card->bufend = card->port1_end - 0x1400; + + if (buffertop >= 98304 && buffertop < card->port1_end) + card->bufend = buffertop; + else + nm256_peek_for_sig (card, port1addr); + + card->port1_start = card->bufend - 98304; + + printk (KERN_INFO "NM256: Mapping port 1 from 0x%x - 0x%x\n", + card->port1_start, card->port1_end); + + card->ports[0] = + ioremap_nocache (port1addr + card->port1_start, + card->port1_end - card->port1_start); + + if (card->ports[0] == NULL) { + printk (KERN_ERR "NM256: Unable to remap port 1\n"); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + /* See if we can get the interrupt. */ + + card->irq = pcidev->irq; + card->has_irq = 0; + + if (nm256_grabInterrupt (card) != 0) { + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + nm256_releaseInterrupt (card); + + /* + * Init the board. + */ + + nm256_initHw (card); + + for (x = 0; x < 2; x++) { + if ((card->dev[x] = + sound_install_audiodrv(AUDIO_DRIVER_VERSION, + "NM256", &nm256_audio_driver, + sizeof(struct audio_driver), + DMA_NODMA, AFMT_U8 | AFMT_S16_LE, + NULL, -1, -1)) >= 0) { + /* 1K minimum buffer size. */ + audio_devs[card->dev[x]]->min_fragment = 10; + /* Maximum of 8K buffer size. */ + audio_devs[card->dev[x]]->max_fragment = 13; + } + else { + printk(KERN_ERR "NM256: Too many PCM devices available\n"); + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + } + + /* Insert the card in the list. */ + card->next_card = nmcard_list; + nmcard_list = card; + + printk(KERN_INFO "Initialized NeoMagic %s audio in PCI native mode\n", + verstr); + + /* + * And our mixer. (We should allow support for other mixers, maybe.) + */ + + nm256_install_mixer (card); + + return 1; +} + +/* + * This loop walks the PCI configuration database and finds where + * the sound cards are. + */ + +int +init_nm256(void) +{ + struct pci_dev *pcidev = NULL; + int count = 0; + + if(! pci_present()) + return -ENODEV; + + while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC, + PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, + pcidev)) != NULL) { + count += nm256_install(pcidev, REV_NM256AV, "256AV"); + } + + while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC, + PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, + pcidev)) != NULL) { + count += nm256_install(pcidev, REV_NM256ZX, "256ZX"); + } + + if (count == 0) + return -ENODEV; + + printk (KERN_INFO "Done installing NM256 audio driver.\n"); + return 0; +} + +/* + * Open the device + * + * DEV - device + * MODE - mode to open device (logical OR of OPEN_READ and OPEN_WRITE) + * + * Called when opening the DMAbuf (dmabuf.c:259) + */ +static int +nm256_audio_open(int dev, int mode) +{ + struct nm256_info *card = nm256_find_card (dev); + int w; + + if (card == NULL) + return -ENODEV; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return -ENODEV; + + if (card->opencnt[w] > 0) + return -EBUSY; + + /* No bits set? Huh? */ + if (! ((mode & OPEN_READ) || (mode & OPEN_WRITE))) + return -EIO; + + /* If it's open for both read and write, and the card's currently + being read or written to, then do the opposite of what has + already been done. Otherwise, don't specify any mode until the + user actually tries to do I/O. */ + + if ((mode & OPEN_WRITE) && (mode & OPEN_READ)) { + if (card->is_open_play) + mode = OPEN_WRITE; + else if (card->is_open_record) + mode = OPEN_READ; + else mode = 0; + } + + if (mode & OPEN_WRITE) { + if (card->is_open_play == 0) { + card->dev_for_play = dev; + card->is_open_play = 1; + } + else + return -EBUSY; + } + + if (mode & OPEN_READ) { + if (card->is_open_record == 0) { + card->dev_for_record = dev; + card->is_open_record = 1; + } + else + return -EBUSY; + } + + card->opencnt[w]++; + return 0; +} + +/* + * Close the device + * + * DEV - device + * + * Called when closing the DMAbuf (dmabuf.c:477) + * after halt_xfer + */ +static void +nm256_audio_close(int dev) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + int w; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return; + + card->opencnt[w]--; + if (card->opencnt[w] <= 0) { + card->opencnt[w] = 0; + + if (card->dev_for_play == dev) { + stopPlay (card); + card->is_open_play = 0; + card->dev_for_play = -1; + } + + if (card->dev_for_record == dev) { + stopRecord (card); + card->is_open_record = 0; + card->dev_for_record = -1; + } + } + } +} + +static int +nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg) +{ + int ret; + u32 oldinfo; + int w; + + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (dev == card->dev[0]) + w = 0; + else + w = 1; + + switch (cmd) + { + case SOUND_PCM_WRITE_RATE: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret != 0) { + oldinfo = card->sinfo[w].samplerate; + card->sinfo[w].samplerate = ret; + ret = nm256_setInfo(dev, card); + if (ret != 0) + card->sinfo[w].samplerate = oldinfo; + } + if (ret == 0) + ret = card->sinfo[w].samplerate; + break; + + case SOUND_PCM_READ_RATE: + ret = card->sinfo[w].samplerate; + break; + + case SNDCTL_DSP_STEREO: + get_user_ret(ret, (int *) arg, -EFAULT); + + card->sinfo[w].stereo = ret ? 1 : 0; + ret = nm256_setInfo (dev, card); + if (ret == 0) + ret = card->sinfo[w].stereo; + + break; + + case SOUND_PCM_WRITE_CHANNELS: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret < 1 || ret > 3) + ret = card->sinfo[w].stereo + 1; + else { + card->sinfo[w].stereo = ret - 1; + ret = nm256_setInfo (dev, card); + if (ret == 0) + ret = card->sinfo[w].stereo + 1; + } + break; + + case SOUND_PCM_READ_CHANNELS: + ret = card->sinfo[w].stereo + 1; + break; + + case SNDCTL_DSP_SETFMT: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret != 0) { + oldinfo = card->sinfo[w].bits; + card->sinfo[w].bits = ret; + ret = nm256_setInfo (dev, card); + if (ret != 0) + card->sinfo[w].bits = oldinfo; + } + if (ret == 0) + ret = card->sinfo[w].bits; + break; + + case SOUND_PCM_READ_BITS: + ret = card->sinfo[w].bits; + break; + + default: + return -EINVAL; + } + return put_user(ret, (int *) arg); +} + +/* Given the dev DEV and an associated physical buffer PHYSBUF, return + a pointer to the actual buffer in kernel space. */ + +static char * +nm256_getDMAbuffer (int dev, unsigned long physbuf) +{ + struct audio_operations *adev = audio_devs[dev]; + struct dma_buffparms *dmap = adev->dmap_out; + char *dma_start = + (char *)(physbuf - (unsigned long)dmap->raw_buf_phys + + (unsigned long)dmap->raw_buf); + + return dma_start; +} + + +/* + * Output a block to sound device + * + * dev - device number + * buf - physical address of buffer + * total_count - total byte count in buffer + * intrflag - set if this has been called from an interrupt + * (via DMAbuf_outputintr) + * restart_dma - set if engine needs to be re-initialised + * + * Called when: + * 1. Starting output (dmabuf.c:1327) + * 2. (dmabuf.c:1504) + * 3. A new buffer needs to be sent to the device (dmabuf.c:1579) + */ +static void +nm256_audio_output_block(int dev, unsigned long physbuf, + int total_count, int intrflag) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + char *dma_buf = nm256_getDMAbuffer (dev, physbuf); + card->is_open_play = 1; + card->dev_for_play = dev; + nm256_write_block (card, dma_buf, total_count); + } +} + +static void +nm256_audio_start_input(int dev, unsigned long physbuf, int count, + int intrflag) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + char *dma_buf = nm256_getDMAbuffer (dev, physbuf); + card->is_open_record = 1; + card->dev_for_record = dev; + nm256_startRecording (card, dma_buf, count); + } +} + +static int +nm256_audio_prepare_for_input(int dev, int bsize, int bcount) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (card->is_open_record && card->dev_for_record != dev) + return -EBUSY; + + audio_devs[dev]->dmap_in->flags |= DMA_NODMA; + return 0; +} + +/* + * Prepare for outputting samples to `dev' + * + * Each buffer that will be passed will be `bsize' bytes long, + * with a total of `bcount' buffers. + * + * Called when: + * 1. A trigger enables audio output (dmabuf.c:978) + * 2. We get a write buffer without dma_mode setup (dmabuf.c:1152) + * 3. We restart a transfer (dmabuf.c:1324) + */ +static int +nm256_audio_prepare_for_output(int dev, int bsize, int bcount) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (card->is_open_play && card->dev_for_play != dev) + return -EBUSY; + + audio_devs[dev]->dmap_out->flags |= DMA_NODMA; + return 0; +} + +/* Stop the current operations associated with DEV. */ +static void +nm256_audio_reset(int dev) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + if (card->dev_for_play == dev) + stopPlay (card); + if (card->dev_for_record == dev) + stopRecord (card); + } +} + +static int +nm256_audio_local_qlen(int dev) +{ + return 0; +} + +static struct audio_driver nm256_audio_driver = +{ + nm256_audio_open, /* open */ + nm256_audio_close, /* close */ + nm256_audio_output_block, /* output_block */ + nm256_audio_start_input, /* start_input */ + nm256_audio_ioctl, /* ioctl */ + nm256_audio_prepare_for_input, /* prepare_for_input */ + nm256_audio_prepare_for_output, /* prepare_for_output */ + nm256_audio_reset, /* reset */ + nm256_audio_local_qlen, /*+local_qlen */ + NULL, /*+copy_from_user */ + NULL, /*+halt_input */ + NULL, /* halt_output */ + NULL, /*+trigger */ + NULL, /*+set_speed */ + NULL, /*+set_bits */ + NULL, /*+set_channels */ +}; + +EXPORT_SYMBOL(init_nm256); + +#ifdef MODULE + +static int loaded = 0; + +MODULE_PARM (usecache, "i"); +MODULE_PARM (buffertop, "i"); +MODULE_PARM (nm256_debug, "i"); + +int +init_module (void) +{ + nmcard_list = NULL; + printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.0\n"); + + if (init_nm256 () == 0) { + SOUND_LOCK; + loaded = 1; + return 0; + } + else + return -ENODEV; +} + +void +cleanup_module (void) +{ + if (loaded) { + struct nm256_info *card; + struct nm256_info *next_card; + + SOUND_LOCK_END; + + for (card = nmcard_list; card != NULL; card = next_card) { + stopPlay (card); + stopRecord (card); + if (card->has_irq) + free_irq (card->irq, card); + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + sound_unload_mixerdev (card->mixer_oss_dev); + sound_unload_audiodev (card->dev[0]); + sound_unload_audiodev (card->dev[1]); + next_card = card->next_card; + kfree_s (card, sizeof (struct nm256_info)); + } + nmcard_list = NULL; + } +} +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/sound/nm256_coeff.h b/drivers/sound/nm256_coeff.h new file mode 100644 index 000000000..c8fc7ecbe --- /dev/null +++ b/drivers/sound/nm256_coeff.h @@ -0,0 +1,4693 @@ +#ifndef NM256_COEFF_H +#define NM256_COEFF_H + +#define NM_TOTAL_COEFF_COUNT 0x3158 + +static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = { + 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA5, 0x01, 0xEF, 0xFC, 0x21, + 0x05, 0x87, 0xF7, 0x62, 0x11, 0xE9, 0x45, 0x5E, 0xF9, 0xB5, 0x01, + 0xDE, 0xFF, 0xA4, 0xFF, 0x60, 0x00, 0xCA, 0xFF, 0x0D, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, + 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, + 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFD, 0xFF, + 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, + 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, + 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x02, 0x00, 0x05, + 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3, + 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF, + 0x60, 0x00, 0xA4, 0xFF, 0xDE, 0xFF, 0xB5, 0x01, 0x5E, 0xF9, 0xE9, + 0x45, 0x62, 0x11, 0x87, 0xF7, 0x21, 0x05, 0xEF, 0xFC, 0xA5, 0x01, + 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, + 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, + 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, + 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xCA, 0x01, 0x95, 0xFC, 0xEA, 0x05, 0xBB, 0xF5, 0x25, 0x17, 0x3C, + 0x43, 0x8D, 0xF6, 0x43, 0x03, 0xF5, 0xFE, 0x26, 0x00, 0x20, 0x00, + 0xE2, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, + 0x01, 0x4C, 0xFC, 0x26, 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, + 0x8F, 0xF1, 0xCA, 0x06, 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD5, 0xFF, 0xBC, 0x00, + 0xF0, 0xFD, 0xEC, 0x04, 0xD9, 0xF3, 0xB1, 0x3E, 0xCD, 0x1E, 0xC1, + 0xF3, 0xAF, 0x06, 0x49, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, + 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, + 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0x98, 0x01, 0x0D, 0xFD, + 0xE0, 0x04, 0x14, 0xF8, 0xC3, 0x0F, 0x89, 0x46, 0x4C, 0xFA, 0x38, + 0x01, 0x25, 0x00, 0x7D, 0xFF, 0x73, 0x00, 0xC2, 0xFF, 0x0F, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, + 0x07, 0x84, 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, + 0x41, 0xFD, 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x15, 0x00, 0x97, 0xFF, 0x37, 0x01, 0x22, 0xFD, 0x23, 0x06, + 0x2F, 0xF2, 0x11, 0x39, 0x7B, 0x26, 0x50, 0xF2, 0x1B, 0x07, 0x32, + 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC8, 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, + 0xF9, 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, + 0xA2, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, + 0x00, 0x6A, 0xFF, 0x53, 0x01, 0xA6, 0xFD, 0xA6, 0x03, 0xA1, 0xFA, + 0xDE, 0x08, 0x76, 0x48, 0x0C, 0xFF, 0xDE, 0xFE, 0x73, 0x01, 0xC9, + 0xFE, 0xCA, 0x00, 0xA0, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78, + 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00, + 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x68, + 0xFF, 0x93, 0x01, 0x92, 0xFC, 0xE2, 0x06, 0x83, 0xF1, 0x8C, 0x32, + 0xED, 0x2D, 0x90, 0xF1, 0x1E, 0x07, 0x57, 0xFC, 0xBD, 0x01, 0x51, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, + 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, + 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, 0x03, 0x01, 0x53, + 0xFE, 0x53, 0x02, 0x39, 0xFD, 0xA9, 0x02, 0xF2, 0x48, 0xB9, 0x04, + 0x54, 0xFC, 0xCA, 0x02, 0x16, 0xFE, 0x20, 0x01, 0x7F, 0xFF, 0x20, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC3, 0x01, + 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, 0x43, 0x20, + 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, 0xDD, 0xFF, + 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCD, 0x01, 0x43, + 0xFC, 0x2A, 0x07, 0xBC, 0xF1, 0x64, 0x2B, 0xE3, 0x34, 0xA3, 0xF1, + 0xAE, 0x06, 0xBD, 0xFC, 0x77, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, 0xFD, + 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, 0xC8, + 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x14, 0x00, 0xAC, 0xFF, 0xAC, 0x00, 0x08, 0xFF, 0xFD, 0x00, 0xB5, + 0xFF, 0x4B, 0xFD, 0xF4, 0x47, 0x30, 0x0B, 0xBC, 0xF9, 0x17, 0x04, + 0x6E, 0xFD, 0x6D, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, 0x26, 0xFD, 0xAD, 0x04, + 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, 0xFB, 0xD4, 0x00, 0x5D, + 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, 0x10, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0x01, 0x07, 0xBE, + 0xF2, 0xD6, 0x23, 0x1F, 0x3B, 0xA5, 0xF2, 0xC5, 0x05, 0x62, 0xFD, + 0x10, 0x01, 0xAB, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, + 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, 0x4D, 0x06, 0x00, 0xF2, + 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, 0x07, 0x34, 0xFC, 0xDD, + 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, + 0x56, 0x00, 0xB9, 0xFF, 0xB8, 0xFF, 0xF7, 0x01, 0xE2, 0xF8, 0x8D, + 0x45, 0x46, 0x12, 0x3C, 0xF7, 0x43, 0x05, 0xDF, 0xFC, 0xAC, 0x01, + 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, + 0xFF, 0x46, 0x01, 0xC3, 0xFD, 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, + 0xA6, 0x48, 0xF8, 0xFF, 0x70, 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, + 0x00, 0x9A, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xDE, 0x01, 0x5D, 0xFC, 0x74, 0x06, 0x63, 0xF4, 0x23, 0x1C, 0x66, + 0x40, 0xAA, 0xF4, 0x65, 0x04, 0x44, 0xFE, 0x8B, 0x00, 0xEE, 0xFF, + 0xF5, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, + 0x01, 0x80, 0xFC, 0xF7, 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, + 0x83, 0xF1, 0x13, 0x07, 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, + 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xED, 0xFF, 0x05, 0x00, 0x5D, 0x00, + 0x95, 0xFE, 0xE2, 0x03, 0x7F, 0xF5, 0xCC, 0x41, 0xC7, 0x19, 0xFF, + 0xF4, 0x37, 0x06, 0x75, 0xFC, 0xD6, 0x01, 0x39, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1B, 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, + 0x02, 0xAA, 0xFD, 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, + 0x05, 0x03, 0xF7, 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBB, 0x01, 0xBA, 0xFC, + 0x95, 0x05, 0x83, 0xF6, 0x8C, 0x14, 0x87, 0x44, 0xBB, 0xF7, 0x98, + 0x02, 0x5A, 0xFF, 0xEE, 0xFF, 0x3C, 0x00, 0xD8, 0xFF, 0x0A, 0x00, + 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, + 0x07, 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, + 0xD5, 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, + 0x00, 0x07, 0x00, 0xBE, 0xFF, 0xEA, 0x00, 0xA2, 0xFD, 0x65, 0x05, + 0x28, 0xF3, 0xDB, 0x3C, 0x78, 0x21, 0x30, 0xF3, 0xDF, 0x06, 0x3A, + 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, + 0xB2, 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, + 0xFC, 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, + 0x79, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x58, 0xFF, 0x82, 0x01, 0x3F, 0xFD, 0x78, 0x04, 0xF2, 0xF8, + 0x50, 0x0D, 0x5E, 0x47, 0xD5, 0xFB, 0x6F, 0x00, 0x96, 0x00, 0x40, + 0xFF, 0x91, 0x00, 0xB7, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81, + 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00, + 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x85, + 0xFF, 0x5B, 0x01, 0xE9, 0xFC, 0x73, 0x06, 0xD8, 0xF1, 0xE5, 0x36, + 0x19, 0x29, 0xF8, 0xF1, 0x29, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x42, + 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, 0xFF, 0x47, 0x00, + 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, 0x8D, + 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, 0xFF, + 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x75, 0xFF, 0x39, + 0x01, 0xE0, 0xFD, 0x33, 0x03, 0x87, 0xFB, 0xA2, 0x06, 0xCB, 0x48, + 0xEA, 0x00, 0x01, 0xFE, 0xE9, 0x01, 0x8A, 0xFE, 0xE8, 0x00, 0x95, + 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, 0xDA, 0x01, + 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, 0x41, 0x1F, + 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, 0xF0, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5B, 0xFF, 0xAB, 0x01, 0x6F, + 0xFC, 0x08, 0x07, 0x7E, 0xF1, 0x21, 0x30, 0x67, 0x30, 0x7D, 0xF1, + 0x05, 0x07, 0x73, 0xFC, 0xA8, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, + 0xFF, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0x67, 0xFE, + 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, 0xA6, 0xF4, 0x5A, + 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x96, 0xFF, 0xE5, 0x00, 0x91, 0xFE, 0xDC, 0x01, 0x1A, + 0xFE, 0xB3, 0x00, 0xC3, 0x48, 0xE1, 0x06, 0x6E, 0xFB, 0x40, 0x03, + 0xDA, 0xFD, 0x3C, 0x01, 0x74, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, + 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, + 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x41, 0xFF, 0xD9, 0x01, 0x36, 0xFC, 0x28, 0x07, 0x01, + 0xF2, 0xCE, 0x28, 0x23, 0x37, 0xE0, 0xF1, 0x6B, 0x06, 0xEF, 0xFC, + 0x57, 0x01, 0x87, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, + 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, 0xFD, 0x9C, 0x05, 0xDC, 0xF2, + 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, 0xF3, 0x06, 0x35, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xB8, 0xFF, + 0x8E, 0x00, 0x46, 0xFF, 0x8A, 0x00, 0x86, 0x00, 0xA7, 0xFB, 0x48, + 0x47, 0x95, 0x0D, 0xD9, 0xF8, 0x84, 0x04, 0x39, 0xFD, 0x85, 0x01, + 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, + 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, + 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, + 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE6, 0x01, 0x3B, 0xFC, 0xDA, 0x06, 0x3F, 0xF3, 0x2C, 0x21, 0x11, + 0x3D, 0x3A, 0xF3, 0x58, 0x05, 0xAA, 0xFD, 0xE5, 0x00, 0xC1, 0xFF, + 0x06, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, + 0x01, 0xCF, 0xFC, 0x96, 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, + 0xD4, 0xF1, 0x2B, 0x07, 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, + 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD9, 0xFF, 0x39, 0x00, 0xF4, 0xFF, + 0x4E, 0xFF, 0xAC, 0x02, 0x98, 0xF7, 0x65, 0x44, 0xD6, 0x14, 0x6C, + 0xF6, 0x9F, 0x05, 0xB6, 0xFC, 0xBD, 0x01, 0x42, 0xFF, 0x32, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, + 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, + 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD5, 0x01, 0x78, 0xFC, + 0x2F, 0x06, 0x13, 0xF5, 0x7C, 0x19, 0xF7, 0x41, 0x9B, 0xF5, 0xD1, + 0x03, 0x9F, 0xFE, 0x57, 0x00, 0x08, 0x00, 0xEC, 0xFF, 0x06, 0x00, + 0xFD, 0xFF, 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, + 0x07, 0x85, 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, + 0x84, 0xFC, 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, + 0x00, 0xF6, 0xFF, 0xEB, 0xFF, 0x91, 0x00, 0x3B, 0xFE, 0x75, 0x04, + 0x92, 0xF4, 0x36, 0x40, 0x6E, 0x1C, 0x50, 0xF4, 0x7B, 0x06, 0x5B, + 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, + 0x9C, 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, + 0xFF, 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, + 0x49, 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x49, 0xFF, 0xAA, 0x01, 0xE4, 0xFC, 0x38, 0x05, 0x54, 0xF7, + 0xFE, 0x11, 0xAA, 0x45, 0x09, 0xF9, 0xE2, 0x01, 0xC4, 0xFF, 0xB3, + 0xFF, 0x59, 0x00, 0xCD, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80, + 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01, + 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA9, + 0xFF, 0x15, 0x01, 0x5B, 0xFD, 0xD0, 0x05, 0x97, 0xF2, 0xE6, 0x3A, + 0x21, 0x24, 0xB1, 0xF2, 0x04, 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x39, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, + 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, + 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, + 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x6A, + 0x01, 0x74, 0xFD, 0x0A, 0x04, 0xD5, 0xF9, 0xED, 0x0A, 0x03, 0x48, + 0x7C, 0xFD, 0x9E, 0xFF, 0x0A, 0x01, 0x01, 0xFF, 0xAF, 0x00, 0xAB, + 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, + 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, 0x3D, 0x91, + 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, 0x02, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x75, 0xFF, 0x7A, 0x01, 0xB8, + 0xFC, 0xB4, 0x06, 0x9E, 0xF1, 0xA2, 0x34, 0xAD, 0x2B, 0xB6, 0xF1, + 0x29, 0x07, 0x45, 0xFC, 0xCB, 0x01, 0x49, 0xFF, 0x31, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, 0xFF, + 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, 0xCA, + 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x20, 0x00, 0x80, 0xFF, 0x1C, 0x01, 0x1C, 0xFE, 0xBD, + 0x02, 0x6E, 0xFC, 0x7D, 0x04, 0xF3, 0x48, 0xE2, 0x02, 0x1F, 0xFD, + 0x60, 0x02, 0x4C, 0xFE, 0x06, 0x01, 0x89, 0xFF, 0x1D, 0x00, 0xFE, + 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, 0x88, 0xFC, 0x09, 0x06, + 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, 0xF6, 0x83, 0x03, 0xCF, + 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, + 0x2E, 0x00, 0x50, 0xFF, 0xBF, 0x01, 0x54, 0xFC, 0x20, 0x07, 0x94, + 0xF1, 0xA6, 0x2D, 0xD0, 0x32, 0x85, 0xF1, 0xDD, 0x06, 0x96, 0xFC, + 0x90, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, + 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, 0xB9, 0x04, 0x27, 0xF4, + 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, 0x06, 0x50, 0xFC, 0xE2, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA2, 0xFF, + 0xC7, 0x00, 0xD0, 0xFE, 0x65, 0x01, 0xF6, 0xFE, 0xD9, 0xFE, 0x6A, + 0x48, 0x1F, 0x09, 0x87, 0xFA, 0xB3, 0x03, 0xA0, 0xFD, 0x56, 0x01, + 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, + 0xFF, 0xA0, 0x01, 0xFB, 0xFC, 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, + 0x2B, 0x46, 0xBB, 0xF9, 0x83, 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, + 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, + 0xE1, 0x01, 0x31, 0xFC, 0x19, 0x07, 0x5B, 0xF2, 0x30, 0x26, 0x4B, + 0x39, 0x3B, 0xF2, 0x1A, 0x06, 0x29, 0xFD, 0x33, 0x01, 0x99, 0xFF, + 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, + 0x01, 0x3A, 0xFD, 0x00, 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, + 0x79, 0xF2, 0x12, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC4, 0xFF, 0x70, 0x00, 0x84, 0xFF, + 0x19, 0x00, 0x4D, 0x01, 0x22, 0xFA, 0x70, 0x46, 0x0A, 0x10, 0xFC, + 0xF7, 0xEB, 0x04, 0x08, 0xFD, 0x9A, 0x01, 0x4F, 0xFF, 0x2E, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, + 0xFD, 0xD2, 0x03, 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, + 0x33, 0xFF, 0x45, 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, + 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4B, 0xFC, + 0xA9, 0x06, 0xD2, 0xF3, 0x81, 0x1E, 0xE4, 0x3E, 0xEF, 0xF3, 0xDE, + 0x04, 0xF9, 0xFD, 0xB7, 0x00, 0xD8, 0xFF, 0xFD, 0xFF, 0x03, 0x00, + 0xFD, 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, + 0x06, 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, + 0x4E, 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE4, 0xFF, 0x1D, 0x00, 0x2D, 0x00, 0xEA, 0xFE, 0x56, 0x03, + 0x6D, 0xF6, 0x17, 0x43, 0x70, 0x17, 0xA6, 0xF5, 0xF3, 0x05, 0x91, + 0xFC, 0xCC, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x86, 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, + 0x03, 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, + 0x14, 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, + 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x99, 0xFC, 0xE1, 0x05, 0xD1, 0xF5, + 0xDC, 0x16, 0x65, 0x43, 0xAD, 0xF6, 0x31, 0x03, 0x00, 0xFF, 0x20, + 0x00, 0x23, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, + 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62, + 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01, + 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0xFF, 0xFF, 0xD3, + 0xFF, 0xC1, 0x00, 0xE7, 0xFD, 0xFA, 0x04, 0xC4, 0xF3, 0x7E, 0x3E, + 0x19, 0x1F, 0xB0, 0xF3, 0xB5, 0x06, 0x47, 0xFC, 0xE4, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, 0x00, + 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, 0x47, + 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x96, + 0x01, 0x13, 0xFD, 0xD5, 0x04, 0x2C, 0xF8, 0x7D, 0x0F, 0xA3, 0x46, + 0x76, 0xFA, 0x22, 0x01, 0x32, 0x00, 0x76, 0xFF, 0x76, 0x00, 0xC1, + 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, 0xE4, 0x01, + 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, 0x3A, 0x74, + 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, 0x11, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x95, 0xFF, 0x3B, 0x01, 0x1B, + 0xFD, 0x2D, 0x06, 0x24, 0xF2, 0xD3, 0x38, 0xC6, 0x26, 0x45, 0xF2, + 0x1D, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, 0xFF, 0xE2, 0xFF, + 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, 0x8F, 0xF7, 0x1D, + 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x51, 0x01, 0xAC, 0xFD, 0x9A, + 0x03, 0xBA, 0xFA, 0x9E, 0x08, 0x81, 0x48, 0x40, 0xFF, 0xC6, 0xFE, + 0x80, 0x01, 0xC2, 0xFE, 0xCE, 0x00, 0x9F, 0xFF, 0x17, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, + 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, + 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFD, 0xFF, + 0x27, 0x00, 0x66, 0xFF, 0x96, 0x01, 0x8E, 0xFC, 0xE7, 0x06, 0x81, + 0xF1, 0x48, 0x32, 0x34, 0x2E, 0x8D, 0xF1, 0x1C, 0x07, 0x5A, 0xFC, + 0xBB, 0x01, 0x53, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, + 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, 0xFE, 0xA6, 0x03, 0xE4, 0xF5, + 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, 0x1A, 0x06, 0x81, 0xFC, 0xD2, + 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8B, 0xFF, + 0xFF, 0x00, 0x5A, 0xFE, 0x46, 0x02, 0x52, 0xFD, 0x70, 0x02, 0xED, + 0x48, 0xF5, 0x04, 0x3B, 0xFC, 0xD7, 0x02, 0x0F, 0xFE, 0x23, 0x01, + 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, + 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, + 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, + 0xCE, 0x01, 0x41, 0xFC, 0x2A, 0x07, 0xC2, 0xF1, 0x1B, 0x2B, 0x25, + 0x35, 0xA8, 0xF1, 0xA7, 0x06, 0xC2, 0xFC, 0x74, 0x01, 0x78, 0xFF, + 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, + 0x00, 0xBF, 0xFD, 0x38, 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, + 0x66, 0xF3, 0xCE, 0x06, 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAE, 0xFF, 0xA9, 0x00, 0x0F, 0xFF, + 0xF0, 0x00, 0xCD, 0xFF, 0x1B, 0xFD, 0xE4, 0x47, 0x73, 0x0B, 0xA2, + 0xF9, 0x23, 0x04, 0x68, 0xFD, 0x70, 0x01, 0x5F, 0xFF, 0x29, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, + 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, + 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, + 0xFD, 0x06, 0xCB, 0xF2, 0x8A, 0x23, 0x58, 0x3B, 0xB4, 0xF2, 0xBA, + 0x05, 0x6A, 0xFD, 0x0B, 0x01, 0xAE, 0xFF, 0x0D, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, + 0x06, 0xF7, 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, + 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, + 0x00, 0xCF, 0xFF, 0x52, 0x00, 0xC0, 0xFF, 0xAC, 0xFF, 0x0C, 0x02, + 0xBC, 0xF8, 0x6D, 0x45, 0x8E, 0x12, 0x24, 0xF7, 0x4D, 0x05, 0xDB, + 0xFC, 0xAE, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x24, 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, + 0xFB, 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, + 0xA3, 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xDD, 0x01, 0x60, 0xFC, 0x6D, 0x06, 0x76, 0xF4, + 0xD8, 0x1B, 0x95, 0x40, 0xC3, 0xF4, 0x56, 0x04, 0x4E, 0xFE, 0x85, + 0x00, 0xF1, 0xFF, 0xF4, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, + 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15, + 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01, + 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x02, + 0x00, 0x63, 0x00, 0x8A, 0xFE, 0xF3, 0x03, 0x63, 0xF5, 0xA1, 0x41, + 0x12, 0x1A, 0xEB, 0xF4, 0x3F, 0x06, 0x72, 0xFC, 0xD7, 0x01, 0x39, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, + 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, + 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, + 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBA, + 0x01, 0xBF, 0xFC, 0x8B, 0x05, 0x99, 0xF6, 0x43, 0x14, 0xA9, 0x44, + 0xDE, 0xF7, 0x85, 0x02, 0x65, 0xFF, 0xE7, 0xFF, 0x3F, 0x00, 0xD6, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD5, 0x01, + 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, 0x36, 0xC5, + 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, 0x1E, 0x00, + 0xFE, 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBC, 0xFF, 0xEF, 0x00, 0x9A, + 0xFD, 0x72, 0x05, 0x16, 0xF3, 0xA5, 0x3C, 0xC4, 0x21, 0x21, 0xF3, + 0xE4, 0x06, 0x39, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, 0x00, + 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, 0x5A, + 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x80, 0x01, 0x45, 0xFD, 0x6C, + 0x04, 0x0B, 0xF9, 0x0B, 0x0D, 0x73, 0x47, 0x02, 0xFC, 0x58, 0x00, + 0xA3, 0x00, 0x39, 0xFF, 0x94, 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, 0xFC, 0xEB, 0x06, + 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, 0xF2, 0x84, 0x05, 0x8D, + 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, + 0x1D, 0x00, 0x83, 0xFF, 0x5E, 0x01, 0xE3, 0xFC, 0x7B, 0x06, 0xD0, + 0xF1, 0xA5, 0x36, 0x62, 0x29, 0xEF, 0xF1, 0x29, 0x07, 0x39, 0xFC, + 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, + 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, 0x67, 0x02, 0x14, 0xF8, + 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, 0x05, 0xC5, 0xFC, 0xB7, + 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, + 0x76, 0xFF, 0x35, 0x01, 0xE7, 0xFD, 0x26, 0x03, 0xA1, 0xFB, 0x64, + 0x06, 0xD2, 0x48, 0x21, 0x01, 0xE8, 0xFD, 0xF7, 0x01, 0x83, 0xFE, + 0xEC, 0x00, 0x93, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, + 0xFF, 0xD9, 0x01, 0x6D, 0xFC, 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, + 0x5F, 0x41, 0x3A, 0xF5, 0x0C, 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, + 0xFF, 0xEF, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, + 0xAD, 0x01, 0x6C, 0xFC, 0x0C, 0x07, 0x7F, 0xF1, 0xDC, 0x2F, 0xAD, + 0x30, 0x7D, 0xF1, 0x01, 0x07, 0x76, 0xFC, 0xA6, 0x01, 0x5E, 0xFF, + 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, + 0x00, 0x5D, 0xFE, 0x3E, 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, + 0x93, 0xF4, 0x62, 0x06, 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x97, 0xFF, 0xE2, 0x00, 0x98, 0xFE, + 0xCF, 0x01, 0x33, 0xFE, 0x7D, 0x00, 0xBB, 0x48, 0x1F, 0x07, 0x54, + 0xFB, 0x4C, 0x03, 0xD3, 0xFD, 0x3F, 0x01, 0x73, 0xFF, 0x23, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, + 0xFC, 0x5D, 0x05, 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, + 0x2A, 0x02, 0x9A, 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, + 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDA, 0x01, 0x35, 0xFC, + 0x27, 0x07, 0x09, 0xF2, 0x85, 0x28, 0x63, 0x37, 0xE9, 0xF1, 0x63, + 0x06, 0xF5, 0xFC, 0x53, 0x01, 0x89, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x00, 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, + 0x05, 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, + 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, + 0x00, 0xB9, 0xFF, 0x8A, 0x00, 0x4D, 0xFF, 0x7D, 0x00, 0x9C, 0x00, + 0x7B, 0xFB, 0x31, 0x47, 0xD9, 0x0D, 0xC0, 0xF8, 0x8F, 0x04, 0x34, + 0xFD, 0x87, 0x01, 0x56, 0xFF, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, + 0xF9, 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, + 0x19, 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD5, 0x06, 0x4F, 0xF3, + 0xE0, 0x20, 0x45, 0x3D, 0x4D, 0xF3, 0x4B, 0x05, 0xB3, 0xFD, 0xE0, + 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, + 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86, + 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01, + 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xDA, 0xFF, 0x36, + 0x00, 0xFA, 0xFF, 0x43, 0xFF, 0xBF, 0x02, 0x75, 0xF7, 0x42, 0x44, + 0x20, 0x15, 0x55, 0xF6, 0xA9, 0x05, 0xB2, 0xFC, 0xBF, 0x01, 0x41, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, + 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, 0xEA, + 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, 0x00, + 0x8D, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD4, + 0x01, 0x7C, 0xFC, 0x27, 0x06, 0x28, 0xF5, 0x31, 0x19, 0x21, 0x42, + 0xB8, 0xF5, 0xC0, 0x03, 0xAA, 0xFE, 0x51, 0x00, 0x0B, 0x00, 0xEA, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, 0xB7, 0x01, + 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, 0x31, 0x7E, + 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, 0x28, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xE8, 0xFF, 0x96, 0x00, 0x31, + 0xFE, 0x84, 0x04, 0x79, 0xF4, 0x07, 0x40, 0xBA, 0x1C, 0x3E, 0xF4, + 0x82, 0x06, 0x58, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, 0xFE, 0x93, 0x01, + 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, 0xE1, 0xFA, 0x86, + 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA8, 0x01, 0xE9, 0xFC, 0x2D, + 0x05, 0x6B, 0xF7, 0xB6, 0x11, 0xC8, 0x45, 0x30, 0xF9, 0xCD, 0x01, + 0xD0, 0xFF, 0xAC, 0xFF, 0x5C, 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, + 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, + 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x10, 0x00, 0xA7, 0xFF, 0x19, 0x01, 0x53, 0xFD, 0xDB, 0x05, 0x88, + 0xF2, 0xAD, 0x3A, 0x6D, 0x24, 0xA4, 0xF2, 0x08, 0x07, 0x32, 0xFC, + 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBF, + 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, 0x00, 0x01, 0x01, 0xB6, 0xFA, + 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, 0xC4, 0x04, 0x1B, 0xFD, 0x92, + 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x63, 0xFF, 0x67, 0x01, 0x7A, 0xFD, 0xFE, 0x03, 0xEE, 0xF9, 0xAA, + 0x0A, 0x16, 0x48, 0xAC, 0xFD, 0x86, 0xFF, 0x17, 0x01, 0xFA, 0xFE, + 0xB3, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, + 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, + 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x73, 0xFF, + 0x7D, 0x01, 0xB3, 0xFC, 0xBB, 0x06, 0x9A, 0xF1, 0x60, 0x34, 0xF5, + 0x2B, 0xB0, 0xF1, 0x28, 0x07, 0x47, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, + 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, + 0x00, 0x10, 0xFF, 0x15, 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, + 0xF1, 0xF5, 0xD3, 0x05, 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x19, 0x01, + 0x23, 0xFE, 0xB0, 0x02, 0x87, 0xFC, 0x41, 0x04, 0xF4, 0x48, 0x1C, + 0x03, 0x06, 0xFD, 0x6E, 0x02, 0x45, 0xFE, 0x09, 0x01, 0x88, 0xFF, + 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, + 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, + 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4F, 0xFF, 0xC1, 0x01, 0x52, 0xFC, + 0x22, 0x07, 0x98, 0xF1, 0x5E, 0x2D, 0x13, 0x33, 0x87, 0xF1, 0xD8, + 0x06, 0x9B, 0xFC, 0x8D, 0x01, 0x6B, 0xFF, 0x25, 0x00, 0xFD, 0xFF, + 0x03, 0x00, 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, + 0x04, 0x10, 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, + 0x4E, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, + 0x00, 0xA3, 0xFF, 0xC3, 0x00, 0xD7, 0xFE, 0x58, 0x01, 0x0F, 0xFF, + 0xA6, 0xFE, 0x5D, 0x48, 0x61, 0x09, 0x6E, 0xFA, 0xC0, 0x03, 0x99, + 0xFD, 0x59, 0x01, 0x68, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2E, 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, + 0xF7, 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, + 0x8E, 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x16, 0x07, 0x67, 0xF2, + 0xE5, 0x25, 0x87, 0x39, 0x47, 0xF2, 0x10, 0x06, 0x30, 0xFD, 0x2F, + 0x01, 0x9C, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x13, 0x00, + 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5, + 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC5, 0xFF, 0x6D, + 0x00, 0x8B, 0xFF, 0x0D, 0x00, 0x63, 0x01, 0xF9, 0xF9, 0x55, 0x46, + 0x51, 0x10, 0xE3, 0xF7, 0xF7, 0x04, 0x03, 0xFD, 0x9D, 0x01, 0x4E, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, + 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, + 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, + 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, + 0x01, 0x4D, 0xFC, 0xA3, 0x06, 0xE4, 0xF3, 0x36, 0x1E, 0x16, 0x3F, + 0x05, 0xF4, 0xCF, 0x04, 0x02, 0xFE, 0xB2, 0x00, 0xDB, 0xFF, 0xFC, + 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, 0x8B, 0x01, + 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, 0x2D, 0x9A, + 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, 0x2F, 0x00, + 0xFD, 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x1A, 0x00, 0x33, 0x00, 0xDF, + 0xFE, 0x68, 0x03, 0x4E, 0xF6, 0xEE, 0x42, 0xBB, 0x17, 0x90, 0xF5, + 0xFC, 0x05, 0x8E, 0xFC, 0xCD, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, 0x02, + 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, 0xA9, + 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC7, 0x01, 0x9D, 0xFC, 0xD8, + 0x05, 0xE7, 0xF5, 0x91, 0x16, 0x89, 0x43, 0xCD, 0xF6, 0x1E, 0x03, + 0x0B, 0xFF, 0x1A, 0x00, 0x26, 0x00, 0xE0, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, 0x48, 0xFC, 0x28, 0x07, + 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, 0xF1, 0xBE, 0x06, 0xB0, + 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, + 0x00, 0x00, 0xD0, 0xFF, 0xC7, 0x00, 0xDE, 0xFD, 0x08, 0x05, 0xB0, + 0xF3, 0x4A, 0x3E, 0x64, 0x1F, 0xA0, 0xF3, 0xBB, 0x06, 0x45, 0xFC, + 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA9, + 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, 0x7A, 0xFF, 0xC5, 0xFD, + 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, 0x03, 0x7D, 0xFD, 0x66, + 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, + 0x52, 0xFF, 0x93, 0x01, 0x18, 0xFD, 0xC9, 0x04, 0x45, 0xF8, 0x36, + 0x0F, 0xBB, 0x46, 0xA1, 0xFA, 0x0C, 0x01, 0x3E, 0x00, 0x70, 0xFF, + 0x7A, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, + 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, + 0x8F, 0x3A, 0x82, 0xF2, 0xE1, 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, + 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x00, 0x93, 0xFF, + 0x3F, 0x01, 0x15, 0xFD, 0x36, 0x06, 0x19, 0xF2, 0x97, 0x38, 0x11, + 0x27, 0x3B, 0xF2, 0x1F, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, + 0xFF, 0xD6, 0xFF, 0xC3, 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, + 0x77, 0xF7, 0x28, 0x05, 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6D, 0xFF, 0x4E, 0x01, + 0xB3, 0xFD, 0x8D, 0x03, 0xD4, 0xFA, 0x5D, 0x08, 0x8D, 0x48, 0x74, + 0xFF, 0xAE, 0xFE, 0x8D, 0x01, 0xBB, 0xFE, 0xD1, 0x00, 0x9E, 0xFF, + 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, + 0xFC, 0x85, 0x06, 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, + 0x8C, 0x04, 0x2C, 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, + 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x65, 0xFF, 0x98, 0x01, 0x8A, 0xFC, + 0xEC, 0x06, 0x7F, 0xF1, 0x04, 0x32, 0x7B, 0x2E, 0x8A, 0xF1, 0x1A, + 0x07, 0x5D, 0xFC, 0xB8, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, + 0x06, 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, + 0x03, 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, + 0x7D, 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, + 0x00, 0x8D, 0xFF, 0xFC, 0x00, 0x61, 0xFE, 0x39, 0x02, 0x6B, 0xFD, + 0x37, 0x02, 0xEB, 0x48, 0x31, 0x05, 0x21, 0xFC, 0xE4, 0x02, 0x08, + 0xFE, 0x26, 0x01, 0x7C, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x32, 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, + 0xF6, 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, + 0xFE, 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x32, + 0x00, 0x47, 0xFF, 0xD0, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xCA, 0xF1, + 0xD1, 0x2A, 0x65, 0x35, 0xAE, 0xF1, 0xA0, 0x06, 0xC7, 0xFC, 0x70, + 0x01, 0x7A, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, + 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61, + 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA5, + 0x00, 0x16, 0xFF, 0xE3, 0x00, 0xE4, 0xFF, 0xEB, 0xFC, 0xD2, 0x47, + 0xB6, 0x0B, 0x89, 0xF9, 0x2F, 0x04, 0x62, 0xFD, 0x72, 0x01, 0x5E, + 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x56, 0xFF, + 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, 0x26, + 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, 0x00, + 0xBA, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, + 0x01, 0x34, 0xFC, 0xF9, 0x06, 0xD9, 0xF2, 0x3F, 0x23, 0x90, 0x3B, + 0xC4, 0xF2, 0xAE, 0x05, 0x72, 0xFD, 0x07, 0x01, 0xB0, 0xFF, 0x0C, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, 0x51, 0x01, + 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, 0x28, 0x0E, + 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x4F, 0x00, 0xC7, 0xFF, 0xA0, + 0xFF, 0x20, 0x02, 0x96, 0xF8, 0x4E, 0x45, 0xD7, 0x12, 0x0D, 0xF7, + 0x58, 0x05, 0xD6, 0xFC, 0xB0, 0x01, 0x47, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, 0x01, 0xD0, 0xFD, + 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, 0x62, 0x00, 0x3F, + 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, 0xFF, 0x19, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x63, 0xFC, 0x66, + 0x06, 0x89, 0xF4, 0x8C, 0x1B, 0xC3, 0x40, 0xDD, 0xF4, 0x46, 0x04, + 0x58, 0xFE, 0x80, 0x00, 0xF4, 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, + 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, + 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, + 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, + 0xEF, 0xFF, 0xFF, 0xFF, 0x69, 0x00, 0x80, 0xFE, 0x04, 0x04, 0x48, + 0xF5, 0x74, 0x41, 0x5D, 0x1A, 0xD7, 0xF4, 0x47, 0x06, 0x6F, 0xFC, + 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x93, + 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, 0x01, 0xDC, 0xFD, 0x3C, 0x01, + 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, 0x1F, 0x03, 0xEA, 0xFD, 0x34, + 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, + 0x44, 0xFF, 0xB8, 0x01, 0xC3, 0xFC, 0x81, 0x05, 0xB0, 0xF6, 0xFA, + 0x13, 0xCC, 0x44, 0x02, 0xF8, 0x71, 0x02, 0x71, 0xFF, 0xE1, 0xFF, + 0x42, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, + 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, + 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, + 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x09, 0x00, 0xBA, 0xFF, + 0xF4, 0x00, 0x91, 0xFD, 0x7E, 0x05, 0x05, 0xF3, 0x6E, 0x3C, 0x10, + 0x22, 0x12, 0xF3, 0xE9, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, + 0xFF, 0xA9, 0x00, 0x4D, 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, + 0x18, 0xF9, 0x66, 0x04, 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5A, 0xFF, 0x7D, 0x01, + 0x4B, 0xFD, 0x60, 0x04, 0x24, 0xF9, 0xC6, 0x0C, 0x86, 0x47, 0x30, + 0xFC, 0x41, 0x00, 0xB0, 0x00, 0x32, 0xFF, 0x98, 0x00, 0xB4, 0xFF, + 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, + 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, + 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x81, 0xFF, 0x62, 0x01, 0xDD, 0xFC, + 0x83, 0x06, 0xC9, 0xF1, 0x66, 0x36, 0xAC, 0x29, 0xE7, 0xF1, 0x2A, + 0x07, 0x3A, 0xFC, 0xD5, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, + 0x02, 0xF0, 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, + 0xC1, 0xFC, 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x77, 0xFF, 0x32, 0x01, 0xED, 0xFD, 0x19, 0x03, + 0xBB, 0xFB, 0x26, 0x06, 0xD7, 0x48, 0x58, 0x01, 0xCF, 0xFD, 0x04, + 0x02, 0x7D, 0xFE, 0xEF, 0x00, 0x92, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, + 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, + 0xF4, 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, + 0x66, 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2B, + 0x00, 0x59, 0xFF, 0xB0, 0x01, 0x69, 0xFC, 0x0F, 0x07, 0x80, 0xF1, + 0x96, 0x2F, 0xF2, 0x30, 0x7C, 0xF1, 0xFD, 0x06, 0x7A, 0xFC, 0xA3, + 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF4, 0xFF, + 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB, + 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x98, 0xFF, 0xDE, + 0x00, 0x9F, 0xFE, 0xC2, 0x01, 0x4B, 0xFE, 0x48, 0x00, 0xB3, 0x48, + 0x5E, 0x07, 0x3B, 0xFB, 0x59, 0x03, 0xCD, 0xFD, 0x42, 0x01, 0x71, + 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, + 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, + 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, + 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDB, + 0x01, 0x35, 0xFC, 0x25, 0x07, 0x13, 0xF2, 0x3A, 0x28, 0xA0, 0x37, + 0xF2, 0xF1, 0x5A, 0x06, 0xFB, 0xFC, 0x4F, 0x01, 0x8B, 0xFF, 0x1A, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, 0x09, 0x01, + 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, 0x23, 0xD2, + 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x11, 0x00, 0xBB, 0xFF, 0x87, 0x00, 0x54, 0xFF, 0x70, + 0x00, 0xB3, 0x00, 0x4E, 0xFB, 0x1A, 0x47, 0x1F, 0x0E, 0xA8, 0xF8, + 0x9B, 0x04, 0x2E, 0xFD, 0x8A, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, 0xFD, + 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, 0xD9, + 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD0, + 0x06, 0x5E, 0xF3, 0x94, 0x20, 0x7B, 0x3D, 0x60, 0xF3, 0x3E, 0x05, + 0xBB, 0xFD, 0xDB, 0x00, 0xC6, 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, + 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, 0xC4, 0xFC, 0xA4, 0x06, + 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, 0xF1, 0x2A, 0x07, 0x40, + 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, + 0xDB, 0xFF, 0x33, 0x00, 0x01, 0x00, 0x38, 0xFF, 0xD3, 0x02, 0x53, + 0xF7, 0x1F, 0x44, 0x69, 0x15, 0x3F, 0xF6, 0xB2, 0x05, 0xAD, 0xFC, + 0xC1, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, + 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, 0xDE, 0x02, 0x2E, 0xFC, + 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, 0xFD, 0x3F, 0x02, 0x5D, + 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3B, 0xFF, 0xD3, 0x01, 0x7F, 0xFC, 0x1F, 0x06, 0x3C, 0xF5, 0xE6, + 0x18, 0x4D, 0x42, 0xD5, 0xF5, 0xAF, 0x03, 0xB4, 0xFE, 0x4B, 0x00, + 0x0E, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, + 0xFF, 0xBA, 0x01, 0x5B, 0xFC, 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, + 0x26, 0x32, 0x80, 0xF1, 0xEA, 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, + 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, 0xFF, 0xE6, 0xFF, + 0x9C, 0x00, 0x27, 0xFE, 0x94, 0x04, 0x61, 0xF4, 0xD7, 0x3F, 0x06, + 0x1D, 0x2B, 0xF4, 0x89, 0x06, 0x56, 0xFC, 0xE0, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, + 0xFE, 0x86, 0x01, 0xBA, 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, + 0xC7, 0xFA, 0x93, 0x03, 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA6, 0x01, + 0xEE, 0xFC, 0x23, 0x05, 0x83, 0xF7, 0x6E, 0x11, 0xE5, 0x45, 0x57, + 0xF9, 0xB8, 0x01, 0xDC, 0xFF, 0xA5, 0xFF, 0x5F, 0x00, 0xCA, 0xFF, + 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, + 0xFC, 0x1E, 0x07, 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, + 0x32, 0x06, 0x18, 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA4, 0xFF, 0x1D, 0x01, 0x4C, 0xFD, + 0xE6, 0x05, 0x7B, 0xF2, 0x71, 0x3A, 0xB8, 0x24, 0x97, 0xF2, 0x0B, + 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x0F, 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, + 0x01, 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, + 0x15, 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x64, 0xFF, 0x65, 0x01, 0x81, 0xFD, 0xF2, 0x03, + 0x08, 0xFA, 0x68, 0x0A, 0x25, 0x48, 0xDE, 0xFD, 0x6E, 0xFF, 0x24, + 0x01, 0xF3, 0xFE, 0xB6, 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, + 0xF3, 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, + 0xC4, 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x23, + 0x00, 0x71, 0xFF, 0x81, 0x01, 0xAE, 0xFC, 0xC1, 0x06, 0x95, 0xF1, + 0x1E, 0x34, 0x3E, 0x2C, 0xAB, 0xF1, 0x27, 0x07, 0x49, 0xFC, 0xC8, + 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, + 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77, + 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01, + 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, + 0xFF, 0x16, 0x01, 0x2A, 0xFE, 0xA3, 0x02, 0xA1, 0xFC, 0x06, 0x04, + 0xF5, 0x48, 0x56, 0x03, 0xED, 0xFC, 0x7B, 0x02, 0x3E, 0xFE, 0x0C, + 0x01, 0x86, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, 0x02, + 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, 0x00, + 0xE4, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, + 0x01, 0x4F, 0xFC, 0x24, 0x07, 0x9C, 0xF1, 0x17, 0x2D, 0x57, 0x33, + 0x8A, 0xF1, 0xD3, 0x06, 0x9F, 0xFC, 0x8A, 0x01, 0x6D, 0xFF, 0x25, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, 0xB4, 0x00, + 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, + 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC0, 0x00, 0xDE, 0xFE, 0x4B, + 0x01, 0x27, 0xFF, 0x73, 0xFE, 0x4F, 0x48, 0xA2, 0x09, 0x54, 0xFA, + 0xCC, 0x03, 0x93, 0xFD, 0x5C, 0x01, 0x67, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, 0x01, 0x05, 0xFD, + 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, 0x0D, 0xFA, 0x58, + 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x14, + 0x07, 0x73, 0xF2, 0x99, 0x25, 0xC2, 0x39, 0x54, 0xF2, 0x05, 0x06, + 0x37, 0xFD, 0x2B, 0x01, 0x9E, 0xFF, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, + 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, + 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC6, 0xFF, 0x69, 0x00, 0x91, 0xFF, 0x00, 0x00, 0x78, 0x01, 0xD0, + 0xF9, 0x39, 0x46, 0x98, 0x10, 0xCB, 0xF7, 0x02, 0x05, 0xFE, 0xFC, + 0x9F, 0x01, 0x4D, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, + 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, 0xFD, 0xB9, 0x03, 0x7B, 0xFA, + 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, 0x03, 0xFF, 0x5F, 0x01, 0xD4, + 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE2, 0x01, 0x4F, 0xFC, 0x9C, 0x06, 0xF5, 0xF3, 0xEA, + 0x1D, 0x47, 0x3F, 0x1B, 0xF4, 0xC1, 0x04, 0x0B, 0xFE, 0xAC, 0x00, + 0xDE, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, + 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, + 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x17, 0x00, + 0x39, 0x00, 0xD4, 0xFE, 0x7A, 0x03, 0x2F, 0xF6, 0xC7, 0x42, 0x06, + 0x18, 0x7B, 0xF5, 0x05, 0x06, 0x8A, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, + 0xFE, 0x67, 0x02, 0x13, 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, + 0x7A, 0xFC, 0xB6, 0x02, 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, + 0xA1, 0xFC, 0xCF, 0x05, 0xFC, 0xF5, 0x47, 0x16, 0xB0, 0x43, 0xEE, + 0xF6, 0x0C, 0x03, 0x16, 0xFF, 0x14, 0x00, 0x29, 0x00, 0xDF, 0xFF, + 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, + 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, + 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCE, 0xFF, 0xCC, 0x00, 0xD5, 0xFD, + 0x16, 0x05, 0x9B, 0xF3, 0x18, 0x3E, 0xB1, 0x1F, 0x8F, 0xF3, 0xC0, + 0x06, 0x43, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x15, 0x00, 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, + 0xFF, 0x94, 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, + 0x77, 0xFD, 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x91, 0x01, 0x1E, 0xFD, 0xBE, 0x04, + 0x5E, 0xF8, 0xF0, 0x0E, 0xD3, 0x46, 0xCB, 0xFA, 0xF6, 0x00, 0x4B, + 0x00, 0x69, 0xFF, 0x7D, 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, + 0xF2, 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, + 0x17, 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x00, 0x91, 0xFF, 0x43, 0x01, 0x0E, 0xFD, 0x40, 0x06, 0x0F, 0xF2, + 0x5B, 0x38, 0x5C, 0x27, 0x30, 0xF2, 0x21, 0x07, 0x33, 0xFC, 0xDE, + 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCC, 0xFF, + 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8, + 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01, + 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6E, + 0xFF, 0x4B, 0x01, 0xB9, 0xFD, 0x80, 0x03, 0xEE, 0xFA, 0x1D, 0x08, + 0x98, 0x48, 0xA8, 0xFF, 0x95, 0xFE, 0x9A, 0x01, 0xB4, 0xFE, 0xD4, + 0x00, 0x9C, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, + 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, + 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9B, + 0x01, 0x86, 0xFC, 0xF1, 0x06, 0x7E, 0xF1, 0xC0, 0x31, 0xC2, 0x2E, + 0x87, 0xF1, 0x17, 0x07, 0x5F, 0xFC, 0xB6, 0x01, 0x55, 0xFF, 0x2D, + 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, 0x54, 0x00, + 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, 0x19, 0x1E, + 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1C, 0x00, 0x8E, 0xFF, 0xF9, 0x00, 0x68, 0xFE, 0x2C, + 0x02, 0x84, 0xFD, 0xFF, 0x01, 0xE6, 0x48, 0x6E, 0x05, 0x07, 0xFC, + 0xF1, 0x02, 0x01, 0xFE, 0x29, 0x01, 0x7B, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, 0xFC, + 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, 0xB6, + 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, 0x00, + 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3E, 0xFC, 0x2B, + 0x07, 0xD0, 0xF1, 0x89, 0x2A, 0xA6, 0x35, 0xB4, 0xF1, 0x99, 0x06, + 0xCD, 0xFC, 0x6D, 0x01, 0x7C, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, + 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, 0xAE, 0xFD, 0x52, 0x05, + 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, 0xF3, 0xD8, 0x06, 0x3C, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, + 0xB0, 0xFF, 0xA2, 0x00, 0x1D, 0xFF, 0xD6, 0x00, 0xFC, 0xFF, 0xBC, + 0xFC, 0xC0, 0x47, 0xFA, 0x0B, 0x70, 0xF9, 0x3C, 0x04, 0x5C, 0xFD, + 0x75, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, 0x89, 0x04, 0xCD, 0xF8, + 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, 0x00, 0x83, 0x00, 0x4A, + 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF5, 0x06, 0xE7, 0xF2, 0xF2, + 0x22, 0xC7, 0x3B, 0xD4, 0xF2, 0xA2, 0x05, 0x7A, 0xFD, 0x02, 0x01, + 0xB2, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, + 0xFF, 0x55, 0x01, 0xF2, 0xFC, 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, + 0xAA, 0x28, 0x05, 0xF2, 0x27, 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, + 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD2, 0xFF, 0x4C, 0x00, + 0xCD, 0xFF, 0x94, 0xFF, 0x34, 0x02, 0x70, 0xF8, 0x2E, 0x45, 0x20, + 0x13, 0xF6, 0xF6, 0x62, 0x05, 0xD1, 0xFC, 0xB2, 0x01, 0x46, 0xFF, + 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, + 0x01, 0xD6, 0xFD, 0x46, 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, + 0x98, 0x00, 0x26, 0xFE, 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, + 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, + 0x66, 0xFC, 0x5E, 0x06, 0x9C, 0xF4, 0x40, 0x1B, 0xEF, 0x40, 0xF7, + 0xF4, 0x35, 0x04, 0x62, 0xFE, 0x7A, 0x00, 0xF7, 0xFF, 0xF2, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, + 0xFC, 0x03, 0x07, 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, + 0x0A, 0x07, 0x6E, 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, + 0xFF, 0x05, 0x00, 0xF0, 0xFF, 0xFC, 0xFF, 0x6E, 0x00, 0x76, 0xFE, + 0x15, 0x04, 0x2C, 0xF5, 0x49, 0x41, 0xA9, 0x1A, 0xC3, 0xF4, 0x4F, + 0x06, 0x6C, 0xFC, 0xD9, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, + 0xFD, 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, + 0xE4, 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB6, 0x01, 0xC8, 0xFC, 0x77, 0x05, + 0xC7, 0xF6, 0xB1, 0x13, 0xED, 0x44, 0x26, 0xF8, 0x5D, 0x02, 0x7D, + 0xFF, 0xDA, 0xFF, 0x46, 0x00, 0xD4, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, + 0xF1, 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, + 0x5C, 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, + 0x00, 0xB7, 0xFF, 0xF9, 0x00, 0x89, 0xFD, 0x8A, 0x05, 0xF4, 0xF2, + 0x37, 0x3C, 0x5B, 0x22, 0x03, 0xF3, 0xED, 0x06, 0x37, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB6, 0xFF, + 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69, + 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, + 0xFF, 0x7A, 0x01, 0x50, 0xFD, 0x54, 0x04, 0x3D, 0xF9, 0x82, 0x0C, + 0x9A, 0x47, 0x5E, 0xFC, 0x2A, 0x00, 0xBD, 0x00, 0x2B, 0xFF, 0x9B, + 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, 0xC0, + 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, 0xFF, + 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x80, 0xFF, 0x66, + 0x01, 0xD8, 0xFC, 0x8B, 0x06, 0xC1, 0xF1, 0x27, 0x36, 0xF6, 0x29, + 0xDF, 0xF1, 0x2A, 0x07, 0x3B, 0xFC, 0xD4, 0x01, 0x44, 0xFF, 0x32, + 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, 0xEA, 0xFF, + 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, 0x14, 0x8E, + 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, 0x32, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x79, 0xFF, 0x2F, 0x01, 0xF4, + 0xFD, 0x0C, 0x03, 0xD4, 0xFB, 0xE9, 0x05, 0xDE, 0x48, 0x8F, 0x01, + 0xB6, 0xFD, 0x11, 0x02, 0x76, 0xFE, 0xF2, 0x00, 0x91, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, 0x01, 0x73, 0xFC, + 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, 0x71, 0xF5, 0xEB, + 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, 0xFF, 0x06, 0x00, + 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB2, 0x01, 0x65, 0xFC, 0x12, + 0x07, 0x82, 0xF1, 0x50, 0x2F, 0x38, 0x31, 0x7C, 0xF1, 0xF9, 0x06, + 0x7E, 0xFC, 0xA1, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, + 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, + 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, + 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, + 0x9A, 0xFF, 0xDB, 0x00, 0xA6, 0xFE, 0xB4, 0x01, 0x64, 0xFE, 0x12, + 0x00, 0xAA, 0x48, 0x9E, 0x07, 0x21, 0xFB, 0x66, 0x03, 0xC6, 0xFD, + 0x45, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, 0xFC, 0x48, 0x05, 0x30, 0xF7, + 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, 0x01, 0x02, 0xB2, 0xFF, 0xBD, + 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x24, 0x07, 0x1C, 0xF2, 0xF0, + 0x27, 0xDF, 0x37, 0xFB, 0xF1, 0x51, 0x06, 0x01, 0xFD, 0x4B, 0x01, + 0x8D, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC, + 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, + 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBC, 0xFF, 0x84, 0x00, + 0x5B, 0xFF, 0x64, 0x00, 0xC9, 0x00, 0x22, 0xFB, 0x02, 0x47, 0x64, + 0x0E, 0x8F, 0xF8, 0xA7, 0x04, 0x29, 0xFD, 0x8C, 0x01, 0x54, 0xFF, + 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, + 0x01, 0x6B, 0xFD, 0x1D, 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, + 0x33, 0xFD, 0xC1, 0xFF, 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, + 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x40, 0xFC, 0xCB, 0x06, 0x6E, 0xF3, 0x49, 0x20, 0xB0, 0x3D, 0x73, + 0xF3, 0x31, 0x05, 0xC4, 0xFD, 0xD6, 0x00, 0xC8, 0xFF, 0x03, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, + 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, + 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x2F, 0x00, 0x07, 0x00, 0x2C, 0xFF, + 0xE6, 0x02, 0x31, 0xF7, 0xFA, 0x43, 0xB3, 0x15, 0x29, 0xF6, 0xBC, + 0x05, 0xA9, 0xFC, 0xC2, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, + 0x02, 0x47, 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, + 0x4D, 0x02, 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFE, + 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, 0x83, 0xFC, 0x16, 0x06, + 0x51, 0xF5, 0x9B, 0x18, 0x75, 0x42, 0xF3, 0xF5, 0x9D, 0x03, 0xBF, + 0xFE, 0x45, 0x00, 0x11, 0x00, 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, + 0x2E, 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, + 0xF1, 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, + 0x94, 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF9, + 0xFF, 0xE3, 0xFF, 0xA1, 0x00, 0x1E, 0xFE, 0xA3, 0x04, 0x49, 0xF4, + 0xA8, 0x3F, 0x52, 0x1D, 0x19, 0xF4, 0x90, 0x06, 0x53, 0xFC, 0xE1, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, + 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C, + 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01, + 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, + 0xFF, 0xA3, 0x01, 0xF3, 0xFC, 0x18, 0x05, 0x9B, 0xF7, 0x27, 0x11, + 0x02, 0x46, 0x7F, 0xF9, 0xA3, 0x01, 0xE8, 0xFF, 0x9F, 0xFF, 0x63, + 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, + 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, + 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, + 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA2, 0xFF, 0x22, + 0x01, 0x45, 0xFD, 0xF1, 0x05, 0x6D, 0xF2, 0x38, 0x3A, 0x03, 0x25, + 0x8B, 0xF2, 0x0E, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x3A, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, 0x7A, 0xFF, + 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, 0x0F, 0x20, + 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, 0x2E, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x62, 0x01, 0x87, + 0xFD, 0xE5, 0x03, 0x21, 0xFA, 0x25, 0x0A, 0x33, 0x48, 0x0F, 0xFE, + 0x57, 0xFF, 0x31, 0x01, 0xEC, 0xFE, 0xB9, 0x00, 0xA7, 0xFF, 0x15, + 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, 0xFC, + 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, 0xF3, + 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, 0x00, + 0xFE, 0xFF, 0x23, 0x00, 0x70, 0xFF, 0x84, 0x01, 0xA9, 0xFC, 0xC7, + 0x06, 0x91, 0xF1, 0xDC, 0x33, 0x87, 0x2C, 0xA5, 0xF1, 0x26, 0x07, + 0x4B, 0xFC, 0xC6, 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, 0xFA, 0xFE, 0x3A, 0x03, + 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, 0xF5, 0xE6, 0x05, 0x97, + 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, + 0x1E, 0x00, 0x84, 0xFF, 0x13, 0x01, 0x31, 0xFE, 0x95, 0x02, 0xBA, + 0xFC, 0xCB, 0x03, 0xF7, 0x48, 0x91, 0x03, 0xD3, 0xFC, 0x88, 0x02, + 0x38, 0xFE, 0x10, 0x01, 0x85, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, + 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, 0xEF, 0x05, 0xB0, 0xF5, + 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, 0x03, 0xEF, 0xFE, 0x2A, + 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4D, 0xFF, 0xC4, 0x01, 0x4D, 0xFC, 0x25, 0x07, 0xA1, 0xF1, 0xCE, + 0x2C, 0x99, 0x33, 0x8E, 0xF1, 0xCD, 0x06, 0xA4, 0xFC, 0x87, 0x01, + 0x6E, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD7, + 0xFF, 0xBA, 0x00, 0xF4, 0xFD, 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, + 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBD, 0x00, + 0xE5, 0xFE, 0x3E, 0x01, 0x3F, 0xFF, 0x41, 0xFE, 0x41, 0x48, 0xE4, + 0x09, 0x3B, 0xFA, 0xD9, 0x03, 0x8D, 0xFD, 0x5F, 0x01, 0x66, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, + 0x01, 0x0B, 0xFD, 0xE6, 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, + 0x37, 0xFA, 0x42, 0x01, 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, + 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, + 0x31, 0xFC, 0x11, 0x07, 0x7F, 0xF2, 0x4E, 0x25, 0xFD, 0x39, 0x60, + 0xF2, 0xFB, 0x05, 0x3E, 0xFD, 0x26, 0x01, 0xA0, 0xFF, 0x12, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, + 0xFD, 0x1E, 0x06, 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, + 0x1A, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x66, 0x00, 0x98, 0xFF, 0xF4, 0xFF, + 0x8E, 0x01, 0xA7, 0xF9, 0x1D, 0x46, 0xDF, 0x10, 0xB3, 0xF7, 0x0D, + 0x05, 0xF8, 0xFC, 0xA1, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, + 0x03, 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, + 0x6C, 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x51, 0xFC, 0x96, 0x06, + 0x07, 0xF4, 0x9E, 0x1D, 0x77, 0x3F, 0x32, 0xF4, 0xB2, 0x04, 0x15, + 0xFE, 0xA7, 0x00, 0xE0, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, + 0x26, 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, + 0xF1, 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, + 0xBE, 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE7, + 0xFF, 0x14, 0x00, 0x3F, 0x00, 0xC9, 0xFE, 0x8C, 0x03, 0x11, 0xF6, + 0x9E, 0x42, 0x50, 0x18, 0x66, 0xF5, 0x0D, 0x06, 0x86, 0xFC, 0xD0, + 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, + 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2, + 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01, + 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC4, 0x01, 0xA5, 0xFC, 0xC5, 0x05, 0x13, 0xF6, 0xFD, 0x15, + 0xD4, 0x43, 0x0F, 0xF7, 0xF9, 0x02, 0x21, 0xFF, 0x0D, 0x00, 0x2C, + 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, 0xFF, + 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, 0xC3, + 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, 0xFF, + 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, 0xCB, 0xFF, 0xD1, + 0x00, 0xCC, 0xFD, 0x24, 0x05, 0x87, 0xF3, 0xE4, 0x3D, 0xFD, 0x1F, + 0x7F, 0xF3, 0xC6, 0x06, 0x41, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, 0x05, 0xFF, + 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, 0x0B, 0xC8, + 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, 0x28, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x8F, 0x01, 0x23, + 0xFD, 0xB2, 0x04, 0x76, 0xF8, 0xAA, 0x0E, 0xED, 0x46, 0xF7, 0xFA, + 0xDF, 0x00, 0x57, 0x00, 0x62, 0xFF, 0x80, 0x00, 0xBD, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x33, 0xFC, + 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, 0x9E, 0xF2, 0xCB, + 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x18, 0x00, 0x8F, 0xFF, 0x47, 0x01, 0x08, 0xFD, 0x49, + 0x06, 0x05, 0xF2, 0x1D, 0x38, 0xA6, 0x27, 0x26, 0xF2, 0x23, 0x07, + 0x33, 0xFC, 0xDD, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, + 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, + 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, + 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x24, 0x00, 0x6F, 0xFF, 0x48, 0x01, 0xC0, 0xFD, 0x73, 0x03, 0x07, + 0xFB, 0xDD, 0x07, 0xA1, 0x48, 0xDD, 0xFF, 0x7D, 0xFE, 0xA7, 0x01, + 0xAD, 0xFE, 0xD8, 0x00, 0x9B, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, 0xFC, 0x78, 0x06, 0x5A, 0xF4, + 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, 0x6D, 0x04, 0x3F, 0xFE, 0x8E, + 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x62, 0xFF, 0x9E, 0x01, 0x82, 0xFC, 0xF5, 0x06, 0x7D, 0xF1, 0x7B, + 0x31, 0x09, 0x2F, 0x84, 0xF1, 0x15, 0x07, 0x62, 0xFC, 0xB4, 0x01, + 0x56, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06, + 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, + 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x8F, 0xFF, 0xF5, 0x00, + 0x6F, 0xFE, 0x1E, 0x02, 0x9D, 0xFD, 0xC7, 0x01, 0xE1, 0x48, 0xAB, + 0x05, 0xEE, 0xFB, 0xFE, 0x02, 0xFB, 0xFD, 0x2C, 0x01, 0x7A, 0xFF, + 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, + 0x01, 0xB8, 0xFC, 0x9A, 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, + 0xA9, 0xF7, 0xA2, 0x02, 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD3, 0x01, + 0x3C, 0xFC, 0x2A, 0x07, 0xD8, 0xF1, 0x3F, 0x2A, 0xE6, 0x35, 0xBB, + 0xF1, 0x92, 0x06, 0xD2, 0xFC, 0x69, 0x01, 0x7E, 0xFF, 0x1F, 0x00, + 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, + 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, + 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0x9F, 0x00, 0x24, 0xFF, 0xC9, 0x00, + 0x13, 0x00, 0x8D, 0xFC, 0xAE, 0x47, 0x3E, 0x0C, 0x56, 0xF9, 0x48, + 0x04, 0x56, 0xFD, 0x78, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, + 0x04, 0xE6, 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, + 0x90, 0x00, 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xF1, 0x06, + 0xF5, 0xF2, 0xA7, 0x22, 0xFF, 0x3B, 0xE4, 0xF2, 0x96, 0x05, 0x81, + 0xFD, 0xFD, 0x00, 0xB5, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, + 0x1C, 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, + 0xF1, 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, + 0xD8, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, + 0xFF, 0x49, 0x00, 0xD4, 0xFF, 0x88, 0xFF, 0x49, 0x02, 0x4B, 0xF8, + 0x0D, 0x45, 0x68, 0x13, 0xDF, 0xF6, 0x6C, 0x05, 0xCC, 0xFC, 0xB4, + 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1, + 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE, + 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDA, 0x01, 0x69, 0xFC, 0x57, 0x06, 0xAF, 0xF4, 0xF5, 0x1A, + 0x1D, 0x41, 0x11, 0xF5, 0x25, 0x04, 0x6C, 0xFE, 0x74, 0x00, 0xF9, + 0xFF, 0xF1, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, + 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, + 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, + 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF1, 0xFF, 0xF9, 0xFF, 0x74, + 0x00, 0x6C, 0xFE, 0x25, 0x04, 0x11, 0xF5, 0x1D, 0x41, 0xF5, 0x1A, + 0xAF, 0xF4, 0x57, 0x06, 0x69, 0xFC, 0xDA, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, 0x8E, 0xFE, + 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, 0x06, 0x7B, + 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, 0x23, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB4, 0x01, 0xCC, + 0xFC, 0x6C, 0x05, 0xDF, 0xF6, 0x68, 0x13, 0x0D, 0x45, 0x4B, 0xF8, + 0x49, 0x02, 0x88, 0xFF, 0xD4, 0xFF, 0x49, 0x00, 0xD3, 0xFF, 0x0B, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, 0xFC, + 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, 0x6F, + 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, + 0x01, 0x00, 0x0B, 0x00, 0xB5, 0xFF, 0xFD, 0x00, 0x81, 0xFD, 0x96, + 0x05, 0xE4, 0xF2, 0xFF, 0x3B, 0xA7, 0x22, 0xF5, 0xF2, 0xF1, 0x06, + 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, + 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, 0x90, 0x00, 0x7A, 0x00, + 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, 0xF8, 0x7E, 0x04, 0x3C, + 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x5C, 0xFF, 0x78, 0x01, 0x56, 0xFD, 0x48, 0x04, 0x56, + 0xF9, 0x3E, 0x0C, 0xAE, 0x47, 0x8D, 0xFC, 0x13, 0x00, 0xC9, 0x00, + 0x24, 0xFF, 0x9F, 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, 0xDD, 0x06, 0x37, 0xF3, + 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, 0x05, 0xA6, 0xFD, 0xE8, + 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, + 0x7E, 0xFF, 0x69, 0x01, 0xD2, 0xFC, 0x92, 0x06, 0xBB, 0xF1, 0xE6, + 0x35, 0x3F, 0x2A, 0xD8, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, + 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, + 0x00, 0xF1, 0xFF, 0x54, 0xFF, 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, + 0xB1, 0x14, 0x77, 0xF6, 0x9A, 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, + 0x2C, 0x01, 0xFB, 0xFD, 0xFE, 0x02, 0xEE, 0xFB, 0xAB, 0x05, 0xE1, + 0x48, 0xC7, 0x01, 0x9D, 0xFD, 0x1E, 0x02, 0x6F, 0xFE, 0xF5, 0x00, + 0x8F, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, + 0x01, 0x77, 0xFC, 0x33, 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, + 0x8D, 0xF5, 0xDA, 0x03, 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x56, 0xFF, 0xB4, 0x01, + 0x62, 0xFC, 0x15, 0x07, 0x84, 0xF1, 0x09, 0x2F, 0x7B, 0x31, 0x7D, + 0xF1, 0xF5, 0x06, 0x82, 0xFC, 0x9E, 0x01, 0x62, 0xFF, 0x28, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, + 0xFE, 0x6D, 0x04, 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, + 0x78, 0x06, 0x5C, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x18, 0x00, 0x9B, 0xFF, 0xD8, 0x00, 0xAD, 0xFE, 0xA7, 0x01, + 0x7D, 0xFE, 0xDD, 0xFF, 0xA1, 0x48, 0xDD, 0x07, 0x07, 0xFB, 0x73, + 0x03, 0xC0, 0xFD, 0x48, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, + 0x05, 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, + 0xBE, 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDD, 0x01, 0x33, 0xFC, 0x23, 0x07, + 0x26, 0xF2, 0xA6, 0x27, 0x1D, 0x38, 0x05, 0xF2, 0x49, 0x06, 0x08, + 0xFD, 0x47, 0x01, 0x8F, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x0E, 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, + 0xF2, 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, + 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBD, + 0xFF, 0x80, 0x00, 0x62, 0xFF, 0x57, 0x00, 0xDF, 0x00, 0xF7, 0xFA, + 0xED, 0x46, 0xAA, 0x0E, 0x76, 0xF8, 0xB2, 0x04, 0x23, 0xFD, 0x8F, + 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E, + 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF, + 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x41, 0xFC, 0xC6, 0x06, 0x7F, 0xF3, 0xFD, 0x1F, + 0xE4, 0x3D, 0x87, 0xF3, 0x24, 0x05, 0xCC, 0xFD, 0xD1, 0x00, 0xCB, + 0xFF, 0x02, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, 0xFF, + 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, 0x89, + 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2C, 0x00, 0x0D, + 0x00, 0x21, 0xFF, 0xF9, 0x02, 0x0F, 0xF7, 0xD4, 0x43, 0xFD, 0x15, + 0x13, 0xF6, 0xC5, 0x05, 0xA5, 0xFC, 0xC4, 0x01, 0x40, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, 0x1E, 0x01, + 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, 0x48, 0xC6, + 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, 0x8A, 0xFF, + 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD0, 0x01, 0x86, + 0xFC, 0x0D, 0x06, 0x66, 0xF5, 0x50, 0x18, 0x9E, 0x42, 0x11, 0xF6, + 0x8C, 0x03, 0xC9, 0xFE, 0x3F, 0x00, 0x14, 0x00, 0xE7, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, 0x01, 0x56, 0xFC, + 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, 0x84, 0xF1, 0xE0, + 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, + 0x03, 0x00, 0xFA, 0xFF, 0xE0, 0xFF, 0xA7, 0x00, 0x15, 0xFE, 0xB2, + 0x04, 0x32, 0xF4, 0x77, 0x3F, 0x9E, 0x1D, 0x07, 0xF4, 0x96, 0x06, + 0x51, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, + 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, + 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, + 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2F, 0x00, 0x4C, 0xFF, 0xA1, 0x01, 0xF8, 0xFC, 0x0D, 0x05, 0xB3, + 0xF7, 0xDF, 0x10, 0x1D, 0x46, 0xA7, 0xF9, 0x8E, 0x01, 0xF4, 0xFF, + 0x98, 0xFF, 0x66, 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, 0xFC, 0x1A, 0x07, 0x56, 0xF2, + 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, 0x1E, 0x06, 0x25, 0xFD, 0x35, + 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x12, 0x00, + 0xA0, 0xFF, 0x26, 0x01, 0x3E, 0xFD, 0xFB, 0x05, 0x60, 0xF2, 0xFD, + 0x39, 0x4E, 0x25, 0x7F, 0xF2, 0x11, 0x07, 0x31, 0xFC, 0xE3, 0x01, + 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, + 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, + 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, + 0x5F, 0x01, 0x8D, 0xFD, 0xD9, 0x03, 0x3B, 0xFA, 0xE4, 0x09, 0x41, + 0x48, 0x41, 0xFE, 0x3F, 0xFF, 0x3E, 0x01, 0xE5, 0xFE, 0xBD, 0x00, + 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x4A, 0xFC, 0xAC, 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, + 0xE4, 0xF3, 0xE5, 0x04, 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, + 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6E, 0xFF, 0x87, 0x01, + 0xA4, 0xFC, 0xCD, 0x06, 0x8E, 0xF1, 0x99, 0x33, 0xCE, 0x2C, 0xA1, + 0xF1, 0x25, 0x07, 0x4D, 0xFC, 0xC4, 0x01, 0x4D, 0xFF, 0x2F, 0x00, + 0xFD, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, + 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, + 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x85, 0xFF, 0x10, 0x01, 0x38, 0xFE, 0x88, 0x02, + 0xD3, 0xFC, 0x91, 0x03, 0xF7, 0x48, 0xCB, 0x03, 0xBA, 0xFC, 0x95, + 0x02, 0x31, 0xFE, 0x13, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, + 0x05, 0xC6, 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, + 0xFA, 0xFE, 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4C, 0xFF, 0xC6, 0x01, 0x4B, 0xFC, 0x26, 0x07, + 0xA5, 0xF1, 0x87, 0x2C, 0xDC, 0x33, 0x91, 0xF1, 0xC7, 0x06, 0xA9, + 0xFC, 0x84, 0x01, 0x70, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x03, 0x00, + 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, + 0xF3, 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, + 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA7, + 0xFF, 0xB9, 0x00, 0xEC, 0xFE, 0x31, 0x01, 0x57, 0xFF, 0x0F, 0xFE, + 0x33, 0x48, 0x25, 0x0A, 0x21, 0xFA, 0xE5, 0x03, 0x87, 0xFD, 0x62, + 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, + 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0, + 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF, + 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, + 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0E, 0x07, 0x8B, 0xF2, 0x03, 0x25, + 0x38, 0x3A, 0x6D, 0xF2, 0xF1, 0x05, 0x45, 0xFD, 0x22, 0x01, 0xA2, + 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, + 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, + 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, + 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x63, 0x00, 0x9F, + 0xFF, 0xE8, 0xFF, 0xA3, 0x01, 0x7F, 0xF9, 0x02, 0x46, 0x27, 0x11, + 0x9B, 0xF7, 0x18, 0x05, 0xF3, 0xFC, 0xA3, 0x01, 0x4C, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, 0x52, 0x01, + 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, 0x48, 0x26, + 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, 0xA0, 0xFF, + 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE1, 0x01, 0x53, + 0xFC, 0x90, 0x06, 0x19, 0xF4, 0x52, 0x1D, 0xA8, 0x3F, 0x49, 0xF4, + 0xA3, 0x04, 0x1E, 0xFE, 0xA1, 0x00, 0xE3, 0xFF, 0xF9, 0xFF, 0x04, + 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, 0xFC, + 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, 0x1D, + 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x07, 0x00, 0xE8, 0xFF, 0x11, 0x00, 0x45, 0x00, 0xBF, 0xFE, 0x9D, + 0x03, 0xF3, 0xF5, 0x75, 0x42, 0x9B, 0x18, 0x51, 0xF5, 0x16, 0x06, + 0x83, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, + 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, 0x4D, 0x02, 0x45, 0xFD, + 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, 0xFC, 0xD1, 0x02, 0x12, + 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x33, 0x00, 0x40, 0xFF, 0xC2, 0x01, 0xA9, 0xFC, 0xBC, 0x05, 0x29, + 0xF6, 0xB3, 0x15, 0xFA, 0x43, 0x31, 0xF7, 0xE6, 0x02, 0x2C, 0xFF, + 0x07, 0x00, 0x2F, 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, + 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, 0x2A, 0x07, 0xBF, 0xF1, + 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, 0x06, 0xBF, 0xFC, 0x75, + 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, + 0xC8, 0xFF, 0xD6, 0x00, 0xC4, 0xFD, 0x31, 0x05, 0x73, 0xF3, 0xB0, + 0x3D, 0x49, 0x20, 0x6E, 0xF3, 0xCB, 0x06, 0x40, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, + 0x00, 0x0C, 0xFF, 0xF7, 0x00, 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, + 0x51, 0x0B, 0xAF, 0xF9, 0x1D, 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, + 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, + 0x8C, 0x01, 0x29, 0xFD, 0xA7, 0x04, 0x8F, 0xF8, 0x64, 0x0E, 0x02, + 0x47, 0x22, 0xFB, 0xC9, 0x00, 0x64, 0x00, 0x5B, 0xFF, 0x84, 0x00, + 0xBC, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0xFF, 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, + 0xAD, 0xF2, 0xBF, 0x05, 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8D, 0xFF, 0x4B, 0x01, + 0x01, 0xFD, 0x51, 0x06, 0xFB, 0xF1, 0xDF, 0x37, 0xF0, 0x27, 0x1C, + 0xF2, 0x24, 0x07, 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, + 0xFF, 0x01, 0x02, 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, + 0x48, 0x05, 0xDD, 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x45, 0x01, 0xC6, 0xFD, + 0x66, 0x03, 0x21, 0xFB, 0x9E, 0x07, 0xAA, 0x48, 0x12, 0x00, 0x64, + 0xFE, 0xB4, 0x01, 0xA6, 0xFE, 0xDB, 0x00, 0x9A, 0xFF, 0x19, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, + 0x06, 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, + 0x49, 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFD, + 0xFF, 0x29, 0x00, 0x61, 0xFF, 0xA1, 0x01, 0x7E, 0xFC, 0xF9, 0x06, + 0x7C, 0xF1, 0x38, 0x31, 0x50, 0x2F, 0x82, 0xF1, 0x12, 0x07, 0x65, + 0xFC, 0xB2, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, + 0xED, 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, + 0xF5, 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, + 0xD7, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, + 0xFF, 0xF2, 0x00, 0x76, 0xFE, 0x11, 0x02, 0xB6, 0xFD, 0x8F, 0x01, + 0xDE, 0x48, 0xE9, 0x05, 0xD4, 0xFB, 0x0C, 0x03, 0xF4, 0xFD, 0x2F, + 0x01, 0x79, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, + 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68, + 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF, + 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, + 0xFF, 0xD4, 0x01, 0x3B, 0xFC, 0x2A, 0x07, 0xDF, 0xF1, 0xF6, 0x29, + 0x27, 0x36, 0xC1, 0xF1, 0x8B, 0x06, 0xD8, 0xFC, 0x66, 0x01, 0x80, + 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xBD, 0xFF, + 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, 0x9E, + 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x9B, 0x00, 0x2B, + 0xFF, 0xBD, 0x00, 0x2A, 0x00, 0x5E, 0xFC, 0x9A, 0x47, 0x82, 0x0C, + 0x3D, 0xF9, 0x54, 0x04, 0x50, 0xFD, 0x7A, 0x01, 0x5B, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x81, 0x01, + 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, 0x47, 0xEB, + 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, 0xB6, 0xFF, + 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, + 0xFC, 0xED, 0x06, 0x03, 0xF3, 0x5B, 0x22, 0x37, 0x3C, 0xF4, 0xF2, + 0x8A, 0x05, 0x89, 0xFD, 0xF9, 0x00, 0xB7, 0xFF, 0x0A, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, 0x01, 0xE6, 0xFC, + 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, 0xF3, 0xF1, 0x29, + 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD4, 0xFF, 0x46, 0x00, 0xDA, 0xFF, 0x7D, 0xFF, 0x5D, + 0x02, 0x26, 0xF8, 0xED, 0x44, 0xB1, 0x13, 0xC7, 0xF6, 0x77, 0x05, + 0xC8, 0xFC, 0xB6, 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, + 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, + 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x35, 0x00, 0x38, 0xFF, 0xD9, 0x01, 0x6C, 0xFC, 0x4F, 0x06, 0xC3, + 0xF4, 0xA9, 0x1A, 0x49, 0x41, 0x2C, 0xF5, 0x15, 0x04, 0x76, 0xFE, + 0x6E, 0x00, 0xFC, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, + 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, 0xFC, 0x0A, 0x07, 0x7E, 0xF1, + 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, 0x03, 0x07, 0x75, 0xFC, 0xA7, + 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF2, 0xFF, + 0xF7, 0xFF, 0x7A, 0x00, 0x62, 0xFE, 0x35, 0x04, 0xF7, 0xF4, 0xEF, + 0x40, 0x40, 0x1B, 0x9C, 0xF4, 0x5E, 0x06, 0x66, 0xFC, 0xDB, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, + 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, + 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, + 0xB2, 0x01, 0xD1, 0xFC, 0x62, 0x05, 0xF6, 0xF6, 0x20, 0x13, 0x2E, + 0x45, 0x70, 0xF8, 0x34, 0x02, 0x94, 0xFF, 0xCD, 0xFF, 0x4C, 0x00, + 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, + 0x01, 0x36, 0xFC, 0x27, 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, + 0xE4, 0xF1, 0x67, 0x06, 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, 0x00, 0xB2, 0xFF, 0x02, 0x01, + 0x7A, 0xFD, 0xA2, 0x05, 0xD4, 0xF2, 0xC7, 0x3B, 0xF2, 0x22, 0xE7, + 0xF2, 0xF5, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, + 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, + 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x75, 0x01, 0x5C, 0xFD, + 0x3C, 0x04, 0x70, 0xF9, 0xFA, 0x0B, 0xC0, 0x47, 0xBC, 0xFC, 0xFC, + 0xFF, 0xD6, 0x00, 0x1D, 0xFF, 0xA2, 0x00, 0xB0, 0xFF, 0x13, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, + 0x06, 0x47, 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, + 0xAE, 0xFD, 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0xFE, + 0xFF, 0x1F, 0x00, 0x7C, 0xFF, 0x6D, 0x01, 0xCD, 0xFC, 0x99, 0x06, + 0xB4, 0xF1, 0xA6, 0x35, 0x89, 0x2A, 0xD0, 0xF1, 0x2B, 0x07, 0x3E, + 0xFC, 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, + 0xD9, 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, + 0xF7, 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, + 0xBE, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, + 0x00, 0x7B, 0xFF, 0x29, 0x01, 0x01, 0xFE, 0xF1, 0x02, 0x07, 0xFC, + 0x6E, 0x05, 0xE6, 0x48, 0xFF, 0x01, 0x84, 0xFD, 0x2C, 0x02, 0x68, + 0xFE, 0xF9, 0x00, 0x8E, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56, + 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00, + 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x55, + 0xFF, 0xB6, 0x01, 0x5F, 0xFC, 0x17, 0x07, 0x87, 0xF1, 0xC2, 0x2E, + 0xC0, 0x31, 0x7E, 0xF1, 0xF1, 0x06, 0x86, 0xFC, 0x9B, 0x01, 0x63, + 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, + 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, + 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9C, 0xFF, 0xD4, 0x00, 0xB4, + 0xFE, 0x9A, 0x01, 0x95, 0xFE, 0xA8, 0xFF, 0x98, 0x48, 0x1D, 0x08, + 0xEE, 0xFA, 0x80, 0x03, 0xB9, 0xFD, 0x4B, 0x01, 0x6E, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA9, 0x01, + 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, 0x45, 0x1C, + 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, 0xCC, 0xFF, + 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDE, 0x01, 0x33, + 0xFC, 0x21, 0x07, 0x30, 0xF2, 0x5C, 0x27, 0x5B, 0x38, 0x0F, 0xF2, + 0x40, 0x06, 0x0E, 0xFD, 0x43, 0x01, 0x91, 0xFF, 0x18, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, 0xFD, + 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, 0x06, + 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x10, 0x00, 0xBE, 0xFF, 0x7D, 0x00, 0x69, 0xFF, 0x4B, 0x00, 0xF6, + 0x00, 0xCB, 0xFA, 0xD3, 0x46, 0xF0, 0x0E, 0x5E, 0xF8, 0xBE, 0x04, + 0x1E, 0xFD, 0x91, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, 0x77, 0xFD, 0x04, 0x04, + 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, 0xFD, 0x92, 0xFF, 0x10, + 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x43, 0xFC, 0xC0, 0x06, 0x8F, + 0xF3, 0xB1, 0x1F, 0x18, 0x3E, 0x9B, 0xF3, 0x16, 0x05, 0xD5, 0xFD, + 0xCC, 0x00, 0xCE, 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, + 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, 0xB8, 0x06, 0x9C, 0xF1, + 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, 0x07, 0x46, 0xFC, 0xCA, + 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, + 0x29, 0x00, 0x14, 0x00, 0x16, 0xFF, 0x0C, 0x03, 0xEE, 0xF6, 0xB0, + 0x43, 0x47, 0x16, 0xFC, 0xF5, 0xCF, 0x05, 0xA1, 0xFC, 0xC6, 0x01, + 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, + 0xFF, 0x1B, 0x01, 0x20, 0xFE, 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, + 0xF4, 0x48, 0xFF, 0x02, 0x13, 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, + 0x01, 0x88, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, + 0xCF, 0x01, 0x8A, 0xFC, 0x05, 0x06, 0x7B, 0xF5, 0x06, 0x18, 0xC7, + 0x42, 0x2F, 0xF6, 0x7A, 0x03, 0xD4, 0xFE, 0x39, 0x00, 0x17, 0x00, + 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, + 0x01, 0x53, 0xFC, 0x21, 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, + 0x86, 0xF1, 0xDB, 0x06, 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDE, 0xFF, 0xAC, 0x00, + 0x0B, 0xFE, 0xC1, 0x04, 0x1B, 0xF4, 0x47, 0x3F, 0xEA, 0x1D, 0xF5, + 0xF3, 0x9C, 0x06, 0x4F, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, + 0x01, 0x03, 0xFF, 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, + 0xB9, 0x03, 0x9D, 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4D, 0xFF, 0x9F, 0x01, 0xFE, 0xFC, + 0x02, 0x05, 0xCB, 0xF7, 0x98, 0x10, 0x39, 0x46, 0xD0, 0xF9, 0x78, + 0x01, 0x00, 0x00, 0x91, 0xFF, 0x69, 0x00, 0xC6, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, + 0x07, 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, + 0x2C, 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x13, 0x00, 0x9E, 0xFF, 0x2B, 0x01, 0x37, 0xFD, 0x05, 0x06, + 0x54, 0xF2, 0xC2, 0x39, 0x99, 0x25, 0x73, 0xF2, 0x14, 0x07, 0x31, + 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC4, 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, + 0xFA, 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, + 0x9C, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, + 0x00, 0x67, 0xFF, 0x5C, 0x01, 0x93, 0xFD, 0xCC, 0x03, 0x54, 0xFA, + 0xA2, 0x09, 0x4F, 0x48, 0x73, 0xFE, 0x27, 0xFF, 0x4B, 0x01, 0xDE, + 0xFE, 0xC0, 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B, + 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00, + 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6D, + 0xFF, 0x8A, 0x01, 0x9F, 0xFC, 0xD3, 0x06, 0x8A, 0xF1, 0x57, 0x33, + 0x17, 0x2D, 0x9C, 0xF1, 0x24, 0x07, 0x4F, 0xFC, 0xC3, 0x01, 0x4E, + 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE4, 0xFF, 0x1B, 0x00, + 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, 0x96, + 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x86, 0xFF, 0x0C, 0x01, 0x3E, + 0xFE, 0x7B, 0x02, 0xED, 0xFC, 0x56, 0x03, 0xF5, 0x48, 0x06, 0x04, + 0xA1, 0xFC, 0xA3, 0x02, 0x2A, 0xFE, 0x16, 0x01, 0x83, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC8, 0x01, + 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, 0x43, 0xBD, + 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, 0xE1, 0xFF, + 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC8, 0x01, 0x49, + 0xFC, 0x27, 0x07, 0xAB, 0xF1, 0x3E, 0x2C, 0x1E, 0x34, 0x95, 0xF1, + 0xC1, 0x06, 0xAE, 0xFC, 0x81, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, 0x00, 0xE2, 0xFD, + 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, 0xA8, 0xF3, 0xB8, + 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x15, 0x00, 0xA8, 0xFF, 0xB6, 0x00, 0xF3, 0xFE, 0x24, 0x01, 0x6E, + 0xFF, 0xDE, 0xFD, 0x25, 0x48, 0x68, 0x0A, 0x08, 0xFA, 0xF2, 0x03, + 0x81, 0xFD, 0x65, 0x01, 0x64, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, + 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, + 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0B, 0x07, 0x97, + 0xF2, 0xB8, 0x24, 0x71, 0x3A, 0x7B, 0xF2, 0xE6, 0x05, 0x4C, 0xFD, + 0x1D, 0x01, 0xA4, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, + 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, 0xFD, 0x32, 0x06, 0x1F, 0xF2, + 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, 0x1E, 0x07, 0x32, 0xFC, 0xDF, + 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF, + 0x5F, 0x00, 0xA5, 0xFF, 0xDC, 0xFF, 0xB8, 0x01, 0x57, 0xF9, 0xE5, + 0x45, 0x6E, 0x11, 0x83, 0xF7, 0x23, 0x05, 0xEE, 0xFC, 0xA6, 0x01, + 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, + 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, + 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, + 0x00, 0x9E, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE0, 0x01, 0x56, 0xFC, 0x89, 0x06, 0x2B, 0xF4, 0x06, 0x1D, 0xD7, + 0x3F, 0x61, 0xF4, 0x94, 0x04, 0x27, 0xFE, 0x9C, 0x00, 0xE6, 0xFF, + 0xF8, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, + 0x01, 0x8C, 0xFC, 0xEA, 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, + 0x8B, 0xF1, 0x1B, 0x07, 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, + 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, 0xFF, 0x0E, 0x00, 0x4B, 0x00, + 0xB4, 0xFE, 0xAF, 0x03, 0xD5, 0xF5, 0x4D, 0x42, 0xE6, 0x18, 0x3C, + 0xF5, 0x1F, 0x06, 0x7F, 0xFC, 0xD3, 0x01, 0x3B, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, + 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, + 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xC1, 0x01, 0xAD, 0xFC, + 0xB2, 0x05, 0x3F, 0xF6, 0x69, 0x15, 0x1F, 0x44, 0x53, 0xF7, 0xD3, + 0x02, 0x38, 0xFF, 0x01, 0x00, 0x33, 0x00, 0xDB, 0xFF, 0x09, 0x00, + 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, + 0x07, 0xC6, 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, + 0xC4, 0xFC, 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, + 0x00, 0x04, 0x00, 0xC6, 0xFF, 0xDB, 0x00, 0xBB, 0xFD, 0x3E, 0x05, + 0x60, 0xF3, 0x7B, 0x3D, 0x94, 0x20, 0x5E, 0xF3, 0xD0, 0x06, 0x3E, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, + 0xAE, 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, + 0xFD, 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, + 0x71, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, + 0x00, 0x55, 0xFF, 0x8A, 0x01, 0x2E, 0xFD, 0x9B, 0x04, 0xA8, 0xF8, + 0x1F, 0x0E, 0x1A, 0x47, 0x4E, 0xFB, 0xB3, 0x00, 0x70, 0x00, 0x54, + 0xFF, 0x87, 0x00, 0xBB, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64, + 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01, + 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8B, + 0xFF, 0x4F, 0x01, 0xFB, 0xFC, 0x5A, 0x06, 0xF2, 0xF1, 0xA0, 0x37, + 0x3A, 0x28, 0x13, 0xF2, 0x25, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, + 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, + 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, + 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, + 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x42, + 0x01, 0xCD, 0xFD, 0x59, 0x03, 0x3B, 0xFB, 0x5E, 0x07, 0xB3, 0x48, + 0x48, 0x00, 0x4B, 0xFE, 0xC2, 0x01, 0x9F, 0xFE, 0xDE, 0x00, 0x98, + 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDD, 0x01, + 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, 0x40, 0xD0, + 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, 0xF4, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA3, 0x01, 0x7A, + 0xFC, 0xFD, 0x06, 0x7C, 0xF1, 0xF2, 0x30, 0x96, 0x2F, 0x80, 0xF1, + 0x0F, 0x07, 0x69, 0xFC, 0xB0, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, + 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, 0xFE, + 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, 0x43, + 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0x1B, 0x00, 0x92, 0xFF, 0xEF, 0x00, 0x7D, 0xFE, 0x04, 0x02, 0xCF, + 0xFD, 0x58, 0x01, 0xD7, 0x48, 0x26, 0x06, 0xBB, 0xFB, 0x19, 0x03, + 0xED, 0xFD, 0x32, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, 0xC1, 0xFC, 0x86, 0x05, + 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, 0xF7, 0x7B, 0x02, 0x6B, + 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x43, 0xFF, 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE7, + 0xF1, 0xAC, 0x29, 0x66, 0x36, 0xC9, 0xF1, 0x83, 0x06, 0xDD, 0xFC, + 0x62, 0x01, 0x81, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x08, + 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, 0x78, 0x05, 0x0E, 0xF3, + 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, 0x06, 0x38, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB4, 0xFF, + 0x98, 0x00, 0x32, 0xFF, 0xB0, 0x00, 0x41, 0x00, 0x30, 0xFC, 0x86, + 0x47, 0xC6, 0x0C, 0x24, 0xF9, 0x60, 0x04, 0x4B, 0xFD, 0x7D, 0x01, + 0x5A, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x5A, + 0xFF, 0x7E, 0x01, 0x48, 0xFD, 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, + 0x7C, 0x47, 0x19, 0xFC, 0x4D, 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, + 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x38, 0xFC, 0xE9, 0x06, 0x12, 0xF3, 0x10, 0x22, 0x6E, + 0x3C, 0x05, 0xF3, 0x7E, 0x05, 0x91, 0xFD, 0xF4, 0x00, 0xBA, 0xFF, + 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, + 0x01, 0xE0, 0xFC, 0x7F, 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, + 0xEB, 0xF1, 0x2A, 0x07, 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, 0xFF, 0x42, 0x00, 0xE1, 0xFF, + 0x71, 0xFF, 0x71, 0x02, 0x02, 0xF8, 0xCC, 0x44, 0xFA, 0x13, 0xB0, + 0xF6, 0x81, 0x05, 0xC3, 0xFC, 0xB8, 0x01, 0x44, 0xFF, 0x31, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, + 0xFD, 0x1F, 0x03, 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, + 0xDC, 0xFD, 0xFD, 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x6F, 0xFC, + 0x47, 0x06, 0xD7, 0xF4, 0x5D, 0x1A, 0x74, 0x41, 0x48, 0xF5, 0x04, + 0x04, 0x80, 0xFE, 0x69, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0x05, 0x00, + 0xFD, 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, + 0x07, 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, + 0x78, 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, + 0x00, 0xF3, 0xFF, 0xF4, 0xFF, 0x80, 0x00, 0x58, 0xFE, 0x46, 0x04, + 0xDD, 0xF4, 0xC3, 0x40, 0x8C, 0x1B, 0x89, 0xF4, 0x66, 0x06, 0x63, + 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, + 0x98, 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, + 0x00, 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, + 0x40, 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x47, 0xFF, 0xB0, 0x01, 0xD6, 0xFC, 0x58, 0x05, 0x0D, 0xF7, + 0xD7, 0x12, 0x4E, 0x45, 0x96, 0xF8, 0x20, 0x02, 0xA0, 0xFF, 0xC7, + 0xFF, 0x4F, 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60, + 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01, + 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 0xB0, + 0xFF, 0x07, 0x01, 0x72, 0xFD, 0xAE, 0x05, 0xC4, 0xF2, 0x90, 0x3B, + 0x3F, 0x23, 0xD9, 0xF2, 0xF9, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, 0x00, + 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, 0xFC, + 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, 0xFF, + 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5E, 0xFF, 0x72, + 0x01, 0x62, 0xFD, 0x2F, 0x04, 0x89, 0xF9, 0xB6, 0x0B, 0xD2, 0x47, + 0xEB, 0xFC, 0xE4, 0xFF, 0xE3, 0x00, 0x16, 0xFF, 0xA5, 0x00, 0xAF, + 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, 0x3D, 0x56, + 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, 0x05, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x7A, 0xFF, 0x70, 0x01, 0xC7, + 0xFC, 0xA0, 0x06, 0xAE, 0xF1, 0x65, 0x35, 0xD1, 0x2A, 0xCA, 0xF1, + 0x2A, 0x07, 0x40, 0xFC, 0xD0, 0x01, 0x47, 0xFF, 0x32, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x3D, 0xFF, + 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, 0x4A, 0xF6, 0xAD, + 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, 0x26, 0x01, 0x08, 0xFE, 0xE4, + 0x02, 0x21, 0xFC, 0x31, 0x05, 0xEB, 0x48, 0x37, 0x02, 0x6B, 0xFD, + 0x39, 0x02, 0x61, 0xFE, 0xFC, 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFE, + 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, + 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, + 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFD, 0xFF, + 0x2D, 0x00, 0x54, 0xFF, 0xB8, 0x01, 0x5D, 0xFC, 0x1A, 0x07, 0x8A, + 0xF1, 0x7B, 0x2E, 0x04, 0x32, 0x7F, 0xF1, 0xEC, 0x06, 0x8A, 0xFC, + 0x98, 0x01, 0x65, 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, + 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, 0xFE, 0x8C, 0x04, 0x6D, 0xF4, + 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, 0x85, 0x06, 0x57, 0xFC, 0xE0, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9E, 0xFF, + 0xD1, 0x00, 0xBB, 0xFE, 0x8D, 0x01, 0xAE, 0xFE, 0x74, 0xFF, 0x8D, + 0x48, 0x5D, 0x08, 0xD4, 0xFA, 0x8D, 0x03, 0xB3, 0xFD, 0x4E, 0x01, + 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, + 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, + 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, + 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xDF, 0x01, 0x32, 0xFC, 0x1F, 0x07, 0x3B, 0xF2, 0x11, 0x27, 0x97, + 0x38, 0x19, 0xF2, 0x36, 0x06, 0x15, 0xFD, 0x3F, 0x01, 0x93, 0xFF, + 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, + 0x01, 0x50, 0xFD, 0xE1, 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, + 0x9D, 0xF2, 0x09, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x7A, 0x00, 0x70, 0xFF, + 0x3E, 0x00, 0x0C, 0x01, 0xA1, 0xFA, 0xBB, 0x46, 0x36, 0x0F, 0x45, + 0xF8, 0xC9, 0x04, 0x18, 0xFD, 0x93, 0x01, 0x52, 0xFF, 0x2D, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, + 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, + 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x45, 0xFC, + 0xBB, 0x06, 0xA0, 0xF3, 0x64, 0x1F, 0x4A, 0x3E, 0xB0, 0xF3, 0x08, + 0x05, 0xDE, 0xFD, 0xC7, 0x00, 0xD0, 0xFF, 0x00, 0x00, 0x02, 0x00, + 0xFE, 0xFF, 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, + 0x06, 0x97, 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, + 0x48, 0xFC, 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE0, 0xFF, 0x26, 0x00, 0x1A, 0x00, 0x0B, 0xFF, 0x1E, 0x03, + 0xCD, 0xF6, 0x89, 0x43, 0x91, 0x16, 0xE7, 0xF5, 0xD8, 0x05, 0x9D, + 0xFC, 0xC7, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x1F, 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, + 0xFC, 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, + 0x42, 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, + 0x00, 0x3C, 0xFF, 0xCD, 0x01, 0x8E, 0xFC, 0xFC, 0x05, 0x90, 0xF5, + 0xBB, 0x17, 0xEE, 0x42, 0x4E, 0xF6, 0x68, 0x03, 0xDF, 0xFE, 0x33, + 0x00, 0x1A, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A, + 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01, + 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0xDB, + 0xFF, 0xB2, 0x00, 0x02, 0xFE, 0xCF, 0x04, 0x05, 0xF4, 0x16, 0x3F, + 0x36, 0x1E, 0xE4, 0xF3, 0xA3, 0x06, 0x4D, 0xFC, 0xE3, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, + 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, + 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, + 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9D, + 0x01, 0x03, 0xFD, 0xF7, 0x04, 0xE3, 0xF7, 0x51, 0x10, 0x55, 0x46, + 0xF9, 0xF9, 0x63, 0x01, 0x0D, 0x00, 0x8B, 0xFF, 0x6D, 0x00, 0xC5, + 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, + 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, 0x39, 0x4D, + 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, 0x13, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x00, 0x9C, 0xFF, 0x2F, 0x01, 0x30, + 0xFD, 0x10, 0x06, 0x47, 0xF2, 0x87, 0x39, 0xE5, 0x25, 0x67, 0xF2, + 0x16, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, 0x00, + 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, 0xFC, + 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x59, 0x01, 0x99, 0xFD, 0xC0, + 0x03, 0x6E, 0xFA, 0x61, 0x09, 0x5D, 0x48, 0xA6, 0xFE, 0x0F, 0xFF, + 0x58, 0x01, 0xD7, 0xFE, 0xC3, 0x00, 0xA3, 0xFF, 0x16, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4E, 0xFC, 0xA0, 0x06, + 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, 0xF4, 0xC8, 0x04, 0x07, + 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, 0x03, 0x00, 0xFD, 0xFF, + 0x25, 0x00, 0x6B, 0xFF, 0x8D, 0x01, 0x9B, 0xFC, 0xD8, 0x06, 0x87, + 0xF1, 0x13, 0x33, 0x5E, 0x2D, 0x98, 0xF1, 0x22, 0x07, 0x52, 0xFC, + 0xC1, 0x01, 0x4F, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE5, + 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, 0x71, 0x03, 0x3F, 0xF6, + 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, 0x06, 0x8C, 0xFC, 0xCE, + 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, + 0x09, 0x01, 0x45, 0xFE, 0x6E, 0x02, 0x06, 0xFD, 0x1C, 0x03, 0xF4, + 0x48, 0x41, 0x04, 0x87, 0xFC, 0xB0, 0x02, 0x23, 0xFE, 0x19, 0x01, + 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, + 0xFF, 0xC6, 0x01, 0x9F, 0xFC, 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, + 0x9E, 0x43, 0xDD, 0xF6, 0x15, 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, + 0x00, 0xDF, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xCA, 0x01, 0x47, 0xFC, 0x28, 0x07, 0xB0, 0xF1, 0xF5, 0x2B, 0x60, + 0x34, 0x9A, 0xF1, 0xBB, 0x06, 0xB3, 0xFC, 0x7D, 0x01, 0x73, 0xFF, + 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, + 0x00, 0xDA, 0xFD, 0x0F, 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, + 0x97, 0xF3, 0xBD, 0x06, 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xAA, 0xFF, 0xB3, 0x00, 0xFA, 0xFE, + 0x17, 0x01, 0x86, 0xFF, 0xAC, 0xFD, 0x16, 0x48, 0xAA, 0x0A, 0xEE, + 0xF9, 0xFE, 0x03, 0x7A, 0xFD, 0x67, 0x01, 0x63, 0xFF, 0x28, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, + 0xFD, 0xC4, 0x04, 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, + 0x01, 0x01, 0x44, 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, + 0x08, 0x07, 0xA4, 0xF2, 0x6D, 0x24, 0xAD, 0x3A, 0x88, 0xF2, 0xDB, + 0x05, 0x53, 0xFD, 0x19, 0x01, 0xA7, 0xFF, 0x10, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, + 0x06, 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, + 0x33, 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, + 0x00, 0xCB, 0xFF, 0x5C, 0x00, 0xAC, 0xFF, 0xD0, 0xFF, 0xCD, 0x01, + 0x30, 0xF9, 0xC8, 0x45, 0xB6, 0x11, 0x6B, 0xF7, 0x2D, 0x05, 0xE9, + 0xFC, 0xA8, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x25, 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, + 0xFA, 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, + 0xB8, 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x58, 0xFC, 0x82, 0x06, 0x3E, 0xF4, + 0xBA, 0x1C, 0x07, 0x40, 0x79, 0xF4, 0x84, 0x04, 0x31, 0xFE, 0x96, + 0x00, 0xE8, 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3, + 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01, + 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEA, 0xFF, 0x0B, + 0x00, 0x51, 0x00, 0xAA, 0xFE, 0xC0, 0x03, 0xB8, 0xF5, 0x21, 0x42, + 0x31, 0x19, 0x28, 0xF5, 0x27, 0x06, 0x7C, 0xFC, 0xD4, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, 0x00, + 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, 0x50, + 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, 0xFF, + 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xBF, + 0x01, 0xB2, 0xFC, 0xA9, 0x05, 0x55, 0xF6, 0x20, 0x15, 0x42, 0x44, + 0x75, 0xF7, 0xBF, 0x02, 0x43, 0xFF, 0xFA, 0xFF, 0x36, 0x00, 0xDA, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, + 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, 0x35, 0xB1, + 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, 0x20, 0x00, + 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE0, 0x00, 0xB3, + 0xFD, 0x4B, 0x05, 0x4D, 0xF3, 0x45, 0x3D, 0xE0, 0x20, 0x4F, 0xF3, + 0xD5, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, 0xFF, 0xDD, 0x00, + 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, 0x7C, 0xF9, 0x35, + 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2C, 0x00, 0x56, 0xFF, 0x87, 0x01, 0x34, 0xFD, 0x8F, + 0x04, 0xC0, 0xF8, 0xD9, 0x0D, 0x31, 0x47, 0x7B, 0xFB, 0x9C, 0x00, + 0x7D, 0x00, 0x4D, 0xFF, 0x8A, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, + 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, + 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x89, 0xFF, 0x53, 0x01, 0xF5, 0xFC, 0x63, 0x06, 0xE9, + 0xF1, 0x63, 0x37, 0x85, 0x28, 0x09, 0xF2, 0x27, 0x07, 0x35, 0xFC, + 0xDA, 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD1, + 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, 0xFF, 0x2A, 0x02, 0x83, 0xF8, + 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, 0x5D, 0x05, 0xD3, 0xFC, 0xB1, + 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x73, 0xFF, 0x3F, 0x01, 0xD3, 0xFD, 0x4C, 0x03, 0x54, 0xFB, 0x1F, + 0x07, 0xBB, 0x48, 0x7D, 0x00, 0x33, 0xFE, 0xCF, 0x01, 0x98, 0xFE, + 0xE2, 0x00, 0x97, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, + 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, + 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5E, 0xFF, + 0xA6, 0x01, 0x76, 0xFC, 0x01, 0x07, 0x7D, 0xF1, 0xAD, 0x30, 0xDC, + 0x2F, 0x7F, 0xF1, 0x0C, 0x07, 0x6C, 0xFC, 0xAD, 0x01, 0x5A, 0xFF, + 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, + 0x00, 0x7B, 0xFE, 0x0C, 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, + 0xCD, 0xF4, 0x4B, 0x06, 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, + 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x93, 0xFF, 0xEC, 0x00, 0x83, 0xFE, + 0xF7, 0x01, 0xE8, 0xFD, 0x21, 0x01, 0xD2, 0x48, 0x64, 0x06, 0xA1, + 0xFB, 0x26, 0x03, 0xE7, 0xFD, 0x35, 0x01, 0x76, 0xFF, 0x22, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, + 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, + 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x39, 0xFC, + 0x29, 0x07, 0xEF, 0xF1, 0x62, 0x29, 0xA5, 0x36, 0xD0, 0xF1, 0x7B, + 0x06, 0xE3, 0xFC, 0x5E, 0x01, 0x83, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, + 0x01, 0x00, 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, + 0x05, 0xFD, 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, + 0x37, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, + 0x00, 0xB5, 0xFF, 0x94, 0x00, 0x39, 0xFF, 0xA3, 0x00, 0x58, 0x00, + 0x02, 0xFC, 0x73, 0x47, 0x0B, 0x0D, 0x0B, 0xF9, 0x6C, 0x04, 0x45, + 0xFD, 0x80, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, + 0xF9, 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, + 0x2E, 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x39, 0xFC, 0xE4, 0x06, 0x21, 0xF3, + 0xC4, 0x21, 0xA5, 0x3C, 0x16, 0xF3, 0x72, 0x05, 0x9A, 0xFD, 0xEF, + 0x00, 0xBC, 0xFF, 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46, + 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD6, 0xFF, 0x3F, + 0x00, 0xE7, 0xFF, 0x65, 0xFF, 0x85, 0x02, 0xDE, 0xF7, 0xA9, 0x44, + 0x43, 0x14, 0x99, 0xF6, 0x8B, 0x05, 0xBF, 0xFC, 0xBA, 0x01, 0x43, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, + 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, + 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, + 0x91, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, + 0x01, 0x72, 0xFC, 0x3F, 0x06, 0xEB, 0xF4, 0x12, 0x1A, 0xA1, 0x41, + 0x63, 0xF5, 0xF3, 0x03, 0x8A, 0xFE, 0x63, 0x00, 0x02, 0x00, 0xEE, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, 0xB1, 0x01, + 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, 0x31, 0x7C, + 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, 0x29, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF4, 0xFF, 0xF1, 0xFF, 0x85, 0x00, 0x4E, + 0xFE, 0x56, 0x04, 0xC3, 0xF4, 0x95, 0x40, 0xD8, 0x1B, 0x76, 0xF4, + 0x6D, 0x06, 0x60, 0xFC, 0xDD, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, 0x01, + 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, 0x60, + 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAE, 0x01, 0xDB, 0xFC, 0x4D, + 0x05, 0x24, 0xF7, 0x8E, 0x12, 0x6D, 0x45, 0xBC, 0xF8, 0x0C, 0x02, + 0xAC, 0xFF, 0xC0, 0xFF, 0x52, 0x00, 0xCF, 0xFF, 0x0C, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x25, 0x07, + 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, 0xF1, 0x56, 0x06, 0xFE, + 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x0D, 0x00, 0xAE, 0xFF, 0x0B, 0x01, 0x6A, 0xFD, 0xBA, 0x05, 0xB4, + 0xF2, 0x58, 0x3B, 0x8A, 0x23, 0xCB, 0xF2, 0xFD, 0x06, 0x34, 0xFC, + 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBB, + 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, 0xBE, 0x00, 0x38, 0xFB, + 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, 0x04, 0x2B, 0xFD, 0x8B, + 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, + 0x5F, 0xFF, 0x70, 0x01, 0x68, 0xFD, 0x23, 0x04, 0xA2, 0xF9, 0x73, + 0x0B, 0xE4, 0x47, 0x1B, 0xFD, 0xCD, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, + 0xA9, 0x00, 0xAE, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE6, 0x01, 0x3F, 0xFC, 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, + 0x96, 0x3D, 0x69, 0xF3, 0x38, 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, + 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x78, 0xFF, + 0x74, 0x01, 0xC2, 0xFC, 0xA7, 0x06, 0xA8, 0xF1, 0x25, 0x35, 0x1B, + 0x2B, 0xC2, 0xF1, 0x2A, 0x07, 0x41, 0xFC, 0xCE, 0x01, 0x47, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, + 0x00, 0x32, 0xFF, 0xDC, 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, + 0x34, 0xF6, 0xB7, 0x05, 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x23, 0x01, + 0x0F, 0xFE, 0xD7, 0x02, 0x3B, 0xFC, 0xF5, 0x04, 0xED, 0x48, 0x70, + 0x02, 0x52, 0xFD, 0x46, 0x02, 0x5A, 0xFE, 0xFF, 0x00, 0x8B, 0xFF, + 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, + 0xFC, 0x1A, 0x06, 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, + 0xA6, 0x03, 0xB9, 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x53, 0xFF, 0xBB, 0x01, 0x5A, 0xFC, + 0x1C, 0x07, 0x8D, 0xF1, 0x34, 0x2E, 0x48, 0x32, 0x81, 0xF1, 0xE7, + 0x06, 0x8E, 0xFC, 0x96, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF, + 0x04, 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, + 0x04, 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, + 0x55, 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, + 0x00, 0x9F, 0xFF, 0xCE, 0x00, 0xC2, 0xFE, 0x80, 0x01, 0xC6, 0xFE, + 0x40, 0xFF, 0x81, 0x48, 0x9E, 0x08, 0xBA, 0xFA, 0x9A, 0x03, 0xAC, + 0xFD, 0x51, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2F, 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, + 0xF7, 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, + 0xA2, 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3D, 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1D, 0x07, 0x45, 0xF2, + 0xC6, 0x26, 0xD3, 0x38, 0x24, 0xF2, 0x2D, 0x06, 0x1B, 0xFD, 0x3B, + 0x01, 0x95, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, + 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54, + 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01, + 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC1, 0xFF, 0x76, + 0x00, 0x76, 0xFF, 0x32, 0x00, 0x22, 0x01, 0x76, 0xFA, 0xA3, 0x46, + 0x7D, 0x0F, 0x2C, 0xF8, 0xD5, 0x04, 0x13, 0xFD, 0x96, 0x01, 0x51, + 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, 0xFF, + 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, 0x2C, + 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, 0x00, + 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x47, 0xFC, 0xB5, 0x06, 0xB0, 0xF3, 0x19, 0x1F, 0x7E, 0x3E, + 0xC4, 0xF3, 0xFA, 0x04, 0xE7, 0xFD, 0xC1, 0x00, 0xD3, 0xFF, 0xFF, + 0xFF, 0x02, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, 0x82, 0x01, + 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, 0x2C, 0xA8, + 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, 0x30, 0x00, + 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, 0x23, 0x00, 0x20, 0x00, 0x00, + 0xFF, 0x31, 0x03, 0xAD, 0xF6, 0x65, 0x43, 0xDC, 0x16, 0xD1, 0xF5, + 0xE1, 0x05, 0x99, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, 0x01, 0x2D, 0xFE, + 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, 0x73, 0x03, 0xE0, + 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, 0xFF, 0x1E, 0x00, + 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCC, 0x01, 0x91, 0xFC, 0xF3, + 0x05, 0xA6, 0xF5, 0x70, 0x17, 0x17, 0x43, 0x6D, 0xF6, 0x56, 0x03, + 0xEA, 0xFE, 0x2D, 0x00, 0x1D, 0x00, 0xE4, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, + 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, + 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, + 0xFD, 0xFF, 0xD8, 0xFF, 0xB7, 0x00, 0xF9, 0xFD, 0xDE, 0x04, 0xEF, + 0xF3, 0xE4, 0x3E, 0x81, 0x1E, 0xD2, 0xF3, 0xA9, 0x06, 0x4B, 0xFC, + 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA5, + 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, 0x01, 0x33, 0xFF, 0x5A, 0xFE, + 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, 0xD2, 0x03, 0x90, 0xFD, 0x5E, + 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, + 0x4F, 0xFF, 0x9A, 0x01, 0x08, 0xFD, 0xEB, 0x04, 0xFC, 0xF7, 0x0A, + 0x10, 0x70, 0x46, 0x22, 0xFA, 0x4D, 0x01, 0x19, 0x00, 0x84, 0xFF, + 0x70, 0x00, 0xC4, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, + 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, + 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, + 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x99, 0xFF, + 0x33, 0x01, 0x29, 0xFD, 0x1A, 0x06, 0x3B, 0xF2, 0x4B, 0x39, 0x30, + 0x26, 0x5B, 0xF2, 0x19, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, + 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, + 0xFF, 0xFA, 0xFF, 0x83, 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, + 0xBF, 0xF7, 0x07, 0x05, 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x56, 0x01, + 0xA0, 0xFD, 0xB3, 0x03, 0x87, 0xFA, 0x1F, 0x09, 0x6A, 0x48, 0xD9, + 0xFE, 0xF6, 0xFE, 0x65, 0x01, 0xD0, 0xFE, 0xC7, 0x00, 0xA2, 0xFF, + 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, + 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, + 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, + 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x69, 0xFF, 0x90, 0x01, 0x96, 0xFC, + 0xDD, 0x06, 0x85, 0xF1, 0xD0, 0x32, 0xA6, 0x2D, 0x94, 0xF1, 0x20, + 0x07, 0x54, 0xFC, 0xBF, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x07, 0x00, 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, + 0x03, 0x20, 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, + 0x88, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, + 0x00, 0x89, 0xFF, 0x06, 0x01, 0x4C, 0xFE, 0x60, 0x02, 0x1F, 0xFD, + 0xE2, 0x02, 0xF3, 0x48, 0x7D, 0x04, 0x6E, 0xFC, 0xBD, 0x02, 0x1C, + 0xFE, 0x1C, 0x01, 0x80, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x33, 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, + 0xF6, 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, + 0x11, 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, + 0x00, 0x49, 0xFF, 0xCB, 0x01, 0x45, 0xFC, 0x29, 0x07, 0xB6, 0xF1, + 0xAD, 0x2B, 0xA2, 0x34, 0x9E, 0xF1, 0xB4, 0x06, 0xB8, 0xFC, 0x7A, + 0x01, 0x75, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, + 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE, + 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAB, 0xFF, 0xAF, + 0x00, 0x01, 0xFF, 0x0A, 0x01, 0x9E, 0xFF, 0x7C, 0xFD, 0x03, 0x48, + 0xED, 0x0A, 0xD5, 0xF9, 0x0A, 0x04, 0x74, 0xFD, 0x6A, 0x01, 0x62, + 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, + 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, + 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, + 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0x04, 0x07, 0xB1, 0xF2, 0x21, 0x24, 0xE6, 0x3A, + 0x97, 0xF2, 0xD0, 0x05, 0x5B, 0xFD, 0x15, 0x01, 0xA9, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, 0x45, 0x01, + 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, 0x27, 0x2B, + 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0D, 0x00, 0xCD, 0xFF, 0x59, 0x00, 0xB3, 0xFF, 0xC4, + 0xFF, 0xE2, 0x01, 0x09, 0xF9, 0xAA, 0x45, 0xFE, 0x11, 0x54, 0xF7, + 0x38, 0x05, 0xE4, 0xFC, 0xAA, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, 0xFD, + 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, 0x89, + 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5B, 0xFC, 0x7B, + 0x06, 0x50, 0xF4, 0x6E, 0x1C, 0x36, 0x40, 0x92, 0xF4, 0x75, 0x04, + 0x3B, 0xFE, 0x91, 0x00, 0xEB, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, + 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, 0x84, 0xFC, 0xF3, 0x06, + 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, 0xF1, 0x16, 0x07, 0x61, + 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, + 0xEC, 0xFF, 0x08, 0x00, 0x57, 0x00, 0x9F, 0xFE, 0xD1, 0x03, 0x9B, + 0xF5, 0xF7, 0x41, 0x7C, 0x19, 0x13, 0xF5, 0x2F, 0x06, 0x78, 0xFC, + 0xD5, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8F, + 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, 0x91, 0xFD, 0xE3, 0x01, + 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, 0x02, 0xFE, 0xFD, 0x2B, + 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, + 0x42, 0xFF, 0xBD, 0x01, 0xB6, 0xFC, 0x9F, 0x05, 0x6C, 0xF6, 0xD6, + 0x14, 0x65, 0x44, 0x98, 0xF7, 0xAC, 0x02, 0x4E, 0xFF, 0xF4, 0xFF, + 0x39, 0x00, 0xD9, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, + 0xFF, 0xD2, 0x01, 0x3D, 0xFC, 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, + 0xC6, 0x35, 0xB7, 0xF1, 0x96, 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, + 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x06, 0x00, 0xC1, 0xFF, + 0xE5, 0x00, 0xAA, 0xFD, 0x58, 0x05, 0x3A, 0xF3, 0x11, 0x3D, 0x2C, + 0x21, 0x3F, 0xF3, 0xDA, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, + 0xFF, 0xD0, 0x00, 0x07, 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, + 0x63, 0xF9, 0x42, 0x04, 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x85, 0x01, + 0x39, 0xFD, 0x84, 0x04, 0xD9, 0xF8, 0x95, 0x0D, 0x48, 0x47, 0xA7, + 0xFB, 0x86, 0x00, 0x8A, 0x00, 0x46, 0xFF, 0x8E, 0x00, 0xB8, 0xFF, + 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, + 0xFC, 0xF3, 0x06, 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, + 0x9C, 0x05, 0x7E, 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x87, 0xFF, 0x57, 0x01, 0xEF, 0xFC, + 0x6B, 0x06, 0xE0, 0xF1, 0x23, 0x37, 0xCE, 0x28, 0x01, 0xF2, 0x28, + 0x07, 0x36, 0xFC, 0xD9, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, + 0x02, 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, + 0xCF, 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x23, 0x00, 0x74, 0xFF, 0x3C, 0x01, 0xDA, 0xFD, 0x40, 0x03, + 0x6E, 0xFB, 0xE1, 0x06, 0xC3, 0x48, 0xB3, 0x00, 0x1A, 0xFE, 0xDC, + 0x01, 0x91, 0xFE, 0xE5, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, + 0xF4, 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, + 0x77, 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, + 0x00, 0x5C, 0xFF, 0xA8, 0x01, 0x73, 0xFC, 0x05, 0x07, 0x7D, 0xF1, + 0x67, 0x30, 0x21, 0x30, 0x7E, 0xF1, 0x08, 0x07, 0x6F, 0xFC, 0xAB, + 0x01, 0x5B, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF0, 0xFF, + 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32, + 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01, + 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE8, + 0x00, 0x8A, 0xFE, 0xE9, 0x01, 0x01, 0xFE, 0xEA, 0x00, 0xCB, 0x48, + 0xA2, 0x06, 0x87, 0xFB, 0x33, 0x03, 0xE0, 0xFD, 0x39, 0x01, 0x75, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, + 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, 0xFD, + 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, 0x00, + 0xD3, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD8, + 0x01, 0x37, 0xFC, 0x29, 0x07, 0xF8, 0xF1, 0x19, 0x29, 0xE5, 0x36, + 0xD8, 0xF1, 0x73, 0x06, 0xE9, 0xFC, 0x5B, 0x01, 0x85, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, 0xFB, 0x00, + 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, 0x22, 0xFC, + 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x12, 0x00, 0xB7, 0xFF, 0x91, 0x00, 0x40, 0xFF, 0x96, + 0x00, 0x6F, 0x00, 0xD5, 0xFB, 0x5E, 0x47, 0x50, 0x0D, 0xF2, 0xF8, + 0x78, 0x04, 0x3F, 0xFD, 0x82, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, 0x01, 0x53, 0xFD, + 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, 0x76, 0xFC, 0x1F, + 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, 0xFF, 0x13, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xDF, + 0x06, 0x30, 0xF3, 0x78, 0x21, 0xDB, 0x3C, 0x28, 0xF3, 0x65, 0x05, + 0xA2, 0xFD, 0xEA, 0x00, 0xBE, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, + 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, + 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, + 0xD8, 0xFF, 0x3C, 0x00, 0xEE, 0xFF, 0x5A, 0xFF, 0x98, 0x02, 0xBB, + 0xF7, 0x87, 0x44, 0x8C, 0x14, 0x83, 0xF6, 0x95, 0x05, 0xBA, 0xFC, + 0xBB, 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, + 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, 0xFD, 0x05, 0x03, 0xE1, 0xFB, + 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, 0xAA, 0xFD, 0x18, 0x02, 0x72, + 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x39, 0xFF, 0xD6, 0x01, 0x75, 0xFC, 0x37, 0x06, 0xFF, 0xF4, 0xC7, + 0x19, 0xCC, 0x41, 0x7F, 0xF5, 0xE2, 0x03, 0x95, 0xFE, 0x5D, 0x00, + 0x05, 0x00, 0xED, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, + 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, + 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, + 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF5, 0xFF, 0xEE, 0xFF, + 0x8B, 0x00, 0x44, 0xFE, 0x65, 0x04, 0xAA, 0xF4, 0x66, 0x40, 0x23, + 0x1C, 0x63, 0xF4, 0x74, 0x06, 0x5D, 0xFC, 0xDE, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, + 0xFE, 0xAE, 0x01, 0x70, 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, + 0x14, 0xFB, 0x6D, 0x03, 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAC, 0x01, + 0xDF, 0xFC, 0x43, 0x05, 0x3C, 0xF7, 0x46, 0x12, 0x8D, 0x45, 0xE2, + 0xF8, 0xF7, 0x01, 0xB8, 0xFF, 0xB9, 0xFF, 0x56, 0x00, 0xCE, 0xFF, + 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, + 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, + 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAB, 0xFF, 0x10, 0x01, 0x62, 0xFD, + 0xC5, 0x05, 0xA5, 0xF2, 0x1F, 0x3B, 0xD6, 0x23, 0xBE, 0xF2, 0x01, + 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x10, 0x00, 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, + 0x00, 0x0C, 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, + 0x26, 0xFD, 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6D, 0x01, 0x6E, 0xFD, 0x17, 0x04, + 0xBC, 0xF9, 0x30, 0x0B, 0xF4, 0x47, 0x4B, 0xFD, 0xB5, 0xFF, 0xFD, + 0x00, 0x08, 0xFF, 0xAC, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, + 0xF3, 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, + 0xD4, 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, + 0x00, 0x77, 0xFF, 0x77, 0x01, 0xBD, 0xFC, 0xAE, 0x06, 0xA3, 0xF1, + 0xE3, 0x34, 0x64, 0x2B, 0xBC, 0xF1, 0x2A, 0x07, 0x43, 0xFC, 0xCD, + 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDD, 0xFF, + 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7, + 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01, + 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, + 0xFF, 0x20, 0x01, 0x16, 0xFE, 0xCA, 0x02, 0x54, 0xFC, 0xB9, 0x04, + 0xF2, 0x48, 0xA9, 0x02, 0x39, 0xFD, 0x53, 0x02, 0x53, 0xFE, 0x03, + 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, + 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, + 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, + 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBD, + 0x01, 0x57, 0xFC, 0x1E, 0x07, 0x90, 0xF1, 0xED, 0x2D, 0x8C, 0x32, + 0x83, 0xF1, 0xE2, 0x06, 0x92, 0xFC, 0x93, 0x01, 0x68, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, 0xA4, 0x00, + 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, 0x1D, 0x10, + 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, 0xCA, 0x00, 0xC9, 0xFE, 0x73, + 0x01, 0xDE, 0xFE, 0x0C, 0xFF, 0x76, 0x48, 0xDE, 0x08, 0xA1, 0xFA, + 0xA6, 0x03, 0xA6, 0xFD, 0x53, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, 0xFC, + 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, 0x98, + 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x32, 0xFC, 0x1B, + 0x07, 0x50, 0xF2, 0x7B, 0x26, 0x11, 0x39, 0x2F, 0xF2, 0x23, 0x06, + 0x22, 0xFD, 0x37, 0x01, 0x97, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, 0x41, 0xFD, 0xF6, 0x05, + 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, 0xF2, 0x0F, 0x07, 0x31, + 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, + 0xC2, 0xFF, 0x73, 0x00, 0x7D, 0xFF, 0x25, 0x00, 0x38, 0x01, 0x4C, + 0xFA, 0x89, 0x46, 0xC3, 0x0F, 0x14, 0xF8, 0xE0, 0x04, 0x0D, 0xFD, + 0x98, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, + 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, 0xDF, 0x03, 0x2E, 0xFA, + 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, 0xFF, 0x38, 0x01, 0xE9, + 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE4, 0x01, 0x49, 0xFC, 0xAF, 0x06, 0xC1, 0xF3, 0xCD, + 0x1E, 0xB1, 0x3E, 0xD9, 0xF3, 0xEC, 0x04, 0xF0, 0xFD, 0xBC, 0x00, + 0xD5, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, + 0xFF, 0x85, 0x01, 0xA6, 0xFC, 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, + 0xAB, 0x2C, 0xA3, 0xF1, 0x26, 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, + 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE2, 0xFF, 0x20, 0x00, + 0x26, 0x00, 0xF5, 0xFE, 0x43, 0x03, 0x8D, 0xF6, 0x3C, 0x43, 0x25, + 0x17, 0xBB, 0xF5, 0xEA, 0x05, 0x95, 0xFC, 0xCA, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, + 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, + 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, + 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, + 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, + 0xFD, 0x4E, 0x05, 0x4A, 0xF3, 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, + 0xD6, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, + 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, + 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, + 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, 0x01, 0x4C, 0xFC, 0x26, + 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, 0x8F, 0xF1, 0xCA, 0x06, + 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x16, + 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, + 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, + 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, 0x07, 0x84, + 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, 0x41, 0xFD, + 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, + 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, + 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, + 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78, + 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00, + 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0x07, 0x00, 0xE8, 0xFF, 0x12, + 0x00, 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, + 0x76, 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, + 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, + 0xC3, 0x01, 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, + 0x43, 0x20, 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, + 0xDD, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, + 0x00, 0xC8, 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, + 0x76, 0xF3, 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, + 0x26, 0xFD, 0xAD, 0x04, 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, + 0xFB, 0xD4, 0x00, 0x5D, 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, + 0x10, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, + 0xFD, 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, + 0x23, 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x46, 0x01, 0xC3, 0xFD, + 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, 0xA6, 0x48, 0xF8, 0xFF, 0x70, + 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, 0x00, 0x9A, 0xFF, 0x19, 0x00, + 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7, + 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07, + 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, + 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, 0x02, 0xAA, 0xFD, + 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, 0x05, 0x03, 0xF7, + 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, 0xDC, + 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, 0xFC, + 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xB2, + 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, 0xFC, + 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, 0x79, + 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81, + 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00, + 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xD3, 0xFF, 0x47, + 0x00, 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, + 0x8D, 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, + 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, + 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, + 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, + 0xF0, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, + 0x00, 0x67, 0xFE, 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, + 0xA6, 0xF4, 0x5A, 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, + 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, + 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, + 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, + 0xFD, 0x9C, 0x05, 0xDC, 0xF2, 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, + 0xF3, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x76, 0x01, 0x59, 0xFD, + 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, 0xB6, 0x47, 0xA4, 0xFC, 0x07, + 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, 0x00, 0xB1, 0xFF, 0x13, 0x00, + 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, 0x01, 0xCF, 0xFC, 0x96, + 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, 0xD4, 0xF1, 0x2B, 0x07, + 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, + 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, + 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, + 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, 0x07, 0x85, + 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, 0x84, 0xFC, + 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9C, + 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, + 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, + 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80, + 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01, + 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, + 0x00, 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, + 0xCD, 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, + 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE5, 0x01, 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, + 0x3D, 0x91, 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, + 0x02, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, + 0x00, 0x1B, 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, + 0x07, 0xF6, 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, + 0x88, 0xFC, 0x09, 0x06, 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, + 0xF6, 0x83, 0x03, 0xCF, 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, + 0x07, 0x00, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, + 0xFE, 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, + 0x99, 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, 0xFF, 0xA0, 0x01, 0xFB, 0xFC, + 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, 0x2B, 0x46, 0xBB, 0xF9, 0x83, + 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, 0x00, 0xC7, 0xFF, 0x0E, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00, + 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07, + 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, 0xFD, 0xD2, 0x03, + 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, 0x33, 0xFF, 0x45, + 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, 0x00, 0xFD, 0xFF, + 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, 0x8C, + 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, 0xFC, + 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x86, + 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, 0x03, + 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, 0x14, + 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, + 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62, + 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01, + 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, + 0x00, 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, + 0x47, 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, + 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, + 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, + 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, + 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, + 0xFF, 0xE2, 0xFF, 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, + 0x8F, 0xF7, 0x1D, 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, + 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, + 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, + 0x04, 0x00, 0x07, 0x00, 0xE9, 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, + 0xFE, 0xA6, 0x03, 0xE4, 0xF5, 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, + 0x1A, 0x06, 0x81, 0xFC, 0xD2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC1, 0x01, 0xAB, 0xFC, + 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, 0x0B, 0x44, 0x42, 0xF7, 0xDC, + 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, 0x00, 0xDC, 0xFF, 0x09, 0x00, + 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, 0x00, 0xBF, 0xFD, 0x38, + 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, 0x66, 0xF3, 0xCE, 0x06, + 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, + 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, + 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, 0x00, 0xFF, 0xFF, + 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, 0x06, 0xF7, + 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, 0x34, 0xFC, + 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, + 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, + 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, + 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, + 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15, + 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01, + 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, + 0x00, 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, + 0x07, 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, + 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, + 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, + 0x36, 0xC5, 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, + 0x1E, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, + 0xFF, 0xB6, 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, + 0x31, 0xF9, 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, + 0x37, 0xFC, 0xEB, 0x06, 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, + 0xF2, 0x84, 0x05, 0x8D, 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, + 0x01, 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, + 0xFF, 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, + 0x7C, 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, + 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD9, 0x01, 0x6D, 0xFC, + 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, 0x5F, 0x41, 0x3A, 0xF5, 0x0C, + 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, 0xFF, 0xEF, 0xFF, 0x05, 0x00, + 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E, + 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06, + 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, + 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, 0xFC, 0x5D, 0x05, + 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, 0x2A, 0x02, 0x9A, + 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, 0xCC, + 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, 0xFC, + 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, + 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, 0xF9, + 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, 0x19, + 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x20, 0x00, + 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86, + 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01, + 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, + 0xFF, 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, + 0xEA, 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, + 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, + 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, + 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, + 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, + 0xFE, 0x93, 0x01, 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, + 0xE1, 0xFA, 0x86, 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, + 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, + 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, + 0xFF, 0xFF, 0x10, 0x00, 0xBF, 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, + 0x00, 0x01, 0x01, 0xB6, 0xFA, 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, + 0xC4, 0x04, 0x1B, 0xFD, 0x92, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x44, 0xFC, + 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, 0x31, 0x3E, 0xA5, 0xF3, 0x0F, + 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, 0xFF, 0x01, 0x00, 0x02, 0x00, + 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, 0x00, 0x10, 0xFF, 0x15, + 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, 0xF1, 0xF5, 0xD3, 0x05, + 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, + 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, + 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0x03, 0x00, + 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, 0x04, 0x10, + 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, 0x4E, 0xFC, + 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, + 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, + 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, + 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x13, 0x00, + 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5, + 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, + 0xFF, 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, + 0x57, 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, + 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, + 0x8B, 0x01, 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, + 0x2D, 0x9A, 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, + 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, + 0xFE, 0x74, 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, + 0x94, 0xFC, 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, + 0x48, 0xFC, 0x28, 0x07, 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, + 0xF1, 0xBE, 0x06, 0xB0, 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, + 0xFE, 0xFF, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, + 0x01, 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, + 0xF8, 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, + 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, 0x8F, 0x3A, 0x82, 0xF2, 0xE1, + 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, 0xFF, 0x10, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3, + 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05, + 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, 0xFC, 0x85, 0x06, + 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, 0x8C, 0x04, 0x2C, + 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, 0x00, 0x06, 0x00, + 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, 0xC7, + 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, 0xFC, + 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, + 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, 0xF6, + 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, 0xFE, + 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x05, 0x00, + 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61, + 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x56, + 0xFF, 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, + 0x26, 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, + 0x00, 0xBA, 0xFF, 0x11, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, + 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, + 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, + 0x01, 0xD0, 0xFD, 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, + 0x62, 0x00, 0x3F, 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, + 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, + 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, + 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, + 0xFD, 0xFF, 0x1B, 0x00, 0x93, 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, + 0x01, 0xDC, 0xFD, 0x3C, 0x01, 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, + 0x1F, 0x03, 0xEA, 0xFD, 0x34, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, 0xFF, 0xD6, 0x01, 0x39, 0xFC, + 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, 0x85, 0x36, 0xCC, 0xF1, 0x7F, + 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, + 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, 0xFF, 0xA9, 0x00, 0x4D, + 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, 0x18, 0xF9, 0x66, 0x04, + 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, + 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, + 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, 0x00, 0x0B, 0x00, + 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, 0x02, 0xF0, + 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, 0xC1, 0xFC, + 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, + 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, + 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, + 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0x05, 0x00, 0xF4, 0xFF, + 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB, + 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x47, + 0xFF, 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, + 0x5C, 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, + 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, + 0x09, 0x01, 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, + 0x23, 0xD2, 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, + 0x01, 0x65, 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, + 0x03, 0xFD, 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, + 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, + 0xC4, 0xFC, 0xA4, 0x06, 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, + 0xF1, 0x2A, 0x07, 0x40, 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, + 0xFE, 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, + 0x5E, 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, + 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0xBA, 0x01, 0x5B, 0xFC, + 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, 0x26, 0x32, 0x80, 0xF1, 0xEA, + 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF, + 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA, + 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03, + 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, 0xFC, 0x1E, 0x07, + 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, 0x32, 0x06, 0x18, + 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, + 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, 0x8B, + 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, 0xFD, + 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, 0xF3, + 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, 0xC4, + 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0xE1, 0xFF, + 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77, + 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01, + 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, + 0xFF, 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, + 0x02, 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, + 0x00, 0xE4, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, + 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, + 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, + 0x01, 0x05, 0xFD, 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, + 0x0D, 0xFA, 0x58, 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, + 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, + 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, + 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, + 0xFD, 0xB9, 0x03, 0x7B, 0xFA, 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, + 0x03, 0xFF, 0x5F, 0x01, 0xD4, 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, + 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, 0xFF, 0x8E, 0x01, 0x99, 0xFC, + 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, 0x82, 0x2D, 0x96, 0xF1, 0x21, + 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, 0xFE, 0x67, 0x02, 0x13, + 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, 0x7A, 0xFC, 0xB6, 0x02, + 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, + 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, + 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x15, 0x00, + 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, 0xFF, 0x94, + 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, 0x77, 0xFD, + 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, + 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, + 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xCC, 0xFF, + 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8, + 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01, + 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, + 0xFF, 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, + 0x1F, 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, + 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, + 0x54, 0x00, 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, + 0x19, 0x1E, 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, + 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, + 0x01, 0xB4, 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, + 0x86, 0xF7, 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, + 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, + 0xAE, 0xFD, 0x52, 0x05, 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, + 0xF3, 0xD8, 0x06, 0x3C, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, + 0xFD, 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, + 0x91, 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, + 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, 0xFF, 0x55, 0x01, 0xF2, 0xFC, + 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, 0xAA, 0x28, 0x05, 0xF2, 0x27, + 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46, + 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE, + 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFD, + 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, 0xFC, 0x03, 0x07, + 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, 0x0A, 0x07, 0x6E, + 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x1A, 0x00, + 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, 0x05, + 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, 0xFD, + 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, + 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, 0xF1, + 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, 0x5C, + 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB6, 0xFF, + 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69, + 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, + 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, + 0xC0, 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, + 0xFF, 0x07, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, + 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, + 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, + 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, + 0x01, 0x73, 0xFC, 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, + 0x71, 0xF5, 0xEB, 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, + 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, + 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, + 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, + 0xFC, 0x48, 0x05, 0x30, 0xF7, 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, + 0x01, 0x02, 0xB2, 0xFF, 0xBD, 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, + 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAC, 0xFF, 0x0E, 0x01, 0x66, 0xFD, + 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, 0xB0, 0x23, 0xC4, 0xF2, 0xFF, + 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, 0x01, 0x6B, 0xFD, 0x1D, + 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, 0x33, 0xFD, 0xC1, 0xFF, + 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, 0xFF, 0x14, 0x00, 0xFE, + 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, + 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, + 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, 0x02, 0x47, + 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, 0x4D, 0x02, + 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, + 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, + 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, + 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA0, 0xFF, + 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C, + 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01, + 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, + 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, + 0xF2, 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, + 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, + 0x7A, 0xFF, 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, + 0x0F, 0x20, 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, + 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x48, 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, + 0xCF, 0xF3, 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, + 0xFA, 0xFE, 0x3A, 0x03, 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, + 0xF5, 0xE6, 0x05, 0x97, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, + 0xFE, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, + 0xFC, 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, + 0x4D, 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, + 0x00, 0x03, 0x00, 0xFE, 0xFF, 0xD7, 0xFF, 0xBA, 0x00, 0xF4, 0xFD, + 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, + 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6, + 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01, + 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0xFF, + 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, 0xFD, 0x1E, 0x06, + 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, 0x1A, 0x07, 0x31, + 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, 0x94, + 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, 0x01, + 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, + 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, 0xF1, + 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, 0xBE, + 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, + 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2, + 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01, + 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, + 0xFF, 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, + 0xC3, 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, + 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, + 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, + 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, + 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, + 0x9E, 0xF2, 0xCB, 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, + 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, + 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, + 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, + 0xFC, 0x78, 0x06, 0x5A, 0xF4, 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, + 0x6D, 0x04, 0x3F, 0xFE, 0x8E, 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, + 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x5A, 0x00, 0x9A, 0xFE, + 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, 0xA1, 0x19, 0x09, 0xF5, 0x33, + 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, 0x01, 0xB8, 0xFC, 0x9A, + 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, 0xA9, 0xF7, 0xA2, 0x02, + 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, 0xFF, 0x0A, 0x00, 0x01, + 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, + 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, 0x04, 0xE6, + 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, 0x90, 0x00, + 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFE, 0xFF, 0x1C, + 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, + 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, + 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1, + 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE, + 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, + 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, + 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, + 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, + 0x8E, 0xFE, 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, + 0x06, 0x7B, 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, + 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, + 0x01, 0x37, 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, + 0xDC, 0xF1, 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x11, 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, + 0x90, 0x00, 0x7A, 0x00, 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, + 0xF8, 0x7E, 0x04, 0x3C, 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, + 0xFC, 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, + 0x5F, 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, + 0x00, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, 0x00, 0xF1, 0xFF, 0x54, 0xFF, + 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, 0xB1, 0x14, 0x77, 0xF6, 0x9A, + 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, + 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33, + 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03, + 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x04, + 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, 0xFE, 0x6D, 0x04, + 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, 0x78, 0x06, 0x5C, + 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, + 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, 0x48, + 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, 0xFF, + 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0E, + 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, 0xF2, + 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, 0xE5, + 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E, + 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF, + 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, + 0xFF, 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, + 0x89, 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, + 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, + 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, + 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, + 0x8A, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, + 0x01, 0x56, 0xFC, 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, + 0x84, 0xF1, 0xE0, 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, + 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, + 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, + 0xFC, 0x1A, 0x07, 0x56, 0xF2, 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, + 0x1E, 0x06, 0x25, 0xFD, 0x35, 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, + 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, 0x00, 0x81, 0xFF, 0x1F, 0x00, + 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, 0xE7, 0x0F, 0x08, 0xF8, 0xE6, + 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, + 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x4A, 0xFC, 0xAC, + 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, 0xE4, 0xF3, 0xE5, 0x04, + 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0x08, + 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, + 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, + 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, + 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, 0x05, 0xC6, + 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, 0xFA, 0xFE, + 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFF, + 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, + 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, + 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0, + 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF, + 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, + 0xFF, 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, + 0xA0, 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, + 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, + 0x52, 0x01, 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, + 0x48, 0x26, 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, + 0xA0, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, + 0x01, 0x90, 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, + 0x8E, 0xF1, 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, + 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, + 0x4D, 0x02, 0x45, 0xFD, 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, + 0xFC, 0xD1, 0x02, 0x12, 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, + 0xFC, 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, + 0xAB, 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, + 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, 0x00, 0x0C, 0xFF, 0xF7, 0x00, + 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, 0x51, 0x0B, 0xAF, 0xF9, 0x1D, + 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF, + 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05, + 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x0C, + 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, 0xFF, 0x01, 0x02, + 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, 0x48, 0x05, 0xDD, + 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, + 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, 0x6C, + 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, 0xFE, + 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xED, + 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, 0xF5, + 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, 0xD7, + 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, + 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68, + 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF, + 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x07, 0x00, 0xBD, + 0xFF, 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, + 0x9E, 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, + 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, + 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, + 0xB6, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, + 0x01, 0xE6, 0xFC, 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, + 0xF3, 0xF1, 0x29, 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, + 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, + 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, + 0x1A, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, + 0xFC, 0x0A, 0x07, 0x7E, 0xF1, 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, + 0x03, 0x07, 0x75, 0xFC, 0xA7, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, + 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, 0x00, 0x95, 0xFE, 0xD5, 0x01, + 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, 0x00, 0x07, 0x61, 0xFB, 0x46, + 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, 0xFF, 0x23, 0x00, 0x00, 0x00, + 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, 0x01, 0x36, 0xFC, 0x27, + 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, 0xE4, 0xF1, 0x67, 0x06, + 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x11, + 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, + 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, + 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, 0x06, 0x47, + 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, 0xAE, 0xFD, + 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD9, + 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, + 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, + 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56, + 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00, + 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF7, 0xFF, 0xEA, + 0xFF, 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, + 0x94, 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xA9, 0x01, 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, + 0x45, 0x1C, 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, + 0xCC, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, + 0x01, 0x57, 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, + 0xAA, 0xF2, 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, + 0x77, 0xFD, 0x04, 0x04, 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, + 0xFD, 0x92, 0xFF, 0x10, 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, + 0x15, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, + 0xFC, 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, + 0x29, 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x1B, 0x01, 0x20, 0xFE, + 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, 0xF4, 0x48, 0xFF, 0x02, 0x13, + 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, 0x01, 0x88, 0xFF, 0x1D, 0x00, + 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21, + 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06, + 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, + 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, 0x01, 0x03, 0xFF, + 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, 0xB9, 0x03, 0x9D, + 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, 0x61, + 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, 0xFD, + 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC4, + 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, 0xFA, + 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, 0x9C, + 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B, + 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00, + 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE4, 0xFF, 0x1B, + 0x00, 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, + 0x96, 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, + 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, + 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, + 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, + 0xE1, 0xFF, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, + 0x00, 0xE2, 0xFD, 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, + 0xA8, 0xF3, 0xB8, 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, + 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, + 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, + 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, + 0xFD, 0x32, 0x06, 0x1F, 0xF2, 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, + 0x1E, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x4F, 0x01, 0xB0, 0xFD, + 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, 0x86, 0x48, 0x5A, 0xFF, 0xBA, + 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, 0x00, 0x9E, 0xFF, 0x17, 0x00, + 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, 0x01, 0x8C, 0xFC, 0xEA, + 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, 0x8B, 0xF1, 0x1B, 0x07, + 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, + 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, + 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, + 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xC6, + 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, 0xC4, 0xFC, + 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAE, + 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, + 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, + 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64, + 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01, + 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, + 0x00, 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, + 0xB2, 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, + 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, + 0xDD, 0x01, 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, + 0x40, 0xD0, 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, + 0xF4, 0xFF, 0x05, 0x00, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, + 0x00, 0x85, 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, + 0xE1, 0xF4, 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, + 0xC1, 0xFC, 0x86, 0x05, 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, + 0xF7, 0x7B, 0x02, 0x6B, 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, + 0x0B, 0x00, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, + 0xFD, 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, + 0xE6, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x5A, 0xFF, 0x7E, 0x01, 0x48, 0xFD, + 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, 0x7C, 0x47, 0x19, 0xFC, 0x4D, + 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, 0x00, 0xB5, 0xFF, 0x12, 0x00, + 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F, + 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07, + 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, 0xFD, 0x1F, 0x03, + 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, 0xDC, 0xFD, 0xFD, + 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, + 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, 0x80, + 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, 0xFC, + 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x98, + 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, 0x00, + 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, 0x40, + 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60, + 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01, + 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, + 0x00, 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, + 0xFC, 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, + 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, + 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, + 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x3D, 0xFF, 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, + 0x4A, 0xF6, 0xAD, 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, + 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, + 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, + 0x06, 0x00, 0x04, 0x00, 0xF8, 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, + 0xFE, 0x8C, 0x04, 0x6D, 0xF4, 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, + 0x85, 0x06, 0x57, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, 0xFF, 0xA7, 0x01, 0xEC, 0xFC, + 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, 0xD7, 0x45, 0x43, 0xF9, 0xC3, + 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, 0x00, 0xCB, 0xFF, 0x0D, 0x00, + 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, 0x01, 0x50, 0xFD, 0xE1, + 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, 0x9D, 0xF2, 0x09, 0x07, + 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, + 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, + 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, 0x00, 0xFE, 0xFF, + 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, 0x06, 0x97, + 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, 0x48, 0xFC, + 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, + 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, + 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, + 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A, + 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01, + 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, + 0x00, 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, + 0x81, 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, + 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, + 0xE2, 0x01, 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, + 0x39, 0x4D, 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, + 0x13, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, + 0xFF, 0x06, 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, + 0xD7, 0xF7, 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, + 0x4E, 0xFC, 0xA0, 0x06, 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, + 0xF4, 0xC8, 0x04, 0x07, 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, + 0x03, 0x00, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, + 0xFE, 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, + 0x00, 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, 0x9F, 0xFC, + 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, 0x9E, 0x43, 0xDD, 0xF6, 0x15, + 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, 0x00, 0xDF, 0xFF, 0x09, 0x00, + 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F, + 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06, + 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, 0xFD, 0xC4, 0x04, + 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, 0x01, 0x01, 0x44, + 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, 0x00, 0xFF, 0xFF, + 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, 0x14, + 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, 0xFC, + 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, + 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, 0xFA, + 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, 0xB8, + 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3, + 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01, + 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, + 0x00, 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, + 0x50, 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, + 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, + 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, + 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, + 0x20, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, + 0xFF, 0xDD, 0x00, 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, + 0x7C, 0xF9, 0x35, 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, + 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, + 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0xD1, 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, + 0xFF, 0x2A, 0x02, 0x83, 0xF8, 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, + 0x5D, 0x05, 0xD3, 0xFC, 0xB1, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, + 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x64, 0xFC, + 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, 0xD9, 0x40, 0xEA, 0xF4, 0x3E, + 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, 0xFF, 0xF3, 0xFF, 0x05, 0x00, + 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, 0x00, 0x7B, 0xFE, 0x0C, + 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, 0xCD, 0xF4, 0x4B, 0x06, + 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, + 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, + 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, + 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0x01, 0x00, + 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, 0x05, 0xFD, + 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, 0x37, 0xFC, + 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, + 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, + 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, + 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46, + 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, + 0xFF, 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, + 0xDB, 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, + 0x00, 0x91, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, + 0xB1, 0x01, 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, + 0x31, 0x7C, 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, + 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, + 0xFE, 0xBB, 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, + 0x2E, 0xFB, 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, + 0x34, 0xFC, 0x25, 0x07, 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, + 0xF1, 0x56, 0x06, 0xFE, 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, + 0xFF, 0xFF, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, + 0x00, 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, + 0xA1, 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3F, 0xFC, + 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, 0x96, 0x3D, 0x69, 0xF3, 0x38, + 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, 0xFF, 0x04, 0x00, 0x02, 0x00, + 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC, + 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05, + 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, 0xFC, 0x1A, 0x06, + 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, 0xA6, 0x03, 0xB9, + 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0x04, 0x00, + 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, 0x55, + 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, 0xFC, + 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, + 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, 0xF7, + 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, 0xA2, + 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, + 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54, + 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01, + 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, + 0xFF, 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, + 0x2C, 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, + 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, + 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, + 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, + 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, + 0x01, 0x2D, 0xFE, 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, + 0x73, 0x03, 0xE0, 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, + 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, + 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, + 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, + 0xFD, 0xFF, 0x16, 0x00, 0xA5, 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, + 0x01, 0x33, 0xFF, 0x5A, 0xFE, 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, + 0xD2, 0x03, 0x90, 0xFD, 0x5E, 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, + 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, 0xDF, 0x39, 0x5A, 0xF2, 0x00, + 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, 0xFF, 0x13, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, 0xFF, 0xFA, 0xFF, 0x83, + 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, 0xBF, 0xF7, 0x07, 0x05, + 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, + 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, + 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0x07, 0x00, + 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, 0x03, 0x20, + 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, 0x88, 0xFC, + 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, + 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, + 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, + 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, + 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE, + 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x53, + 0xFF, 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, + 0xE1, 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, + 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, + 0x45, 0x01, 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, + 0x27, 0x2B, 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, + 0x01, 0xBC, 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, + 0xC3, 0xFF, 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, + 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, + 0x84, 0xFC, 0xF3, 0x06, 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, + 0xF1, 0x16, 0x07, 0x61, 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, + 0xFD, 0xFF, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, + 0x02, 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, + 0xF8, 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD2, 0x01, 0x3D, 0xFC, + 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, 0xC6, 0x35, 0xB7, 0xF1, 0x96, + 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, + 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07, + 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04, + 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF3, 0x06, + 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, 0x9C, 0x05, 0x7E, + 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, + 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, 0x5E, + 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, 0xFC, + 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, + 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, 0xF4, + 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, 0x77, + 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF0, 0xFF, + 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32, + 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01, + 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x45, + 0xFF, 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, + 0xFD, 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, + 0x00, 0xD3, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, + 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, + 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, + 0x01, 0x53, 0xFD, 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, + 0x76, 0xFC, 0x1F, 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, + 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, + 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, + 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, + 0xFD, 0x05, 0x03, 0xE1, 0xFB, 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, + 0xAA, 0xFD, 0x18, 0x02, 0x72, 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, + 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB3, 0x01, 0x64, 0xFC, + 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, 0x5A, 0x31, 0x7D, 0xF1, 0xF7, + 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, + 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, 0xFE, 0xAE, 0x01, 0x70, + 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, 0x14, 0xFB, 0x6D, 0x03, + 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, + 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, + 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x10, 0x00, + 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, 0x00, 0x0C, + 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, 0x26, 0xFD, + 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, + 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, + 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDD, 0xFF, + 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7, + 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01, + 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3B, + 0xFF, 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, + 0x89, 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, + 0x00, 0xE8, 0xFF, 0x07, 0x00, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, + 0xA4, 0x00, 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, + 0x1D, 0x10, 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, + 0x01, 0xF6, 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, + 0x93, 0xF9, 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, + 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, + 0x41, 0xFD, 0xF6, 0x05, 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, + 0xF2, 0x0F, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, + 0xFD, 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, + 0x4B, 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, + 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, 0xFF, 0x85, 0x01, 0xA6, 0xFC, + 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, 0xAB, 0x2C, 0xA3, 0xF1, 0x26, + 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, 0xFF, 0x30, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, + 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, + 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFD, + 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, + 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, + 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, + 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, + 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x02, 0x00, 0x05, + 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3, + 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, + 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, + 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x84, + 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, + 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, + 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, + 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, + 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, 0xFF, 0x64, 0x00, 0x9B, + 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, 0x10, 0x46, 0x03, 0x11, + 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, 0x01, 0x4C, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, 0x42, 0x00, + 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, 0x18, 0x5C, + 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, + 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, + 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, + 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, + 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, + 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, + 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7, + 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07, + 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, + 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, + 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, + 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, + 0xF2, 0x81, 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, + 0xFB, 0x00, 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, + 0x00, 0x38, 0xFF, 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, + 0xCE, 0x1A, 0x32, 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, + 0x00, 0xFB, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, + 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, + 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, + 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, + 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, + 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, + 0x00, 0xB1, 0xFF, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, + 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, + 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, + 0x8F, 0xFF, 0x1C, 0x00, 0x18, 0x00, 0x9C, 0xFF, 0xD6, 0x00, 0xB1, + 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, 0x9C, 0x48, 0xFD, 0x07, + 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, 0x01, 0x6E, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, 0x65, 0xFF, + 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, 0x0E, 0x6A, + 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, 0x2D, 0x00, + 0xFF, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, + 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, + 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, + 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, + 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, + 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00, + 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07, + 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, + 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, + 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x30, 0x00, 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, + 0xF1, 0x62, 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, + 0x82, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x3A, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, + 0xDD, 0x24, 0x54, 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, + 0x01, 0xA3, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, + 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, + 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, + 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, + 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, + 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, + 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, + 0xBB, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x43, + 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, 0x7E, 0x07, 0xAF, 0x48, + 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, 0xFE, 0xDD, 0x00, 0x99, + 0xFF, 0x19, 0x00, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, 0x79, 0xFE, + 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, 0x06, 0xC7, + 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, 0x22, 0x00, + 0x00, 0x00, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, + 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, + 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, + 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, + 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, + 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E, + 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06, + 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, + 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, + 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, + 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, + 0x20, 0x00, 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, + 0xF1, 0x86, 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, + 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2D, + 0x00, 0x54, 0xFF, 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, + 0x9F, 0x2E, 0xE3, 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, + 0x01, 0x64, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, + 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, + 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, + 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, + 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, + 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, + 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, + 0xE5, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9E, + 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, 0x75, 0x10, 0x48, 0x46, + 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, 0xFF, 0x6B, 0x00, 0xC6, + 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x5B, 0x01, + 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, 0x48, 0x8D, + 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, 0xA4, 0xFF, + 0x16, 0x00, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, + 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, + 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, + 0x00, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, + 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, + 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3, + 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05, + 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x06, + 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, + 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, + 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x02, 0x00, + 0x05, 0x00, 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, + 0xF3, 0x61, 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, + 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x1A, + 0x00, 0x8A, 0xFF, 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, + 0x82, 0x37, 0x60, 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, + 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x29, 0x00, + 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, + 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x43, + 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, + 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, + 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, + 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, + 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, + 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, 0x38, 0x1A, 0x8C, 0x41, + 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, 0x00, 0x01, 0x00, 0xEE, + 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, 0xAF, 0x01, + 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, 0x45, 0xA9, + 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, 0xD0, 0xFF, + 0x0C, 0x00, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, + 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, + 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, + 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, + 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, + 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA, + 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03, + 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0x0F, + 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, + 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, + 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x08, 0x00, + 0xE1, 0xFF, 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, + 0xF6, 0x77, 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, + 0xC8, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFD, + 0xFF, 0xD9, 0xFF, 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, + 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x14, 0x00, + 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, + 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x25, 0x00, 0x6A, + 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, + 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, + 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, + 0x22, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, 0x46, 0x24, 0xC8, 0x3A, + 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, 0x01, 0xA8, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, + 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, 0x40, 0x85, + 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, 0xF7, 0xFF, + 0x04, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, + 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, + 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, + 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, + 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, + 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46, + 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE, + 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0x1A, + 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, + 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, + 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0x12, 0x00, + 0xB6, 0xFF, 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, + 0xFB, 0x69, 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, + 0x81, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD7, + 0xFF, 0x3E, 0x00, 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, + 0x99, 0x44, 0x68, 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, + 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF5, 0xFF, + 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, + 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, + 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC, + 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, + 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, + 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, + 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2E, 0x00, 0x52, 0xFF, 0xBC, + 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, 0x11, 0x2E, 0x6B, 0x32, + 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, 0x01, 0x67, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE0, 0x01, + 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, 0x38, 0x2A, + 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, 0x16, 0x00, + 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, + 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, + 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, + 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, + 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, + 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, + 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6, + 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01, + 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, + 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, + 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0x1D, 0x00, + 0x8A, 0xFF, 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, + 0x02, 0xF2, 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, + 0x1E, 0x01, 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAC, + 0xFF, 0xAE, 0x00, 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, + 0xFD, 0x47, 0x0E, 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, + 0x01, 0x61, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, + 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, + 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, + 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06, + 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, + 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, + 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, + 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1C, 0x00, 0x86, 0xFF, 0x59, + 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, 0x04, 0x37, 0xF3, 0x28, + 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x41, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, + 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, + 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, + 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, + 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, + 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, + 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, + 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, + 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33, + 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03, + 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0xFF, + 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, + 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, + 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, + 0xF9, 0x0E, 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, + 0x05, 0xFF, 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x7F, 0xFF, 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, + 0x9B, 0x04, 0xF2, 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, + 0xFE, 0x04, 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0x17, 0x00, 0xA1, 0xFF, + 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, + 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, + 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xC3, 0xFF, 0x71, + 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, + 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, + 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, + 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, + 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, 0x98, 0x3E, 0xF3, 0x1E, + 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, 0x39, 0x01, + 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, 0x26, 0x4B, + 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, + 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, + 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, + 0xFF, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, + 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, + 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, + 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF, + 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05, + 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, + 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, + 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFF, 0xFF, + 0x32, 0x00, 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, + 0xF6, 0x68, 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, + 0xEA, 0xFF, 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x59, 0xFF, 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, + 0x2D, 0x0D, 0x69, 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, + 0xFF, 0x93, 0x00, 0xB6, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, + 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, + 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0x1A, 0x00, 0x96, 0xFF, 0xE3, + 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, + 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, + 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, + 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, + 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD9, 0xFF, 0x37, 0x00, 0xF7, + 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, 0x53, 0x44, 0xFB, 0x14, + 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, 0x01, 0x42, 0xFF, 0x32, + 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, 0x00, + 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, 0x1C, 0x47, + 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, + 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, + 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, + 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, + 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, + 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21, + 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06, + 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, + 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, + 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, + 0xF3, 0x5B, 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, + 0xB4, 0x00, 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, + 0x00, 0x3E, 0xFF, 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, + 0xB6, 0x16, 0x77, 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, + 0x00, 0x25, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFF, 0xFF, 0x2D, 0x00, + 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, + 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, + 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x25, 0x00, 0x6C, + 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, + 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, + 0x00, 0x9E, 0xFF, 0x17, 0x00, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, + 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, + 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAE, 0xFF, 0xA7, 0x00, 0x12, + 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, 0xDC, 0x47, 0x95, 0x0B, + 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, 0x01, 0x5F, 0xFF, 0x29, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, 0xC3, 0xFF, + 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, 0x12, 0x19, + 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, 0x30, 0x00, + 0xFF, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, + 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, + 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, + 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, + 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, + 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F, + 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07, + 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, + 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, + 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x34, 0x00, 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, + 0xF2, 0x60, 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, + 0x51, 0x01, 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, + 0xBA, 0x20, 0x61, 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, + 0x00, 0xC5, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, + 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, + 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, + 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, + 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, + 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, + 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, + 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, + 0xA9, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x82, 0xFF, 0x18, + 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, 0x24, 0x04, 0xF5, 0x48, + 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, 0xFE, 0x0B, 0x01, 0x87, + 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, 0xDB, 0xFE, + 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, 0x09, 0x61, + 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, 0x26, 0x00, + 0x00, 0x00, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, + 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, + 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, + 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, + 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, + 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, + 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F, + 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06, + 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, + 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, + 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x28, 0x00, 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, + 0xF1, 0xE3, 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, + 0xB7, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x32, + 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, + 0xAE, 0x2A, 0x86, 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, + 0x01, 0x7B, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, + 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, + 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, + 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, + 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, + 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, + 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, + 0xD5, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, 0xFF, 0x7C, + 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, 0xA4, 0x0C, 0x90, 0x47, + 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, 0xFF, 0x99, 0x00, 0xB3, + 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, 0x31, 0x01, + 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, 0x48, 0x73, + 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, 0x91, 0xFF, + 0x1B, 0x00, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, + 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, + 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, + 0x00, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, + 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, + 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, + 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC, + 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05, + 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x04, + 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, + 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, + 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, + 0x11, 0x00, 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, + 0xF2, 0x54, 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, + 0xE4, 0x01, 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x23, + 0x00, 0x71, 0xFF, 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, + 0xFD, 0x33, 0x62, 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, + 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2F, 0x00, + 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, + 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, + 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3B, + 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, + 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, + 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, + 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, + 0xFB, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC5, + 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, 0x22, 0x16, 0xC3, 0x43, + 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, 0x00, 0x2B, 0x00, 0xDE, + 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x90, 0x01, + 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, 0x46, 0xE1, + 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, 0xBE, 0xFF, + 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, + 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, + 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, + 0x00, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, + 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, + 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, + 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07, + 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04, + 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x0B, + 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, + 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, + 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x05, 0x00, + 0xF0, 0xFF, 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, + 0xF5, 0x32, 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, + 0xDA, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, + 0x00, 0xB6, 0xFF, 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, + 0x1C, 0x3C, 0x81, 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1E, 0x00, + 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, + 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2C, 0x00, 0x57, + 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, + 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, + 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, + 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, + 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, + 0x19, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, + 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, 0x22, 0x20, 0xCA, 0x3D, + 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, 0x00, 0xCA, 0xFF, 0x03, + 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, + 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, 0x42, 0x02, + 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, 0xE8, 0xFF, + 0x07, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, + 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, + 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, + 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, + 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, + 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, + 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, + 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, + 0x00, 0xF4, 0xFF, 0x1A, 0x00, 0xFF, 0x00, 0x07, 0x03, 0x16, 0x06, + 0x7C, 0x09, 0x2A, 0x0C, 0x2E, 0x0D, 0x2A, 0x0C, 0x7C, 0x09, 0x16, + 0x06, 0x07, 0x03, 0xFF, 0x00, 0x1A, 0x00, 0xF4, 0xFF, 0xF2, 0xFF, + 0xA0, 0xFF, 0x71, 0xFF, 0x71, 0x00, 0x86, 0x03, 0x73, 0x08, 0x88, + 0x0D, 0x78, 0x10, 0xC9, 0x0F, 0xD5, 0x0B, 0x8B, 0x06, 0x28, 0x02, + 0xDF, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDC, + 0xFF, 0x80, 0xFF, 0x9A, 0xFF, 0x46, 0x01, 0x1E, 0x05, 0x5A, 0x0A, + 0xED, 0x0E, 0xAA, 0x10, 0xAF, 0x0E, 0xFD, 0x09, 0xCB, 0x04, 0x18, + 0x01, 0x8E, 0xFF, 0x85, 0xFF, 0xE1, 0xFF, 0xFC, 0xFF, 0xBD, 0xFF, + 0x6D, 0xFF, 0xF6, 0xFF, 0x65, 0x02, 0xE5, 0x06, 0x2B, 0x0C, 0xF3, + 0x0F, 0x60, 0x10, 0x3B, 0x0D, 0x16, 0x08, 0x3F, 0x03, 0x50, 0x00, + 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, 0xFF, 0xEF, 0xFF, 0x9A, 0xFF, 0x75, + 0xFF, 0x91, 0x00, 0xC9, 0x03, 0xC8, 0x08, 0xCC, 0x0D, 0x89, 0x10, + 0x9F, 0x0F, 0x85, 0x0B, 0x3B, 0x06, 0xF4, 0x01, 0xCD, 0xFF, 0x72, + 0xFF, 0xC9, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD7, 0xFF, 0x7B, 0xFF, + 0xA5, 0xFF, 0x73, 0x01, 0x6A, 0x05, 0xAD, 0x0A, 0x21, 0x0F, 0xA6, + 0x10, 0x74, 0x0E, 0xA9, 0x09, 0x83, 0x04, 0xF0, 0x00, 0x85, 0xFF, + 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, 0xFF, 0xB7, 0xFF, 0x6C, 0xFF, 0x0C, + 0x00, 0x9D, 0x02, 0x37, 0x07, 0x78, 0x0C, 0x15, 0x10, 0x47, 0x10, + 0xF3, 0x0C, 0xC2, 0x07, 0x01, 0x03, 0x35, 0x00, 0x6D, 0xFF, 0xAD, + 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, 0x94, 0xFF, 0x7A, 0xFF, 0xB3, 0x00, + 0x0D, 0x04, 0x1C, 0x09, 0x0D, 0x0E, 0x97, 0x10, 0x73, 0x0F, 0x35, + 0x0B, 0xEB, 0x05, 0xC1, 0x01, 0xBD, 0xFF, 0x75, 0xFF, 0xCE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x77, 0xFF, 0xB3, 0xFF, 0xA1, + 0x01, 0xB7, 0x05, 0xFF, 0x0A, 0x53, 0x0F, 0x9E, 0x10, 0x37, 0x0E, + 0x55, 0x09, 0x3B, 0x04, 0xCB, 0x00, 0x7E, 0xFF, 0x90, 0xFF, 0xE9, + 0xFF, 0xF8, 0xFF, 0xB1, 0xFF, 0x6C, 0xFF, 0x24, 0x00, 0xD8, 0x02, + 0x8A, 0x07, 0xC2, 0x0C, 0x34, 0x10, 0x2A, 0x10, 0xAA, 0x0C, 0x6F, + 0x07, 0xC4, 0x02, 0x1C, 0x00, 0x6C, 0xFF, 0xB3, 0xFF, 0xF9, 0xFF, + 0xE8, 0xFF, 0x8E, 0xFF, 0x80, 0xFF, 0xD7, 0x00, 0x53, 0x04, 0x71, + 0x09, 0x4C, 0x0E, 0xA1, 0x10, 0x43, 0x0F, 0xE3, 0x0A, 0x9D, 0x05, + 0x91, 0x01, 0xAE, 0xFF, 0x79, 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC2, 0xFF, 0xD2, 0x01, 0x06, 0x06, + 0x50, 0x0B, 0x82, 0x0F, 0x93, 0x10, 0xF8, 0x0D, 0x00, 0x09, 0xF6, + 0x03, 0xA7, 0x00, 0x78, 0xFF, 0x96, 0xFF, 0xEC, 0xFF, 0xF6, 0xFF, + 0xAB, 0xFF, 0x6D, 0xFF, 0x3E, 0x00, 0x15, 0x03, 0xDE, 0x07, 0x0B, + 0x0D, 0x50, 0x10, 0x0A, 0x10, 0x5E, 0x0C, 0x1C, 0x07, 0x8A, 0x02, + 0x04, 0x00, 0x6C, 0xFF, 0xB9, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, 0x89, + 0xFF, 0x88, 0xFF, 0xFD, 0x00, 0x9B, 0x04, 0xC5, 0x09, 0x88, 0x0E, + 0xA8, 0x10, 0x10, 0x0F, 0x91, 0x0A, 0x50, 0x05, 0x64, 0x01, 0xA1, + 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, + 0x71, 0xFF, 0xD3, 0xFF, 0x05, 0x02, 0x55, 0x06, 0xA0, 0x0B, 0xAD, + 0x0F, 0x84, 0x10, 0xB6, 0x0D, 0xAC, 0x08, 0xB3, 0x03, 0x86, 0x00, + 0x74, 0xFF, 0x9C, 0xFF, 0xF0, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, 0x6F, + 0xFF, 0x5A, 0x00, 0x54, 0x03, 0x32, 0x08, 0x52, 0x0D, 0x68, 0x10, + 0xE6, 0x0F, 0x11, 0x0C, 0xCA, 0x06, 0x52, 0x02, 0xEF, 0xFF, 0x6E, + 0xFF, 0xBF, 0xFF, 0xFC, 0xFF, 0xDF, 0xFF, 0x84, 0xFF, 0x91, 0xFF, + 0x25, 0x01, 0xE4, 0x04, 0x19, 0x0A, 0xC2, 0x0E, 0xAA, 0x10, 0xDA, + 0x0E, 0x3E, 0x0A, 0x05, 0x05, 0x38, 0x01, 0x96, 0xFF, 0x81, 0xFF, + 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE6, + 0xFF, 0x3A, 0x02, 0xA6, 0x06, 0xEF, 0x0B, 0xD6, 0x0F, 0x71, 0x10, + 0x71, 0x0D, 0x57, 0x08, 0x71, 0x03, 0x67, 0x00, 0x70, 0xFF, 0xA2, + 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x78, 0x00, + 0x95, 0x03, 0x86, 0x08, 0x98, 0x0D, 0x7C, 0x10, 0xC0, 0x0F, 0xC3, + 0x0B, 0x79, 0x06, 0x1C, 0x02, 0xDB, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, + 0xFE, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9C, 0xFF, 0x50, + 0x01, 0x2F, 0x05, 0x6C, 0x0A, 0xF9, 0x0E, 0xA9, 0x10, 0xA2, 0x0E, + 0xEA, 0x09, 0xBB, 0x04, 0x0F, 0x01, 0x8C, 0xFF, 0x87, 0xFF, 0xE2, + 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xFA, 0xFF, 0x71, 0x02, + 0xF7, 0x06, 0x3C, 0x0C, 0xFB, 0x0F, 0x5B, 0x10, 0x2B, 0x0D, 0x03, + 0x08, 0x31, 0x03, 0x4A, 0x00, 0x6E, 0xFF, 0xA8, 0xFF, 0xF5, 0xFF, + 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x98, 0x00, 0xD8, 0x03, 0xDB, + 0x08, 0xDB, 0x0D, 0x8D, 0x10, 0x96, 0x0F, 0x73, 0x0B, 0x29, 0x06, + 0xE8, 0x01, 0xC9, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, 0x00, + 0x00, 0xD6, 0xFF, 0x7A, 0xFF, 0xA8, 0xFF, 0x7D, 0x01, 0x7B, 0x05, + 0xBF, 0x0A, 0x2D, 0x0F, 0xA5, 0x10, 0x67, 0x0E, 0x96, 0x09, 0x73, + 0x04, 0xE7, 0x00, 0x84, 0xFF, 0x8C, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, + 0xB6, 0xFF, 0x6C, 0xFF, 0x11, 0x00, 0xAA, 0x02, 0x4A, 0x07, 0x88, + 0x0C, 0x1C, 0x10, 0x41, 0x10, 0xE3, 0x0C, 0xAF, 0x07, 0xF3, 0x02, + 0x2F, 0x00, 0x6C, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, + 0xFF, 0x7B, 0xFF, 0xBB, 0x00, 0x1C, 0x04, 0x2F, 0x09, 0x1B, 0x0E, + 0x9A, 0x10, 0x68, 0x0F, 0x23, 0x0B, 0xDA, 0x05, 0xB7, 0x01, 0xB9, + 0xFF, 0x76, 0xFF, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF, + 0x76, 0xFF, 0xB6, 0xFF, 0xAC, 0x01, 0xC8, 0x05, 0x11, 0x0B, 0x5E, + 0x0F, 0x9C, 0x10, 0x29, 0x0E, 0x42, 0x09, 0x2C, 0x04, 0xC2, 0x00, + 0x7D, 0xFF, 0x92, 0xFF, 0xEA, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, 0x6C, + 0xFF, 0x29, 0x00, 0xE6, 0x02, 0x9D, 0x07, 0xD3, 0x0C, 0x3B, 0x10, + 0x23, 0x10, 0x99, 0x0C, 0x5C, 0x07, 0xB7, 0x02, 0x16, 0x00, 0x6C, + 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8D, 0xFF, 0x82, 0xFF, + 0xDF, 0x00, 0x63, 0x04, 0x84, 0x09, 0x59, 0x0E, 0xA3, 0x10, 0x38, + 0x0F, 0xD1, 0x0A, 0x8C, 0x05, 0x87, 0x01, 0xAB, 0xFF, 0x79, 0xFF, + 0xD5, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC6, + 0xFF, 0xDD, 0x01, 0x17, 0x06, 0x62, 0x0B, 0x8C, 0x0F, 0x90, 0x10, + 0xE9, 0x0D, 0xED, 0x08, 0xE7, 0x03, 0xA0, 0x00, 0x77, 0xFF, 0x97, + 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xA9, 0xFF, 0x6D, 0xFF, 0x44, 0x00, + 0x23, 0x03, 0xF1, 0x07, 0x1B, 0x0D, 0x55, 0x10, 0x02, 0x10, 0x4D, + 0x0C, 0x0A, 0x07, 0x7E, 0x02, 0xFF, 0xFF, 0x6D, 0xFF, 0xBA, 0xFF, + 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x8A, 0xFF, 0x06, 0x01, 0xAB, + 0x04, 0xD8, 0x09, 0x95, 0x0E, 0xA9, 0x10, 0x05, 0x0F, 0x7F, 0x0A, + 0x40, 0x05, 0x5A, 0x01, 0x9F, 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, + 0x00, 0xFE, 0xFF, 0xC6, 0xFF, 0x70, 0xFF, 0xD7, 0xFF, 0x10, 0x02, + 0x67, 0x06, 0xB1, 0x0B, 0xB7, 0x0F, 0x80, 0x10, 0xA7, 0x0D, 0x99, + 0x08, 0xA4, 0x03, 0x7F, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, 0xFF, + 0xF3, 0xFF, 0xA3, 0xFF, 0x70, 0xFF, 0x60, 0x00, 0x62, 0x03, 0x45, + 0x08, 0x62, 0x0D, 0x6C, 0x10, 0xDE, 0x0F, 0x00, 0x0C, 0xB8, 0x06, + 0x46, 0x02, 0xEA, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFD, 0xFF, 0x00, + 0x00, 0xDE, 0xFF, 0x83, 0xFF, 0x94, 0xFF, 0x2F, 0x01, 0xF4, 0x04, + 0x2B, 0x0A, 0xCE, 0x0E, 0xAA, 0x10, 0xCE, 0x0E, 0x2B, 0x0A, 0xF4, + 0x04, 0x2F, 0x01, 0x94, 0xFF, 0x83, 0xFF, 0xDE, 0xFF, 0xFD, 0xFF, + 0xC0, 0xFF, 0x6E, 0xFF, 0xEA, 0xFF, 0x46, 0x02, 0xB8, 0x06, 0x00, + 0x0C, 0xDE, 0x0F, 0x6C, 0x10, 0x62, 0x0D, 0x45, 0x08, 0x62, 0x03, + 0x60, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, + 0xFF, 0x73, 0xFF, 0x7F, 0x00, 0xA4, 0x03, 0x99, 0x08, 0xA7, 0x0D, + 0x80, 0x10, 0xB7, 0x0F, 0xB1, 0x0B, 0x67, 0x06, 0x10, 0x02, 0xD7, + 0xFF, 0x70, 0xFF, 0xC6, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, 0xFF, + 0x7E, 0xFF, 0x9F, 0xFF, 0x5A, 0x01, 0x40, 0x05, 0x7F, 0x0A, 0x05, + 0x0F, 0xA9, 0x10, 0x95, 0x0E, 0xD8, 0x09, 0xAB, 0x04, 0x06, 0x01, + 0x8A, 0xFF, 0x88, 0xFF, 0xE3, 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, + 0xFF, 0xFF, 0xFF, 0x7E, 0x02, 0x0A, 0x07, 0x4D, 0x0C, 0x02, 0x10, + 0x55, 0x10, 0x1B, 0x0D, 0xF1, 0x07, 0x23, 0x03, 0x44, 0x00, 0x6D, + 0xFF, 0xA9, 0xFF, 0xF6, 0xFF, 0xED, 0xFF, 0x97, 0xFF, 0x77, 0xFF, + 0xA0, 0x00, 0xE7, 0x03, 0xED, 0x08, 0xE9, 0x0D, 0x90, 0x10, 0x8C, + 0x0F, 0x62, 0x0B, 0x17, 0x06, 0xDD, 0x01, 0xC6, 0xFF, 0x73, 0xFF, + 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x79, 0xFF, 0xAB, + 0xFF, 0x87, 0x01, 0x8C, 0x05, 0xD1, 0x0A, 0x38, 0x0F, 0xA3, 0x10, + 0x59, 0x0E, 0x84, 0x09, 0x63, 0x04, 0xDF, 0x00, 0x82, 0xFF, 0x8D, + 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0xB4, 0xFF, 0x6C, 0xFF, 0x16, 0x00, + 0xB7, 0x02, 0x5C, 0x07, 0x99, 0x0C, 0x23, 0x10, 0x3B, 0x10, 0xD3, + 0x0C, 0x9D, 0x07, 0xE6, 0x02, 0x29, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, + 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7D, 0xFF, 0xC2, 0x00, 0x2C, + 0x04, 0x42, 0x09, 0x29, 0x0E, 0x9C, 0x10, 0x5E, 0x0F, 0x11, 0x0B, + 0xC8, 0x05, 0xAC, 0x01, 0xB6, 0xFF, 0x76, 0xFF, 0xD1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB9, 0xFF, 0xB7, 0x01, + 0xDA, 0x05, 0x23, 0x0B, 0x68, 0x0F, 0x9A, 0x10, 0x1B, 0x0E, 0x2F, + 0x09, 0x1C, 0x04, 0xBB, 0x00, 0x7B, 0xFF, 0x93, 0xFF, 0xEA, 0xFF, + 0xF7, 0xFF, 0xAE, 0xFF, 0x6C, 0xFF, 0x2F, 0x00, 0xF3, 0x02, 0xAF, + 0x07, 0xE3, 0x0C, 0x41, 0x10, 0x1C, 0x10, 0x88, 0x0C, 0x4A, 0x07, + 0xAA, 0x02, 0x11, 0x00, 0x6C, 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE6, + 0xFF, 0x8C, 0xFF, 0x84, 0xFF, 0xE7, 0x00, 0x73, 0x04, 0x96, 0x09, + 0x67, 0x0E, 0xA5, 0x10, 0x2D, 0x0F, 0xBF, 0x0A, 0x7B, 0x05, 0x7D, + 0x01, 0xA8, 0xFF, 0x7A, 0xFF, 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, + 0xCA, 0xFF, 0x72, 0xFF, 0xC9, 0xFF, 0xE8, 0x01, 0x29, 0x06, 0x73, + 0x0B, 0x96, 0x0F, 0x8D, 0x10, 0xDB, 0x0D, 0xDB, 0x08, 0xD8, 0x03, + 0x98, 0x00, 0x76, 0xFF, 0x99, 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA8, + 0xFF, 0x6E, 0xFF, 0x4A, 0x00, 0x31, 0x03, 0x03, 0x08, 0x2B, 0x0D, + 0x5B, 0x10, 0xFB, 0x0F, 0x3C, 0x0C, 0xF7, 0x06, 0x71, 0x02, 0xFA, + 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, 0xFC, 0xFF, 0xE2, 0xFF, 0x87, 0xFF, + 0x8C, 0xFF, 0x0F, 0x01, 0xBB, 0x04, 0xEA, 0x09, 0xA2, 0x0E, 0xA9, + 0x10, 0xF9, 0x0E, 0x6C, 0x0A, 0x2F, 0x05, 0x50, 0x01, 0x9C, 0xFF, + 0x7F, 0xFF, 0xDB, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, 0x70, + 0xFF, 0xDB, 0xFF, 0x1C, 0x02, 0x79, 0x06, 0xC3, 0x0B, 0xC0, 0x0F, + 0x7C, 0x10, 0x98, 0x0D, 0x86, 0x08, 0x95, 0x03, 0x78, 0x00, 0x72, + 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA2, 0xFF, 0x70, 0xFF, + 0x67, 0x00, 0x71, 0x03, 0x57, 0x08, 0x71, 0x0D, 0x71, 0x10, 0xD6, + 0x0F, 0xEF, 0x0B, 0xA6, 0x06, 0x3A, 0x02, 0xE6, 0xFF, 0x6E, 0xFF, + 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x96, + 0xFF, 0x38, 0x01, 0x05, 0x05, 0x3E, 0x0A, 0xDA, 0x0E, 0xAA, 0x10, + 0xC2, 0x0E, 0x19, 0x0A, 0xE4, 0x04, 0x25, 0x01, 0x91, 0xFF, 0x84, + 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0x6E, 0xFF, 0xEF, 0xFF, + 0x52, 0x02, 0xCA, 0x06, 0x11, 0x0C, 0xE6, 0x0F, 0x68, 0x10, 0x52, + 0x0D, 0x32, 0x08, 0x54, 0x03, 0x5A, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, + 0xF4, 0xFF, 0xF0, 0xFF, 0x9C, 0xFF, 0x74, 0xFF, 0x86, 0x00, 0xB3, + 0x03, 0xAC, 0x08, 0xB6, 0x0D, 0x84, 0x10, 0xAD, 0x0F, 0xA0, 0x0B, + 0x55, 0x06, 0x05, 0x02, 0xD3, 0xFF, 0x71, 0xFF, 0xC7, 0xFF, 0xFE, + 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA1, 0xFF, 0x64, 0x01, + 0x50, 0x05, 0x91, 0x0A, 0x10, 0x0F, 0xA8, 0x10, 0x88, 0x0E, 0xC5, + 0x09, 0x9B, 0x04, 0xFD, 0x00, 0x88, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, + 0xFB, 0xFF, 0xB9, 0xFF, 0x6C, 0xFF, 0x04, 0x00, 0x8A, 0x02, 0x1C, + 0x07, 0x5E, 0x0C, 0x0A, 0x10, 0x50, 0x10, 0x0B, 0x0D, 0xDE, 0x07, + 0x15, 0x03, 0x3E, 0x00, 0x6D, 0xFF, 0xAB, 0xFF, 0xF6, 0xFF, 0xEC, + 0xFF, 0x96, 0xFF, 0x78, 0xFF, 0xA7, 0x00, 0xF6, 0x03, 0x00, 0x09, + 0xF8, 0x0D, 0x93, 0x10, 0x82, 0x0F, 0x50, 0x0B, 0x06, 0x06, 0xD2, + 0x01, 0xC2, 0xFF, 0x74, 0xFF, 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0xD4, 0xFF, 0x79, 0xFF, 0xAE, 0xFF, 0x91, 0x01, 0x9D, 0x05, 0xE3, + 0x0A, 0x43, 0x0F, 0xA1, 0x10, 0x4C, 0x0E, 0x71, 0x09, 0x53, 0x04, + 0xD7, 0x00, 0x80, 0xFF, 0x8E, 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB3, + 0xFF, 0x6C, 0xFF, 0x1C, 0x00, 0xC4, 0x02, 0x6F, 0x07, 0xAA, 0x0C, + 0x2A, 0x10, 0x34, 0x10, 0xC2, 0x0C, 0x8A, 0x07, 0xD8, 0x02, 0x24, + 0x00, 0x6C, 0xFF, 0xB1, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x90, 0xFF, + 0x7E, 0xFF, 0xCB, 0x00, 0x3B, 0x04, 0x55, 0x09, 0x37, 0x0E, 0x9E, + 0x10, 0x53, 0x0F, 0xFF, 0x0A, 0xB7, 0x05, 0xA1, 0x01, 0xB3, 0xFF, + 0x77, 0xFF, 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x75, + 0xFF, 0xBD, 0xFF, 0xC1, 0x01, 0xEB, 0x05, 0x35, 0x0B, 0x73, 0x0F, + 0x97, 0x10, 0x0D, 0x0E, 0x1C, 0x09, 0x0D, 0x04, 0xB3, 0x00, 0x7A, + 0xFF, 0x94, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAD, 0xFF, 0x6D, 0xFF, + 0x35, 0x00, 0x01, 0x03, 0xC2, 0x07, 0xF3, 0x0C, 0x47, 0x10, 0x15, + 0x10, 0x78, 0x0C, 0x37, 0x07, 0x9D, 0x02, 0x0C, 0x00, 0x6C, 0xFF, + 0xB7, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, 0xF0, + 0x00, 0x83, 0x04, 0xA9, 0x09, 0x74, 0x0E, 0xA6, 0x10, 0x21, 0x0F, + 0xAD, 0x0A, 0x6A, 0x05, 0x73, 0x01, 0xA5, 0xFF, 0x7B, 0xFF, 0xD7, + 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC9, 0xFF, 0x72, 0xFF, 0xCD, 0xFF, + 0xF4, 0x01, 0x3B, 0x06, 0x85, 0x0B, 0x9F, 0x0F, 0x89, 0x10, 0xCC, + 0x0D, 0xC8, 0x08, 0xC9, 0x03, 0x91, 0x00, 0x75, 0xFF, 0x9A, 0xFF, + 0xEF, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x50, 0x00, 0x3F, + 0x03, 0x16, 0x08, 0x3B, 0x0D, 0x60, 0x10, 0xF3, 0x0F, 0x2B, 0x0C, + 0xE5, 0x06, 0x65, 0x02, 0xF6, 0xFF, 0x6D, 0xFF, 0xBD, 0xFF, 0xFC, + 0xFF, 0xE1, 0xFF, 0x85, 0xFF, 0x8E, 0xFF, 0x18, 0x01, 0xCB, 0x04, + 0xFD, 0x09, 0xAF, 0x0E, 0xAA, 0x10, 0xED, 0x0E, 0x5A, 0x0A, 0x1E, + 0x05, 0x46, 0x01, 0x9A, 0xFF, 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, + 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, 0xFF, 0xDF, 0xFF, 0x28, 0x02, 0x8B, + 0x06, 0xD5, 0x0B, 0xC9, 0x0F, 0x78, 0x10, 0x88, 0x0D, 0x73, 0x08, + 0x86, 0x03, 0x71, 0x00, 0x71, 0xFF, 0xA0, 0xFF, 0xF2, 0xFF, 0xF2, + 0xFF, 0xA1, 0xFF, 0x71, 0xFF, 0x6E, 0x00, 0x7F, 0x03, 0x6A, 0x08, + 0x81, 0x0D, 0x76, 0x10, 0xCD, 0x0F, 0xDD, 0x0B, 0x94, 0x06, 0x2E, + 0x02, 0xE1, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, + 0xDC, 0xFF, 0x80, 0xFF, 0x98, 0xFF, 0x42, 0x01, 0x16, 0x05, 0x50, + 0x0A, 0xE7, 0x0E, 0xAA, 0x10, 0xB5, 0x0E, 0x06, 0x0A, 0xD3, 0x04, + 0x1C, 0x01, 0x8F, 0xFF, 0x85, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, 0xBE, + 0xFF, 0x6D, 0xFF, 0xF3, 0xFF, 0x5E, 0x02, 0xDC, 0x06, 0x23, 0x0C, + 0xEF, 0x0F, 0x63, 0x10, 0x43, 0x0D, 0x1F, 0x08, 0x46, 0x03, 0x53, + 0x00, 0x6E, 0xFF, 0xA6, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, 0xFF, + 0x75, 0xFF, 0x8D, 0x00, 0xC1, 0x03, 0xBE, 0x08, 0xC4, 0x0D, 0x88, + 0x10, 0xA4, 0x0F, 0x8E, 0x0B, 0x43, 0x06, 0xF9, 0x01, 0xCF, 0xFF, + 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, 0x7C, + 0xFF, 0xA4, 0xFF, 0x6E, 0x01, 0x61, 0x05, 0xA3, 0x0A, 0x1C, 0x0F, + 0xA7, 0x10, 0x7B, 0x0E, 0xB2, 0x09, 0x8B, 0x04, 0xF4, 0x00, 0x86, + 0xFF, 0x8A, 0xFF, 0xE4, 0xFF, 0xFA, 0xFF, 0xB8, 0xFF, 0x6C, 0xFF, + 0x09, 0x00, 0x97, 0x02, 0x2E, 0x07, 0x6F, 0x0C, 0x11, 0x10, 0x4A, + 0x10, 0xFB, 0x0C, 0xCB, 0x07, 0x07, 0x03, 0x38, 0x00, 0x6D, 0xFF, + 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, 0xAF, + 0x00, 0x05, 0x04, 0x13, 0x09, 0x06, 0x0E, 0x96, 0x10, 0x78, 0x0F, + 0x3E, 0x0B, 0xF4, 0x05, 0xC7, 0x01, 0xBF, 0xFF, 0x74, 0xFF, 0xCE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x78, 0xFF, 0xB1, 0xFF, + 0x9C, 0x01, 0xAE, 0x05, 0xF6, 0x0A, 0x4E, 0x0F, 0x9F, 0x10, 0x3E, + 0x0E, 0x5E, 0x09, 0x43, 0x04, 0xCF, 0x00, 0x7F, 0xFF, 0x90, 0xFF, + 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x21, 0x00, 0xD2, + 0x02, 0x81, 0x07, 0xBA, 0x0C, 0x31, 0x10, 0x2E, 0x10, 0xB2, 0x0C, + 0x78, 0x07, 0xCB, 0x02, 0x1E, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, 0xF9, + 0xFF, 0xE8, 0xFF, 0x8F, 0xFF, 0x80, 0xFF, 0xD3, 0x00, 0x4B, 0x04, + 0x67, 0x09, 0x45, 0x0E, 0xA0, 0x10, 0x48, 0x0F, 0xEC, 0x0A, 0xA6, + 0x05, 0x97, 0x01, 0xB0, 0xFF, 0x78, 0xFF, 0xD3, 0xFF, 0x00, 0x00, + 0xFF, 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC0, 0xFF, 0xCC, 0x01, 0xFD, + 0x05, 0x47, 0x0B, 0x7D, 0x0F, 0x94, 0x10, 0xFF, 0x0D, 0x0A, 0x09, + 0xFE, 0x03, 0xAB, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, 0xF7, + 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x3B, 0x00, 0x0E, 0x03, 0xD5, 0x07, + 0x03, 0x0D, 0x4D, 0x10, 0x0E, 0x10, 0x67, 0x0C, 0x25, 0x07, 0x91, + 0x02, 0x07, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, + 0x89, 0xFF, 0x87, 0xFF, 0xF9, 0x00, 0x93, 0x04, 0xBC, 0x09, 0x82, + 0x0E, 0xA7, 0x10, 0x16, 0x0F, 0x9A, 0x0A, 0x59, 0x05, 0x69, 0x01, + 0xA3, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC8, + 0xFF, 0x71, 0xFF, 0xD1, 0xFF, 0xFF, 0x01, 0x4C, 0x06, 0x97, 0x0B, + 0xA9, 0x0F, 0x86, 0x10, 0xBD, 0x0D, 0xB5, 0x08, 0xBA, 0x03, 0x8A, + 0x00, 0x74, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, + 0x6F, 0xFF, 0x57, 0x00, 0x4D, 0x03, 0x29, 0x08, 0x4B, 0x0D, 0x65, + 0x10, 0xEB, 0x0F, 0x1A, 0x0C, 0xD3, 0x06, 0x58, 0x02, 0xF1, 0xFF, + 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x84, 0xFF, 0x90, + 0xFF, 0x21, 0x01, 0xDC, 0x04, 0x10, 0x0A, 0xBB, 0x0E, 0xAA, 0x10, + 0xE1, 0x0E, 0x47, 0x0A, 0x0D, 0x05, 0x3D, 0x01, 0x97, 0xFF, 0x81, + 0xFF, 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC2, 0xFF, 0x6F, 0xFF, + 0xE4, 0xFF, 0x34, 0x02, 0x9D, 0x06, 0xE6, 0x0B, 0xD1, 0x0F, 0x73, + 0x10, 0x79, 0x0D, 0x61, 0x08, 0x78, 0x03, 0x6A, 0x00, 0x70, 0xFF, + 0xA1, 0xFF, 0xF2, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x74, + 0x00, 0x8E, 0x03, 0x7D, 0x08, 0x90, 0x0D, 0x7A, 0x10, 0xC4, 0x0F, + 0xCC, 0x0B, 0x82, 0x06, 0x22, 0x02, 0xDD, 0xFF, 0x6F, 0xFF, 0xC4, + 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9B, 0xFF, + 0x4B, 0x01, 0x26, 0x05, 0x63, 0x0A, 0xF3, 0x0E, 0xAA, 0x10, 0xA8, + 0x0E, 0xF4, 0x09, 0xC3, 0x04, 0x13, 0x01, 0x8D, 0xFF, 0x86, 0xFF, + 0xE1, 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xF8, 0xFF, 0x6B, + 0x02, 0xEE, 0x06, 0x34, 0x0C, 0xF7, 0x0F, 0x5D, 0x10, 0x33, 0x0D, + 0x0D, 0x08, 0x38, 0x03, 0x4D, 0x00, 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, + 0xFF, 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x94, 0x00, 0xD0, 0x03, + 0xD1, 0x08, 0xD3, 0x0D, 0x8B, 0x10, 0x9A, 0x0F, 0x7C, 0x0B, 0x32, + 0x06, 0xEE, 0x01, 0xCB, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, + 0x00, 0x00, 0xD6, 0xFF, 0x7B, 0xFF, 0xA7, 0xFF, 0x78, 0x01, 0x72, + 0x05, 0xB6, 0x0A, 0x27, 0x0F, 0xA5, 0x10, 0x6E, 0x0E, 0xA0, 0x09, + 0x7B, 0x04, 0xEC, 0x00, 0x85, 0xFF, 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, + 0xFF, 0xB6, 0xFF, 0x6C, 0xFF, 0x0E, 0x00, 0xA4, 0x02, 0x41, 0x07, + 0x80, 0x0C, 0x19, 0x10, 0x44, 0x10, 0xEB, 0x0C, 0xB9, 0x07, 0xFA, + 0x02, 0x32, 0x00, 0x6D, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, + 0x93, 0xFF, 0x7B, 0xFF, 0xB7, 0x00, 0x15, 0x04, 0x26, 0x09, 0x14, + 0x0E, 0x98, 0x10, 0x6D, 0x0F, 0x2C, 0x0B, 0xE3, 0x05, 0xBC, 0x01, + 0xBB, 0xFF, 0x75, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, + 0xFF, 0x77, 0xFF, 0xB5, 0xFF, 0xA6, 0x01, 0xC0, 0x05, 0x08, 0x0B, + 0x58, 0x0F, 0x9D, 0x10, 0x30, 0x0E, 0x4B, 0x09, 0x34, 0x04, 0xC6, + 0x00, 0x7D, 0xFF, 0x91, 0xFF, 0xE9, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, + 0x6C, 0xFF, 0x27, 0x00, 0xDF, 0x02, 0x94, 0x07, 0xCA, 0x0C, 0x37, + 0x10, 0x27, 0x10, 0xA1, 0x0C, 0x65, 0x07, 0xBE, 0x02, 0x19, 0x00, + 0x6C, 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8E, 0xFF, 0x81, + 0xFF, 0xDB, 0x00, 0x5B, 0x04, 0x7A, 0x09, 0x53, 0x0E, 0xA2, 0x10, + 0x3D, 0x0F, 0xDA, 0x0A, 0x95, 0x05, 0x8C, 0x01, 0xAD, 0xFF, 0x79, + 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCC, 0xFF, 0x73, 0xFF, + 0xC4, 0xFF, 0xD7, 0x01, 0x0E, 0x06, 0x59, 0x0B, 0x87, 0x0F, 0x91, + 0x10, 0xF0, 0x0D, 0xF7, 0x08, 0xEF, 0x03, 0xA3, 0x00, 0x78, 0xFF, + 0x97, 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xAA, 0xFF, 0x6D, 0xFF, 0x41, + 0x00, 0x1C, 0x03, 0xE7, 0x07, 0x13, 0x0D, 0x52, 0x10, 0x06, 0x10, + 0x56, 0x0C, 0x13, 0x07, 0x84, 0x02, 0x02, 0x00, 0x6D, 0xFF, 0xBA, + 0xFF, 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x89, 0xFF, 0x01, 0x01, + 0xA3, 0x04, 0xCE, 0x09, 0x8F, 0x0E, 0xA8, 0x10, 0x0A, 0x0F, 0x88, + 0x0A, 0x48, 0x05, 0x5F, 0x01, 0xA0, 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, + 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, 0x70, 0xFF, 0xD5, 0xFF, 0x0B, + 0x02, 0x5E, 0x06, 0xA9, 0x0B, 0xB2, 0x0F, 0x82, 0x10, 0xAE, 0x0D, + 0xA2, 0x08, 0xAB, 0x03, 0x82, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, + 0xFF, 0xF3, 0xFF, 0xA4, 0xFF, 0x6F, 0xFF, 0x5D, 0x00, 0x5B, 0x03, + 0x3B, 0x08, 0x5A, 0x0D, 0x6A, 0x10, 0xE2, 0x0F, 0x09, 0x0C, 0xC1, + 0x06, 0x4C, 0x02, 0xEC, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFC, 0xFF, + 0xDF, 0xFF, 0x83, 0xFF, 0x93, 0xFF, 0x2A, 0x01, 0xEC, 0x04, 0x22, + 0x0A, 0xC8, 0x0E, 0xAB, 0x10, 0xD4, 0x0E, 0x35, 0x0A, 0xFD, 0x04, + 0x33, 0x01, 0x95, 0xFF, 0x82, 0xFF, 0xDE, 0xFF, 0x00, 0x00, 0xFD, + 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE8, 0xFF, 0x40, 0x02, 0xAF, 0x06, + 0xF7, 0x0B, 0xDA, 0x0F, 0x6F, 0x10, 0x6A, 0x0D, 0x4E, 0x08, 0x6A, + 0x03, 0x64, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, + 0x9E, 0xFF, 0x72, 0xFF, 0x7B, 0x00, 0x9C, 0x03, 0x90, 0x08, 0x9F, + 0x0D, 0x7E, 0x10, 0xBB, 0x0F, 0xBA, 0x0B, 0x70, 0x06, 0x16, 0x02, + 0xD9, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, + 0xFF, 0x7E, 0xFF, 0x9D, 0xFF, 0x55, 0x01, 0x37, 0x05, 0x75, 0x0A, + 0xFF, 0x0E, 0xA9, 0x10, 0x9C, 0x0E, 0xE1, 0x09, 0xB3, 0x04, 0x0A, + 0x01, 0x8B, 0xFF, 0x87, 0xFF, 0xE2, 0xFF, 0xFB, 0xFF, 0xBB, 0xFF, + 0x6D, 0xFF, 0xFD, 0xFF, 0x77, 0x02, 0x01, 0x07, 0x45, 0x0C, 0xFF, + 0x0F, 0x58, 0x10, 0x23, 0x0D, 0xFA, 0x07, 0x2A, 0x03, 0x47, 0x00, + 0x6E, 0xFF, 0xA9, 0xFF, 0xF5, 0xFF, 0xED, 0xFF, 0x98, 0xFF, 0x77, + 0xFF, 0x9C, 0x00, 0xDF, 0x03, 0xE4, 0x08, 0xE2, 0x0D, 0x8E, 0x10, + 0x91, 0x0F, 0x6B, 0x0B, 0x20, 0x06, 0xE3, 0x01, 0xC8, 0xFF, 0x73, + 0xFF, 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x7A, 0xFF, + 0xAA, 0xFF, 0x82, 0x01, 0x83, 0x05, 0xC8, 0x0A, 0x32, 0x0F, 0xA4, + 0x10, 0x60, 0x0E, 0x8D, 0x09, 0x6B, 0x04, 0xE3, 0x00, 0x83, 0xFF, + 0x8D, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, 0xB5, 0xFF, 0x6C, 0xFF, 0x14, + 0x00, 0xB1, 0x02, 0x53, 0x07, 0x91, 0x0C, 0x20, 0x10, 0x3E, 0x10, + 0xDB, 0x0C, 0xA6, 0x07, 0xEC, 0x02, 0x2C, 0x00, 0x6C, 0xFF, 0xAF, + 0xFF, 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7C, 0xFF, 0xBE, 0x00, + 0x24, 0x04, 0x38, 0x09, 0x22, 0x0E, 0x9B, 0x10, 0x63, 0x0F, 0x1A, + 0x0B, 0xD1, 0x05, 0xB1, 0x01, 0xB8, 0xFF, 0x76, 0xFF, 0xD0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB8, 0xFF, 0xB1, + 0x01, 0xD1, 0x05, 0x1A, 0x0B, 0x63, 0x0F, 0x9B, 0x10, 0x22, 0x0E, + 0x38, 0x09, 0x24, 0x04, 0xBE, 0x00, 0x7C, 0xFF, 0x92, 0xFF, 0xEA, + 0xFF, 0xF8, 0xFF, 0xAF, 0xFF, 0x6C, 0xFF, 0x2C, 0x00, 0xEC, 0x02, + 0xA6, 0x07, 0xDB, 0x0C, 0x3E, 0x10, 0x20, 0x10, 0x91, 0x0C, 0x53, + 0x07, 0xB1, 0x02, 0x14, 0x00, 0x6C, 0xFF, 0xB5, 0xFF, 0xFA, 0xFF, + 0xE6, 0xFF, 0x8D, 0xFF, 0x83, 0xFF, 0xE3, 0x00, 0x6B, 0x04, 0x8D, + 0x09, 0x60, 0x0E, 0xA4, 0x10, 0x32, 0x0F, 0xC8, 0x0A, 0x83, 0x05, + 0x82, 0x01, 0xAA, 0xFF, 0x7A, 0xFF, 0xD5, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC8, 0xFF, 0xE3, 0x01, 0x20, 0x06, + 0x6B, 0x0B, 0x91, 0x0F, 0x8E, 0x10, 0xE2, 0x0D, 0xE4, 0x08, 0xDF, + 0x03, 0x9C, 0x00, 0x77, 0xFF, 0x98, 0xFF, 0xED, 0xFF, 0xF5, 0xFF, + 0xA9, 0xFF, 0x6E, 0xFF, 0x47, 0x00, 0x2A, 0x03, 0xFA, 0x07, 0x23, + 0x0D, 0x58, 0x10, 0xFF, 0x0F, 0x45, 0x0C, 0x01, 0x07, 0x77, 0x02, + 0xFD, 0xFF, 0x6D, 0xFF, 0xBB, 0xFF, 0xFB, 0xFF, 0xE2, 0xFF, 0x87, + 0xFF, 0x8B, 0xFF, 0x0A, 0x01, 0xB3, 0x04, 0xE1, 0x09, 0x9C, 0x0E, + 0xA9, 0x10, 0xFF, 0x0E, 0x75, 0x0A, 0x37, 0x05, 0x55, 0x01, 0x9D, + 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, + 0x70, 0xFF, 0xD9, 0xFF, 0x16, 0x02, 0x70, 0x06, 0xBA, 0x0B, 0xBB, + 0x0F, 0x7E, 0x10, 0x9F, 0x0D, 0x90, 0x08, 0x9C, 0x03, 0x7B, 0x00, + 0x72, 0xFF, 0x9E, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA3, 0xFF, 0x70, + 0xFF, 0x64, 0x00, 0x6A, 0x03, 0x4E, 0x08, 0x6A, 0x0D, 0x6F, 0x10, + 0xDA, 0x0F, 0xF7, 0x0B, 0xAF, 0x06, 0x40, 0x02, 0xE8, 0xFF, 0x6E, + 0xFF, 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDE, 0xFF, 0x82, 0xFF, + 0x95, 0xFF, 0x33, 0x01, 0xFD, 0x04, 0x35, 0x0A, 0xD4, 0x0E, 0xAB, + 0x10, 0xC8, 0x0E, 0x22, 0x0A, 0xEC, 0x04, 0x2A, 0x01, 0x93, 0xFF, + 0x83, 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xC0, 0xFF, 0x6E, 0xFF, 0xEC, + 0xFF, 0x4C, 0x02, 0xC1, 0x06, 0x09, 0x0C, 0xE2, 0x0F, 0x6A, 0x10, + 0x5A, 0x0D, 0x3B, 0x08, 0x5B, 0x03, 0x5D, 0x00, 0x6F, 0xFF, 0xA4, + 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, 0xFF, 0x73, 0xFF, 0x82, 0x00, + 0xAB, 0x03, 0xA2, 0x08, 0xAE, 0x0D, 0x82, 0x10, 0xB2, 0x0F, 0xA9, + 0x0B, 0x5E, 0x06, 0x0B, 0x02, 0xD5, 0xFF, 0x70, 0xFF, 0xC7, 0xFF, + 0xFE, 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA0, 0xFF, 0x5F, + 0x01, 0x48, 0x05, 0x88, 0x0A, 0x0A, 0x0F, 0xA8, 0x10, 0x8F, 0x0E, + 0xCE, 0x09, 0xA3, 0x04, 0x01, 0x01, 0x89, 0xFF, 0x88, 0xFF, 0xE3, + 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, 0xFF, 0x02, 0x00, 0x84, 0x02, + 0x13, 0x07, 0x56, 0x0C, 0x06, 0x10, 0x52, 0x10, 0x13, 0x0D, 0xE7, + 0x07, 0x1C, 0x03, 0x41, 0x00, 0x6D, 0xFF, 0xAA, 0xFF, 0xF6, 0xFF, + 0xED, 0xFF, 0x97, 0xFF, 0x78, 0xFF, 0xA3, 0x00, 0xEF, 0x03, 0xF7, + 0x08, 0xF0, 0x0D, 0x91, 0x10, 0x87, 0x0F, 0x59, 0x0B, 0x0E, 0x06, + 0xD7, 0x01, 0xC4, 0xFF, 0x73, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0xD4, 0xFF, 0x79, 0xFF, 0xAD, 0xFF, 0x8C, 0x01, 0x95, 0x05, + 0xDA, 0x0A, 0x3D, 0x0F, 0xA2, 0x10, 0x53, 0x0E, 0x7A, 0x09, 0x5B, + 0x04, 0xDB, 0x00, 0x81, 0xFF, 0x8E, 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, + 0xB4, 0xFF, 0x6C, 0xFF, 0x19, 0x00, 0xBE, 0x02, 0x65, 0x07, 0xA1, + 0x0C, 0x27, 0x10, 0x37, 0x10, 0xCA, 0x0C, 0x94, 0x07, 0xDF, 0x02, + 0x27, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x91, + 0xFF, 0x7D, 0xFF, 0xC6, 0x00, 0x34, 0x04, 0x4B, 0x09, 0x30, 0x0E, + 0x9D, 0x10, 0x58, 0x0F, 0x08, 0x0B, 0xC0, 0x05, 0xA6, 0x01, 0xB5, + 0xFF, 0x77, 0xFF, 0xD1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, + 0x75, 0xFF, 0xBB, 0xFF, 0xBC, 0x01, 0xE3, 0x05, 0x2C, 0x0B, 0x6D, + 0x0F, 0x98, 0x10, 0x14, 0x0E, 0x26, 0x09, 0x15, 0x04, 0xB7, 0x00, + 0x7B, 0xFF, 0x93, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAE, 0xFF, 0x6D, + 0xFF, 0x32, 0x00, 0xFA, 0x02, 0xB9, 0x07, 0xEB, 0x0C, 0x44, 0x10, + 0x19, 0x10, 0x80, 0x0C, 0x41, 0x07, 0xA4, 0x02, 0x0E, 0x00, 0x6C, + 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, + 0xEC, 0x00, 0x7B, 0x04, 0xA0, 0x09, 0x6E, 0x0E, 0xA5, 0x10, 0x27, + 0x0F, 0xB6, 0x0A, 0x72, 0x05, 0x78, 0x01, 0xA7, 0xFF, 0x7B, 0xFF, + 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xCA, 0xFF, 0x72, 0xFF, 0xCB, + 0xFF, 0xEE, 0x01, 0x32, 0x06, 0x7C, 0x0B, 0x9A, 0x0F, 0x8B, 0x10, + 0xD3, 0x0D, 0xD1, 0x08, 0xD0, 0x03, 0x94, 0x00, 0x76, 0xFF, 0x99, + 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x4D, 0x00, + 0x38, 0x03, 0x0D, 0x08, 0x33, 0x0D, 0x5D, 0x10, 0xF7, 0x0F, 0x34, + 0x0C, 0xEE, 0x06, 0x6B, 0x02, 0xF8, 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, + 0xFC, 0xFF, 0xE1, 0xFF, 0x86, 0xFF, 0x8D, 0xFF, 0x13, 0x01, 0xC3, + 0x04, 0xF4, 0x09, 0xA8, 0x0E, 0xAA, 0x10, 0xF3, 0x0E, 0x63, 0x0A, + 0x26, 0x05, 0x4B, 0x01, 0x9B, 0xFF, 0x7F, 0xFF, 0xDB, 0xFF, 0x00, + 0x00, 0xFD, 0xFF, 0xC4, 0xFF, 0x6F, 0xFF, 0xDD, 0xFF, 0x22, 0x02, + 0x82, 0x06, 0xCC, 0x0B, 0xC4, 0x0F, 0x7A, 0x10, 0x90, 0x0D, 0x7D, + 0x08, 0x8E, 0x03, 0x74, 0x00, 0x72, 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, + 0xF2, 0xFF, 0xA1, 0xFF, 0x70, 0xFF, 0x6A, 0x00, 0x78, 0x03, 0x61, + 0x08, 0x79, 0x0D, 0x73, 0x10, 0xD1, 0x0F, 0xE6, 0x0B, 0x9D, 0x06, + 0x34, 0x02, 0xE4, 0xFF, 0x6F, 0xFF, 0xC2, 0xFF, 0xFD, 0xFF, 0x00, + 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x97, 0xFF, 0x3D, 0x01, 0x0D, 0x05, + 0x47, 0x0A, 0xE1, 0x0E, 0xAA, 0x10, 0xBB, 0x0E, 0x10, 0x0A, 0xDC, + 0x04, 0x21, 0x01, 0x90, 0xFF, 0x84, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, + 0xBE, 0xFF, 0x6D, 0xFF, 0xF1, 0xFF, 0x58, 0x02, 0xD3, 0x06, 0x1A, + 0x0C, 0xEB, 0x0F, 0x65, 0x10, 0x4B, 0x0D, 0x29, 0x08, 0x4D, 0x03, + 0x57, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, + 0xFF, 0x74, 0xFF, 0x8A, 0x00, 0xBA, 0x03, 0xB5, 0x08, 0xBD, 0x0D, + 0x86, 0x10, 0xA9, 0x0F, 0x97, 0x0B, 0x4C, 0x06, 0xFF, 0x01, 0xD1, + 0xFF, 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, + 0x7C, 0xFF, 0xA3, 0xFF, 0x69, 0x01, 0x59, 0x05, 0x9A, 0x0A, 0x16, + 0x0F, 0xA7, 0x10, 0x82, 0x0E, 0xBC, 0x09, 0x93, 0x04, 0xF9, 0x00, + 0x87, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, 0xFB, 0xFF, 0xB8, 0xFF, 0x6C, + 0xFF, 0x07, 0x00, 0x91, 0x02, 0x25, 0x07, 0x67, 0x0C, 0x0E, 0x10, + 0x4D, 0x10, 0x03, 0x0D, 0xD5, 0x07, 0x0E, 0x03, 0x3B, 0x00, 0x6D, + 0xFF, 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, + 0xAB, 0x00, 0xFE, 0x03, 0x0A, 0x09, 0xFF, 0x0D, 0x94, 0x10, 0x7D, + 0x0F, 0x47, 0x0B, 0xFD, 0x05, 0xCC, 0x01, 0xC0, 0xFF, 0x74, 0xFF, + 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD3, 0xFF, 0x78, 0xFF, 0xB0, + 0xFF, 0x97, 0x01, 0xA6, 0x05, 0xEC, 0x0A, 0x48, 0x0F, 0xA0, 0x10, + 0x45, 0x0E, 0x67, 0x09, 0x4B, 0x04, 0xD3, 0x00, 0x80, 0xFF, 0x8F, + 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x1E, 0x00, + 0xCB, 0x02, 0x78, 0x07, 0xB2, 0x0C, 0x2E, 0x10, 0x31, 0x10, 0xBA, + 0x0C, 0x81, 0x07, 0xD2, 0x02, 0x21, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, + 0xF9, 0xFF, 0xE8, 0xFF, 0x90, 0xFF, 0x7F, 0xFF, 0xCF, 0x00, 0x43, + 0x04, 0x5E, 0x09, 0x3E, 0x0E, 0x9F, 0x10, 0x4E, 0x0F, 0xF6, 0x0A, + 0xAE, 0x05, 0x9C, 0x01, 0xB1, 0xFF, 0x78, 0xFF, 0xD2, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x74, 0xFF, 0xBF, 0xFF, 0xC7, 0x01, + 0xF4, 0x05, 0x3E, 0x0B, 0x78, 0x0F, 0x96, 0x10, 0x06, 0x0E, 0x13, + 0x09, 0x05, 0x04, 0xAF, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, + 0xF7, 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x38, 0x00, 0x07, 0x03, 0xCB, + 0x07, 0xFB, 0x0C, 0x4A, 0x10, 0x11, 0x10, 0x6F, 0x0C, 0x2E, 0x07, + 0x97, 0x02, 0x09, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFA, 0xFF, 0xE4, + 0xFF, 0x8A, 0xFF, 0x86, 0xFF, 0xF4, 0x00, 0x8B, 0x04, 0xB2, 0x09, + 0x7B, 0x0E, 0xA7, 0x10, 0x1C, 0x0F, 0xA3, 0x0A, 0x61, 0x05, 0x6E, + 0x01, 0xA4, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, + 0xC8, 0xFF, 0x71, 0xFF, 0xCF, 0xFF, 0xF9, 0x01, 0x43, 0x06, 0x8E, + 0x0B, 0xA4, 0x0F, 0x88, 0x10, 0xC4, 0x0D, 0xBE, 0x08, 0xC1, 0x03, + 0x8D, 0x00, 0x75, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA6, + 0xFF, 0x6E, 0xFF, 0x53, 0x00, 0x46, 0x03, 0x1F, 0x08, 0x43, 0x0D, + 0x63, 0x10, 0xEF, 0x0F, 0x23, 0x0C, 0xDC, 0x06, 0x5E, 0x02, 0xF3, + 0xFF, 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x85, 0xFF, + 0x8F, 0xFF, 0x1C, 0x01, 0xD3, 0x04, 0x06, 0x0A, 0xB5, 0x0E, 0xAA, + 0x10, 0xE7, 0x0E, 0x50, 0x0A, 0x16, 0x05, 0x42, 0x01, 0x98, 0xFF, + 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, + 0xFF, 0xE1, 0xFF, 0x2E, 0x02, 0x94, 0x06, 0xDD, 0x0B, 0xCD, 0x0F, + 0x76, 0x10, 0x81, 0x0D, 0x6A, 0x08, 0x7F, 0x03, 0x6E, 0x00, 0x71, + 0xFF, 0xA1, 0xFF, 0xF2, 0xFF, 0x00, 0x00, 0x15, 0x00, 0xD1, 0xFF, + 0x8B, 0xFE, 0xBC, 0xFD, 0xE1, 0x00, 0x84, 0x09, 0xB0, 0x13, 0x47, + 0x18, 0xB0, 0x13, 0x84, 0x09, 0xE1, 0x00, 0xBC, 0xFD, 0x8B, 0xFE, + 0xD1, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xDA, 0x00, 0x30, + 0x00, 0x5D, 0xFC, 0xB3, 0xFC, 0x35, 0x0A, 0xC2, 0x1C, 0x24, 0x20, + 0x48, 0x10, 0x5D, 0xFF, 0x74, 0xFB, 0x3A, 0xFF, 0xFB, 0x00, 0x42, + 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2C, 0x00, 0xF3, 0x00, 0xAD, 0xFF, + 0xC5, 0xFB, 0x11, 0xFE, 0xAF, 0x0D, 0xEF, 0x1E, 0x68, 0x1E, 0xBC, + 0x0C, 0xA7, 0xFD, 0xEA, 0xFB, 0xD3, 0xFF, 0xEE, 0x00, 0x24, 0x00, + 0xFA, 0xFF, 0xF7, 0xFF, 0x4C, 0x00, 0xFB, 0x00, 0x0C, 0xFF, 0x5F, + 0xFB, 0xE8, 0xFF, 0x3D, 0x11, 0x7E, 0x20, 0x13, 0x1C, 0x4C, 0x09, + 0x6A, 0xFC, 0x8C, 0xFC, 0x4E, 0x00, 0xD1, 0x00, 0x0E, 0x00, 0xFD, + 0xFF, 0xF7, 0xFF, 0x72, 0x00, 0xEC, 0x00, 0x55, 0xFE, 0x3D, 0xFB, + 0x37, 0x02, 0xBE, 0x14, 0x5D, 0x21, 0x40, 0x19, 0x18, 0x06, 0xA2, + 0xFB, 0x47, 0xFD, 0xA7, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xFF, 0x9B, 0x00, 0xC0, 0x00, 0x92, 0xFD, 0x73, + 0xFB, 0xF2, 0x04, 0x0E, 0x18, 0x81, 0x21, 0x0C, 0x16, 0x37, 0x03, + 0x47, 0xFB, 0x0B, 0xFE, 0xDF, 0x00, 0x82, 0x00, 0xF9, 0xFF, 0xFE, + 0xFF, 0x08, 0x00, 0xC3, 0x00, 0x74, 0x00, 0xD2, 0xFC, 0x10, 0xFC, + 0x08, 0x08, 0x0A, 0x1B, 0xE9, 0x20, 0x9A, 0x12, 0xBE, 0x00, 0x49, + 0xFB, 0xC8, 0xFE, 0xF9, 0x00, 0x5A, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, + 0x1B, 0x00, 0xE4, 0x00, 0x06, 0x00, 0x24, 0xFC, 0x1E, 0xFD, 0x65, + 0x0B, 0x94, 0x1D, 0x9D, 0x1F, 0x0D, 0x0F, 0xB8, 0xFE, 0x96, 0xFB, + 0x72, 0xFF, 0xF9, 0x00, 0x37, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x36, + 0x00, 0xF8, 0x00, 0x78, 0xFF, 0x9B, 0xFB, 0xA6, 0xFE, 0xE9, 0x0E, + 0x8D, 0x1F, 0xAA, 0x1D, 0x87, 0x0B, 0x2B, 0xFD, 0x1E, 0xFC, 0x02, + 0x00, 0xE5, 0x00, 0x1C, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x58, 0x00, + 0xF9, 0x00, 0xCF, 0xFE, 0x4A, 0xFB, 0xA7, 0x00, 0x77, 0x12, 0xE0, + 0x20, 0x26, 0x1B, 0x28, 0x08, 0x18, 0xFC, 0xCB, 0xFC, 0x71, 0x00, + 0xC5, 0x00, 0x08, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x80, 0x00, 0xE1, + 0x00, 0x13, 0xFE, 0x45, 0xFB, 0x1D, 0x03, 0xEB, 0x15, 0x7F, 0x21, + 0x2D, 0x18, 0x0E, 0x05, 0x77, 0xFB, 0x8B, 0xFD, 0xBE, 0x00, 0x9D, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA9, 0x00, + 0xAA, 0x00, 0x4F, 0xFD, 0x9D, 0xFB, 0xFA, 0x05, 0x22, 0x19, 0x62, + 0x21, 0xE0, 0x14, 0x50, 0x02, 0x3E, 0xFB, 0x4E, 0xFE, 0xEB, 0x00, + 0x73, 0x00, 0xF7, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xD0, 0x00, 0x52, + 0x00, 0x93, 0xFC, 0x60, 0xFC, 0x2C, 0x09, 0xFA, 0x1B, 0x8A, 0x20, + 0x60, 0x11, 0xFD, 0xFF, 0x5C, 0xFB, 0x06, 0xFF, 0xFB, 0x00, 0x4D, + 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x23, 0x00, 0xED, 0x00, 0xD9, 0xFF, + 0xEF, 0xFB, 0x98, 0xFD, 0x99, 0x0C, 0x54, 0x1E, 0x02, 0x1F, 0xD2, + 0x0D, 0x20, 0xFE, 0xC0, 0xFB, 0xA7, 0xFF, 0xF4, 0x00, 0x2D, 0x00, + 0xF9, 0xFF, 0xF8, 0xFF, 0x41, 0x00, 0xFB, 0x00, 0x41, 0xFF, 0x78, + 0xFB, 0x4A, 0xFF, 0x25, 0x10, 0x16, 0x20, 0xDA, 0x1C, 0x56, 0x0A, + 0xBE, 0xFC, 0x56, 0xFC, 0x2C, 0x00, 0xDB, 0x00, 0x14, 0x00, 0xFD, + 0xFF, 0xF7, 0xFF, 0x66, 0x00, 0xF4, 0x00, 0x8F, 0xFE, 0x3F, 0xFB, + 0x75, 0x01, 0xAE, 0x13, 0x2C, 0x21, 0x2A, 0x1A, 0x0D, 0x07, 0xD4, + 0xFB, 0x0C, 0xFD, 0x8F, 0x00, 0xB7, 0x00, 0x03, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0xFA, 0xFF, 0x8E, 0x00, 0xD1, 0x00, 0xCF, 0xFD, 0x58, + 0xFB, 0x10, 0x04, 0x10, 0x17, 0x8A, 0x21, 0x10, 0x17, 0x10, 0x04, + 0x58, 0xFB, 0xCF, 0xFD, 0xD1, 0x00, 0x8E, 0x00, 0xFA, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0xB7, 0x00, 0x8F, 0x00, 0x0C, 0xFD, 0xD4, 0xFB, + 0x0D, 0x07, 0x2A, 0x1A, 0x2C, 0x21, 0xAE, 0x13, 0x75, 0x01, 0x3F, + 0xFB, 0x8F, 0xFE, 0xF4, 0x00, 0x66, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, + 0x14, 0x00, 0xDB, 0x00, 0x2C, 0x00, 0x56, 0xFC, 0xBE, 0xFC, 0x56, + 0x0A, 0xDA, 0x1C, 0x16, 0x20, 0x25, 0x10, 0x4A, 0xFF, 0x78, 0xFB, + 0x41, 0xFF, 0xFB, 0x00, 0x41, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2D, + 0x00, 0xF4, 0x00, 0xA7, 0xFF, 0xC0, 0xFB, 0x20, 0xFE, 0xD2, 0x0D, + 0x02, 0x1F, 0x54, 0x1E, 0x99, 0x0C, 0x98, 0xFD, 0xEF, 0xFB, 0xD9, + 0xFF, 0xED, 0x00, 0x23, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4D, 0x00, + 0xFB, 0x00, 0x06, 0xFF, 0x5C, 0xFB, 0xFD, 0xFF, 0x60, 0x11, 0x8A, + 0x20, 0xFA, 0x1B, 0x2C, 0x09, 0x60, 0xFC, 0x93, 0xFC, 0x52, 0x00, + 0xD0, 0x00, 0x0D, 0x00, 0xFE, 0xFF, 0xF7, 0xFF, 0x73, 0x00, 0xEB, + 0x00, 0x4E, 0xFE, 0x3E, 0xFB, 0x50, 0x02, 0xE0, 0x14, 0x62, 0x21, + 0x22, 0x19, 0xFA, 0x05, 0x9D, 0xFB, 0x4F, 0xFD, 0xAA, 0x00, 0xA9, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x9D, 0x00, + 0xBE, 0x00, 0x8B, 0xFD, 0x77, 0xFB, 0x0E, 0x05, 0x2D, 0x18, 0x7F, + 0x21, 0xEB, 0x15, 0x1D, 0x03, 0x45, 0xFB, 0x13, 0xFE, 0xE1, 0x00, + 0x80, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x08, 0x00, 0xC5, 0x00, 0x71, + 0x00, 0xCB, 0xFC, 0x18, 0xFC, 0x28, 0x08, 0x26, 0x1B, 0xE0, 0x20, + 0x77, 0x12, 0xA7, 0x00, 0x4A, 0xFB, 0xCF, 0xFE, 0xF9, 0x00, 0x58, + 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1C, 0x00, 0xE5, 0x00, 0x02, 0x00, + 0x1E, 0xFC, 0x2B, 0xFD, 0x87, 0x0B, 0xAA, 0x1D, 0x8D, 0x1F, 0xE9, + 0x0E, 0xA6, 0xFE, 0x9B, 0xFB, 0x78, 0xFF, 0xF8, 0x00, 0x36, 0x00, + 0xF9, 0xFF, 0xF8, 0xFF, 0x37, 0x00, 0xF9, 0x00, 0x72, 0xFF, 0x96, + 0xFB, 0xB8, 0xFE, 0x0D, 0x0F, 0x9D, 0x1F, 0x94, 0x1D, 0x65, 0x0B, + 0x1E, 0xFD, 0x24, 0xFC, 0x06, 0x00, 0xE4, 0x00, 0x1B, 0x00, 0xFC, + 0xFF, 0xF7, 0xFF, 0x5A, 0x00, 0xF9, 0x00, 0xC8, 0xFE, 0x49, 0xFB, + 0xBE, 0x00, 0x9A, 0x12, 0xE9, 0x20, 0x0A, 0x1B, 0x08, 0x08, 0x10, + 0xFC, 0xD2, 0xFC, 0x74, 0x00, 0xC3, 0x00, 0x08, 0x00, 0xFE, 0xFF, + 0xF9, 0xFF, 0x82, 0x00, 0xDF, 0x00, 0x0B, 0xFE, 0x47, 0xFB, 0x37, + 0x03, 0x0C, 0x16, 0x81, 0x21, 0x0E, 0x18, 0xF2, 0x04, 0x73, 0xFB, + 0x92, 0xFD, 0xC0, 0x00, 0x9B, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xAB, 0x00, 0xA7, 0x00, 0x47, 0xFD, 0xA2, 0xFB, + 0x18, 0x06, 0x40, 0x19, 0x5D, 0x21, 0xBE, 0x14, 0x37, 0x02, 0x3D, + 0xFB, 0x55, 0xFE, 0xEC, 0x00, 0x72, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, + 0x0E, 0x00, 0xD1, 0x00, 0x4E, 0x00, 0x8C, 0xFC, 0x6A, 0xFC, 0x4C, + 0x09, 0x13, 0x1C, 0x7E, 0x20, 0x3D, 0x11, 0xE8, 0xFF, 0x5F, 0xFB, + 0x0C, 0xFF, 0xFB, 0x00, 0x4C, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x24, + 0x00, 0xEE, 0x00, 0xD3, 0xFF, 0xEA, 0xFB, 0xA7, 0xFD, 0xBC, 0x0C, + 0x68, 0x1E, 0xEF, 0x1E, 0xAF, 0x0D, 0x11, 0xFE, 0xC5, 0xFB, 0xAD, + 0xFF, 0xF3, 0x00, 0x2C, 0x00, 0xFA, 0xFF, 0xF8, 0xFF, 0x42, 0x00, + 0xFB, 0x00, 0x3A, 0xFF, 0x74, 0xFB, 0x5D, 0xFF, 0x48, 0x10, 0x24, + 0x20, 0xC2, 0x1C, 0x35, 0x0A, 0xB3, 0xFC, 0x5D, 0xFC, 0x30, 0x00, + 0xDA, 0x00, 0x13, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x67, 0x00, 0xF3, + 0x00, 0x88, 0xFE, 0x3E, 0xFB, 0x8C, 0x01, 0xD0, 0x13, 0x33, 0x21, + 0x0D, 0x1A, 0xEE, 0x06, 0xCD, 0xFB, 0x13, 0xFD, 0x92, 0x00, 0xB6, + 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFA, 0xFF, 0x90, 0x00, + 0xCF, 0x00, 0xC7, 0xFD, 0x5B, 0xFB, 0x2B, 0x04, 0x31, 0x17, 0x8A, + 0x21, 0xF0, 0x16, 0xF4, 0x03, 0x56, 0xFB, 0xD6, 0xFD, 0xD3, 0x00, + 0x8D, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0xB9, 0x00, 0x8C, + 0x00, 0x05, 0xFD, 0xDB, 0xFB, 0x2C, 0x07, 0x47, 0x1A, 0x25, 0x21, + 0x8B, 0x13, 0x5D, 0x01, 0x40, 0xFB, 0x97, 0xFE, 0xF5, 0x00, 0x64, + 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x15, 0x00, 0xDC, 0x00, 0x27, 0x00, + 0x50, 0xFC, 0xCA, 0xFC, 0x78, 0x0A, 0xF2, 0x1C, 0x07, 0x20, 0x02, + 0x10, 0x37, 0xFF, 0x7B, 0xFB, 0x47, 0xFF, 0xFB, 0x00, 0x40, 0x00, + 0xF8, 0xFF, 0xF9, 0xFF, 0x2E, 0x00, 0xF5, 0x00, 0xA2, 0xFF, 0xBB, + 0xFB, 0x31, 0xFE, 0xF5, 0x0D, 0x14, 0x1F, 0x3F, 0x1E, 0x77, 0x0C, + 0x8A, 0xFD, 0xF5, 0xFB, 0xDE, 0xFF, 0xEC, 0x00, 0x22, 0x00, 0xFB, + 0xFF, 0xF7, 0xFF, 0x4E, 0x00, 0xFB, 0x00, 0xFF, 0xFE, 0x59, 0xFB, + 0x11, 0x00, 0x83, 0x11, 0x96, 0x20, 0xE0, 0x1B, 0x0B, 0x09, 0x56, + 0xFC, 0x99, 0xFC, 0x56, 0x00, 0xCE, 0x00, 0x0D, 0x00, 0xFE, 0xFF, + 0xF8, 0xFF, 0x75, 0x00, 0xEA, 0x00, 0x47, 0xFE, 0x3E, 0xFB, 0x69, + 0x02, 0x02, 0x15, 0x66, 0x21, 0x04, 0x19, 0xDC, 0x05, 0x98, 0xFB, + 0x56, 0xFD, 0xAD, 0x00, 0xA8, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x9E, 0x00, 0xBC, 0x00, 0x83, 0xFD, 0x7B, 0xFB, + 0x2B, 0x05, 0x4C, 0x18, 0x7C, 0x21, 0xCA, 0x15, 0x03, 0x03, 0x44, + 0xFB, 0x1A, 0xFE, 0xE2, 0x00, 0x7E, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, + 0x09, 0x00, 0xC6, 0x00, 0x6D, 0x00, 0xC3, 0xFC, 0x20, 0xFC, 0x49, + 0x08, 0x41, 0x1B, 0xD6, 0x20, 0x54, 0x12, 0x92, 0x00, 0x4C, 0xFB, + 0xD6, 0xFE, 0xFA, 0x00, 0x57, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, + 0x00, 0xE6, 0x00, 0xFD, 0xFF, 0x18, 0xFC, 0x38, 0xFD, 0xA9, 0x0B, + 0xC0, 0x1D, 0x7C, 0x1F, 0xC6, 0x0E, 0x95, 0xFE, 0x9F, 0xFB, 0x7E, + 0xFF, 0xF8, 0x00, 0x35, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x38, 0x00, + 0xF9, 0x00, 0x6C, 0xFF, 0x92, 0xFB, 0xC9, 0xFE, 0x2F, 0x0F, 0xAD, + 0x1F, 0x7D, 0x1D, 0x42, 0x0B, 0x12, 0xFD, 0x2A, 0xFC, 0x0B, 0x00, + 0xE3, 0x00, 0x1A, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5B, 0x00, 0xF8, + 0x00, 0xC1, 0xFE, 0x47, 0xFB, 0xD4, 0x00, 0xBC, 0x12, 0xF3, 0x20, + 0xEF, 0x1A, 0xE9, 0x07, 0x08, 0xFC, 0xD9, 0xFC, 0x78, 0x00, 0xC2, + 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x83, 0x00, 0xDD, 0x00, + 0x04, 0xFE, 0x49, 0xFB, 0x52, 0x03, 0x2D, 0x16, 0x83, 0x21, 0xEF, + 0x17, 0xD5, 0x04, 0x6F, 0xFB, 0x9A, 0xFD, 0xC3, 0x00, 0x9A, 0x00, + 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xAD, 0x00, 0xA4, + 0x00, 0x40, 0xFD, 0xA8, 0xFB, 0x36, 0x06, 0x5E, 0x19, 0x58, 0x21, + 0x9C, 0x14, 0x1E, 0x02, 0x3D, 0xFB, 0x5D, 0xFE, 0xED, 0x00, 0x70, + 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, 0x00, 0xD2, 0x00, 0x4A, 0x00, + 0x85, 0xFC, 0x74, 0xFC, 0x6D, 0x09, 0x2D, 0x1C, 0x72, 0x20, 0x1A, + 0x11, 0xD4, 0xFF, 0x61, 0xFB, 0x13, 0xFF, 0xFC, 0x00, 0x4A, 0x00, + 0xF7, 0xFF, 0xFA, 0xFF, 0x25, 0x00, 0xEF, 0x00, 0xCE, 0xFF, 0xE4, + 0xFB, 0xB5, 0xFD, 0xDE, 0x0C, 0x7C, 0x1E, 0xDD, 0x1E, 0x8C, 0x0D, + 0x01, 0xFE, 0xCA, 0xFB, 0xB3, 0xFF, 0xF3, 0x00, 0x2B, 0x00, 0xFA, + 0xFF, 0xF8, 0xFF, 0x44, 0x00, 0xFB, 0x00, 0x34, 0xFF, 0x71, 0xFB, + 0x71, 0xFF, 0x6B, 0x10, 0x32, 0x20, 0xA9, 0x1C, 0x13, 0x0A, 0xA8, + 0xFC, 0x63, 0xFC, 0x35, 0x00, 0xD9, 0x00, 0x12, 0x00, 0xFD, 0xFF, + 0xF7, 0xFF, 0x69, 0x00, 0xF2, 0x00, 0x81, 0xFE, 0x3E, 0xFB, 0xA4, + 0x01, 0xF2, 0x13, 0x3A, 0x21, 0xF0, 0x19, 0xCF, 0x06, 0xC7, 0xFB, + 0x1B, 0xFD, 0x96, 0x00, 0xB4, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFB, 0xFF, 0x92, 0x00, 0xCD, 0x00, 0xC0, 0xFD, 0x5E, 0xFB, + 0x47, 0x04, 0x51, 0x17, 0x8A, 0x21, 0xD0, 0x16, 0xD9, 0x03, 0x53, + 0xFB, 0xDE, 0xFD, 0xD5, 0x00, 0x8B, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, + 0x04, 0x00, 0xBA, 0x00, 0x89, 0x00, 0xFD, 0xFC, 0xE2, 0xFB, 0x4B, + 0x07, 0x63, 0x1A, 0x1D, 0x21, 0x69, 0x13, 0x46, 0x01, 0x41, 0xFB, + 0x9E, 0xFE, 0xF5, 0x00, 0x63, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x16, + 0x00, 0xDD, 0x00, 0x23, 0x00, 0x49, 0xFC, 0xD5, 0xFC, 0x99, 0x0A, + 0x09, 0x1D, 0xF9, 0x1F, 0xDF, 0x0F, 0x24, 0xFF, 0x7F, 0xFB, 0x4D, + 0xFF, 0xFB, 0x00, 0x3F, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2F, 0x00, + 0xF5, 0x00, 0x9C, 0xFF, 0xB6, 0xFB, 0x41, 0xFE, 0x17, 0x0E, 0x26, + 0x1F, 0x2B, 0x1E, 0x54, 0x0C, 0x7C, 0xFD, 0xFA, 0xFB, 0xE3, 0xFF, + 0xEB, 0x00, 0x21, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x50, 0x00, 0xFB, + 0x00, 0xF8, 0xFE, 0x57, 0xFB, 0x26, 0x00, 0xA6, 0x11, 0xA1, 0x20, + 0xC6, 0x1B, 0xEA, 0x08, 0x4D, 0xFC, 0xA0, 0xFC, 0x5A, 0x00, 0xCD, + 0x00, 0x0C, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0xE9, 0x00, + 0x3F, 0xFE, 0x3F, 0xFB, 0x82, 0x02, 0x23, 0x15, 0x6B, 0x21, 0xE5, + 0x18, 0xBE, 0x05, 0x93, 0xFB, 0x5E, 0xFD, 0xAF, 0x00, 0xA6, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xA0, 0x00, 0xB9, + 0x00, 0x7C, 0xFD, 0x80, 0xFB, 0x48, 0x05, 0x6B, 0x18, 0x79, 0x21, + 0xA9, 0x15, 0xE9, 0x02, 0x43, 0xFB, 0x21, 0xFE, 0xE3, 0x00, 0x7D, + 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x09, 0x00, 0xC7, 0x00, 0x69, 0x00, + 0xBC, 0xFC, 0x29, 0xFC, 0x69, 0x08, 0x5C, 0x1B, 0xCC, 0x20, 0x32, + 0x12, 0x7C, 0x00, 0x4E, 0xFB, 0xDD, 0xFE, 0xFA, 0x00, 0x56, 0x00, + 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, 0x00, 0xE7, 0x00, 0xF8, 0xFF, 0x12, + 0xFC, 0x45, 0xFD, 0xCB, 0x0B, 0xD6, 0x1D, 0x6C, 0x1F, 0xA3, 0x0E, + 0x84, 0xFE, 0xA4, 0xFB, 0x84, 0xFF, 0xF7, 0x00, 0x34, 0x00, 0xF9, + 0xFF, 0xF8, 0xFF, 0x3A, 0x00, 0xFA, 0x00, 0x66, 0xFF, 0x8E, 0xFB, + 0xDB, 0xFE, 0x53, 0x0F, 0xBD, 0x1F, 0x66, 0x1D, 0x21, 0x0B, 0x05, + 0xFD, 0x30, 0xFC, 0x10, 0x00, 0xE2, 0x00, 0x19, 0x00, 0xFC, 0xFF, + 0xF7, 0xFF, 0x5D, 0x00, 0xF8, 0x00, 0xBA, 0xFE, 0x46, 0xFB, 0xEA, + 0x00, 0xDF, 0x12, 0xFC, 0x20, 0xD3, 0x1A, 0xC9, 0x07, 0x00, 0xFC, + 0xE0, 0xFC, 0x7B, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, + 0xFF, 0x85, 0x00, 0xDC, 0x00, 0xFC, 0xFD, 0x4A, 0xFB, 0x6C, 0x03, + 0x4E, 0x16, 0x85, 0x21, 0xCF, 0x17, 0xB8, 0x04, 0x6C, 0xFB, 0xA2, + 0xFD, 0xC5, 0x00, 0x98, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0x01, 0x00, 0xAE, 0x00, 0xA1, 0x00, 0x38, 0xFD, 0xAE, 0xFB, 0x54, + 0x06, 0x7C, 0x19, 0x53, 0x21, 0x7B, 0x14, 0x05, 0x02, 0x3D, 0xFB, + 0x64, 0xFE, 0xEE, 0x00, 0x6F, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, + 0x00, 0xD4, 0x00, 0x46, 0x00, 0x7E, 0xFC, 0x7E, 0xFC, 0x8E, 0x09, + 0x46, 0x1C, 0x66, 0x20, 0xF7, 0x10, 0xC0, 0xFF, 0x64, 0xFB, 0x1A, + 0xFF, 0xFC, 0x00, 0x49, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x26, 0x00, + 0xF0, 0x00, 0xC9, 0xFF, 0xDF, 0xFB, 0xC4, 0xFD, 0x01, 0x0D, 0x90, + 0x1E, 0xCA, 0x1E, 0x69, 0x0D, 0xF1, 0xFD, 0xCF, 0xFB, 0xB8, 0xFF, + 0xF2, 0x00, 0x29, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x45, 0x00, 0xFC, + 0x00, 0x2D, 0xFF, 0x6D, 0xFB, 0x84, 0xFF, 0x8E, 0x10, 0x3F, 0x20, + 0x91, 0x1C, 0xF2, 0x09, 0x9D, 0xFC, 0x6A, 0xFC, 0x39, 0x00, 0xD7, + 0x00, 0x12, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6A, 0x00, 0xF1, 0x00, + 0x7A, 0xFE, 0x3D, 0xFB, 0xBC, 0x01, 0x14, 0x14, 0x41, 0x21, 0xD4, + 0x19, 0xB0, 0x06, 0xC0, 0xFB, 0x22, 0xFD, 0x99, 0x00, 0xB3, 0x00, + 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x93, 0x00, 0xCB, + 0x00, 0xB8, 0xFD, 0x61, 0xFB, 0x63, 0x04, 0x71, 0x17, 0x89, 0x21, + 0xB0, 0x16, 0xBD, 0x03, 0x51, 0xFB, 0xE6, 0xFD, 0xD7, 0x00, 0x8A, + 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0xBC, 0x00, 0x86, 0x00, + 0xF6, 0xFC, 0xE9, 0xFB, 0x6A, 0x07, 0x80, 0x1A, 0x15, 0x21, 0x47, + 0x13, 0x2F, 0x01, 0x42, 0xFB, 0xA5, 0xFE, 0xF6, 0x00, 0x61, 0x00, + 0xF7, 0xFF, 0xFC, 0xFF, 0x16, 0x00, 0xDF, 0x00, 0x1E, 0x00, 0x43, + 0xFC, 0xE1, 0xFC, 0xBB, 0x0A, 0x21, 0x1D, 0xEA, 0x1F, 0xBC, 0x0F, + 0x12, 0xFF, 0x82, 0xFB, 0x54, 0xFF, 0xFA, 0x00, 0x3D, 0x00, 0xF8, + 0xFF, 0xF9, 0xFF, 0x30, 0x00, 0xF6, 0x00, 0x96, 0xFF, 0xB1, 0xFB, + 0x51, 0xFE, 0x3A, 0x0E, 0x38, 0x1F, 0x16, 0x1E, 0x32, 0x0C, 0x6E, + 0xFD, 0x00, 0xFC, 0xE8, 0xFF, 0xEA, 0x00, 0x20, 0x00, 0xFB, 0xFF, + 0xF7, 0xFF, 0x51, 0x00, 0xFB, 0x00, 0xF1, 0xFE, 0x54, 0xFB, 0x3B, + 0x00, 0xC9, 0x11, 0xAD, 0x20, 0xAC, 0x1B, 0xCA, 0x08, 0x44, 0xFC, + 0xA7, 0xFC, 0x5E, 0x00, 0xCC, 0x00, 0x0B, 0x00, 0xFE, 0xFF, 0xF8, + 0xFF, 0x78, 0x00, 0xE7, 0x00, 0x38, 0xFE, 0x40, 0xFB, 0x9B, 0x02, + 0x45, 0x15, 0x6F, 0x21, 0xC7, 0x18, 0xA1, 0x05, 0x8E, 0xFB, 0x65, + 0xFD, 0xB2, 0x00, 0xA5, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xA2, 0x00, 0xB7, 0x00, 0x74, 0xFD, 0x84, 0xFB, 0x66, + 0x05, 0x8A, 0x18, 0x76, 0x21, 0x87, 0x15, 0xCF, 0x02, 0x41, 0xFB, + 0x29, 0xFE, 0xE5, 0x00, 0x7B, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0A, + 0x00, 0xC9, 0x00, 0x66, 0x00, 0xB5, 0xFC, 0x32, 0xFC, 0x89, 0x08, + 0x77, 0x1B, 0xC2, 0x20, 0x0F, 0x12, 0x66, 0x00, 0x50, 0xFB, 0xE4, + 0xFE, 0xFA, 0x00, 0x54, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1E, 0x00, + 0xE8, 0x00, 0xF3, 0xFF, 0x0C, 0xFC, 0x53, 0xFD, 0xED, 0x0B, 0xEB, + 0x1D, 0x5A, 0x1F, 0x80, 0x0E, 0x73, 0xFE, 0xA8, 0xFB, 0x8A, 0xFF, + 0xF7, 0x00, 0x32, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3B, 0x00, 0xFA, + 0x00, 0x60, 0xFF, 0x8A, 0xFB, 0xED, 0xFE, 0x76, 0x0F, 0xCC, 0x1F, + 0x4F, 0x1D, 0xFF, 0x0A, 0xF9, 0xFC, 0x36, 0xFC, 0x15, 0x00, 0xE1, + 0x00, 0x18, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5E, 0x00, 0xF7, 0x00, + 0xB3, 0xFE, 0x44, 0xFB, 0x01, 0x01, 0x02, 0x13, 0x04, 0x21, 0xB8, + 0x1A, 0xA9, 0x07, 0xF8, 0xFB, 0xE7, 0xFC, 0x7F, 0x00, 0xBF, 0x00, + 0x06, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x86, 0x00, 0xDA, 0x00, 0xF5, + 0xFD, 0x4C, 0xFB, 0x87, 0x03, 0x6E, 0x16, 0x86, 0x21, 0xB0, 0x17, + 0x9C, 0x04, 0x68, 0xFB, 0xA9, 0xFD, 0xC7, 0x00, 0x96, 0x00, 0xFB, + 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xB0, 0x00, 0x9F, 0x00, + 0x31, 0xFD, 0xB4, 0xFB, 0x73, 0x06, 0x99, 0x19, 0x4D, 0x21, 0x59, + 0x14, 0xED, 0x01, 0x3D, 0xFB, 0x6B, 0xFE, 0xEF, 0x00, 0x6D, 0x00, + 0xF7, 0xFF, 0xFD, 0xFF, 0x10, 0x00, 0xD5, 0x00, 0x42, 0x00, 0x77, + 0xFC, 0x88, 0xFC, 0xAF, 0x09, 0x5F, 0x1C, 0x59, 0x20, 0xD4, 0x10, + 0xAC, 0xFF, 0x67, 0xFB, 0x20, 0xFF, 0xFC, 0x00, 0x48, 0x00, 0xF7, + 0xFF, 0xFA, 0xFF, 0x27, 0x00, 0xF0, 0x00, 0xC3, 0xFF, 0xD9, 0xFB, + 0xD3, 0xFD, 0x24, 0x0D, 0xA3, 0x1E, 0xB7, 0x1E, 0x46, 0x0D, 0xE2, + 0xFD, 0xD4, 0xFB, 0xBE, 0xFF, 0xF1, 0x00, 0x28, 0x00, 0xFA, 0xFF, + 0xF7, 0xFF, 0x46, 0x00, 0xFC, 0x00, 0x27, 0xFF, 0x6A, 0xFB, 0x98, + 0xFF, 0xB1, 0x10, 0x4C, 0x20, 0x78, 0x1C, 0xD1, 0x09, 0x93, 0xFC, + 0x71, 0xFC, 0x3D, 0x00, 0xD6, 0x00, 0x11, 0x00, 0xFD, 0xFF, 0xF7, + 0xFF, 0x6C, 0x00, 0xF0, 0x00, 0x72, 0xFE, 0x3D, 0xFB, 0xD4, 0x01, + 0x36, 0x14, 0x47, 0x21, 0xB6, 0x19, 0x91, 0x06, 0xBA, 0xFB, 0x29, + 0xFD, 0x9C, 0x00, 0xB1, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0xFB, 0xFF, 0x95, 0x00, 0xC9, 0x00, 0xB1, 0xFD, 0x65, 0xFB, 0x80, + 0x04, 0x90, 0x17, 0x88, 0x21, 0x8F, 0x16, 0xA2, 0x03, 0x4E, 0xFB, + 0xED, 0xFD, 0xD9, 0x00, 0x88, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x05, + 0x00, 0xBD, 0x00, 0x82, 0x00, 0xEF, 0xFC, 0xF0, 0xFB, 0x8A, 0x07, + 0x9C, 0x1A, 0x0D, 0x21, 0x24, 0x13, 0x18, 0x01, 0x43, 0xFB, 0xAC, + 0xFE, 0xF7, 0x00, 0x60, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x17, 0x00, + 0xE0, 0x00, 0x1A, 0x00, 0x3D, 0xFC, 0xED, 0xFC, 0xDD, 0x0A, 0x38, + 0x1D, 0xDB, 0x1F, 0x99, 0x0F, 0xFF, 0xFE, 0x86, 0xFB, 0x5A, 0xFF, + 0xFA, 0x00, 0x3C, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x31, 0x00, 0xF6, + 0x00, 0x90, 0xFF, 0xAD, 0xFB, 0x62, 0xFE, 0x5D, 0x0E, 0x49, 0x1F, + 0x01, 0x1E, 0x10, 0x0C, 0x60, 0xFD, 0x06, 0xFC, 0xEE, 0xFF, 0xE9, + 0x00, 0x1F, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x53, 0x00, 0xFB, 0x00, + 0xEB, 0xFE, 0x52, 0xFB, 0x51, 0x00, 0xEC, 0x11, 0xB7, 0x20, 0x91, + 0x1B, 0xA9, 0x08, 0x3B, 0xFC, 0xAE, 0xFC, 0x62, 0x00, 0xCA, 0x00, + 0x0B, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7A, 0x00, 0xE6, 0x00, 0x30, + 0xFE, 0x40, 0xFB, 0xB5, 0x02, 0x66, 0x15, 0x73, 0x21, 0xA9, 0x18, + 0x83, 0x05, 0x89, 0xFB, 0x6D, 0xFD, 0xB4, 0x00, 0xA3, 0x00, 0xFE, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xA3, 0x00, 0xB4, 0x00, + 0x6D, 0xFD, 0x89, 0xFB, 0x83, 0x05, 0xA9, 0x18, 0x73, 0x21, 0x66, + 0x15, 0xB5, 0x02, 0x40, 0xFB, 0x30, 0xFE, 0xE6, 0x00, 0x7A, 0x00, + 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, 0xCA, 0x00, 0x62, 0x00, 0xAE, + 0xFC, 0x3B, 0xFC, 0xA9, 0x08, 0x91, 0x1B, 0xB7, 0x20, 0xEC, 0x11, + 0x51, 0x00, 0x52, 0xFB, 0xEB, 0xFE, 0xFB, 0x00, 0x53, 0x00, 0xF7, + 0xFF, 0xFB, 0xFF, 0x1F, 0x00, 0xE9, 0x00, 0xEE, 0xFF, 0x06, 0xFC, + 0x60, 0xFD, 0x10, 0x0C, 0x01, 0x1E, 0x49, 0x1F, 0x5D, 0x0E, 0x62, + 0xFE, 0xAD, 0xFB, 0x90, 0xFF, 0xF6, 0x00, 0x31, 0x00, 0xF9, 0xFF, + 0xF8, 0xFF, 0x3C, 0x00, 0xFA, 0x00, 0x5A, 0xFF, 0x86, 0xFB, 0xFF, + 0xFE, 0x99, 0x0F, 0xDB, 0x1F, 0x38, 0x1D, 0xDD, 0x0A, 0xED, 0xFC, + 0x3D, 0xFC, 0x1A, 0x00, 0xE0, 0x00, 0x17, 0x00, 0xFC, 0xFF, 0xF7, + 0xFF, 0x60, 0x00, 0xF7, 0x00, 0xAC, 0xFE, 0x43, 0xFB, 0x18, 0x01, + 0x24, 0x13, 0x0D, 0x21, 0x9C, 0x1A, 0x8A, 0x07, 0xF0, 0xFB, 0xEF, + 0xFC, 0x82, 0x00, 0xBD, 0x00, 0x05, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, + 0x88, 0x00, 0xD9, 0x00, 0xED, 0xFD, 0x4E, 0xFB, 0xA2, 0x03, 0x8F, + 0x16, 0x88, 0x21, 0x90, 0x17, 0x80, 0x04, 0x65, 0xFB, 0xB1, 0xFD, + 0xC9, 0x00, 0x95, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, + 0x00, 0xB1, 0x00, 0x9C, 0x00, 0x29, 0xFD, 0xBA, 0xFB, 0x91, 0x06, + 0xB6, 0x19, 0x47, 0x21, 0x36, 0x14, 0xD4, 0x01, 0x3D, 0xFB, 0x72, + 0xFE, 0xF0, 0x00, 0x6C, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x11, 0x00, + 0xD6, 0x00, 0x3D, 0x00, 0x71, 0xFC, 0x93, 0xFC, 0xD1, 0x09, 0x78, + 0x1C, 0x4C, 0x20, 0xB1, 0x10, 0x98, 0xFF, 0x6A, 0xFB, 0x27, 0xFF, + 0xFC, 0x00, 0x46, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x28, 0x00, 0xF1, + 0x00, 0xBE, 0xFF, 0xD4, 0xFB, 0xE2, 0xFD, 0x46, 0x0D, 0xB7, 0x1E, + 0xA3, 0x1E, 0x24, 0x0D, 0xD3, 0xFD, 0xD9, 0xFB, 0xC3, 0xFF, 0xF0, + 0x00, 0x27, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x48, 0x00, 0xFC, 0x00, + 0x20, 0xFF, 0x67, 0xFB, 0xAC, 0xFF, 0xD4, 0x10, 0x59, 0x20, 0x5F, + 0x1C, 0xAF, 0x09, 0x88, 0xFC, 0x77, 0xFC, 0x42, 0x00, 0xD5, 0x00, + 0x10, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6D, 0x00, 0xEF, 0x00, 0x6B, + 0xFE, 0x3D, 0xFB, 0xED, 0x01, 0x59, 0x14, 0x4D, 0x21, 0x99, 0x19, + 0x73, 0x06, 0xB4, 0xFB, 0x31, 0xFD, 0x9F, 0x00, 0xB0, 0x00, 0x01, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x96, 0x00, 0xC7, 0x00, + 0xA9, 0xFD, 0x68, 0xFB, 0x9C, 0x04, 0xB0, 0x17, 0x86, 0x21, 0x6E, + 0x16, 0x87, 0x03, 0x4C, 0xFB, 0xF5, 0xFD, 0xDA, 0x00, 0x86, 0x00, + 0xF9, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0xBF, 0x00, 0x7F, 0x00, 0xE7, + 0xFC, 0xF8, 0xFB, 0xA9, 0x07, 0xB8, 0x1A, 0x04, 0x21, 0x02, 0x13, + 0x01, 0x01, 0x44, 0xFB, 0xB3, 0xFE, 0xF7, 0x00, 0x5E, 0x00, 0xF7, + 0xFF, 0xFC, 0xFF, 0x18, 0x00, 0xE1, 0x00, 0x15, 0x00, 0x36, 0xFC, + 0xF9, 0xFC, 0xFF, 0x0A, 0x4F, 0x1D, 0xCC, 0x1F, 0x76, 0x0F, 0xED, + 0xFE, 0x8A, 0xFB, 0x60, 0xFF, 0xFA, 0x00, 0x3B, 0x00, 0xF8, 0xFF, + 0xF9, 0xFF, 0x32, 0x00, 0xF7, 0x00, 0x8A, 0xFF, 0xA8, 0xFB, 0x73, + 0xFE, 0x80, 0x0E, 0x5A, 0x1F, 0xEB, 0x1D, 0xED, 0x0B, 0x53, 0xFD, + 0x0C, 0xFC, 0xF3, 0xFF, 0xE8, 0x00, 0x1E, 0x00, 0xFB, 0xFF, 0xF7, + 0xFF, 0x54, 0x00, 0xFA, 0x00, 0xE4, 0xFE, 0x50, 0xFB, 0x66, 0x00, + 0x0F, 0x12, 0xC2, 0x20, 0x77, 0x1B, 0x89, 0x08, 0x32, 0xFC, 0xB5, + 0xFC, 0x66, 0x00, 0xC9, 0x00, 0x0A, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, + 0x7B, 0x00, 0xE5, 0x00, 0x29, 0xFE, 0x41, 0xFB, 0xCF, 0x02, 0x87, + 0x15, 0x76, 0x21, 0x8A, 0x18, 0x66, 0x05, 0x84, 0xFB, 0x74, 0xFD, + 0xB7, 0x00, 0xA2, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, + 0xFF, 0xA5, 0x00, 0xB2, 0x00, 0x65, 0xFD, 0x8E, 0xFB, 0xA1, 0x05, + 0xC7, 0x18, 0x6F, 0x21, 0x45, 0x15, 0x9B, 0x02, 0x40, 0xFB, 0x38, + 0xFE, 0xE7, 0x00, 0x78, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, + 0xCC, 0x00, 0x5E, 0x00, 0xA7, 0xFC, 0x44, 0xFC, 0xCA, 0x08, 0xAC, + 0x1B, 0xAD, 0x20, 0xC9, 0x11, 0x3B, 0x00, 0x54, 0xFB, 0xF1, 0xFE, + 0xFB, 0x00, 0x51, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x20, 0x00, 0xEA, + 0x00, 0xE8, 0xFF, 0x00, 0xFC, 0x6E, 0xFD, 0x32, 0x0C, 0x16, 0x1E, + 0x38, 0x1F, 0x3A, 0x0E, 0x51, 0xFE, 0xB1, 0xFB, 0x96, 0xFF, 0xF6, + 0x00, 0x30, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3D, 0x00, 0xFA, 0x00, + 0x54, 0xFF, 0x82, 0xFB, 0x12, 0xFF, 0xBC, 0x0F, 0xEA, 0x1F, 0x21, + 0x1D, 0xBB, 0x0A, 0xE1, 0xFC, 0x43, 0xFC, 0x1E, 0x00, 0xDF, 0x00, + 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x61, 0x00, 0xF6, 0x00, 0xA5, + 0xFE, 0x42, 0xFB, 0x2F, 0x01, 0x47, 0x13, 0x15, 0x21, 0x80, 0x1A, + 0x6A, 0x07, 0xE9, 0xFB, 0xF6, 0xFC, 0x86, 0x00, 0xBC, 0x00, 0x05, + 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8A, 0x00, 0xD7, 0x00, 0xE6, 0xFD, + 0x51, 0xFB, 0xBD, 0x03, 0xB0, 0x16, 0x89, 0x21, 0x71, 0x17, 0x63, + 0x04, 0x61, 0xFB, 0xB8, 0xFD, 0xCB, 0x00, 0x93, 0x00, 0xFB, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0xB3, 0x00, 0x99, 0x00, 0x22, + 0xFD, 0xC0, 0xFB, 0xB0, 0x06, 0xD4, 0x19, 0x41, 0x21, 0x14, 0x14, + 0xBC, 0x01, 0x3D, 0xFB, 0x7A, 0xFE, 0xF1, 0x00, 0x6A, 0x00, 0xF7, + 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD7, 0x00, 0x39, 0x00, 0x6A, 0xFC, + 0x9D, 0xFC, 0xF2, 0x09, 0x91, 0x1C, 0x3F, 0x20, 0x8E, 0x10, 0x84, + 0xFF, 0x6D, 0xFB, 0x2D, 0xFF, 0xFC, 0x00, 0x45, 0x00, 0xF7, 0xFF, + 0xFA, 0xFF, 0x29, 0x00, 0xF2, 0x00, 0xB8, 0xFF, 0xCF, 0xFB, 0xF1, + 0xFD, 0x69, 0x0D, 0xCA, 0x1E, 0x90, 0x1E, 0x01, 0x0D, 0xC4, 0xFD, + 0xDF, 0xFB, 0xC9, 0xFF, 0xF0, 0x00, 0x26, 0x00, 0xFA, 0xFF, 0xF7, + 0xFF, 0x49, 0x00, 0xFC, 0x00, 0x1A, 0xFF, 0x64, 0xFB, 0xC0, 0xFF, + 0xF7, 0x10, 0x66, 0x20, 0x46, 0x1C, 0x8E, 0x09, 0x7E, 0xFC, 0x7E, + 0xFC, 0x46, 0x00, 0xD4, 0x00, 0x0F, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, + 0x6F, 0x00, 0xEE, 0x00, 0x64, 0xFE, 0x3D, 0xFB, 0x05, 0x02, 0x7B, + 0x14, 0x53, 0x21, 0x7C, 0x19, 0x54, 0x06, 0xAE, 0xFB, 0x38, 0xFD, + 0xA1, 0x00, 0xAE, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFC, + 0xFF, 0x98, 0x00, 0xC5, 0x00, 0xA2, 0xFD, 0x6C, 0xFB, 0xB8, 0x04, + 0xCF, 0x17, 0x85, 0x21, 0x4E, 0x16, 0x6C, 0x03, 0x4A, 0xFB, 0xFC, + 0xFD, 0xDC, 0x00, 0x85, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x07, 0x00, + 0xC0, 0x00, 0x7B, 0x00, 0xE0, 0xFC, 0x00, 0xFC, 0xC9, 0x07, 0xD3, + 0x1A, 0xFC, 0x20, 0xDF, 0x12, 0xEA, 0x00, 0x46, 0xFB, 0xBA, 0xFE, + 0xF8, 0x00, 0x5D, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x19, 0x00, 0xE2, + 0x00, 0x10, 0x00, 0x30, 0xFC, 0x05, 0xFD, 0x21, 0x0B, 0x66, 0x1D, + 0xBD, 0x1F, 0x53, 0x0F, 0xDB, 0xFE, 0x8E, 0xFB, 0x66, 0xFF, 0xFA, + 0x00, 0x3A, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x34, 0x00, 0xF7, 0x00, + 0x84, 0xFF, 0xA4, 0xFB, 0x84, 0xFE, 0xA3, 0x0E, 0x6C, 0x1F, 0xD6, + 0x1D, 0xCB, 0x0B, 0x45, 0xFD, 0x12, 0xFC, 0xF8, 0xFF, 0xE7, 0x00, + 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x56, 0x00, 0xFA, 0x00, 0xDD, + 0xFE, 0x4E, 0xFB, 0x7C, 0x00, 0x32, 0x12, 0xCC, 0x20, 0x5C, 0x1B, + 0x69, 0x08, 0x29, 0xFC, 0xBC, 0xFC, 0x69, 0x00, 0xC7, 0x00, 0x09, + 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7D, 0x00, 0xE3, 0x00, 0x21, 0xFE, + 0x43, 0xFB, 0xE9, 0x02, 0xA9, 0x15, 0x79, 0x21, 0x6B, 0x18, 0x48, + 0x05, 0x80, 0xFB, 0x7C, 0xFD, 0xB9, 0x00, 0xA0, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x00, 0xAF, 0x00, 0x5E, + 0xFD, 0x93, 0xFB, 0xBE, 0x05, 0xE5, 0x18, 0x6B, 0x21, 0x23, 0x15, + 0x82, 0x02, 0x3F, 0xFB, 0x3F, 0xFE, 0xE9, 0x00, 0x77, 0x00, 0xF8, + 0xFF, 0xFE, 0xFF, 0x0C, 0x00, 0xCD, 0x00, 0x5A, 0x00, 0xA0, 0xFC, + 0x4D, 0xFC, 0xEA, 0x08, 0xC6, 0x1B, 0xA1, 0x20, 0xA6, 0x11, 0x26, + 0x00, 0x57, 0xFB, 0xF8, 0xFE, 0xFB, 0x00, 0x50, 0x00, 0xF7, 0xFF, + 0xFB, 0xFF, 0x21, 0x00, 0xEB, 0x00, 0xE3, 0xFF, 0xFA, 0xFB, 0x7C, + 0xFD, 0x54, 0x0C, 0x2B, 0x1E, 0x26, 0x1F, 0x17, 0x0E, 0x41, 0xFE, + 0xB6, 0xFB, 0x9C, 0xFF, 0xF5, 0x00, 0x2F, 0x00, 0xF9, 0xFF, 0xF8, + 0xFF, 0x3F, 0x00, 0xFB, 0x00, 0x4D, 0xFF, 0x7F, 0xFB, 0x24, 0xFF, + 0xDF, 0x0F, 0xF9, 0x1F, 0x09, 0x1D, 0x99, 0x0A, 0xD5, 0xFC, 0x49, + 0xFC, 0x23, 0x00, 0xDD, 0x00, 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, + 0x63, 0x00, 0xF5, 0x00, 0x9E, 0xFE, 0x41, 0xFB, 0x46, 0x01, 0x69, + 0x13, 0x1D, 0x21, 0x63, 0x1A, 0x4B, 0x07, 0xE2, 0xFB, 0xFD, 0xFC, + 0x89, 0x00, 0xBA, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8B, + 0x00, 0xD5, 0x00, 0xDE, 0xFD, 0x53, 0xFB, 0xD9, 0x03, 0xD0, 0x16, + 0x8A, 0x21, 0x51, 0x17, 0x47, 0x04, 0x5E, 0xFB, 0xC0, 0xFD, 0xCD, + 0x00, 0x92, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, + 0xB4, 0x00, 0x96, 0x00, 0x1B, 0xFD, 0xC7, 0xFB, 0xCF, 0x06, 0xF0, + 0x19, 0x3A, 0x21, 0xF2, 0x13, 0xA4, 0x01, 0x3E, 0xFB, 0x81, 0xFE, + 0xF2, 0x00, 0x69, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD9, + 0x00, 0x35, 0x00, 0x63, 0xFC, 0xA8, 0xFC, 0x13, 0x0A, 0xA9, 0x1C, + 0x32, 0x20, 0x6B, 0x10, 0x71, 0xFF, 0x71, 0xFB, 0x34, 0xFF, 0xFB, + 0x00, 0x44, 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2B, 0x00, 0xF3, 0x00, + 0xB3, 0xFF, 0xCA, 0xFB, 0x01, 0xFE, 0x8C, 0x0D, 0xDD, 0x1E, 0x7C, + 0x1E, 0xDE, 0x0C, 0xB5, 0xFD, 0xE4, 0xFB, 0xCE, 0xFF, 0xEF, 0x00, + 0x25, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4A, 0x00, 0xFC, 0x00, 0x13, + 0xFF, 0x61, 0xFB, 0xD4, 0xFF, 0x1A, 0x11, 0x72, 0x20, 0x2D, 0x1C, + 0x6D, 0x09, 0x74, 0xFC, 0x85, 0xFC, 0x4A, 0x00, 0xD2, 0x00, 0x0F, + 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x70, 0x00, 0xED, 0x00, 0x5D, 0xFE, + 0x3D, 0xFB, 0x1E, 0x02, 0x9C, 0x14, 0x58, 0x21, 0x5E, 0x19, 0x36, + 0x06, 0xA8, 0xFB, 0x40, 0xFD, 0xA4, 0x00, 0xAD, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x9A, 0x00, 0xC3, 0x00, 0x9A, + 0xFD, 0x6F, 0xFB, 0xD5, 0x04, 0xEF, 0x17, 0x83, 0x21, 0x2D, 0x16, + 0x52, 0x03, 0x49, 0xFB, 0x04, 0xFE, 0xDD, 0x00, 0x83, 0x00, 0xF9, + 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xC2, 0x00, 0x78, 0x00, 0xD9, 0xFC, + 0x08, 0xFC, 0xE9, 0x07, 0xEF, 0x1A, 0xF3, 0x20, 0xBC, 0x12, 0xD4, + 0x00, 0x47, 0xFB, 0xC1, 0xFE, 0xF8, 0x00, 0x5B, 0x00, 0xF7, 0xFF, + 0xFC, 0xFF, 0x1A, 0x00, 0xE3, 0x00, 0x0B, 0x00, 0x2A, 0xFC, 0x12, + 0xFD, 0x42, 0x0B, 0x7D, 0x1D, 0xAD, 0x1F, 0x2F, 0x0F, 0xC9, 0xFE, + 0x92, 0xFB, 0x6C, 0xFF, 0xF9, 0x00, 0x38, 0x00, 0xF8, 0xFF, 0xF9, + 0xFF, 0x35, 0x00, 0xF8, 0x00, 0x7E, 0xFF, 0x9F, 0xFB, 0x95, 0xFE, + 0xC6, 0x0E, 0x7C, 0x1F, 0xC0, 0x1D, 0xA9, 0x0B, 0x38, 0xFD, 0x18, + 0xFC, 0xFD, 0xFF, 0xE6, 0x00, 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, + 0x57, 0x00, 0xFA, 0x00, 0xD6, 0xFE, 0x4C, 0xFB, 0x92, 0x00, 0x54, + 0x12, 0xD6, 0x20, 0x41, 0x1B, 0x49, 0x08, 0x20, 0xFC, 0xC3, 0xFC, + 0x6D, 0x00, 0xC6, 0x00, 0x09, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7E, + 0x00, 0xE2, 0x00, 0x1A, 0xFE, 0x44, 0xFB, 0x03, 0x03, 0xCA, 0x15, + 0x7C, 0x21, 0x4C, 0x18, 0x2B, 0x05, 0x7B, 0xFB, 0x83, 0xFD, 0xBC, + 0x00, 0x9E, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xA8, 0x00, 0xAD, 0x00, 0x56, 0xFD, 0x98, 0xFB, 0xDC, 0x05, 0x04, + 0x19, 0x66, 0x21, 0x02, 0x15, 0x69, 0x02, 0x3E, 0xFB, 0x47, 0xFE, + 0xEA, 0x00, 0x75, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xCE, + 0x00, 0x56, 0x00, 0x99, 0xFC, 0x56, 0xFC, 0x0B, 0x09, 0xE0, 0x1B, + 0x96, 0x20, 0x83, 0x11, 0x11, 0x00, 0x59, 0xFB, 0xFF, 0xFE, 0xFB, + 0x00, 0x4E, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x22, 0x00, 0xEC, 0x00, + 0xDE, 0xFF, 0xF5, 0xFB, 0x8A, 0xFD, 0x77, 0x0C, 0x3F, 0x1E, 0x14, + 0x1F, 0xF5, 0x0D, 0x31, 0xFE, 0xBB, 0xFB, 0xA2, 0xFF, 0xF5, 0x00, + 0x2E, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x40, 0x00, 0xFB, 0x00, 0x47, + 0xFF, 0x7B, 0xFB, 0x37, 0xFF, 0x02, 0x10, 0x07, 0x20, 0xF2, 0x1C, + 0x78, 0x0A, 0xCA, 0xFC, 0x50, 0xFC, 0x27, 0x00, 0xDC, 0x00, 0x15, + 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x64, 0x00, 0xF5, 0x00, 0x97, 0xFE, + 0x40, 0xFB, 0x5D, 0x01, 0x8B, 0x13, 0x25, 0x21, 0x47, 0x1A, 0x2C, + 0x07, 0xDB, 0xFB, 0x05, 0xFD, 0x8C, 0x00, 0xB9, 0x00, 0x04, 0x00, + 0xFF, 0xFF, 0xFA, 0xFF, 0x8D, 0x00, 0xD3, 0x00, 0xD6, 0xFD, 0x56, + 0xFB, 0xF4, 0x03, 0xF0, 0x16, 0x8A, 0x21, 0x31, 0x17, 0x2B, 0x04, + 0x5B, 0xFB, 0xC7, 0xFD, 0xCF, 0x00, 0x90, 0x00, 0xFA, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xB6, 0x00, 0x92, 0x00, 0x13, 0xFD, + 0xCD, 0xFB, 0xEE, 0x06, 0x0D, 0x1A, 0x33, 0x21, 0xD0, 0x13, 0x8C, + 0x01, 0x3E, 0xFB, 0x88, 0xFE, 0xF3, 0x00, 0x67, 0x00, 0xF7, 0xFF, + 0x06, 0x00, 0x1D, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xA1, 0x02, 0xA6, + 0xF8, 0x56, 0x02, 0xA5, 0x28, 0xA5, 0x28, 0x56, 0x02, 0xA6, 0xF8, + 0xA1, 0x02, 0xFE, 0x00, 0x03, 0xFF, 0x1D, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x21, 0x00, 0xA6, 0xFF, 0x3F, 0xFF, 0x0B, 0x03, 0x42, 0xFE, + 0x3E, 0xF8, 0x7F, 0x15, 0xAC, 0x30, 0x7F, 0x15, 0x3E, 0xF8, 0x42, + 0xFE, 0x0B, 0x03, 0x3F, 0xFF, 0xA6, 0xFF, 0x21, 0x00, 0x00, 0x00, + 0xFA, 0xFF, 0xCE, 0xFF, 0x14, 0x01, 0x00, 0xFD, 0x35, 0x06, 0xD5, + 0xF4, 0xDA, 0x15, 0x92, 0x40, 0xAE, 0xFE, 0xF3, 0xFC, 0x68, 0x03, + 0x86, 0xFD, 0x51, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEC, + 0xFF, 0xF9, 0xFF, 0xC6, 0x00, 0x55, 0xFD, 0x35, 0x06, 0x90, 0xF3, + 0xE5, 0x1C, 0x6B, 0x3D, 0x71, 0xFA, 0x34, 0xFF, 0x46, 0x02, 0xFF, + 0xFD, 0x2D, 0x01, 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDB, 0xFF, + 0x2D, 0x00, 0x60, 0x00, 0xE1, 0xFD, 0xCE, 0x05, 0xED, 0xF2, 0xF3, + 0x23, 0x20, 0x39, 0x22, 0xF7, 0x44, 0x01, 0x1F, 0x01, 0x89, 0xFE, + 0xFB, 0x00, 0x9C, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC9, 0xFF, 0x68, + 0x00, 0xE5, 0xFF, 0xA0, 0xFE, 0xFB, 0x04, 0x0C, 0xF3, 0xC5, 0x2A, + 0xD8, 0x33, 0xC9, 0xF4, 0x0B, 0x03, 0x05, 0x00, 0x1A, 0xFF, 0xC1, + 0x00, 0xAD, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB5, 0xFF, 0xA5, 0x00, + 0x5C, 0xFF, 0x8C, 0xFF, 0xBF, 0x03, 0x06, 0xF4, 0x22, 0x31, 0xC8, + 0x2D, 0x63, 0xF3, 0x76, 0x04, 0x08, 0xFF, 0xA7, 0xFF, 0x84, 0x00, + 0xC0, 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA4, 0xFF, 0xE1, 0x00, 0xCB, + 0xFE, 0x9B, 0x00, 0x21, 0x02, 0xEE, 0xF5, 0xCD, 0x36, 0x24, 0x27, + 0xE1, 0xF2, 0x7A, 0x05, 0x33, 0xFE, 0x2A, 0x00, 0x47, 0x00, 0xD3, + 0xFF, 0x04, 0x00, 0x0F, 0x00, 0x95, 0xFF, 0x17, 0x01, 0x3D, 0xFE, + 0xBD, 0x01, 0x30, 0x00, 0xCC, 0xF8, 0x92, 0x3B, 0x2A, 0x20, 0x2E, + 0xF3, 0x12, 0x06, 0x8F, 0xFD, 0x9A, 0x00, 0x10, 0x00, 0xE5, 0xFF, + 0x02, 0x00, 0x10, 0x00, 0x8C, 0xFF, 0x42, 0x01, 0xBB, 0xFD, 0xE4, + 0x02, 0x01, 0xFE, 0x9C, 0xFC, 0x45, 0x3F, 0x16, 0x19, 0x2D, 0xF4, + 0x41, 0x06, 0x21, 0xFD, 0xF3, 0x00, 0xE0, 0xFF, 0xF4, 0xFF, 0x01, + 0x00, 0x10, 0x00, 0x8B, 0xFF, 0x5D, 0x01, 0x4F, 0xFD, 0xFB, 0x03, + 0xB2, 0xFB, 0x53, 0x01, 0xC2, 0x41, 0x24, 0x12, 0xBA, 0xF5, 0x0F, + 0x06, 0xE9, 0xFC, 0x33, 0x01, 0xBB, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x93, 0xFF, 0x63, 0x01, 0x04, 0xFD, 0xEF, 0x04, 0x62, + 0xF9, 0xD7, 0x06, 0xF2, 0x42, 0x8D, 0x0B, 0xB0, 0xF7, 0x87, 0x05, + 0xE6, 0xFC, 0x58, 0x01, 0xA0, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0xA5, 0xFF, 0x52, 0x01, 0xE2, 0xFC, 0xAD, 0x05, + 0x35, 0xF7, 0x08, 0x0D, 0xCB, 0x42, 0x81, 0x05, 0xE8, 0xF9, 0xBB, + 0x04, 0x12, 0xFD, 0x64, 0x01, 0x90, 0xFF, 0x0E, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xC2, 0xFF, 0x27, 0x01, 0xF1, 0xFC, 0x22, 0x06, 0x54, + 0xF5, 0xB8, 0x13, 0x4A, 0x41, 0x29, 0x00, 0x3C, 0xFC, 0xBD, 0x03, + 0x66, 0xFD, 0x58, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF1, + 0xFF, 0xEB, 0xFF, 0xE1, 0x00, 0x35, 0xFD, 0x40, 0x06, 0xE4, 0xF3, + 0xB7, 0x1A, 0x85, 0x3E, 0xA6, 0xFB, 0x86, 0xFE, 0xA0, 0x02, 0xD7, + 0xFD, 0x39, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xE1, 0xFF, + 0x1C, 0x00, 0x82, 0x00, 0xB0, 0xFD, 0xF9, 0x05, 0x0C, 0xF3, 0xCB, + 0x21, 0x8F, 0x3A, 0x0D, 0xF8, 0xA9, 0x00, 0x79, 0x01, 0x5D, 0xFE, + 0x0B, 0x01, 0x98, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCE, 0xFF, 0x55, + 0x00, 0x0D, 0x00, 0x60, 0xFE, 0x48, 0x05, 0xEC, 0xF2, 0xB6, 0x28, + 0x91, 0x35, 0x68, 0xF5, 0x88, 0x02, 0x5A, 0x00, 0xED, 0xFE, 0xD4, + 0x00, 0xA8, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0x92, 0x00, + 0x87, 0xFF, 0x3F, 0xFF, 0x2B, 0x04, 0xA1, 0xF3, 0x3D, 0x2F, 0xB8, + 0x2F, 0xB8, 0xF3, 0x11, 0x04, 0x52, 0xFF, 0x7C, 0xFF, 0x97, 0x00, + 0xBA, 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA9, 0xFF, 0xCF, 0x00, 0xF8, + 0xFE, 0x44, 0x00, 0xAA, 0x02, 0x3E, 0xF5, 0x24, 0x35, 0x3B, 0x29, + 0xF2, 0xF2, 0x35, 0x05, 0x70, 0xFE, 0x03, 0x00, 0x5A, 0x00, 0xCD, + 0xFF, 0x05, 0x00, 0x0E, 0x00, 0x99, 0xFF, 0x07, 0x01, 0x68, 0xFE, + 0x63, 0x01, 0xD0, 0x00, 0xD0, 0xF7, 0x35, 0x3A, 0x55, 0x22, 0x02, + 0xF3, 0xEF, 0x05, 0xBC, 0xFD, 0x7A, 0x00, 0x20, 0x00, 0xDF, 0xFF, + 0x03, 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x36, 0x01, 0xE1, 0xFD, 0x8A, + 0x02, 0xB2, 0xFE, 0x56, 0xFB, 0x40, 0x3E, 0x42, 0x1B, 0xCE, 0xF3, + 0x3E, 0x06, 0x3D, 0xFD, 0xDB, 0x00, 0xEE, 0xFF, 0xF0, 0xFF, 0x01, + 0x00, 0x11, 0x00, 0x8A, 0xFF, 0x57, 0x01, 0x6D, 0xFD, 0xA8, 0x03, + 0x69, 0xFC, 0xC8, 0xFF, 0x20, 0x41, 0x40, 0x14, 0x33, 0xF5, 0x28, + 0x06, 0xF5, 0xFC, 0x22, 0x01, 0xC5, 0xFF, 0xFD, 0xFF, 0x00, 0x00, + 0x0F, 0x00, 0x8F, 0xFF, 0x64, 0x01, 0x17, 0xFD, 0xA9, 0x04, 0x16, + 0xFA, 0x10, 0x05, 0xB8, 0x42, 0x87, 0x0D, 0x0D, 0xF7, 0xB9, 0x05, + 0xE2, 0xFC, 0x50, 0x01, 0xA7, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0A, 0x00, 0x9E, 0xFF, 0x5A, 0x01, 0xE8, 0xFC, 0x7A, 0x05, + 0xDA, 0xF7, 0x10, 0x0B, 0xFB, 0x42, 0x4B, 0x07, 0x35, 0xF9, 0x00, + 0x05, 0x00, 0xFD, 0x63, 0x01, 0x94, 0xFF, 0x0D, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xB8, 0xFF, 0x37, 0x01, 0xE7, 0xFC, 0x07, 0x06, 0xDE, + 0xF5, 0x9F, 0x11, 0xE4, 0x41, 0xB8, 0x01, 0x84, 0xFB, 0x0F, 0x04, + 0x48, 0xFD, 0x5E, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF5, + 0xFF, 0xDD, 0xFF, 0xF9, 0x00, 0x1B, 0xFD, 0x41, 0x06, 0x47, 0xF4, + 0x8B, 0x18, 0x81, 0x3F, 0xF1, 0xFC, 0xD5, 0xFD, 0xFA, 0x02, 0xB2, + 0xFD, 0x45, 0x01, 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE6, 0xFF, + 0x0C, 0x00, 0xA2, 0x00, 0x85, 0xFD, 0x1A, 0x06, 0x3C, 0xF3, 0x9F, + 0x1F, 0xE6, 0x3B, 0x0E, 0xF9, 0x07, 0x00, 0xD4, 0x01, 0x33, 0xFE, + 0x1B, 0x01, 0x94, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD4, 0xFF, 0x43, + 0x00, 0x33, 0x00, 0x25, 0xFE, 0x89, 0x05, 0xE0, 0xF2, 0x9C, 0x26, + 0x33, 0x37, 0x1E, 0xF6, 0xFD, 0x01, 0xB0, 0x00, 0xC0, 0xFE, 0xE6, + 0x00, 0xA2, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC1, 0xFF, 0x7F, 0x00, + 0xB2, 0xFF, 0xF6, 0xFE, 0x8E, 0x04, 0x51, 0xF3, 0x49, 0x2D, 0x98, + 0x31, 0x23, 0xF4, 0xA2, 0x03, 0xA0, 0xFF, 0x51, 0xFF, 0xAA, 0x00, + 0xB4, 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAE, 0xFF, 0xBD, 0x00, 0x25, + 0xFF, 0xF1, 0xFF, 0x2B, 0x03, 0xA5, 0xF4, 0x68, 0x33, 0x48, 0x2B, + 0x17, 0xF3, 0xE7, 0x04, 0xB1, 0xFE, 0xDB, 0xFF, 0x6C, 0x00, 0xC7, + 0xFF, 0x06, 0x00, 0x0D, 0x00, 0x9E, 0xFF, 0xF7, 0x00, 0x94, 0xFE, + 0x09, 0x01, 0x6A, 0x01, 0xEB, 0xF6, 0xC1, 0x38, 0x7D, 0x24, 0xE8, + 0xF2, 0xC1, 0x05, 0xEE, 0xFD, 0x57, 0x00, 0x31, 0x00, 0xDA, 0xFF, + 0x03, 0x00, 0x10, 0x00, 0x91, 0xFF, 0x29, 0x01, 0x09, 0xFE, 0x2F, + 0x02, 0x5F, 0xFF, 0x27, 0xFA, 0x20, 0x3D, 0x70, 0x1D, 0x7D, 0xF3, + 0x31, 0x06, 0x5E, 0xFD, 0xBF, 0x00, 0xFD, 0xFF, 0xEB, 0xFF, 0x02, + 0x00, 0x11, 0x00, 0x8B, 0xFF, 0x4E, 0x01, 0x8E, 0xFD, 0x52, 0x03, + 0x20, 0xFD, 0x52, 0xFE, 0x60, 0x40, 0x63, 0x16, 0xB7, 0xF4, 0x39, + 0x06, 0x05, 0xFD, 0x0F, 0x01, 0xD1, 0xFF, 0xF9, 0xFF, 0x00, 0x00, + 0x10, 0x00, 0x8D, 0xFF, 0x62, 0x01, 0x2E, 0xFD, 0x5E, 0x04, 0xCC, + 0xFA, 0x5B, 0x03, 0x5E, 0x42, 0x8E, 0x0F, 0x71, 0xF6, 0xE4, 0x05, + 0xE2, 0xFC, 0x45, 0x01, 0xAF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0x99, 0xFF, 0x60, 0x01, 0xF2, 0xFC, 0x40, 0x05, + 0x85, 0xF8, 0x26, 0x09, 0x0C, 0x43, 0x26, 0x09, 0x85, 0xF8, 0x40, + 0x05, 0xF2, 0xFC, 0x60, 0x01, 0x99, 0xFF, 0x0B, 0x00, 0x00, 0x00, + 0x04, 0x00, 0xAF, 0xFF, 0x45, 0x01, 0xE2, 0xFC, 0xE4, 0x05, 0x71, + 0xF6, 0x8E, 0x0F, 0x5E, 0x42, 0x5B, 0x03, 0xCC, 0xFA, 0x5E, 0x04, + 0x2E, 0xFD, 0x62, 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xF9, + 0xFF, 0xD1, 0xFF, 0x0F, 0x01, 0x05, 0xFD, 0x39, 0x06, 0xB7, 0xF4, + 0x63, 0x16, 0x60, 0x40, 0x52, 0xFE, 0x20, 0xFD, 0x52, 0x03, 0x8E, + 0xFD, 0x4E, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEB, 0xFF, + 0xFD, 0xFF, 0xBF, 0x00, 0x5E, 0xFD, 0x31, 0x06, 0x7D, 0xF3, 0x70, + 0x1D, 0x20, 0x3D, 0x27, 0xFA, 0x5F, 0xFF, 0x2F, 0x02, 0x09, 0xFE, + 0x29, 0x01, 0x91, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDA, 0xFF, 0x31, + 0x00, 0x57, 0x00, 0xEE, 0xFD, 0xC1, 0x05, 0xE8, 0xF2, 0x7D, 0x24, + 0xC1, 0x38, 0xEB, 0xF6, 0x6A, 0x01, 0x09, 0x01, 0x94, 0xFE, 0xF7, + 0x00, 0x9E, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC7, 0xFF, 0x6C, 0x00, + 0xDB, 0xFF, 0xB1, 0xFE, 0xE7, 0x04, 0x17, 0xF3, 0x48, 0x2B, 0x68, + 0x33, 0xA5, 0xF4, 0x2B, 0x03, 0xF1, 0xFF, 0x25, 0xFF, 0xBD, 0x00, + 0xAE, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB4, 0xFF, 0xAA, 0x00, 0x51, + 0xFF, 0xA0, 0xFF, 0xA2, 0x03, 0x23, 0xF4, 0x98, 0x31, 0x49, 0x2D, + 0x51, 0xF3, 0x8E, 0x04, 0xF6, 0xFE, 0xB2, 0xFF, 0x7F, 0x00, 0xC1, + 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA2, 0xFF, 0xE6, 0x00, 0xC0, 0xFE, + 0xB0, 0x00, 0xFD, 0x01, 0x1E, 0xF6, 0x33, 0x37, 0x9C, 0x26, 0xE0, + 0xF2, 0x89, 0x05, 0x25, 0xFE, 0x33, 0x00, 0x43, 0x00, 0xD4, 0xFF, + 0x04, 0x00, 0x0F, 0x00, 0x94, 0xFF, 0x1B, 0x01, 0x33, 0xFE, 0xD4, + 0x01, 0x07, 0x00, 0x0E, 0xF9, 0xE6, 0x3B, 0x9F, 0x1F, 0x3C, 0xF3, + 0x1A, 0x06, 0x85, 0xFD, 0xA2, 0x00, 0x0C, 0x00, 0xE6, 0xFF, 0x02, + 0x00, 0x11, 0x00, 0x8C, 0xFF, 0x45, 0x01, 0xB2, 0xFD, 0xFA, 0x02, + 0xD5, 0xFD, 0xF1, 0xFC, 0x81, 0x3F, 0x8B, 0x18, 0x47, 0xF4, 0x41, + 0x06, 0x1B, 0xFD, 0xF9, 0x00, 0xDD, 0xFF, 0xF5, 0xFF, 0x01, 0x00, + 0x10, 0x00, 0x8B, 0xFF, 0x5E, 0x01, 0x48, 0xFD, 0x0F, 0x04, 0x84, + 0xFB, 0xB8, 0x01, 0xE4, 0x41, 0x9F, 0x11, 0xDE, 0xF5, 0x07, 0x06, + 0xE7, 0xFC, 0x37, 0x01, 0xB8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x0D, + 0x00, 0x94, 0xFF, 0x63, 0x01, 0x00, 0xFD, 0x00, 0x05, 0x35, 0xF9, + 0x4B, 0x07, 0xFB, 0x42, 0x10, 0x0B, 0xDA, 0xF7, 0x7A, 0x05, 0xE8, + 0xFC, 0x5A, 0x01, 0x9E, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0xA7, 0xFF, 0x50, 0x01, 0xE2, 0xFC, 0xB9, 0x05, 0x0D, + 0xF7, 0x87, 0x0D, 0xB8, 0x42, 0x10, 0x05, 0x16, 0xFA, 0xA9, 0x04, + 0x17, 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0xC5, 0xFF, 0x22, 0x01, 0xF5, 0xFC, 0x28, 0x06, 0x33, 0xF5, + 0x40, 0x14, 0x20, 0x41, 0xC8, 0xFF, 0x69, 0xFC, 0xA8, 0x03, 0x6D, + 0xFD, 0x57, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF0, 0xFF, + 0xEE, 0xFF, 0xDB, 0x00, 0x3D, 0xFD, 0x3E, 0x06, 0xCE, 0xF3, 0x42, + 0x1B, 0x40, 0x3E, 0x56, 0xFB, 0xB2, 0xFE, 0x8A, 0x02, 0xE1, 0xFD, + 0x36, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDF, 0xFF, 0x20, + 0x00, 0x7A, 0x00, 0xBC, 0xFD, 0xEF, 0x05, 0x02, 0xF3, 0x55, 0x22, + 0x35, 0x3A, 0xD0, 0xF7, 0xD0, 0x00, 0x63, 0x01, 0x68, 0xFE, 0x07, + 0x01, 0x99, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCD, 0xFF, 0x5A, 0x00, + 0x03, 0x00, 0x70, 0xFE, 0x35, 0x05, 0xF2, 0xF2, 0x3B, 0x29, 0x24, + 0x35, 0x3E, 0xF5, 0xAA, 0x02, 0x44, 0x00, 0xF8, 0xFE, 0xCF, 0x00, + 0xA9, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBA, 0xFF, 0x97, 0x00, 0x7C, + 0xFF, 0x52, 0xFF, 0x11, 0x04, 0xB8, 0xF3, 0xB8, 0x2F, 0x3D, 0x2F, + 0xA1, 0xF3, 0x2B, 0x04, 0x3F, 0xFF, 0x87, 0xFF, 0x92, 0x00, 0xBB, + 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA8, 0xFF, 0xD4, 0x00, 0xED, 0xFE, + 0x5A, 0x00, 0x88, 0x02, 0x68, 0xF5, 0x91, 0x35, 0xB6, 0x28, 0xEC, + 0xF2, 0x48, 0x05, 0x60, 0xFE, 0x0D, 0x00, 0x55, 0x00, 0xCE, 0xFF, + 0x05, 0x00, 0x0E, 0x00, 0x98, 0xFF, 0x0B, 0x01, 0x5D, 0xFE, 0x79, + 0x01, 0xA9, 0x00, 0x0D, 0xF8, 0x8F, 0x3A, 0xCB, 0x21, 0x0C, 0xF3, + 0xF9, 0x05, 0xB0, 0xFD, 0x82, 0x00, 0x1C, 0x00, 0xE1, 0xFF, 0x03, + 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x39, 0x01, 0xD7, 0xFD, 0xA0, 0x02, + 0x86, 0xFE, 0xA6, 0xFB, 0x85, 0x3E, 0xB7, 0x1A, 0xE4, 0xF3, 0x40, + 0x06, 0x35, 0xFD, 0xE1, 0x00, 0xEB, 0xFF, 0xF1, 0xFF, 0x01, 0x00, + 0x11, 0x00, 0x8A, 0xFF, 0x58, 0x01, 0x66, 0xFD, 0xBD, 0x03, 0x3C, + 0xFC, 0x29, 0x00, 0x4A, 0x41, 0xB8, 0x13, 0x54, 0xF5, 0x22, 0x06, + 0xF1, 0xFC, 0x27, 0x01, 0xC2, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x0E, + 0x00, 0x90, 0xFF, 0x64, 0x01, 0x12, 0xFD, 0xBB, 0x04, 0xE8, 0xF9, + 0x81, 0x05, 0xCB, 0x42, 0x08, 0x0D, 0x35, 0xF7, 0xAD, 0x05, 0xE2, + 0xFC, 0x52, 0x01, 0xA5, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0xA0, 0xFF, 0x58, 0x01, 0xE6, 0xFC, 0x87, 0x05, 0xB0, + 0xF7, 0x8D, 0x0B, 0xF2, 0x42, 0xD7, 0x06, 0x62, 0xF9, 0xEF, 0x04, + 0x04, 0xFD, 0x63, 0x01, 0x93, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xBB, 0xFF, 0x33, 0x01, 0xE9, 0xFC, 0x0F, 0x06, 0xBA, 0xF5, + 0x24, 0x12, 0xC2, 0x41, 0x53, 0x01, 0xB2, 0xFB, 0xFB, 0x03, 0x4F, + 0xFD, 0x5D, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF4, 0xFF, + 0xE0, 0xFF, 0xF3, 0x00, 0x21, 0xFD, 0x41, 0x06, 0x2D, 0xF4, 0x16, + 0x19, 0x45, 0x3F, 0x9C, 0xFC, 0x01, 0xFE, 0xE4, 0x02, 0xBB, 0xFD, + 0x42, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE5, 0xFF, 0x10, + 0x00, 0x9A, 0x00, 0x8F, 0xFD, 0x12, 0x06, 0x2E, 0xF3, 0x2A, 0x20, + 0x92, 0x3B, 0xCC, 0xF8, 0x30, 0x00, 0xBD, 0x01, 0x3D, 0xFE, 0x17, + 0x01, 0x95, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD3, 0xFF, 0x47, 0x00, + 0x2A, 0x00, 0x33, 0xFE, 0x7A, 0x05, 0xE1, 0xF2, 0x24, 0x27, 0xCD, + 0x36, 0xEE, 0xF5, 0x21, 0x02, 0x9B, 0x00, 0xCB, 0xFE, 0xE1, 0x00, + 0xA4, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0x84, 0x00, 0xA7, + 0xFF, 0x08, 0xFF, 0x76, 0x04, 0x63, 0xF3, 0xC8, 0x2D, 0x22, 0x31, + 0x06, 0xF4, 0xBF, 0x03, 0x8C, 0xFF, 0x5C, 0xFF, 0xA5, 0x00, 0xB5, + 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAD, 0xFF, 0xC1, 0x00, 0x1A, 0xFF, + 0x05, 0x00, 0x0B, 0x03, 0xC9, 0xF4, 0xD8, 0x33, 0xC5, 0x2A, 0x0C, + 0xF3, 0xFB, 0x04, 0xA0, 0xFE, 0xE5, 0xFF, 0x68, 0x00, 0xC9, 0xFF, + 0x06, 0x00, 0x0D, 0x00, 0x9C, 0xFF, 0xFB, 0x00, 0x89, 0xFE, 0x1F, + 0x01, 0x44, 0x01, 0x22, 0xF7, 0x20, 0x39, 0xF3, 0x23, 0xED, 0xF2, + 0xCE, 0x05, 0xE1, 0xFD, 0x60, 0x00, 0x2D, 0x00, 0xDB, 0xFF, 0x03, + 0x00, 0x10, 0x00, 0x90, 0xFF, 0x2D, 0x01, 0xFF, 0xFD, 0x46, 0x02, + 0x34, 0xFF, 0x71, 0xFA, 0x6B, 0x3D, 0xE5, 0x1C, 0x90, 0xF3, 0x35, + 0x06, 0x55, 0xFD, 0xC6, 0x00, 0xF9, 0xFF, 0xEC, 0xFF, 0x01, 0x00, + 0x11, 0x00, 0x8B, 0xFF, 0x51, 0x01, 0x86, 0xFD, 0x68, 0x03, 0xF3, + 0xFC, 0xAE, 0xFE, 0x92, 0x40, 0xDA, 0x15, 0xD5, 0xF4, 0x35, 0x06, + 0x00, 0xFD, 0x14, 0x01, 0xCE, 0xFF, 0xFA, 0xFF, 0x00, 0x00, 0x0F, + 0x00, 0x8D, 0xFF, 0x63, 0x01, 0x28, 0xFD, 0x71, 0x04, 0x9E, 0xFA, + 0xC7, 0x03, 0x79, 0x42, 0x0B, 0x0F, 0x97, 0xF6, 0xDA, 0x05, 0xE2, + 0xFC, 0x48, 0x01, 0xAD, 0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x9A, 0xFF, 0x5F, 0x01, 0xEF, 0xFC, 0x4F, 0x05, 0x5A, + 0xF8, 0x9F, 0x09, 0x0A, 0x43, 0xAE, 0x08, 0xB1, 0xF8, 0x30, 0x05, + 0xF5, 0xFC, 0x61, 0x01, 0x97, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, + 0x00, 0xB1, 0xFF, 0x41, 0x01, 0xE3, 0xFC, 0xED, 0x05, 0x4C, 0xF6, + 0x11, 0x10, 0x42, 0x42, 0xF1, 0x02, 0xFA, 0xFA, 0x4B, 0x04, 0x34, + 0xFD, 0x61, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF8, 0xFF, + 0xD4, 0xFF, 0x0A, 0x01, 0x0A, 0xFD, 0x3C, 0x06, 0x9A, 0xF4, 0xED, + 0x16, 0x2A, 0x40, 0xF8, 0xFD, 0x4D, 0xFD, 0x3C, 0x03, 0x97, 0xFD, + 0x4C, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEA, 0xFF, 0x00, + 0x00, 0xB8, 0x00, 0x67, 0xFD, 0x2C, 0x06, 0x6B, 0xF3, 0xFC, 0x1D, + 0xD3, 0x3C, 0xDF, 0xF9, 0x89, 0xFF, 0x18, 0x02, 0x13, 0xFE, 0x26, + 0x01, 0x92, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD9, 0xFF, 0x36, 0x00, + 0x4E, 0x00, 0xFB, 0xFD, 0xB4, 0x05, 0xE4, 0xF2, 0x04, 0x25, 0x5F, + 0x38, 0xB6, 0xF6, 0x90, 0x01, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, + 0x9F, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC6, 0xFF, 0x71, 0x00, 0xD1, + 0xFF, 0xC2, 0xFE, 0xD1, 0x04, 0x23, 0xF3, 0xC9, 0x2B, 0xF5, 0x32, + 0x83, 0xF4, 0x49, 0x03, 0xDC, 0xFF, 0x30, 0xFF, 0xB8, 0x00, 0xB0, + 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB3, 0xFF, 0xAE, 0x00, 0x46, 0xFF, + 0xB4, 0xFF, 0x85, 0x03, 0x42, 0xF4, 0x0E, 0x32, 0xCA, 0x2C, 0x41, + 0xF3, 0xA5, 0x04, 0xE4, 0xFE, 0xBC, 0xFF, 0x7A, 0x00, 0xC3, 0xFF, + 0x07, 0x00, 0x0D, 0x00, 0xA1, 0xFF, 0xEA, 0x00, 0xB5, 0xFE, 0xC6, + 0x00, 0xD9, 0x01, 0x4F, 0xF6, 0x99, 0x37, 0x16, 0x26, 0xE0, 0xF2, + 0x98, 0x05, 0x16, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0xD6, 0xFF, 0x04, + 0x00, 0x0F, 0x00, 0x93, 0xFF, 0x1F, 0x01, 0x28, 0xFE, 0xEB, 0x01, + 0xDD, 0xFF, 0x52, 0xF9, 0x36, 0x3C, 0x13, 0x1F, 0x4B, 0xF3, 0x20, + 0x06, 0x7B, 0xFD, 0xA9, 0x00, 0x08, 0x00, 0xE7, 0xFF, 0x02, 0x00, + 0x11, 0x00, 0x8C, 0xFF, 0x47, 0x01, 0xA9, 0xFD, 0x10, 0x03, 0xA8, + 0xFD, 0x47, 0xFD, 0xBB, 0x3F, 0x01, 0x18, 0x62, 0xF4, 0x40, 0x06, + 0x15, 0xFD, 0xFF, 0x00, 0xDA, 0xFF, 0xF6, 0xFF, 0x01, 0x00, 0x10, + 0x00, 0x8B, 0xFF, 0x5F, 0x01, 0x41, 0xFD, 0x23, 0x04, 0x56, 0xFB, + 0x1F, 0x02, 0x06, 0x42, 0x19, 0x11, 0x02, 0xF6, 0xFF, 0x05, 0xE5, + 0xFC, 0x3B, 0x01, 0xB6, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, + 0x95, 0xFF, 0x62, 0x01, 0xFC, 0xFC, 0x10, 0x05, 0x09, 0xF9, 0xC1, + 0x07, 0x03, 0x43, 0x94, 0x0A, 0x05, 0xF8, 0x6C, 0x05, 0xEA, 0xFC, + 0x5C, 0x01, 0x9D, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0xA9, 0xFF, 0x4D, 0x01, 0xE1, 0xFC, 0xC4, 0x05, 0xE6, 0xF6, + 0x08, 0x0E, 0xA5, 0x42, 0xA1, 0x04, 0x43, 0xFA, 0x97, 0x04, 0x1D, + 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0xFF, + 0xC8, 0xFF, 0x1E, 0x01, 0xF8, 0xFC, 0x2D, 0x06, 0x13, 0xF5, 0xC8, + 0x14, 0xF2, 0x40, 0x69, 0xFF, 0x97, 0xFC, 0x92, 0x03, 0x75, 0xFD, + 0x55, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEF, 0xFF, 0xF2, + 0xFF, 0xD4, 0x00, 0x45, 0xFD, 0x3B, 0x06, 0xB8, 0xF3, 0xCE, 0x1B, + 0xFB, 0x3D, 0x08, 0xFB, 0xDE, 0xFE, 0x73, 0x02, 0xEB, 0xFD, 0x33, + 0x01, 0x8F, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDE, 0xFF, 0x25, 0x00, + 0x71, 0x00, 0xC8, 0xFD, 0xE5, 0x05, 0xFA, 0xF2, 0xDF, 0x22, 0xDB, + 0x39, 0x94, 0xF7, 0xF7, 0x00, 0x4C, 0x01, 0x73, 0xFE, 0x03, 0x01, + 0x9A, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCC, 0xFF, 0x5E, 0x00, 0xF9, + 0xFF, 0x80, 0xFE, 0x23, 0x05, 0xF9, 0xF2, 0xC0, 0x29, 0xB8, 0x34, + 0x16, 0xF5, 0xCB, 0x02, 0x2F, 0x00, 0x03, 0xFF, 0xCA, 0x00, 0xAA, + 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xB8, 0xFF, 0x9B, 0x00, 0x72, 0xFF, + 0x65, 0xFF, 0xF6, 0x03, 0xD1, 0xF3, 0x31, 0x30, 0xC1, 0x2E, 0x8B, + 0xF3, 0x45, 0x04, 0x2D, 0xFF, 0x92, 0xFF, 0x8D, 0x00, 0xBD, 0xFF, + 0x08, 0x00, 0x0C, 0x00, 0xA6, 0xFF, 0xD8, 0x00, 0xE2, 0xFE, 0x6F, + 0x00, 0x66, 0x02, 0x93, 0xF5, 0xFB, 0x35, 0x31, 0x28, 0xE7, 0xF2, + 0x59, 0x05, 0x51, 0xFE, 0x17, 0x00, 0x50, 0x00, 0xD0, 0xFF, 0x05, + 0x00, 0x0E, 0x00, 0x97, 0xFF, 0x0F, 0x01, 0x53, 0xFE, 0x90, 0x01, + 0x81, 0x00, 0x4B, 0xF8, 0xE6, 0x3A, 0x3F, 0x21, 0x16, 0xF3, 0x02, + 0x06, 0xA5, 0xFD, 0x8A, 0x00, 0x18, 0x00, 0xE2, 0xFF, 0x02, 0x00, + 0x10, 0x00, 0x8D, 0xFF, 0x3C, 0x01, 0xCE, 0xFD, 0xB7, 0x02, 0x5A, + 0xFE, 0xF7, 0xFB, 0xC6, 0x3E, 0x2C, 0x1A, 0xFC, 0xF3, 0x41, 0x06, + 0x2E, 0xFD, 0xE7, 0x00, 0xE7, 0xFF, 0xF2, 0xFF, 0x01, 0x00, 0x10, + 0x00, 0x8B, 0xFF, 0x5A, 0x01, 0x5E, 0xFD, 0xD2, 0x03, 0x0E, 0xFC, + 0x8B, 0x00, 0x75, 0x41, 0x32, 0x13, 0x75, 0xF5, 0x1C, 0x06, 0xEE, + 0xFC, 0x2B, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, + 0x91, 0xFF, 0x64, 0x01, 0x0D, 0xFD, 0xCD, 0x04, 0xBB, 0xF9, 0xF2, + 0x05, 0xD9, 0x42, 0x88, 0x0C, 0x5E, 0xF7, 0xA1, 0x05, 0xE3, 0xFC, + 0x54, 0x01, 0xA3, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0xA2, 0xFF, 0x56, 0x01, 0xE5, 0xFC, 0x94, 0x05, 0x87, 0xF7, + 0x0A, 0x0C, 0xE6, 0x42, 0x64, 0x06, 0x8E, 0xF9, 0xDE, 0x04, 0x09, + 0xFD, 0x64, 0x01, 0x92, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xFF, 0x2F, 0x01, 0xEC, 0xFC, 0x16, 0x06, 0x98, 0xF5, 0xAB, + 0x12, 0x9C, 0x41, 0xEE, 0x00, 0xE0, 0xFB, 0xE6, 0x03, 0x57, 0xFD, + 0x5B, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF3, 0xFF, 0xE4, + 0xFF, 0xED, 0x00, 0x27, 0xFD, 0x41, 0x06, 0x14, 0xF4, 0xA1, 0x19, + 0x06, 0x3F, 0x49, 0xFC, 0x2E, 0xFE, 0xCD, 0x02, 0xC4, 0xFD, 0x3F, + 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE3, 0xFF, 0x14, 0x00, + 0x92, 0x00, 0x9A, 0xFD, 0x0A, 0x06, 0x22, 0xF3, 0xB4, 0x20, 0x3C, + 0x3B, 0x8B, 0xF8, 0x58, 0x00, 0xA7, 0x01, 0x48, 0xFE, 0x13, 0x01, + 0x96, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD1, 0xFF, 0x4C, 0x00, 0x20, + 0x00, 0x42, 0xFE, 0x6A, 0x05, 0xE3, 0xF2, 0xAB, 0x27, 0x66, 0x36, + 0xC0, 0xF5, 0x44, 0x02, 0x85, 0x00, 0xD7, 0xFE, 0xDD, 0x00, 0xA5, + 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xBE, 0xFF, 0x89, 0x00, 0x9D, 0xFF, + 0x1A, 0xFF, 0x5E, 0x04, 0x76, 0xF3, 0x45, 0x2E, 0xAA, 0x30, 0xEB, + 0xF3, 0xDB, 0x03, 0x79, 0xFF, 0x67, 0xFF, 0xA0, 0x00, 0xB7, 0xFF, + 0x09, 0x00, 0x0B, 0x00, 0xAC, 0xFF, 0xC6, 0x00, 0x0E, 0xFF, 0x1A, + 0x00, 0xEB, 0x02, 0xEF, 0xF4, 0x49, 0x34, 0x43, 0x2A, 0x02, 0xF3, + 0x0F, 0x05, 0x90, 0xFE, 0xEF, 0xFF, 0x63, 0x00, 0xCA, 0xFF, 0x06, + 0x00, 0x0E, 0x00, 0x9B, 0xFF, 0xFF, 0x00, 0x7E, 0xFE, 0x36, 0x01, + 0x1E, 0x01, 0x5B, 0xF7, 0x7E, 0x39, 0x69, 0x23, 0xF3, 0xF2, 0xD9, + 0x05, 0xD4, 0xFD, 0x69, 0x00, 0x29, 0x00, 0xDD, 0xFF, 0x03, 0x00, + 0x10, 0x00, 0x90, 0xFF, 0x30, 0x01, 0xF5, 0xFD, 0x5C, 0x02, 0x09, + 0xFF, 0xBC, 0xFA, 0xB5, 0x3D, 0x5A, 0x1C, 0xA3, 0xF3, 0x38, 0x06, + 0x4D, 0xFD, 0xCD, 0x00, 0xF5, 0xFF, 0xED, 0xFF, 0x01, 0x00, 0x11, + 0x00, 0x8B, 0xFF, 0x53, 0x01, 0x7E, 0xFD, 0x7D, 0x03, 0xC5, 0xFC, + 0x0B, 0xFF, 0xC3, 0x40, 0x51, 0x15, 0xF4, 0xF4, 0x31, 0x06, 0xFC, + 0xFC, 0x19, 0x01, 0xCB, 0xFF, 0xFB, 0xFF, 0x00, 0x00, 0x0F, 0x00, + 0x8E, 0xFF, 0x63, 0x01, 0x22, 0xFD, 0x84, 0x04, 0x71, 0xFA, 0x34, + 0x04, 0x90, 0x42, 0x89, 0x0E, 0xBE, 0xF6, 0xCF, 0x05, 0xE1, 0xFC, + 0x4A, 0x01, 0xAB, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, + 0x00, 0x9B, 0xFF, 0x5D, 0x01, 0xEC, 0xFC, 0x5D, 0x05, 0x2F, 0xF8, + 0x19, 0x0A, 0x07, 0x43, 0x37, 0x08, 0xDD, 0xF8, 0x21, 0x05, 0xF8, + 0xFC, 0x62, 0x01, 0x96, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, + 0xB4, 0xFF, 0x3E, 0x01, 0xE4, 0xFC, 0xF6, 0x05, 0x26, 0xF6, 0x95, + 0x10, 0x26, 0x42, 0x87, 0x02, 0x28, 0xFB, 0x37, 0x04, 0x3B, 0xFD, + 0x60, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF7, 0xFF, 0xD7, + 0xFF, 0x04, 0x01, 0x0F, 0xFD, 0x3E, 0x06, 0x7D, 0xF4, 0x76, 0x17, + 0xF4, 0x3F, 0x9F, 0xFD, 0x7B, 0xFD, 0x26, 0x03, 0xA0, 0xFD, 0x4A, + 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE9, 0xFF, 0x04, 0x00, + 0xB1, 0x00, 0x71, 0xFD, 0x26, 0x06, 0x5A, 0xF3, 0x88, 0x1E, 0x87, + 0x3C, 0x98, 0xF9, 0xB3, 0xFF, 0x02, 0x02, 0x1E, 0xFE, 0x22, 0x01, + 0x93, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD7, 0xFF, 0x3A, 0x00, 0x45, + 0x00, 0x09, 0xFE, 0xA7, 0x05, 0xE1, 0xF2, 0x8D, 0x25, 0xFD, 0x37, + 0x82, 0xF6, 0xB5, 0x01, 0xDC, 0x00, 0xAA, 0xFE, 0xEE, 0x00, 0xA0, + 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC4, 0xFF, 0x76, 0x00, 0xC7, 0xFF, + 0xD3, 0xFE, 0xBC, 0x04, 0x31, 0xF3, 0x4A, 0x2C, 0x83, 0x32, 0x61, + 0xF4, 0x68, 0x03, 0xC8, 0xFF, 0x3B, 0xFF, 0xB3, 0x00, 0xB1, 0xFF, + 0x0A, 0x00, 0x0A, 0x00, 0xB1, 0xFF, 0xB3, 0x00, 0x3B, 0xFF, 0xC8, + 0xFF, 0x68, 0x03, 0x61, 0xF4, 0x83, 0x32, 0x4A, 0x2C, 0x31, 0xF3, + 0xBC, 0x04, 0xD3, 0xFE, 0xC7, 0xFF, 0x76, 0x00, 0xC4, 0xFF, 0x06, + 0x00, 0x0D, 0x00, 0xA0, 0xFF, 0xEE, 0x00, 0xAA, 0xFE, 0xDC, 0x00, + 0xB5, 0x01, 0x82, 0xF6, 0xFD, 0x37, 0x8D, 0x25, 0xE1, 0xF2, 0xA7, + 0x05, 0x09, 0xFE, 0x45, 0x00, 0x3A, 0x00, 0xD7, 0xFF, 0x04, 0x00, + 0x0F, 0x00, 0x93, 0xFF, 0x22, 0x01, 0x1E, 0xFE, 0x02, 0x02, 0xB3, + 0xFF, 0x98, 0xF9, 0x87, 0x3C, 0x88, 0x1E, 0x5A, 0xF3, 0x26, 0x06, + 0x71, 0xFD, 0xB1, 0x00, 0x04, 0x00, 0xE9, 0xFF, 0x02, 0x00, 0x11, + 0x00, 0x8B, 0xFF, 0x4A, 0x01, 0xA0, 0xFD, 0x26, 0x03, 0x7B, 0xFD, + 0x9F, 0xFD, 0xF4, 0x3F, 0x76, 0x17, 0x7D, 0xF4, 0x3E, 0x06, 0x0F, + 0xFD, 0x04, 0x01, 0xD7, 0xFF, 0xF7, 0xFF, 0x01, 0x00, 0x10, 0x00, + 0x8C, 0xFF, 0x60, 0x01, 0x3B, 0xFD, 0x37, 0x04, 0x28, 0xFB, 0x87, + 0x02, 0x26, 0x42, 0x95, 0x10, 0x26, 0xF6, 0xF6, 0x05, 0xE4, 0xFC, + 0x3E, 0x01, 0xB4, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x96, + 0xFF, 0x62, 0x01, 0xF8, 0xFC, 0x21, 0x05, 0xDD, 0xF8, 0x37, 0x08, + 0x07, 0x43, 0x19, 0x0A, 0x2F, 0xF8, 0x5D, 0x05, 0xEC, 0xFC, 0x5D, + 0x01, 0x9B, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0xAB, 0xFF, 0x4A, 0x01, 0xE1, 0xFC, 0xCF, 0x05, 0xBE, 0xF6, 0x89, + 0x0E, 0x90, 0x42, 0x34, 0x04, 0x71, 0xFA, 0x84, 0x04, 0x22, 0xFD, + 0x63, 0x01, 0x8E, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xCB, + 0xFF, 0x19, 0x01, 0xFC, 0xFC, 0x31, 0x06, 0xF4, 0xF4, 0x51, 0x15, + 0xC3, 0x40, 0x0B, 0xFF, 0xC5, 0xFC, 0x7D, 0x03, 0x7E, 0xFD, 0x53, + 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xED, 0xFF, 0xF5, 0xFF, + 0xCD, 0x00, 0x4D, 0xFD, 0x38, 0x06, 0xA3, 0xF3, 0x5A, 0x1C, 0xB5, + 0x3D, 0xBC, 0xFA, 0x09, 0xFF, 0x5C, 0x02, 0xF5, 0xFD, 0x30, 0x01, + 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDD, 0xFF, 0x29, 0x00, 0x69, + 0x00, 0xD4, 0xFD, 0xD9, 0x05, 0xF3, 0xF2, 0x69, 0x23, 0x7E, 0x39, + 0x5B, 0xF7, 0x1E, 0x01, 0x36, 0x01, 0x7E, 0xFE, 0xFF, 0x00, 0x9B, + 0xFF, 0x0E, 0x00, 0x06, 0x00, 0xCA, 0xFF, 0x63, 0x00, 0xEF, 0xFF, + 0x90, 0xFE, 0x0F, 0x05, 0x02, 0xF3, 0x43, 0x2A, 0x49, 0x34, 0xEF, + 0xF4, 0xEB, 0x02, 0x1A, 0x00, 0x0E, 0xFF, 0xC6, 0x00, 0xAC, 0xFF, + 0x0B, 0x00, 0x09, 0x00, 0xB7, 0xFF, 0xA0, 0x00, 0x67, 0xFF, 0x79, + 0xFF, 0xDB, 0x03, 0xEB, 0xF3, 0xAA, 0x30, 0x45, 0x2E, 0x76, 0xF3, + 0x5E, 0x04, 0x1A, 0xFF, 0x9D, 0xFF, 0x89, 0x00, 0xBE, 0xFF, 0x07, + 0x00, 0x0C, 0x00, 0xA5, 0xFF, 0xDD, 0x00, 0xD7, 0xFE, 0x85, 0x00, + 0x44, 0x02, 0xC0, 0xF5, 0x66, 0x36, 0xAB, 0x27, 0xE3, 0xF2, 0x6A, + 0x05, 0x42, 0xFE, 0x20, 0x00, 0x4C, 0x00, 0xD1, 0xFF, 0x04, 0x00, + 0x0F, 0x00, 0x96, 0xFF, 0x13, 0x01, 0x48, 0xFE, 0xA7, 0x01, 0x58, + 0x00, 0x8B, 0xF8, 0x3C, 0x3B, 0xB4, 0x20, 0x22, 0xF3, 0x0A, 0x06, + 0x9A, 0xFD, 0x92, 0x00, 0x14, 0x00, 0xE3, 0xFF, 0x02, 0x00, 0x10, + 0x00, 0x8D, 0xFF, 0x3F, 0x01, 0xC4, 0xFD, 0xCD, 0x02, 0x2E, 0xFE, + 0x49, 0xFC, 0x06, 0x3F, 0xA1, 0x19, 0x14, 0xF4, 0x41, 0x06, 0x27, + 0xFD, 0xED, 0x00, 0xE4, 0xFF, 0xF3, 0xFF, 0x01, 0x00, 0x10, 0x00, + 0x8B, 0xFF, 0x5B, 0x01, 0x57, 0xFD, 0xE6, 0x03, 0xE0, 0xFB, 0xEE, + 0x00, 0x9C, 0x41, 0xAB, 0x12, 0x98, 0xF5, 0x16, 0x06, 0xEC, 0xFC, + 0x2F, 0x01, 0xBD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x92, + 0xFF, 0x64, 0x01, 0x09, 0xFD, 0xDE, 0x04, 0x8E, 0xF9, 0x64, 0x06, + 0xE6, 0x42, 0x0A, 0x0C, 0x87, 0xF7, 0x94, 0x05, 0xE5, 0xFC, 0x56, + 0x01, 0xA2, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0xA3, 0xFF, 0x54, 0x01, 0xE3, 0xFC, 0xA1, 0x05, 0x5E, 0xF7, 0x88, + 0x0C, 0xD9, 0x42, 0xF2, 0x05, 0xBB, 0xF9, 0xCD, 0x04, 0x0D, 0xFD, + 0x64, 0x01, 0x91, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0xFF, 0x2B, 0x01, 0xEE, 0xFC, 0x1C, 0x06, 0x75, 0xF5, 0x32, 0x13, + 0x75, 0x41, 0x8B, 0x00, 0x0E, 0xFC, 0xD2, 0x03, 0x5E, 0xFD, 0x5A, + 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF2, 0xFF, 0xE7, 0xFF, + 0xE7, 0x00, 0x2E, 0xFD, 0x41, 0x06, 0xFC, 0xF3, 0x2C, 0x1A, 0xC6, + 0x3E, 0xF7, 0xFB, 0x5A, 0xFE, 0xB7, 0x02, 0xCE, 0xFD, 0x3C, 0x01, + 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE2, 0xFF, 0x18, 0x00, 0x8A, + 0x00, 0xA5, 0xFD, 0x02, 0x06, 0x16, 0xF3, 0x3F, 0x21, 0xE6, 0x3A, + 0x4B, 0xF8, 0x81, 0x00, 0x90, 0x01, 0x53, 0xFE, 0x0F, 0x01, 0x97, + 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xD0, 0xFF, 0x50, 0x00, 0x17, 0x00, + 0x51, 0xFE, 0x59, 0x05, 0xE7, 0xF2, 0x31, 0x28, 0xFB, 0x35, 0x93, + 0xF5, 0x66, 0x02, 0x6F, 0x00, 0xE2, 0xFE, 0xD8, 0x00, 0xA6, 0xFF, + 0x0C, 0x00, 0x08, 0x00, 0xBD, 0xFF, 0x8D, 0x00, 0x92, 0xFF, 0x2D, + 0xFF, 0x45, 0x04, 0x8B, 0xF3, 0xC1, 0x2E, 0x31, 0x30, 0xD1, 0xF3, + 0xF6, 0x03, 0x65, 0xFF, 0x72, 0xFF, 0x9B, 0x00, 0xB8, 0xFF, 0x08, + 0x00, 0x0B, 0x00, 0xAA, 0xFF, 0xCA, 0x00, 0x03, 0xFF, 0x2F, 0x00, + 0xCB, 0x02, 0x16, 0xF5, 0xB8, 0x34, 0xC0, 0x29, 0xF9, 0xF2, 0x23, + 0x05, 0x80, 0xFE, 0xF9, 0xFF, 0x5E, 0x00, 0xCC, 0xFF, 0x05, 0x00, + 0x0E, 0x00, 0x9A, 0xFF, 0x03, 0x01, 0x73, 0xFE, 0x4C, 0x01, 0xF7, + 0x00, 0x94, 0xF7, 0xDB, 0x39, 0xDF, 0x22, 0xFA, 0xF2, 0xE5, 0x05, + 0xC8, 0xFD, 0x71, 0x00, 0x25, 0x00, 0xDE, 0xFF, 0x03, 0x00, 0x10, + 0x00, 0x8F, 0xFF, 0x33, 0x01, 0xEB, 0xFD, 0x73, 0x02, 0xDE, 0xFE, + 0x08, 0xFB, 0xFB, 0x3D, 0xCE, 0x1B, 0xB8, 0xF3, 0x3B, 0x06, 0x45, + 0xFD, 0xD4, 0x00, 0xF2, 0xFF, 0xEF, 0xFF, 0x01, 0x00, 0x11, 0x00, + 0x8A, 0xFF, 0x55, 0x01, 0x75, 0xFD, 0x92, 0x03, 0x97, 0xFC, 0x69, + 0xFF, 0xF2, 0x40, 0xC8, 0x14, 0x13, 0xF5, 0x2D, 0x06, 0xF8, 0xFC, + 0x1E, 0x01, 0xC8, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x8F, + 0xFF, 0x64, 0x01, 0x1D, 0xFD, 0x97, 0x04, 0x43, 0xFA, 0xA1, 0x04, + 0xA5, 0x42, 0x08, 0x0E, 0xE6, 0xF6, 0xC4, 0x05, 0xE1, 0xFC, 0x4D, + 0x01, 0xA9, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, + 0x9D, 0xFF, 0x5C, 0x01, 0xEA, 0xFC, 0x6C, 0x05, 0x05, 0xF8, 0x94, + 0x0A, 0x03, 0x43, 0xC1, 0x07, 0x09, 0xF9, 0x10, 0x05, 0xFC, 0xFC, + 0x62, 0x01, 0x95, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB6, + 0xFF, 0x3B, 0x01, 0xE5, 0xFC, 0xFF, 0x05, 0x02, 0xF6, 0x19, 0x11, + 0x06, 0x42, 0x1F, 0x02, 0x56, 0xFB, 0x23, 0x04, 0x41, 0xFD, 0x5F, + 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF6, 0xFF, 0xDA, 0xFF, + 0xFF, 0x00, 0x15, 0xFD, 0x40, 0x06, 0x62, 0xF4, 0x01, 0x18, 0xBB, + 0x3F, 0x47, 0xFD, 0xA8, 0xFD, 0x10, 0x03, 0xA9, 0xFD, 0x47, 0x01, + 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE7, 0xFF, 0x08, 0x00, 0xA9, + 0x00, 0x7B, 0xFD, 0x20, 0x06, 0x4B, 0xF3, 0x13, 0x1F, 0x36, 0x3C, + 0x52, 0xF9, 0xDD, 0xFF, 0xEB, 0x01, 0x28, 0xFE, 0x1F, 0x01, 0x93, + 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD6, 0xFF, 0x3F, 0x00, 0x3C, 0x00, + 0x16, 0xFE, 0x98, 0x05, 0xE0, 0xF2, 0x16, 0x26, 0x99, 0x37, 0x4F, + 0xF6, 0xD9, 0x01, 0xC6, 0x00, 0xB5, 0xFE, 0xEA, 0x00, 0xA1, 0xFF, + 0x0D, 0x00, 0x07, 0x00, 0xC3, 0xFF, 0x7A, 0x00, 0xBC, 0xFF, 0xE4, + 0xFE, 0xA5, 0x04, 0x41, 0xF3, 0xCA, 0x2C, 0x0E, 0x32, 0x42, 0xF4, + 0x85, 0x03, 0xB4, 0xFF, 0x46, 0xFF, 0xAE, 0x00, 0xB3, 0xFF, 0x09, + 0x00, 0x0A, 0x00, 0xB0, 0xFF, 0xB8, 0x00, 0x30, 0xFF, 0xDC, 0xFF, + 0x49, 0x03, 0x83, 0xF4, 0xF5, 0x32, 0xC9, 0x2B, 0x23, 0xF3, 0xD1, + 0x04, 0xC2, 0xFE, 0xD1, 0xFF, 0x71, 0x00, 0xC6, 0xFF, 0x06, 0x00, + 0x0D, 0x00, 0x9F, 0xFF, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, 0x90, + 0x01, 0xB6, 0xF6, 0x5F, 0x38, 0x04, 0x25, 0xE4, 0xF2, 0xB4, 0x05, + 0xFB, 0xFD, 0x4E, 0x00, 0x36, 0x00, 0xD9, 0xFF, 0x04, 0x00, 0x0F, + 0x00, 0x92, 0xFF, 0x26, 0x01, 0x13, 0xFE, 0x18, 0x02, 0x89, 0xFF, + 0xDF, 0xF9, 0xD3, 0x3C, 0xFC, 0x1D, 0x6B, 0xF3, 0x2C, 0x06, 0x67, + 0xFD, 0xB8, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0x02, 0x00, 0x11, 0x00, + 0x8B, 0xFF, 0x4C, 0x01, 0x97, 0xFD, 0x3C, 0x03, 0x4D, 0xFD, 0xF8, + 0xFD, 0x2A, 0x40, 0xED, 0x16, 0x9A, 0xF4, 0x3C, 0x06, 0x0A, 0xFD, + 0x0A, 0x01, 0xD4, 0xFF, 0xF8, 0xFF, 0x01, 0x00, 0x10, 0x00, 0x8C, + 0xFF, 0x61, 0x01, 0x34, 0xFD, 0x4B, 0x04, 0xFA, 0xFA, 0xF1, 0x02, + 0x42, 0x42, 0x11, 0x10, 0x4C, 0xF6, 0xED, 0x05, 0xE3, 0xFC, 0x41, + 0x01, 0xB1, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x97, 0xFF, + 0x61, 0x01, 0xF5, 0xFC, 0x30, 0x05, 0xB1, 0xF8, 0xAE, 0x08, 0x0A, + 0x43, 0x9F, 0x09, 0x5A, 0xF8, 0x4F, 0x05, 0xEF, 0xFC, 0x5F, 0x01, + 0x9A, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xAD, + 0xFF, 0x48, 0x01, 0xE2, 0xFC, 0xDA, 0x05, 0x97, 0xF6, 0x0B, 0x0F, + 0x79, 0x42, 0xC7, 0x03, 0x9E, 0xFA, 0x71, 0x04, 0x28, 0xFD, 0x63, + 0x01, 0x8D, 0xFF, 0x0F, 0x00 +}; + +static u16 +CoefficientSizes[] = { + /* Playback */ + 0x00C0, 0x5000, 0x0060, 0x2800, 0x0040, 0x0060, 0x1400, 0x0000, + /* Record */ + 0x0020, 0x1260, 0x0020, 0x1260, 0x0000, 0x0040, 0x1260, 0x0000, +}; + +#ifndef JUST_DATA + +static u16 +nm256_getStartOffset (u8 which) +{ + u16 offset = 0; + + while (which-- > 0) + offset += CoefficientSizes[which]; + + return offset; +} + +static void +nm256_loadOneCoefficient (struct nm256_info *card, u32 port, u16 which) +{ + u32 coeffBuf = (which < 8) ? card->coeffBuf : card->allCoeffBuf; + u16 offset = nm256_getStartOffset (which); + u16 size = CoefficientSizes[which]; + + card->coeffsCurrent = 0; + + if (nm256_debug) + printk (KERN_INFO "NM256: Loading coefficient buffer 0x%x-0x%x with coefficient %d\n", + coeffBuf, coeffBuf + size - 1, which); + nm256_writeBuffer8 (card, coefficients + offset, 1, coeffBuf, size); + nm256_writePort32 (card, 2, port + 0, coeffBuf); + nm256_writePort32 (card, 2, port + 4, coeffBuf + size - 1); +} + +static void +nm256_loadAllCoefficients (struct nm256_info *card) +{ + nm256_writeBuffer8 (card, coefficients, 1, card->allCoeffBuf, + NM_TOTAL_COEFF_COUNT * 4); + card->coeffsCurrent = 1; +} + +void +nm256_loadCoefficient (struct nm256_info *card, int which, int number) +{ + static u16 addrs[3] = { 0x1c, 0x21c, 0x408 }; + /* The enable register for the specified engine. */ + u32 poffset = (which == 1 ? 0x200 : 1); + + if (nm256_readPort8 (card, 2, poffset) & 1) { + printk (KERN_ERR "NM256: Engine was enabled while loading coefficients!\n"); + return; + } + + /* The recording engine uses coefficient values 8-15. */ + if (which == 1) + number += 8; + + if (! nm256_cachedCoefficients (card)) + nm256_loadOneCoefficient (card, addrs[which], number); + else { + u32 base = card->allCoeffBuf; + u32 offset = nm256_getStartOffset (number); + u32 endOffset = offset + CoefficientSizes[number]; + + if (nm256_debug) + printk (KERN_DEBUG "loading coefficient %d at port 0x%x, offset %d (0x%x-0x%x)\n", + number, addrs[which], offset, base + offset, + base + endOffset - 1); + + if (! card->coeffsCurrent) + nm256_loadAllCoefficients (card); + + nm256_writePort32 (card, 2, addrs[which], base + offset); + nm256_writePort32 (card, 2, addrs[which] + 4, base + endOffset - 1); + } +} + +#endif /* JUST_DATA */ + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/sound/opl3.c b/drivers/sound/opl3.c index 8898c655a..295ccfa17 100644 --- a/drivers/sound/opl3.c +++ b/drivers/sound/opl3.c @@ -32,8 +32,6 @@ #include "sound_config.h" #include "soundmodule.h" -#ifdef CONFIG_YM3812 - #include "opl3.h" #define MAX_VOICE 18 @@ -1218,10 +1216,10 @@ void cleanup_module(void) SOUND_LOCK_END; } +MODULE_PARM(io, "i"); + #endif EXPORT_SYMBOL(opl3_init); EXPORT_SYMBOL(opl3_detect); -MODULE_PARM(io, "i"); -#endif diff --git a/drivers/sound/opl3sa.c b/drivers/sound/opl3sa.c index 341438748..9e5fd5a6b 100644 --- a/drivers/sound/opl3sa.c +++ b/drivers/sound/opl3sa.c @@ -187,7 +187,7 @@ int probe_opl3sa_mpu(struct address_info *hw_config) { #if defined(CONFIG_UART401) && defined(CONFIG_MIDI) unsigned char conf; - static char irq_bits[] = { + static signed char irq_bits[] = { -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4 }; diff --git a/drivers/sound/sb_audio.c b/drivers/sound/sb_audio.c index baca53992..f91d3dcdf 100644 --- a/drivers/sound/sb_audio.c +++ b/drivers/sound/sb_audio.c @@ -742,6 +742,14 @@ static void sb16_audio_output_block(int dev, unsigned long buf, int count, restore_flags(flags); } + +/* + * This fails on the Cyrix MediaGX. If you don't have the DMA enabled + * before the first sample arrives it locks up. However even if you + * do enable the DMA in time you just get DMA timeouts and missing + * interrupts and stuff, so for now I've not bothered fixing this either. + */ + static void sb16_audio_start_input(int dev, unsigned long buf, int count, int intrflag) { unsigned long flags, cnt; diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c index 44b40e736..a21da2d69 100644 --- a/drivers/sound/sb_card.c +++ b/drivers/sound/sb_card.c @@ -179,7 +179,7 @@ int init_module(void) return -ENODEV; #ifdef CONFIG_MIDI config_mpu.io_base = mpu_io; - if (mpu_io && probe_sbmpu(&config_mpu)) + if (probe_sbmpu(&config_mpu)) sbmpu = 1; if (sbmpu) attach_sbmpu(&config_mpu); diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index e55696f36..37dd03f4f 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -18,7 +18,7 @@ */ #include <linux/config.h> #include <linux/delay.h> -#include <asm/init.h> +#include <linux/init.h> #include "sound_config.h" #include "sound_firmware.h" @@ -116,7 +116,8 @@ static void sb_intr (sb_devc *devc) #if defined(CONFIG_MIDI)&& defined(CONFIG_UART401) if (src & 4) /* MPU401 interrupt */ - uart401intr(devc->irq, devc->midi_irq_cookie, NULL); + if(devc->midi_irq_cookie) + uart401intr(devc->irq, devc->midi_irq_cookie, NULL); #endif if (!(src & 3)) @@ -897,7 +898,7 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu) } if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI)) { - if (devc->irq > 0); + if (devc->irq > 0) free_irq(devc->irq, devc); sound_unload_mixerdev(devc->my_mixerdev); @@ -1215,7 +1216,17 @@ int probe_sbmpu(struct address_info *hw_config) last_devc = 0; if (hw_config->io_base <= 0) + { + /* The real vibra16 is fine about this, but we have to go + wipe up after Cyrix again */ + + if(devc->model == MDL_SB16 && devc->minor >= 12) + { + unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06; + sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */ + } return 0; + } #if defined(CONFIG_SOUND_MPU401) if (devc->model == MDL_ESS) diff --git a/drivers/sound/sb_ess.c b/drivers/sound/sb_ess.c index c43ebf130..e4664b06a 100644 --- a/drivers/sound/sb_ess.c +++ b/drivers/sound/sb_ess.c @@ -1200,7 +1200,9 @@ FKS_test (devc); /* AAS: info stolen from ALSA: these boards have different clocks */ switch(devc->submodel) { +/* APPARENTLY NOT 1869 case SUBMDL_ES1869: +*/ case SUBMDL_ES1887: case SUBMDL_ES1888: devc->caps |= SB_CAP_ES18XX_RATE; diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c index 0e696b113..8b8190cb1 100644 --- a/drivers/sound/sonicvibes.c +++ b/drivers/sound/sonicvibes.c @@ -70,6 +70,17 @@ * Note: dmaio hack might still be wrong on archs other than i386 * 15.06.99 0.15 Fix bad allocation bug. * Thanks to Deti Fliegl <fliegl@in.tum.de> + * 28.06.99 0.16 Add pci_set_master + * 03.08.99 0.17 adapt to Linus' new __setup/__initcall + * added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr" + * 12.08.99 0.18 module_init/__setup fixes + * 24.08.99 0.19 get rid of the dmaio kludge, replace with allocate_resource + * 31.08.99 0.20 add spin_lock_init + * __initlocaldata to fix gcc 2.7.x problems + * use new resource allocation to allocate DDMA IO space + * replaced current->state = x with set_current_state(x) + * 03.09.99 0.21 change read semantics for MIDI to match + * OSS more closely; remove possible wakeup race * */ @@ -89,7 +100,7 @@ #include <asm/dma.h> #include <linux/init.h> #include <linux/poll.h> -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/hardirq.h> @@ -117,6 +128,12 @@ #define SV_EXTENT_GAME 0x8 #define SV_EXTENT_DMA 0x10 +#define RESOURCE_SB 0 +#define RESOURCE_ENH 1 +#define RESOURCE_SYNTH 2 +#define RESOURCE_MIDI 3 +#define RESOURCE_GAME 4 +#define RESOURCE_DDMA 7 #define SV_MIDI_DATA 0 #define SV_MIDI_COMMAND 1 @@ -1250,7 +1267,7 @@ static int drain_dac(struct sv_state *s, int nonblock) if (s->dma_dac.mapped || !s->dma_dac.ready) return 0; - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac.wait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1262,16 +1279,16 @@ static int drain_dac(struct sv_state *s, int nonblock) break; if (nonblock) { remove_wait_queue(&s->dma_dac.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } - tmo = (count * HZ) / s->ratedac; + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "sv: dma timed out??\n"); } remove_wait_queue(&s->dma_dac.wait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; return 0; @@ -1870,6 +1887,7 @@ static /*const*/ struct file_operations sv_audio_fops = { static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct sv_state *s = (struct sv_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1880,7 +1898,10 @@ static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_ return -ESPIPE; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.iwait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.ird; @@ -1891,15 +1912,25 @@ static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_ if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.iwait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIINBUF; spin_lock_irqsave(&s->lock, flags); s->midi.ird = ptr; @@ -1908,13 +1939,17 @@ static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_ count -= cnt; buffer += cnt; ret += cnt; + break; } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); return ret; } static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct sv_state *s = (struct sv_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1925,7 +1960,10 @@ static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count return -ESPIPE; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.owait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.owr; @@ -1938,15 +1976,25 @@ static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.owait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIOUTBUF; spin_lock_irqsave(&s->lock, flags); s->midi.owr = ptr; @@ -1959,6 +2007,8 @@ static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count sv_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); return ret; } @@ -2053,7 +2103,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -2065,7 +2115,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) break; if (file->f_flags & O_NONBLOCK) { remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } tmo = (count * HZ) / 3100; @@ -2073,7 +2123,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) printk(KERN_DEBUG "sv: midi timed out??\n"); } remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); } down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); @@ -2292,7 +2342,15 @@ static int reverb[NR_DEVICE] = { 0, }; static int wavetable[NR_DEVICE] = { 0, }; #endif -static unsigned dmaio = 0xac00; +MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); +#if 0 +MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); +#endif + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("S3 SonicVibes Driver"); /* --------------------------------------------------------------------- */ @@ -2311,37 +2369,54 @@ static struct initvol { { SOUND_MIXER_WRITE_PCM, 0x4040 } }; -#ifdef MODULE -int __init init_module(void) -#else -int __init init_sonicvibes(void) -#endif +#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \ + ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) +#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) + +static int __init init_sonicvibes(void) { - struct sv_state *s; + static const char __initlocaldata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller"; + struct sv_state *s; struct pci_dev *pcidev = NULL; mm_segment_t fs; int i, val, index = 0; + char *ddmaname; + unsigned ddmanamelen; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "sv: version v0.15 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "sv: version v0.20 time " __TIME__ " " __DATE__ "\n"); #if 0 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); #endif while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, pcidev))) { - if (pcidev->base_address[1] == 0 || - (pcidev->base_address[1] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) - continue; - if (pcidev->base_address[2] == 0 || - (pcidev->base_address[2] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) - continue; - if (pcidev->base_address[3] == 0 || - (pcidev->base_address[3] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + if (!RSRCISIOREGION(pcidev, RESOURCE_SB) || + !RSRCISIOREGION(pcidev, RESOURCE_ENH) || + !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) || + !RSRCISIOREGION(pcidev, RESOURCE_MIDI) || + !RSRCISIOREGION(pcidev, RESOURCE_GAME)) continue; if (pcidev->irq == 0) continue; + /* try to allocate a DDMA resource if not already available */ + if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) { + /* take care of ISA aliases */ + ddmanamelen = strlen(sv_ddma_name)+1; + if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL))) + continue; + memcpy(ddmaname, sv_ddma_name, ddmanamelen); + pcidev->resource[RESOURCE_DDMA].name = ddmaname; + if (allocate_resource(&ioport_resource, pcidev->resource+RESOURCE_DDMA, + 2*SV_EXTENT_DMA, 0x1000, 0x10000-2*SV_EXTENT_DMA, 1024)) { + pcidev->resource[RESOURCE_DDMA].name = NULL; + kfree(ddmaname); + printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n"); + continue; + } + pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO; + } if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) { printk(KERN_WARNING "sv: out of memory\n"); continue; @@ -2353,35 +2428,19 @@ int __init init_sonicvibes(void) init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); s->magic = SV_MAGIC; - s->iosb = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; - s->ioenh = pcidev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; - s->iosynth = pcidev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK; - s->iomidi = pcidev->base_address[3] & PCI_BASE_ADDRESS_IO_MASK; - s->iogame = pcidev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; - pci_read_config_dword(pcidev, 0x40, &s->iodmaa); - pci_read_config_dword(pcidev, 0x48, &s->iodmac); - dmaio &= ~(SV_EXTENT_DMA-1); - s->iodmaa &= ~(SV_EXTENT_DMA-1); - s->iodmac &= ~(SV_EXTENT_DMA-1); - if (!(s->iodmaa)) { - s->iodmaa = dmaio; - dmaio += SV_EXTENT_DMA; - printk(KERN_INFO "sv: BIOS did not allocate DDMA channel A io, allocated at %#x\n", - s->iodmaa); - } - if (!(s->iodmac)) { - s->iodmac = dmaio; - dmaio += SV_EXTENT_DMA; - printk(KERN_INFO "sv: BIOS did not allocate DDMA channel C io, allocated at %#x\n", - s->iodmac); - } + s->iosb = RSRCADDRESS(pcidev, RESOURCE_SB); + s->ioenh = RSRCADDRESS(pcidev, RESOURCE_ENH); + s->iosynth = RSRCADDRESS(pcidev, RESOURCE_SYNTH); + s->iomidi = RSRCADDRESS(pcidev, RESOURCE_MIDI); + s->iogame = RSRCADDRESS(pcidev, RESOURCE_GAME); + s->iodmaa = RSRCADDRESS(pcidev, RESOURCE_DDMA); + s->iodmac = RSRCADDRESS(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA; pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */ pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */ printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n", s->iosb, s->ioenh, s->iosynth, s->iomidi, s->iogame, s->iodmaa, s->iodmac); - if (s->ioenh == 0 || s->iodmaa == 0 || s->iodmac == 0) - continue; s->irq = pcidev->irq; /* hack */ @@ -2423,8 +2482,8 @@ int __init init_sonicvibes(void) wrindir(s, SV_CIDRIVECONTROL, 0); /* drive current 16mA */ wrindir(s, SV_CIENABLE, s->enable = 0); /* disable DMAA and DMAC */ outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK); - //outb(0xff, s->iodmaa + SV_DMA_RESET); - //outb(0xff, s->iodmac + SV_DMA_RESET); + /* outb(0xff, s->iodmaa + SV_DMA_RESET); */ + /* outb(0xff, s->iodmac + SV_DMA_RESET); */ inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */ wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */ @@ -2450,6 +2509,7 @@ int __init init_sonicvibes(void) goto err_dev3; if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) goto err_dev4; + pci_set_master(pcidev); /* enable bus mastering */ /* initialize the chips */ fs = get_fs(); set_fs(KERNEL_DS); @@ -2496,24 +2556,7 @@ int __init init_sonicvibes(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); -#if 0 -MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); -#endif - -MODULE_PARM(dmaio, "i"); -MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate them starting at this address"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("S3 SonicVibes Driver"); - -void cleanup_module(void) +static void __exit cleanup_sonicvibes(void) { struct sv_state *s; @@ -2523,8 +2566,8 @@ void cleanup_module(void) synchronize_irq(); inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ wrindir(s, SV_CIENABLE, 0); /* disable DMAA and DMAC */ - //outb(0, s->iodmaa + SV_DMA_RESET); - //outb(0, s->iodmac + SV_DMA_RESET); + /*outb(0, s->iodmaa + SV_DMA_RESET);*/ + /*outb(0, s->iodmac + SV_DMA_RESET);*/ free_irq(s->irq, s); release_region(s->iodmac, SV_EXTENT_DMA); release_region(s->iodmaa, SV_EXTENT_DMA); @@ -2542,4 +2585,32 @@ void cleanup_module(void) printk(KERN_INFO "sv: unloading\n"); } +module_init(init_sonicvibes); +module_exit(cleanup_sonicvibes); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE + +/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */ + +static int __init sonicvibes_setup(char *str) +{ + static unsigned __initlocaldata nr_dev = 0; + + if (nr_dev >= NR_DEVICE) + return 0; +#if 0 + if (get_option(&str, &reverb[nr_dev]) == 2) + (void)get_option(&str, &wavetable[nr_dev]); +#else + (void)get_option(&str, &reverb[nr_dev]); +#endif + + nr_dev++; + return 1; +} + +__setup("sonicvibes=", sonicvibes_setup); + #endif /* MODULE */ diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h index 8fa4685ff..1029df1f2 100644 --- a/drivers/sound/sound_calls.h +++ b/drivers/sound/sound_calls.h @@ -157,6 +157,7 @@ void gus_midi_interrupt(int dummy); /* From mpu401.c */ void attach_mpu401(struct address_info * hw_config); int probe_mpu401(struct address_info *hw_config); +int intchk_mpu401(void *dev_id); void mpuintr(int irq, void *dev_id, struct pt_regs * dummy); /* From uart6850.c */ diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index a1ec23557..8e31dfe12 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -52,15 +52,6 @@ struct sound_unit struct sound_unit *next; }; -#ifdef CONFIG_SOUND_SONICVIBES -extern int init_sonicvibes(void); -#endif -#ifdef CONFIG_SOUND_ES1370 -extern int init_es1370(void); -#endif -#ifdef CONFIG_SOUND_ES1371 -extern int init_es1371(void); -#endif #ifdef CONFIG_SOUND_MSNDCLAS extern int msnd_classic_init(void); #endif @@ -395,23 +386,17 @@ int soundcore_init(void) /* * Now init non OSS drivers */ -#ifdef CONFIG_SOUND_SONICVIBES - init_sonicvibes(); -#endif #ifdef CONFIG_SOUND_CMPCI init_cmpci(); #endif -#ifdef CONFIG_SOUND_ES1370 - init_es1370(); -#endif -#ifdef CONFIG_SOUND_ES1371 - init_es1371(); -#endif #ifdef CONFIG_SOUND_MSNDCLAS msnd_classic_init(); #endif #ifdef CONFIG_SOUND_MSNDPIN msnd_pinnacle_init(); #endif +#ifdef CONFIG_SOUND_VWSND + init_vwsnd(); +#endif return 0; } diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 6731180b4..631dea62e 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -39,6 +39,7 @@ #endif /* __KERNEL__ */ #include <linux/delay.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> #include "soundmodule.h" struct notifier_block *sound_locker=(struct notifier_block *)0; @@ -375,60 +376,76 @@ static ssize_t sndstat_file_read(struct file * file, char * buf, size_t nbytes, static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos) { int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int ret = -EINVAL; + /* + * The OSS drivers aren't remotely happy without this locking, + * and unless someone fixes them when they are about to bite the + * big one anyway, we might as well bandage here.. + */ + + lock_kernel(); + DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count)); switch (dev & 0x0f) { case SND_DEV_STATUS: - return sndstat_file_read(file, buf, count, ppos); + ret = sndstat_file_read(file, buf, count, ppos); #ifdef CONFIG_AUDIO case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - return audio_read(dev, file, buf, count); + ret = audio_read(dev, file, buf, count); + break; #endif #ifdef CONFIG_SEQUENCER case SND_DEV_SEQ: case SND_DEV_SEQ2: - return sequencer_read(dev, file, buf, count); + ret = sequencer_read(dev, file, buf, count); + break; #endif #ifdef CONFIG_MIDI case SND_DEV_MIDIN: - return MIDIbuf_read(dev, file, buf, count); + ret = MIDIbuf_read(dev, file, buf, count); #endif - - default:; } - return -EINVAL; + unlock_kernel(); + return ret; } static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { int dev = MINOR(file->f_dentry->d_inode->i_rdev); - + int ret = -EINVAL; + + lock_kernel(); DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count)); switch (dev & 0x0f) { #ifdef CONFIG_SEQUENCER case SND_DEV_SEQ: case SND_DEV_SEQ2: - return sequencer_write(dev, file, buf, count); + ret = sequencer_write(dev, file, buf, count); + break; #endif #ifdef CONFIG_AUDIO case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - return audio_write(dev, file, buf, count); + ret = audio_write(dev, file, buf, count); + break; #endif #ifdef CONFIG_MIDI case SND_DEV_MIDIN: - return MIDIbuf_write(dev, file, buf, count); + ret = MIDIbuf_write(dev, file, buf, count); + break; #endif } - return -EINVAL; + unlock_kernel(); + return ret; } static long long sound_lseek(struct file *file, long long offset, int orig) @@ -858,8 +875,11 @@ static int sound[20] = { int traceinit = 0; static int dmabuf = 0; +static int dmabug = 0; + MODULE_PARM(traceinit, "i"); MODULE_PARM(dmabuf, "i"); +MODULE_PARM(dmabug, "i"); int init_module(void) { @@ -868,6 +888,15 @@ int init_module(void) int i; trace_init=traceinit; + +#ifdef HAS_BRIDGE_BUGGY_FUNC + if(dmabug) + isa_dma_bridge_buggy = dmabug; +#else + if(dmabug) + printk(KERN_ERR "sound: rebuild with PCI_QUIRKS enabled to configure this.\n"); +#endif + /* * "sound=" command line handling by Harald Milz. */ diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 25bfaf3a7..4acffcf6d 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -125,7 +125,7 @@ static char old_hardware = 0; static void sleep(unsigned howlong) { current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout(howlong); } static unsigned char sscape_read(struct sscape_info *devc, int reg) diff --git a/drivers/sound/via82cxxx.c b/drivers/sound/via82cxxx.c new file mode 100644 index 000000000..79d87e2e0 --- /dev/null +++ b/drivers/sound/via82cxxx.c @@ -0,0 +1,256 @@ +/* + * Support for VIA 82Cxxx Audio Codecs + * Copyright 1999 Jeff Garzik <jgarzik@pobox.com> + * + * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2. + * See the "COPYING" file distributed with this software for more info. + * + ******************************************************************** + * + * TODO: + * + * - Integrate AC'97 support, when AC'97 interface released + * + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/io.h> + +#include "sound_config.h" +#include "soundmodule.h" +#include "sb.h" + +#ifndef SOUND_LOCK +#define SOUND_LOCK do {} while (0) +#define SOUND_LOCK_END do {} while (0) +#endif + +#define MAX_CARDS 2 + +#define PFX "via82cxxx: " + +#define VIA_VERSION "1.0.0" +#define VIA_CARD_NAME "VIA 82Cxxx Audio driver " VIA_VERSION + +#define VIA_FUNC_ENABLE 0x42 +#define VIA_PNP_CONTROL 0x43 + +#define VIA_CR42_SB_ENABLE 0x01 +#define VIA_CR42_MIDI_ENABLE 0x02 +#define VIA_CR42_FM_ENABLE 0x04 + +#define via_probe_midi probe_uart401 +#define via_attach_midi attach_uart401 +#define via_unload_midi unload_uart401 + +static struct address_info sb_data[MAX_CARDS]; +static struct address_info opl3_data[MAX_CARDS]; +static unsigned cards = 0; + + +static void __init via_attach_sb(struct address_info *hw_config) +{ + if(!sb_dsp_init(hw_config)) + hw_config->slots[0] = -1; +} + + +static int __init via_probe_sb(struct address_info *hw_config) +{ + if (check_region(hw_config->io_base, 16)) + { + printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n", + hw_config->io_base); + return 0; + } + return sb_dsp_detect(hw_config, 0, 0); +} + + +static void __exit via_unload_sb(struct address_info *hw_config, int unload_mpu) +{ + if(hw_config->slots[0]!=-1) + sb_dsp_unload(hw_config, unload_mpu); +} + + +static int __init via82cxxx_install (struct pci_dev *pcidev) +{ + int sb_io_base = 0; + int sb_irq = 0; + int sb_dma = 0; + int midi_base = 0; + u8 tmp8; + + memset (&sb_data[cards], 0, sizeof (struct address_info)); + memset (&opl3_data[cards], 0, sizeof (struct address_info)); + + sb_data[cards].name = opl3_data[cards].name = VIA_CARD_NAME; + opl3_data[cards].irq = -1; + + /* turn on features, if not already */ + pci_read_config_byte (pcidev, VIA_FUNC_ENABLE, &tmp8); + tmp8 |= VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE | + VIA_CR42_FM_ENABLE; + pci_write_config_byte (pcidev, VIA_FUNC_ENABLE, tmp8); + + /* read legacy PNP info byte */ + pci_read_config_byte (pcidev, VIA_PNP_CONTROL, &tmp8); + pci_write_config_byte (pcidev, VIA_PNP_CONTROL, tmp8); + + switch ((tmp8 >> 6) & 0x03) { + case 0: sb_irq = 5; break; + case 1: sb_irq = 7; break; + case 2: sb_irq = 9; break; + case 3: sb_irq = 10; break; + default: /* do nothing */ break; + } + switch ((tmp8 >> 4) & 0x03) { + case 0: sb_dma = 0; break; + case 1: sb_dma = 1; break; + case 2: sb_dma = 2; break; + case 3: sb_dma = 3; break; + default: /* do nothing */ break; + } + switch ((tmp8 >> 2) & 0x03) { + case 0: midi_base = 0x300; break; + case 1: midi_base = 0x310; break; + case 2: midi_base = 0x320; break; + case 3: midi_base = 0x330; break; + default: /* do nothing */ break; + } + switch (tmp8 & 0x03) { + case 0: sb_io_base = 0x220; break; + case 1: sb_io_base = 0x240; break; + case 2: sb_io_base = 0x260; break; + case 3: sb_io_base = 0x280; break; + default: /* do nothing */ break; + } + + udelay(100); + + printk(KERN_INFO PFX "legacy " + "MIDI: 0x%X, SB: 0x%X / %d IRQ / %d DMA\n", + midi_base, sb_io_base, sb_irq, sb_dma); + + sb_data[cards].card_subtype = MDL_SBPRO; + sb_data[cards].io_base = sb_io_base; + sb_data[cards].irq = sb_irq; + sb_data[cards].dma = sb_dma; + + opl3_data[cards].io_base = midi_base; + + /* register legacy SoundBlaster Pro */ + if (!via_probe_sb (&sb_data[cards])) { + printk (KERN_ERR PFX + "SB probe @ 0x%X failed, aborting\n", + sb_io_base); + return -1; + } + via_attach_sb (&sb_data[cards]); + + /* register legacy MIDI */ + if (!via_probe_midi (&opl3_data[cards])) { + printk (KERN_ERR PFX + "MIDI probe @ 0x%X failed, aborting\n", + midi_base); + via_unload_sb (&sb_data[cards], 0); + return -1; + } + via_attach_midi (&opl3_data[cards]); + + cards++; + return 0; +} + + +/* + * This loop walks the PCI configuration database and finds where + * the sound cards are. + */ + +static int __init probe_via82cxxx (void) +{ + struct pci_dev *pcidev = NULL; + + while ((pcidev = pci_find_device (PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C686_5, + pcidev)) != NULL) { + + if (via82cxxx_install (pcidev) != 0) { + printk (KERN_ERR PFX "audio init failed\n"); + return -1; + } + + if (cards == MAX_CARDS) { + printk (KERN_DEBUG PFX "maximum number of cards reached\n"); + break; + } + } + + return 0; +} + + +/* + * This function is called when the user or kernel loads the + * module into memory. + */ + + +static int __init init_via82cxxx_module(void) +{ + if (!pci_present ()) { + printk (KERN_DEBUG PFX "PCI not present, exiting\n"); + return -ENODEV; + } + + if (probe_via82cxxx() != 0) { + printk(KERN_ERR PFX "probe failed, aborting\n"); + /* XXX unload cards registered so far, if any */ + return -ENODEV; + } + + if (cards == 0) { + printk(KERN_DEBUG PFX "No chips found, aborting\n"); + return -ENODEV; + } + + printk (KERN_INFO PFX VIA_CARD_NAME " loaded\n"); + + /* + * Binds us to the sound subsystem + */ + SOUND_LOCK; + return 0; +} + +/* + * This is called when it is removed. It will only be removed + * when its use count is 0. For sound the SOUND_LOCK/SOUND_UNLOCK + * macros hide the entire work for this. + */ + +static void __exit cleanup_via82cxxx_module(void) +{ + int i; + + for (i = 0; i < cards; i++) + via_unload_sb (&sb_data[i], 1); + + /* + * Final clean up with the sound layer + */ + SOUND_LOCK_END; +} + +module_init(init_via82cxxx_module); +module_exit(cleanup_via82cxxx_module); + diff --git a/drivers/sound/vwsnd.c b/drivers/sound/vwsnd.c new file mode 100644 index 000000000..5863587b4 --- /dev/null +++ b/drivers/sound/vwsnd.c @@ -0,0 +1,3525 @@ +/* + * Sound driver for Silicon Graphics 320 and 540 Visual Workstations' + * onboard audio. See notes in ../../Documentation/sound/vwsnd . + * + * Copyright 1999 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#undef VWSND_DEBUG /* define for debugging */ + +/* + * XXX to do - + * + * External sync. + * Rename swbuf, hwbuf, u&i, hwptr&swptr to something rational. + * Bug - if select() called before read(), pcm_setup() not called. + * Bug - output doesn't stop soon enough if process killed. + */ + +/* + * Things to test - + * + * Will readv/writev work? Write a test. + * + * insmod/rmmod 100 million times. + * + * Run I/O until int ptrs wrap around (roughly 6.2 hours @ DAT + * rate). + * + * Concurrent threads banging on mixer simultaneously, both UP + * and SMP kernels. Especially, watch for thread A changing + * OUTSRC while thread B changes gain -- both write to the same + * ad1843 register. + * + * What happens if a client opens /dev/audio then forks? + * Do two procs have /dev/audio open? Test. + * + * Pump audio through the CD, MIC and line inputs and verify that + * they mix/mute into the output. + * + * Apps: + * amp + * mpg123 + * x11amp + * mxv + * kmedia + * esound + * need more input apps + * + * Run tests while bombarding with signals. setitimer(2) will do it... */ + +/* + * This driver is organized in nine sections. + * The nine sections are: + * + * debug stuff + * low level lithium access + * high level lithium access + * AD1843 access + * PCM I/O + * audio driver + * mixer driver + * probe/attach/unload + * initialization and loadable kernel module interface + * + * That is roughly the order of increasing abstraction, so forward + * dependencies are minimal. + */ + +/* + * Locking Notes + * + * INC_USE_COUNT and DEC_USE_COUNT keep track of the number of + * open descriptors to this driver. When the driver is compiled + * as a module, they call MOD_{INC,DEC}_USE_COUNT; otherwise they + * bump vwsnd_use_count. The global device list, vwsnd_dev_list, + * is immutable when the IN_USE is true. + * + * devc->open_lock is a semaphore that is used to enforce the + * single reader/single writer rule for /dev/audio. The rule is + * that each device may have at most one reader and one writer. + * Open will block until the previous client has closed the + * device, unless O_NONBLOCK is specified. + * + * The semaphore devc->io_sema serializes PCM I/O syscalls. This + * is unnecessary in Linux 2.2, because the kernel lock + * serializes read, write, and ioctl globally, but it's there, + * ready for the brave, new post-kernel-lock world. + * + * Locking between interrupt and baselevel is handled by the + * "lock" spinlock in vwsnd_port (one lock each for read and + * write). Each half holds the lock just long enough to see what + * area it owns and update its pointers. See pcm_output() and + * pcm_input() for most of the gory stuff. + * + * devc->mix_sema serializes all mixer ioctls. This is also + * redundant because of the kernel lock. + * + * The lowest level lock is lith->lithium_lock. It is a + * spinlock which is held during the two-register tango of + * reading/writing an AD1843 register. See + * li_{read,write}_ad1843_reg(). + */ + +/* + * Sample Format Notes + * + * Lithium's DMA engine has two formats: 16-bit 2's complement + * and 8-bit unsigned . 16-bit transfers the data unmodified, 2 + * bytes per sample. 8-bit unsigned transfers 1 byte per sample + * and XORs each byte with 0x80. Lithium can input or output + * either mono or stereo in either format. + * + * The AD1843 has four formats: 16-bit 2's complement, 8-bit + * unsigned, 8-bit mu-Law and 8-bit A-Law. + * + * This driver supports five formats: AFMT_S8, AFMT_U8, + * AFMT_MU_LAW, AFMT_A_LAW, and AFMT_S16_LE. + * + * For AFMT_U8 output, we keep the AD1843 in 16-bit mode, and + * rely on Lithium's XOR to translate between U8 and S8. + * + * For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR + * the 0x80 bit in software to compensate for Lithium's XOR. + * This happens in pcm_copy_{in,out}(). + */ + +#include <linux/module.h> +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <asm/fixmap.h> +#include <asm/cobalt.h> +#include <asm/semaphore.h> + +#include "sound_config.h" + +/*****************************************************************************/ +/* debug stuff */ + +#ifdef VWSND_DEBUG + +#include <linux/interrupt.h> /* for in_interrupt() */ + +static int shut_up = 1; + +/* + * dbgassert - called when an assertion fails. + */ + +static void dbgassert(const char *fcn, int line, const char *expr) +{ + if (in_interrupt()) + panic("ASSERTION FAILED IN INTERRUPT, %s:%s:%d %s\n", + __FILE__, fcn, line, expr); + else { + int x; + printk(KERN_ERR "ASSERTION FAILED, %s:%s:%d %s\n", + __FILE__, fcn, line, expr); + x = * (volatile int *) 0; /* force proc to exit */ + } +} + +/* + * Bunch of useful debug macros: + * + * ASSERT - print unless e nonzero (panic if in interrupt) + * DBGDO - include arbitrary code if debugging + * DBGX - debug print raw (w/o function name) + * DBGP - debug print w/ function name + * DBGE - debug print function entry + * DBGC - debug print function call + * DBGR - debug print function return + * DBGXV - debug print raw when verbose + * DBGPV - debug print when verbose + * DBGEV - debug print function entry when verbose + * DBGRV - debug print function return when verbose + */ + +#define ASSERT(e) ((e) ? (void) 0 : dbgassert(__FUNCTION__, __LINE__, #e)) +#define DBGDO(x) x +#define DBGX(fmt, args...) (in_interrupt() ? 0 : printk(KERN_ERR fmt, ##args)) +#define DBGP(fmt, args...) (DBGX(__FUNCTION__ ": " fmt, ##args)) +#define DBGE(fmt, args...) (DBGX(__FUNCTION__ fmt, ##args)) +#define DBGC(rtn) (DBGP("calling %s\n", rtn)) +#define DBGR() (DBGP("returning\n")) +#define DBGXV(fmt, args...) (shut_up ? 0 : DBGX(fmt, ##args)) +#define DBGPV(fmt, args...) (shut_up ? 0 : DBGP(fmt, ##args)) +#define DBGEV(fmt, args...) (shut_up ? 0 : DBGE(fmt, ##args)) +#define DBGCV(rtn) (shut_up ? 0 : DBGC(rtn)) +#define DBGRV() (shut_up ? 0 : DBGR()) + +#else /* !VWSND_DEBUG */ + +#define ASSERT(e) ((void) 0) +#define DBGDO(x) /* don't */ +#define DBGX(fmt, args...) ((void) 0) +#define DBGP(fmt, args...) ((void) 0) +#define DBGE(fmt, args...) ((void) 0) +#define DBGC(rtn) ((void) 0) +#define DBGR() ((void) 0) +#define DBGPV(fmt, args...) ((void) 0) +#define DBGXV(fmt, args...) ((void) 0) +#define DBGEV(fmt, args...) ((void) 0) +#define DBGCV(rtn) ((void) 0) +#define DBGRV() ((void) 0) + +#endif /* !VWSND_DEBUG */ + +/*****************************************************************************/ +/* low level lithium access */ + +/* + * We need to talk to Lithium registers on three pages. Here are + * the pages' offsets from the base address (0xFF001000). + */ + +enum { + LI_PAGE0_OFFSET = 0x01000 - 0x1000, /* FF001000 */ + LI_PAGE1_OFFSET = 0x0F000 - 0x1000, /* FF00F000 */ + LI_PAGE2_OFFSET = 0x10000 - 0x1000, /* FF010000 */ +}; + +/* low-level lithium data */ + +typedef struct lithium { + caddr_t page0; /* virtual addresses */ + caddr_t page1; + caddr_t page2; + spinlock_t lock; /* protects codec and UST/MSC access */ +} lithium_t; + +/* + * li_create initializes the lithium_t structure and sets up vm mappings + * to access the registers. + * Returns 0 on success, -errno on failure. + */ + +static int li_create(lithium_t *lith, unsigned long baseaddr) +{ + static void li_destroy(lithium_t *); + + lith->lock = SPIN_LOCK_UNLOCKED; + lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE); + lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE); + lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE); + if (!lith->page0 || !lith->page1 || !lith->page2) { + li_destroy(lith); + return -ENOMEM; + } + return 0; +} + +/* + * li_destroy destroys the lithium_t structure and vm mappings. + */ + +static void li_destroy(lithium_t *lith) +{ + if (lith->page0) { + iounmap(lith->page0); + lith->page0 = NULL; + } + if (lith->page1) { + iounmap(lith->page1); + lith->page1 = NULL; + } + if (lith->page2) { + iounmap(lith->page2); + lith->page2 = NULL; + } +} + +/* + * basic register accessors - read/write long/byte + */ + +static __inline__ unsigned long li_readl(lithium_t *lith, int off) +{ + return * (volatile unsigned long *) (lith->page0 + off); +} + +static __inline__ unsigned char li_readb(lithium_t *lith, int off) +{ + return * (volatile unsigned char *) (lith->page0 + off); +} + +static __inline__ void li_writel(lithium_t *lith, int off, unsigned long val) +{ + * (volatile unsigned long *) (lith->page0 + off) = val; +} + +static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val) +{ + * (volatile unsigned char *) (lith->page0 + off) = val; +} + +/*****************************************************************************/ +/* High Level Lithium Access */ + +/* + * Lithium DMA Notes + * + * Lithium has two dedicated DMA channels for audio. They are known + * as comm1 and comm2 (communication areas 1 and 2). Comm1 is for + * input, and comm2 is for output. Each is controlled by three + * registers: BASE (base address), CFG (config) and CCTL + * (config/control). + * + * Each DMA channel points to a physically contiguous ring buffer in + * main memory of up to 8 Kbytes. (This driver always uses 8 Kb.) + * There are three pointers into the ring buffer: read, write, and + * trigger. The pointers are 8 bits each. Each pointer points to + * 32-byte "chunks" of data. The DMA engine moves 32 bytes at a time, + * so there is no finer-granularity control. + * + * In comm1, the hardware updates the write ptr, and software updates + * the read ptr. In comm2, it's the opposite: hardware updates the + * read ptr, and software updates the write ptr. I designate the + * hardware-updated ptr as the hwptr, and the software-updated ptr as + * the swptr. + * + * The trigger ptr and trigger mask are used to trigger interrupts. + * From the Lithium spec, section 5.6.8, revision of 12/15/1998: + * + * Trigger Mask Value + * + * A three bit wide field that represents a power of two mask + * that is used whenever the trigger pointer is compared to its + * respective read or write pointer. A value of zero here + * implies a mask of 0xFF and a value of seven implies a mask + * 0x01. This value can be used to sub-divide the ring buffer + * into pie sections so that interrupts monitor the progress of + * hardware from section to section. + * + * My interpretation of that is, whenever the hw ptr is updated, it is + * compared with the trigger ptr, and the result is masked by the + * trigger mask. (Actually, by the complement of the trigger mask.) + * If the result is zero, an interrupt is triggered. I.e., interrupt + * if ((hwptr & ~mask) == (trptr & ~mask)). The mask is formed from + * the trigger register value as mask = (1 << (8 - tmreg)) - 1. + * + * In yet different words, setting tmreg to 0 causes an interrupt after + * every 256 DMA chunks (8192 bytes) or once per traversal of the + * ring buffer. Setting it to 7 caues an interrupt every 2 DMA chunks + * (64 bytes) or 128 times per traversal of the ring buffer. + */ + +/* Lithium register offsets and bit definitions */ + +#define LI_HOST_CONTROLLER 0x000 +# define LI_HC_RESET 0x00008000 +# define LI_HC_LINK_ENABLE 0x00004000 +# define LI_HC_LINK_FAILURE 0x00000004 +# define LI_HC_LINK_CODEC 0x00000002 +# define LI_HC_LINK_READY 0x00000001 + +#define LI_INTR_STATUS 0x010 +#define LI_INTR_MASK 0x014 +# define LI_INTR_LINK_ERR 0x00008000 +# define LI_INTR_COMM2_TRIG 0x00000008 +# define LI_INTR_COMM2_UNDERFLOW 0x00000004 +# define LI_INTR_COMM1_TRIG 0x00000002 +# define LI_INTR_COMM1_OVERFLOW 0x00000001 + +#define LI_CODEC_COMMAND 0x018 +# define LI_CC_BUSY 0x00008000 +# define LI_CC_DIR 0x00000080 +# define LI_CC_DIR_RD LI_CC_DIR +# define LI_CC_DIR_WR (!LI_CC_DIR) +# define LI_CC_ADDR_MASK 0x0000007F + +#define LI_CODEC_DATA 0x01C + +#define LI_COMM1_BASE 0x100 +#define LI_COMM1_CTL 0x104 +# define LI_CCTL_RESET 0x80000000 +# define LI_CCTL_SIZE 0x70000000 +# define LI_CCTL_DMA_ENABLE 0x08000000 +# define LI_CCTL_TMASK 0x07000000 /* trigger mask */ +# define LI_CCTL_TPTR 0x00FF0000 /* trigger pointer */ +# define LI_CCTL_RPTR 0x0000FF00 +# define LI_CCTL_WPTR 0x000000FF +#define LI_COMM1_CFG 0x108 +# define LI_CCFG_LOCK 0x00008000 +# define LI_CCFG_SLOT 0x00000070 +# define LI_CCFG_DIRECTION 0x00000008 +# define LI_CCFG_DIR_IN (!LI_CCFG_DIRECTION) +# define LI_CCFG_DIR_OUT LI_CCFG_DIRECTION +# define LI_CCFG_MODE 0x00000004 +# define LI_CCFG_MODE_MONO (!LI_CCFG_MODE) +# define LI_CCFG_MODE_STEREO LI_CCFG_MODE +# define LI_CCFG_FORMAT 0x00000003 +# define LI_CCFG_FMT_8BIT 0x00000000 +# define LI_CCFG_FMT_16BIT 0x00000001 +#define LI_COMM2_BASE 0x10C +#define LI_COMM2_CTL 0x110 + /* bit definitions are the same as LI_COMM1_CTL */ +#define LI_COMM2_CFG 0x114 + /* bit definitions are the same as LI_COMM1_CFG */ + +#define LI_UST_LOW 0x200 /* 64-bit Unadjusted System Time is */ +#define LI_UST_HIGH 0x204 /* microseconds since boot */ + +#define LI_AUDIO1_UST 0x300 /* UST-MSC pairs */ +#define LI_AUDIO1_MSC 0x304 /* MSC (Media Stream Counter) */ +#define LI_AUDIO2_UST 0x308 /* counts samples actually */ +#define LI_AUDIO2_MSC 0x30C /* processed as of time UST */ + +/* + * Lithium's DMA engine operates on chunks of 32 bytes. We call that + * a DMACHUNK. + */ + +#define DMACHUNK_SHIFT 5 +#define DMACHUNK_SIZE (1 << DMACHUNK_SHIFT) +#define BYTES_TO_CHUNKS(bytes) ((bytes) >> DMACHUNK_SHIFT) +#define CHUNKS_TO_BYTES(chunks) ((chunks) << DMACHUNK_SHIFT) + +/* + * Two convenient macros to shift bitfields into/out of position. + * + * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)). + * As long as mask is constant, we trust the compiler will change the + * multipy and divide into shifts. + */ + +#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask)) +#define UNSHIFT_FIELD(val, mask) (((val) & (mask)) / ((mask) & -(mask))) + +/* + * dma_chan_desc is invariant information about a Lithium + * DMA channel. There are two instances, li_comm1 and li_comm2. + * + * Note that the CCTL register fields are write ptr and read ptr, but what + * we care about are which pointer is updated by software and which by + * hardware. + */ + +typedef struct dma_chan_desc { + int basereg; + int cfgreg; + int ctlreg; + int hwptrreg; + int swptrreg; + int ustreg; + int mscreg; + unsigned long swptrmask; + int ad1843_slot; + int direction; /* LI_CCTL_DIR_IN/OUT */ +} dma_chan_desc_t; + +static const dma_chan_desc_t li_comm1 = { + LI_COMM1_BASE, /* base register offset */ + LI_COMM1_CFG, /* config register offset */ + LI_COMM1_CTL, /* control register offset */ + LI_COMM1_CTL + 0, /* hw ptr reg offset (write ptr) */ + LI_COMM1_CTL + 1, /* sw ptr reg offset (read ptr) */ + LI_AUDIO1_UST, /* ust reg offset */ + LI_AUDIO1_MSC, /* msc reg offset */ + LI_CCTL_RPTR, /* sw ptr bitmask in ctlval */ + 2, /* ad1843 serial slot */ + LI_CCFG_DIR_IN /* direction */ +}; + +static const dma_chan_desc_t li_comm2 = { + LI_COMM2_BASE, /* base register offset */ + LI_COMM2_CFG, /* config register offset */ + LI_COMM2_CTL, /* control register offset */ + LI_COMM2_CTL + 1, /* hw ptr reg offset (read ptr) */ + LI_COMM2_CTL + 0, /* sw ptr reg offset (writr ptr) */ + LI_AUDIO2_UST, /* ust reg offset */ + LI_AUDIO2_MSC, /* msc reg offset */ + LI_CCTL_WPTR, /* sw ptr bitmask in ctlval */ + 2, /* ad1843 serial slot */ + LI_CCFG_DIR_OUT /* direction */ +}; + +/* + * dma_chan is variable information about a Lithium DMA channel. + * + * The desc field points to invariant information. + * The lith field points to a lithium_t which is passed + * to li_read* and li_write* to access the registers. + * The *val fields shadow the lithium registers' contents. + */ + +typedef struct dma_chan { + const dma_chan_desc_t *desc; + lithium_t *lith; + unsigned long baseval; + unsigned long cfgval; + unsigned long ctlval; +} dma_chan_t; + +/* + * ustmsc is a UST/MSC pair (Unadjusted System Time/Media Stream Counter). + * UST is time in microseconds since the system booted, and MSC is a + * counter that increments with every audio sample. + */ + +typedef struct ustmsc { + unsigned long long ust; + unsigned long msc; +} ustmsc_t; + +/* + * li_ad1843_wait waits until lithium says the AD1843 register + * exchange is not busy. Returns 0 on success, -EBUSY on timeout. + * + * Locking: must be called with lithium_lock held. + */ + +static int li_ad1843_wait(lithium_t *lith) +{ + unsigned long later = jiffies + 2; + while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY) + if (jiffies >= later) + return -EBUSY; + return 0; +} + +/* + * li_read_ad1843_reg returns the current contents of a 16 bit AD1843 register. + * + * Returns unsigned register value on success, -errno on failure. + */ + +static int li_read_ad1843_reg(lithium_t *lith, int reg) +{ + int val; + + ASSERT(!in_interrupt()); + spin_lock(&lith->lock); + { + val = li_ad1843_wait(lith); + if (val == 0) { + li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_RD | reg); + val = li_ad1843_wait(lith); + } + if (val == 0) + val = li_readl(lith, LI_CODEC_DATA); + } + spin_unlock(&lith->lock); + + DBGXV("li_read_ad1843_reg(lith=0x%p, reg=%d) returns 0x%04x\n", + lith, reg, val); + + return val; +} + +/* + * li_write_ad1843_reg writes the specified value to a 16 bit AD1843 register. + */ + +static void li_write_ad1843_reg(lithium_t *lith, int reg, int newval) +{ + spin_lock(&lith->lock); + { + if (li_ad1843_wait(lith) == 0) { + li_writel(lith, LI_CODEC_DATA, newval); + li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_WR | reg); + } + } + spin_unlock(&lith->lock); +} + +/* + * li_setup_dma calculates all the register settings for DMA in a particular + * mode. It takes too many arguments. + */ + +static void li_setup_dma(dma_chan_t *chan, + const dma_chan_desc_t *desc, + lithium_t *lith, + unsigned long buffer_paddr, + int bufshift, + int fragshift, + int channels, + int sampsize) +{ + unsigned long mode, format; + unsigned long size, tmask; + + DBGEV("(chan=0x%p, desc=0x%p, lith=0x%p, buffer_paddr=0x%lx, " + "bufshift=%d, fragshift=%d, channels=%d, sampsize=%d)\n", + chan, desc, lith, buffer_paddr, + bufshift, fragshift, channels, sampsize); + + /* Reset the channel first. */ + + li_writel(lith, desc->ctlreg, LI_CCTL_RESET); + + ASSERT(channels == 1 || channels == 2); + if (channels == 2) + mode = LI_CCFG_MODE_STEREO; + else + mode = LI_CCFG_MODE_MONO; + ASSERT(sampsize == 1 || sampsize == 2); + if (sampsize == 2) + format = LI_CCFG_FMT_16BIT; + else + format = LI_CCFG_FMT_8BIT; + chan->desc = desc; + chan->lith = lith; + + /* + * Lithium DMA address register takes a 40-bit physical + * address, right-shifted by 8 so it fits in 32 bits. Bit 37 + * must be set -- it enables cache coherence. + */ + + ASSERT(!(buffer_paddr & 0xFF)); + chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8); + + chan->cfgval = (!LI_CCFG_LOCK | + SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) | + desc->direction | + mode | + format); + + size = bufshift - 6; + tmask = 13 - fragshift; /* See Lithium DMA Notes above. */ + ASSERT(size >= 2 && size <= 7); + ASSERT(tmask >= 1 && tmask <= 7); + chan->ctlval = (!LI_CCTL_RESET | + SHIFT_FIELD(size, LI_CCTL_SIZE) | + !LI_CCTL_DMA_ENABLE | + SHIFT_FIELD(tmask, LI_CCTL_TMASK) | + SHIFT_FIELD(0, LI_CCTL_TPTR)); + + DBGPV("basereg 0x%x = 0x%lx\n", desc->basereg, chan->baseval); + DBGPV("cfgreg 0x%x = 0x%lx\n", desc->cfgreg, chan->cfgval); + DBGPV("ctlreg 0x%x = 0x%lx\n", desc->ctlreg, chan->ctlval); + + li_writel(lith, desc->basereg, chan->baseval); + li_writel(lith, desc->cfgreg, chan->cfgval); + li_writel(lith, desc->ctlreg, chan->ctlval); + + DBGRV(); +} + +static void li_shutdown_dma(dma_chan_t *chan) +{ + lithium_t *lith = chan->lith; + caddr_t lith1 = lith->page1; + + DBGEV("(chan=0x%p)\n", chan); + + chan->ctlval &= ~LI_CCTL_DMA_ENABLE; + DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval); + li_writel(lith, chan->desc->ctlreg, chan->ctlval); + + /* + * Offset 0x500 on Lithium page 1 is an undocumented, + * unsupported register that holds the zero sample value. + * Lithium is supposed to output zero samples when DMA is + * inactive, and repeat the last sample when DMA underflows. + * But it has a bug, where, after underflow occurs, the zero + * sample is not reset. + * + * I expect this to break in a future rev of Lithium. + */ + + if (lith1 && chan->desc->direction == LI_CCFG_DIR_OUT) + * (volatile unsigned long *) (lith1 + 0x500) = 0; +} + +/* + * li_activate_dma always starts dma at the beginning of the buffer. + * + * N.B., these may be called from interrupt. + */ + +static __inline__ void li_activate_dma(dma_chan_t *chan) +{ + chan->ctlval |= LI_CCTL_DMA_ENABLE; + DBGPV("ctlval = 0x%lx\n", chan->ctlval); + li_writel(chan->lith, chan->desc->ctlreg, chan->ctlval); +} + +static void li_deactivate_dma(dma_chan_t *chan) +{ + lithium_t *lith = chan->lith; + caddr_t lith2 = lith->page2; + + chan->ctlval &= ~(LI_CCTL_DMA_ENABLE | LI_CCTL_RPTR | LI_CCTL_WPTR); + DBGPV("ctlval = 0x%lx\n", chan->ctlval); + DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval); + li_writel(lith, chan->desc->ctlreg, chan->ctlval); + + /* + * Offsets 0x98 and 0x9C on Lithium page 2 are undocumented, + * unsupported registers that are internal copies of the DMA + * read and write pointers. Because of a Lithium bug, these + * registers aren't zeroed correctly when DMA is shut off. So + * we whack them directly. + * + * I expect this to break in a future rev of Lithium. + */ + + if (lith2 && chan->desc->direction == LI_CCFG_DIR_OUT) { + * (volatile unsigned long *) (lith2 + 0x98) = 0; + * (volatile unsigned long *) (lith2 + 0x9C) = 0; + } +} + +/* + * read/write the ring buffer pointers. These routines' arguments and results + * are byte offsets from the beginning of the ring buffer. + */ + +static __inline__ int li_read_swptr(dma_chan_t *chan) +{ + const unsigned long mask = chan->desc->swptrmask; + + return CHUNKS_TO_BYTES(UNSHIFT_FIELD(chan->ctlval, mask)); +} + +static __inline__ int li_read_hwptr(dma_chan_t *chan) +{ + return CHUNKS_TO_BYTES(li_readb(chan->lith, chan->desc->hwptrreg)); +} + +static __inline__ void li_write_swptr(dma_chan_t *chan, int val) +{ + const unsigned long mask = chan->desc->swptrmask; + + ASSERT(!(val & ~CHUNKS_TO_BYTES(0xFF))); + val = BYTES_TO_CHUNKS(val); + chan->ctlval = (chan->ctlval & ~mask) | SHIFT_FIELD(val, mask); + li_writeb(chan->lith, chan->desc->swptrreg, val); +} + +/* li_read_USTMSC() returns a UST/MSC pair for the given channel. */ + +static void li_read_USTMSC(dma_chan_t *chan, ustmsc_t *ustmsc) +{ + lithium_t *lith = chan->lith; + const dma_chan_desc_t *desc = chan->desc; + unsigned long now_low, now_high0, now_high1, chan_ust; + + spin_lock(&lith->lock); + { + /* + * retry until we do all five reads without the + * high word changing. (High word increments + * every 2^32 microseconds, i.e., not often) + */ + do { + now_high0 = li_readl(lith, LI_UST_HIGH); + now_low = li_readl(lith, LI_UST_LOW); + + /* + * Lithium guarantees these two reads will be + * atomic -- ust will not increment after msc + * is read. + */ + + ustmsc->msc = li_readl(lith, desc->mscreg); + chan_ust = li_readl(lith, desc->ustreg); + + now_high1 = li_readl(lith, LI_UST_HIGH); + } while (now_high0 != now_high1); + } + spin_unlock(&lith->lock); + ustmsc->ust = ((unsigned long long) now_high0 << 32 | chan_ust); +} + +static void li_enable_interrupts(lithium_t *lith, unsigned int mask) +{ + DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask); + + /* clear any already-pending interrupts. */ + + li_writel(lith, LI_INTR_STATUS, mask); + + /* enable the interrupts. */ + + mask |= li_readl(lith, LI_INTR_MASK); + li_writel(lith, LI_INTR_MASK, mask); +} + +static void li_disable_interrupts(lithium_t *lith, unsigned int mask) +{ + unsigned int keepmask; + + DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask); + + /* disable the interrupts */ + + keepmask = li_readl(lith, LI_INTR_MASK) & ~mask; + li_writel(lith, LI_INTR_MASK, keepmask); + + /* clear any pending interrupts. */ + + li_writel(lith, LI_INTR_STATUS, mask); +} + +/* Get the interrupt status and clear all pending interrupts. */ + +static unsigned int li_get_clear_intr_status(lithium_t *lith) +{ + unsigned int status; + + status = li_readl(lith, LI_INTR_STATUS); + li_writel(lith, LI_INTR_STATUS, ~0); + return status & li_readl(lith, LI_INTR_MASK); +} + +static int li_init(lithium_t *lith) +{ + /* 1. System power supplies stabilize. */ + + /* 2. Assert the ~RESET signal. */ + + li_writel(lith, LI_HOST_CONTROLLER, LI_HC_RESET); + udelay(1); + + /* 3. Deassert the ~RESET signal and enter a wait period to allow + the AD1843 internal clocks and the external crystal oscillator + to stabilize. */ + + li_writel(lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE); + udelay(1); + + return 0; +} + +/*****************************************************************************/ +/* AD1843 access */ + +/* + * AD1843 bitfield definitions. All are named as in the AD1843 data + * sheet, with ad1843_ prepended and individual bit numbers removed. + * + * E.g., bits LSS0 through LSS2 become ad1843_LSS. + * + * Only the bitfields we need are defined. + */ + +typedef struct ad1843_bitfield { + char reg; + char lo_bit; + char nbits; +} ad1843_bitfield_t; + +static const ad1843_bitfield_t + ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */ + ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */ + ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */ + ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */ + ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */ + ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */ + ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */ + ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */ + ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */ + ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */ + ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */ + ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */ + ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */ + ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */ + ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */ + ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */ + ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */ + ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */ + ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */ + ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */ + ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */ + ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */ + ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */ + ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */ + ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */ + ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */ + ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */ + ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */ + ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */ + ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */ + ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */ + ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */ + ad1843_C2C = { 20, 0, 16 }, /* Clock 1 Sample Rate Select */ + ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */ + ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */ + ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */ + ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */ + ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */ + ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */ + ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */ + ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */ + ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */ + ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */ + ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */ + ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */ + ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */ + ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */ + ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */ + ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */ + ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */ + ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */ + +/* + * The various registers of the AD1843 use three different formats for + * specifying gain. The ad1843_gain structure parameterizes the + * formats. + */ + +typedef struct ad1843_gain { + + int negative; /* nonzero if gain is negative. */ + const ad1843_bitfield_t *lfield; + const ad1843_bitfield_t *rfield; + +} ad1843_gain_t; + +static const ad1843_gain_t ad1843_gain_RECLEV + = { 0, &ad1843_LIG, &ad1843_RIG }; +static const ad1843_gain_t ad1843_gain_LINE + = { 1, &ad1843_LX1M, &ad1843_RX1M }; +static const ad1843_gain_t ad1843_gain_CD + = { 1, &ad1843_LX2M, &ad1843_RX2M }; +static const ad1843_gain_t ad1843_gain_MIC + = { 1, &ad1843_LMCM, &ad1843_RMCM }; +static const ad1843_gain_t ad1843_gain_PCM + = { 1, &ad1843_LDA1G, &ad1843_RDA1G }; + +/* read the current value of an AD1843 bitfield. */ + +static int ad1843_read_bits(lithium_t *lith, const ad1843_bitfield_t *field) +{ + int w = li_read_ad1843_reg(lith, field->reg); + int val = w >> field->lo_bit & ((1 << field->nbits) - 1); + + DBGXV("ad1843_read_bits(lith=0x%p, field->{%d %d %d}) returns 0x%x\n", + lith, field->reg, field->lo_bit, field->nbits, val); + + return val; +} + +/* + * write a new value to an AD1843 bitfield and return the old value. + */ + +static int ad1843_write_bits(lithium_t *lith, + const ad1843_bitfield_t *field, + int newval) +{ + int w = li_read_ad1843_reg(lith, field->reg); + int mask = ((1 << field->nbits) - 1) << field->lo_bit; + int oldval = (w & mask) >> field->lo_bit; + int newbits = (newval << field->lo_bit) & mask; + w = (w & ~mask) | newbits; + (void) li_write_ad1843_reg(lith, field->reg, w); + + DBGXV("ad1843_write_bits(lith=0x%p, field->{%d %d %d}, val=0x%x) " + "returns 0x%x\n", + lith, field->reg, field->lo_bit, field->nbits, newval, + oldval); + + return oldval; +} + +/* + * ad1843_read_multi reads multiple bitfields from the same AD1843 + * register. It uses a single read cycle to do it. (Reading the + * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20 + * microseconds.) + * + * Called ike this. + * + * ad1843_read_multi(lith, nfields, + * &ad1843_FIELD1, &val1, + * &ad1843_FIELD2, &val2, ...); + */ + +static void ad1843_read_multi(lithium_t *lith, int argcount, ...) +{ + va_list ap; + const ad1843_bitfield_t *fp; + int w = 0, mask, *value, reg = -1; + + va_start(ap, argcount); + while (--argcount >= 0) { + fp = va_arg(ap, const ad1843_bitfield_t *); + value = va_arg(ap, int *); + if (reg == -1) { + reg = fp->reg; + w = li_read_ad1843_reg(lith, reg); + } + ASSERT(reg == fp->reg); + mask = (1 << fp->nbits) - 1; + *value = w >> fp->lo_bit & mask; + } + va_end(ap); +} + +/* + * ad1843_write_multi stores multiple bitfields into the same AD1843 + * register. It uses one read and one write cycle to do it. + * + * Called like this. + * + * ad1843_write_multi(lith, nfields, + * &ad1843_FIELD1, val1, + * &ad1843_FIELF2, val2, ...); + */ + +static void ad1843_write_multi(lithium_t *lith, int argcount, ...) +{ + va_list ap; + int reg; + const ad1843_bitfield_t *fp; + int value; + int w, m, mask, bits; + + mask = 0; + bits = 0; + reg = -1; + + va_start(ap, argcount); + while (--argcount >= 0) { + fp = va_arg(ap, const ad1843_bitfield_t *); + value = va_arg(ap, int); + if (reg == -1) + reg = fp->reg; + ASSERT(fp->reg == reg); + m = ((1 << fp->nbits) - 1) << fp->lo_bit; + mask |= m; + bits |= (value << fp->lo_bit) & m; + } + va_end(ap); + ASSERT(!(bits & ~mask)); + if (~mask & 0xFFFF) + w = li_read_ad1843_reg(lith, reg); + else + w = 0; + w = (w & ~mask) | bits; + (void) li_write_ad1843_reg(lith, reg, w); +} + +/* + * ad1843_get_gain reads the specified register and extracts the gain value + * using the supplied gain type. It returns the gain in OSS format. + */ + +static int ad1843_get_gain(lithium_t *lith, const ad1843_gain_t *gp) +{ + int lg, rg; + unsigned short mask = (1 << gp->lfield->nbits) - 1; + + ad1843_read_multi(lith, 2, gp->lfield, &lg, gp->rfield, &rg); + if (gp->negative) { + lg = mask - lg; + rg = mask - rg; + } + lg = (lg * 100 + (mask >> 1)) / mask; + rg = (rg * 100 + (mask >> 1)) / mask; + return lg << 0 | rg << 8; +} + +/* + * Set an audio channel's gain. Converts from OSS format to AD1843's + * format. + * + * Returns the new gain, which may be lower than the old gain. + */ + +static int ad1843_set_gain(lithium_t *lith, + const ad1843_gain_t *gp, + int newval) +{ + unsigned short mask = (1 << gp->lfield->nbits) - 1; + + int lg = newval >> 0 & 0xFF; + int rg = newval >> 8; + if (lg < 0 || lg > 100 || rg < 0 || rg > 100) + return -EINVAL; + lg = (lg * mask + (mask >> 1)) / 100; + rg = (rg * mask + (mask >> 1)) / 100; + if (gp->negative) { + lg = mask - lg; + rg = mask - rg; + } + ad1843_write_multi(lith, 2, gp->lfield, lg, gp->rfield, rg); + return ad1843_get_gain(lith, gp); +} + +/* Returns the current recording source, in OSS format. */ + +static int ad1843_get_recsrc(lithium_t *lith) +{ + int ls = ad1843_read_bits(lith, &ad1843_LSS); + + switch (ls) { + case 1: + return SOUND_MASK_MIC; + case 2: + return SOUND_MASK_LINE; + case 3: + return SOUND_MASK_CD; + case 6: + return SOUND_MASK_PCM; + default: + ASSERT(0); + return -1; + } +} + +/* + * Enable/disable digital resample mode in the AD1843. + * + * The AD1843 requires that ADL, ADR, DA1 and DA2 be powered down + * while switching modes. So we save DA1's state (DA2's state is not + * interesting), power them down, switch into/out of resample mode, + * power them up, and restore state. + * + * This will cause audible glitches if D/A or A/D is going on, so the + * driver disallows that (in mixer_write_ioctl()). + * + * The open question is, is this worth doing? I'm leaving it in, + * because it's written, but... + */ + +static void ad1843_set_resample_mode(lithium_t *lith, int onoff) +{ + /* Save DA1 mute and gain (addr 9 is DA1 analog gain/attenuation) */ + int save_da1 = li_read_ad1843_reg(lith, 9); + + /* Power down A/D and D/A. */ + ad1843_write_multi(lith, 4, + &ad1843_DA1EN, 0, + &ad1843_DA2EN, 0, + &ad1843_ADLEN, 0, + &ad1843_ADREN, 0); + + /* Switch mode */ + ASSERT(onoff == 0 || onoff == 1); + ad1843_write_bits(lith, &ad1843_DRSFLT, onoff); + + /* Power up A/D and D/A. */ + ad1843_write_multi(lith, 3, + &ad1843_DA1EN, 1, + &ad1843_ADLEN, 1, + &ad1843_ADREN, 1); + + /* Restore DA1 mute and gain. */ + li_write_ad1843_reg(lith, 9, save_da1); +} + +/* + * Set recording source. Arg newsrc specifies an OSS channel mask. + * + * The complication is that when we switch into/out of loopback mode + * (i.e., src = SOUND_MASK_PCM), we change the AD1843 into/out of + * digital resampling mode. + * + * Returns newsrc on success, -errno on failure. + */ + +static int ad1843_set_recsrc(lithium_t *lith, int newsrc) +{ + int bits; + int oldbits; + + switch (newsrc) { + case SOUND_MASK_PCM: + bits = 6; + break; + + case SOUND_MASK_MIC: + bits = 1; + break; + + case SOUND_MASK_LINE: + bits = 2; + break; + + case SOUND_MASK_CD: + bits = 3; + break; + + default: + return -EINVAL; + } + oldbits = ad1843_read_bits(lith, &ad1843_LSS); + if (newsrc == SOUND_MASK_PCM && oldbits != 6) { + DBGP("enabling digital resample mode\n"); + ad1843_set_resample_mode(lith, 1); + ad1843_write_multi(lith, 2, + &ad1843_DAADL, 2, + &ad1843_DAADR, 2); + } else if (newsrc != SOUND_MASK_PCM && oldbits == 6) { + DBGP("disabling digital resample mode\n"); + ad1843_set_resample_mode(lith, 0); + ad1843_write_multi(lith, 2, + &ad1843_DAADL, 0, + &ad1843_DAADR, 0); + } + ad1843_write_multi(lith, 2, &ad1843_LSS, bits, &ad1843_RSS, bits); + return newsrc; +} + +/* + * Return current output sources, in OSS format. + */ + +static int ad1843_get_outsrc(lithium_t *lith) +{ + int pcm, line, mic, cd; + + pcm = ad1843_read_bits(lith, &ad1843_LDA1GM) ? 0 : SOUND_MASK_PCM; + line = ad1843_read_bits(lith, &ad1843_LX1MM) ? 0 : SOUND_MASK_LINE; + cd = ad1843_read_bits(lith, &ad1843_LX2MM) ? 0 : SOUND_MASK_CD; + mic = ad1843_read_bits(lith, &ad1843_LMCMM) ? 0 : SOUND_MASK_MIC; + + return pcm | line | cd | mic; +} + +/* + * Set output sources. Arg is a mask of active sources in OSS format. + * + * Returns source mask on success, -errno on failure. + */ + +static int ad1843_set_outsrc(lithium_t *lith, int mask) +{ + int pcm, line, mic, cd; + + if (mask & ~(SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_CD | SOUND_MASK_MIC)) + return -EINVAL; + pcm = (mask & SOUND_MASK_PCM) ? 0 : 1; + line = (mask & SOUND_MASK_LINE) ? 0 : 1; + mic = (mask & SOUND_MASK_MIC) ? 0 : 1; + cd = (mask & SOUND_MASK_CD) ? 0 : 1; + + ad1843_write_multi(lith, 2, &ad1843_LDA1GM, pcm, &ad1843_RDA1GM, pcm); + ad1843_write_multi(lith, 2, &ad1843_LX1MM, line, &ad1843_RX1MM, line); + ad1843_write_multi(lith, 2, &ad1843_LX2MM, cd, &ad1843_RX2MM, cd); + ad1843_write_multi(lith, 2, &ad1843_LMCMM, mic, &ad1843_RMCMM, mic); + + return mask; +} + +/* Setup ad1843 for D/A conversion. */ + +static void ad1843_setup_dac(lithium_t *lith, + int framerate, + int fmt, + int channels) +{ + int ad_fmt = 0, ad_mode = 0; + + DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n", + lith, framerate, fmt, channels); + + switch (fmt) { + case AFMT_S8: ad_fmt = 1; break; + case AFMT_U8: ad_fmt = 1; break; + case AFMT_S16_LE: ad_fmt = 1; break; + case AFMT_MU_LAW: ad_fmt = 2; break; + case AFMT_A_LAW: ad_fmt = 3; break; + default: ASSERT(0); + } + + switch (channels) { + case 2: ad_mode = 0; break; + case 1: ad_mode = 1; break; + default: ASSERT(0); + } + + DBGPV("ad_mode = %d, ad_fmt = %d\n", ad_mode, ad_fmt); + ASSERT(framerate >= 4000 && framerate <= 49000); + ad1843_write_bits(lith, &ad1843_C1C, framerate); + ad1843_write_multi(lith, 2, + &ad1843_DA1SM, ad_mode, &ad1843_DA1F, ad_fmt); +} + +static void ad1843_shutdown_dac(lithium_t *lith) +{ + ad1843_write_bits(lith, &ad1843_DA1F, 1); +} + +static void ad1843_setup_adc(lithium_t *lith, int framerate, int fmt, int channels) +{ + int da_fmt = 0; + + DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n", + lith, framerate, fmt, channels); + + switch (fmt) { + case AFMT_S8: da_fmt = 1; break; + case AFMT_U8: da_fmt = 1; break; + case AFMT_S16_LE: da_fmt = 1; break; + case AFMT_MU_LAW: da_fmt = 2; break; + case AFMT_A_LAW: da_fmt = 3; break; + default: ASSERT(0); + } + + DBGPV("da_fmt = %d\n", da_fmt); + ASSERT(framerate >= 4000 && framerate <= 49000); + ad1843_write_bits(lith, &ad1843_C2C, framerate); + ad1843_write_multi(lith, 2, + &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt); +} + +static void ad1843_shutdown_adc(lithium_t *lith) +{ + /* nothing to do */ +} + +/* + * Fully initialize the ad1843. As described in the AD1843 data + * sheet, section "START-UP SEQUENCE". The numbered comments are + * subsection headings from the data sheet. See the data sheet, pages + * 52-54, for more info. + * + * return 0 on success, -errno on failure. */ + +static int ad1843_init(lithium_t *lith) +{ + unsigned long later; + int err; + + err = li_init(lith); + if (err) + return err; + + if (ad1843_read_bits(lith, &ad1843_INIT) != 0) { + printk(KERN_ERR "vwsnd sound: AD1843 won't initialize\n"); + return -EIO; + } + + ad1843_write_bits(lith, &ad1843_SCF, 1); + + /* 4. Put the conversion resources into standby. */ + + ad1843_write_bits(lith, &ad1843_PDNI, 0); + later = jiffies + HZ / 2; /* roughly half a second */ + DBGDO(shut_up++); + while (ad1843_read_bits(lith, &ad1843_PDNO)) { + if (jiffies > later) { + printk(KERN_ERR + "vwsnd audio: AD1843 won't power up\n"); + return -EIO; + } + schedule(); + } + DBGDO(shut_up--); + + /* 5. Power up the clock generators and enable clock output pins. */ + + ad1843_write_multi(lith, 2, &ad1843_C1EN, 1, &ad1843_C2EN, 1); + + /* 6. Configure conversion resources while they are in standby. */ + + /* DAC1 uses clock 1 as source, ADC uses clock 2. Always. */ + + ad1843_write_multi(lith, 3, + &ad1843_DA1C, 1, + &ad1843_ADLC, 2, + &ad1843_ADRC, 2); + + /* 7. Enable conversion resources. */ + + ad1843_write_bits(lith, &ad1843_ADTLK, 1); + ad1843_write_multi(lith, 5, + &ad1843_ANAEN, 1, + &ad1843_AAMEN, 1, + &ad1843_DA1EN, 1, + &ad1843_ADLEN, 1, + &ad1843_ADREN, 1); + + /* 8. Configure conversion resources while they are enabled. */ + + ad1843_write_bits(lith, &ad1843_DA1C, 1); + + /* Unmute all channels. */ + + ad1843_set_outsrc(lith, + (SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_MIC | SOUND_MASK_CD)); + ad1843_write_multi(lith, 2, &ad1843_LDA1AM, 0, &ad1843_RDA1AM, 0); + + /* Set default recording source to Line In and set + * mic gain to +20 dB. + */ + + ad1843_set_recsrc(lith, SOUND_MASK_LINE); + ad1843_write_multi(lith, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1); + + /* Set Speaker Out level to +/- 4V and unmute it. */ + + ad1843_write_multi(lith, 2, &ad1843_HPOS, 1, &ad1843_HPOM, 0); + + return 0; +} + +/*****************************************************************************/ +/* PCM I/O */ + +#define READ_INTR_MASK (LI_INTR_COMM1_TRIG | LI_INTR_COMM1_OVERFLOW) +#define WRITE_INTR_MASK (LI_INTR_COMM2_TRIG | LI_INTR_COMM2_UNDERFLOW) + +typedef enum vwsnd_port_swstate { /* software state */ + SW_OFF, + SW_INITIAL, + SW_RUN, + SW_DRAIN, +} vwsnd_port_swstate_t; + +typedef enum vwsnd_port_hwstate { /* hardware state */ + HW_STOPPED, + HW_RUNNING, +} vwsnd_port_hwstate_t; + +/* + * These flags are read by ISR, but only written at baseline. + */ + +typedef enum vwsnd_port_flags { + DISABLED = 1 << 0, + ERFLOWN = 1 << 1, /* overflown or underflown */ + HW_BUSY = 1 << 2, +} vwsnd_port_flags_t; + +/* + * vwsnd_port is the per-port data structure. Each device has two + * ports, one for input and one for output. + * + * Locking: + * + * port->lock protects: hwstate, flags, swb_[iu]_avail. + * + * devc->io_sema protects: swstate, sw_*, swb_[iu]_idx. + * + * everything else is only written by open/release or + * pcm_{setup,shutdown}(), which are serialized by a + * combination of devc->open_sema and devc->io_sema. + */ + +typedef struct vwsnd_port { + + spinlock_t lock; + wait_queue_head_t queue; + vwsnd_port_swstate_t swstate; + vwsnd_port_hwstate_t hwstate; + vwsnd_port_flags_t flags; + + int sw_channels; + int sw_samplefmt; + int sw_framerate; + int sample_size; + int frame_size; + unsigned int zero_word; /* zero for the sample format */ + + int sw_fragshift; + int sw_fragcount; + int sw_subdivshift; + + unsigned int hw_fragshift; + unsigned int hw_fragsize; + unsigned int hw_fragcount; + + int hwbuf_size; + unsigned long hwbuf_paddr; + unsigned long hwbuf_vaddr; + caddr_t hwbuf; /* hwbuf == hwbuf_vaddr */ + int hwbuf_max; /* max bytes to preload */ + + caddr_t swbuf; + unsigned int swbuf_size; /* size in bytes */ + unsigned int swb_u_idx; /* index of next user byte */ + unsigned int swb_i_idx; /* index of next intr byte */ + unsigned int swb_u_avail; /* # bytes avail to user */ + unsigned int swb_i_avail; /* # bytes avail to intr */ + + dma_chan_t chan; + + /* Accounting */ + + int byte_count; + int frag_count; + int MSC_offset; + +} vwsnd_port_t; + +/* vwsnd_dev is the per-device data structure. */ + +typedef struct vwsnd_dev { + struct vwsnd_dev *next_dev; + int audio_minor; /* minor number of audio device */ + int mixer_minor; /* minor number of mixer device */ + + struct semaphore open_sema; + struct semaphore io_sema; + struct semaphore mix_sema; + mode_t open_mode; + wait_queue_head_t open_wait; + + lithium_t lith; + + vwsnd_port_t rport; + vwsnd_port_t wport; +} vwsnd_dev_t; + +static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */ + +#ifdef MODULE + +# define INC_USE_COUNT MOD_INC_USE_COUNT +# define DEC_USE_COUNT MOD_DEC_USE_COUNT +# define IN_USE MOD_IN_USE + +#else + +static atomic_t vwsnd_use_count = ATOMIC_INIT(0); + +# define INC_USE_COUNT (atomic_inc(&vwsnd_use_count)) +# define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count)) +# define IN_USE (atomic_read(&vwsnd_use_count) != 0) + +#endif + +/* + * Lithium can only DMA multiples of 32 bytes. Its DMA buffer may + * be up to 8 Kb. This driver always uses 8 Kb. + * + * Memory bug workaround -- I'm not sure what's going on here, but + * somehow pcm_copy_out() was triggering segv's going on to the next + * page of the hw buffer. So, I make the hw buffer one size bigger + * than we actually use. That way, the following page is allocated + * and mapped, and no error. I suspect that something is broken + * in Cobalt, but haven't really investigated. HBO is the actual + * size of the buffer, and HWBUF_ORDER is what we allocate. + */ + +#define HWBUF_SHIFT 13 +#define HWBUF_SIZE (1 << HWBUF_SHIFT) +# define HBO (HWBUF_SHIFT > PAGE_SHIFT ? HWBUF_SHIFT - PAGE_SHIFT : 0) +# define HWBUF_ORDER (HBO + 1) /* next size bigger */ +#define MIN_SPEED 4000 +#define MAX_SPEED 49000 + +#define MIN_FRAGSHIFT (DMACHUNK_SHIFT + 1) +#define MAX_FRAGSHIFT (PAGE_SHIFT) +#define MIN_FRAGSIZE (1 << MIN_FRAGSHIFT) +#define MAX_FRAGSIZE (1 << MAX_FRAGSHIFT) +#define MIN_FRAGCOUNT(fragsize) 3 +#define MAX_FRAGCOUNT(fragsize) (32 * PAGE_SIZE / (fragsize)) +#define DEFAULT_FRAGSHIFT 12 +#define DEFAULT_FRAGCOUNT 16 +#define DEFAULT_SUBDIVSHIFT 0 + +/* + * The software buffer (swbuf) is a ring buffer shared between user + * level and interrupt level. Each level owns some of the bytes in + * the buffer, and may give bytes away by calling swb_inc_{u,i}(). + * User level calls _u for user, and interrupt level calls _i for + * interrupt. + * + * port->swb_{u,i}_avail is the number of bytes available to that level. + * + * port->swb_{u,i}_idx is the index of the first available byte in the + * buffer. + * + * Each level calls swb_inc_{u,i}() to atomically increment its index, + * recalculate the number of bytes available for both sides, and + * return the number of bytes available. Since each side can only + * give away bytes, the other side can only increase the number of + * bytes available to this side. Each side updates its own index + * variable, swb_{u,i}_idx, so no lock is needed to read it. + * + * To query the number of bytes available, call swb_inc_{u,i} with an + * increment of zero. + */ + +static __inline__ unsigned int __swb_inc_u(vwsnd_port_t *port, int inc) +{ + if (inc) { + port->swb_u_idx += inc; + port->swb_u_idx %= port->swbuf_size; + port->swb_u_avail -= inc; + port->swb_i_avail += inc; + } + return port->swb_u_avail; +} + +static __inline__ unsigned int swb_inc_u(vwsnd_port_t *port, int inc) +{ + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&port->lock, flags); + { + ret = __swb_inc_u(port, inc); + } + spin_unlock_irqrestore(&port->lock, flags); + return ret; +} + +static __inline__ unsigned int __swb_inc_i(vwsnd_port_t *port, int inc) +{ + if (inc) { + port->swb_i_idx += inc; + port->swb_i_idx %= port->swbuf_size; + port->swb_i_avail -= inc; + port->swb_u_avail += inc; + } + return port->swb_i_avail; +} + +static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc) +{ + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&port->lock, flags); + { + ret = __swb_inc_i(port, inc); + } + spin_unlock_irqrestore(&port->lock, flags); + return ret; +} + +/* + * pcm_setup - this routine initializes all port state after + * mode-setting ioctls have been done, but before the first I/O is + * done. + * + * Locking: called with devc->io_sema held. + * + * Returns 0 on success, -errno on failure. + */ + +static int pcm_setup(vwsnd_dev_t *devc, + vwsnd_port_t *rport, + vwsnd_port_t *wport) +{ + vwsnd_port_t *aport = rport ? rport : wport; + int sample_size; + unsigned int zero_word; + + DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport); + + ASSERT(aport != NULL); + if (aport->swbuf != NULL) + return 0; + switch (aport->sw_samplefmt) { + case AFMT_MU_LAW: + sample_size = 1; + zero_word = 0xFFFFFFFF ^ 0x80808080; + break; + + case AFMT_A_LAW: + sample_size = 1; + zero_word = 0xD5D5D5D5 ^ 0x80808080; + break; + + case AFMT_U8: + sample_size = 1; + zero_word = 0x80808080; + break; + + case AFMT_S8: + sample_size = 1; + zero_word = 0x00000000; + break; + + case AFMT_S16_LE: + sample_size = 2; + zero_word = 0x00000000; + break; + + default: + sample_size = 0; /* prevent compiler warning */ + zero_word = 0; + ASSERT(0); + } + aport->sample_size = sample_size; + aport->zero_word = zero_word; + aport->frame_size = aport->sw_channels * aport->sample_size; + aport->hw_fragshift = aport->sw_fragshift - aport->sw_subdivshift; + aport->hw_fragsize = 1 << aport->hw_fragshift; + aport->hw_fragcount = aport->sw_fragcount << aport->sw_subdivshift; + ASSERT(aport->hw_fragsize >= MIN_FRAGSIZE); + ASSERT(aport->hw_fragsize <= MAX_FRAGSIZE); + ASSERT(aport->hw_fragcount >= MIN_FRAGCOUNT(aport->hw_fragsize)); + ASSERT(aport->hw_fragcount <= MAX_FRAGCOUNT(aport->hw_fragsize)); + if (rport) { + int hwfrags, swfrags; + rport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE; + hwfrags = rport->hwbuf_max >> aport->hw_fragshift; + swfrags = aport->hw_fragcount - hwfrags; + if (swfrags < 2) + swfrags = 2; + rport->swbuf_size = swfrags * aport->hw_fragsize; + DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags); + DBGPV("read hwbuf_max = %d, swbuf_size = %d\n", + rport->hwbuf_max, rport->swbuf_size); + } + if (wport) { + int hwfrags, swfrags; + int total_bytes = aport->hw_fragcount * aport->hw_fragsize; + wport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE; + if (wport->hwbuf_max > total_bytes) + wport->hwbuf_max = total_bytes; + hwfrags = wport->hwbuf_max >> aport->hw_fragshift; + DBGPV("hwfrags = %d\n", hwfrags); + swfrags = aport->hw_fragcount - hwfrags; + if (swfrags < 2) + swfrags = 2; + wport->swbuf_size = swfrags * aport->hw_fragsize; + DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags); + DBGPV("write hwbuf_max = %d, swbuf_size = %d\n", + wport->hwbuf_max, wport->swbuf_size); + } + + aport->swb_u_idx = 0; + aport->swb_i_idx = 0; + aport->byte_count = 0; + + /* + * Is this a Cobalt bug? We need to make this buffer extend + * one page further than we actually use -- somehow memcpy + * causes an exceptoin otherwise. I suspect there's a bug in + * Cobalt (or somewhere) where it's generating a fault on a + * speculative load or something. Obviously, I haven't taken + * the time to track it down. + */ + + aport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE); + if (!aport->swbuf) + return -ENOMEM; + if (rport && wport) { + ASSERT(aport == rport); + ASSERT(wport->swbuf == NULL); + /* One extra page - see comment above. */ + wport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE); + if (!wport->swbuf) { + vfree(aport->swbuf); + aport->swbuf = NULL; + return -ENOMEM; + } + wport->sample_size = rport->sample_size; + wport->zero_word = rport->zero_word; + wport->frame_size = rport->frame_size; + wport->hw_fragshift = rport->hw_fragshift; + wport->hw_fragsize = rport->hw_fragsize; + wport->hw_fragcount = rport->hw_fragcount; + wport->swbuf_size = rport->swbuf_size; + wport->hwbuf_max = rport->hwbuf_max; + wport->swb_u_idx = rport->swb_u_idx; + wport->swb_i_idx = rport->swb_i_idx; + wport->byte_count = rport->byte_count; + } + if (rport) { + rport->swb_u_avail = 0; + rport->swb_i_avail = rport->swbuf_size; + rport->swstate = SW_RUN; + li_setup_dma(&rport->chan, + &li_comm1, + &devc->lith, + rport->hwbuf_paddr, + HWBUF_SHIFT, + rport->hw_fragshift, + rport->sw_channels, + rport->sample_size); + ad1843_setup_adc(&devc->lith, + rport->sw_framerate, + rport->sw_samplefmt, + rport->sw_channels); + li_enable_interrupts(&devc->lith, READ_INTR_MASK); + if (!(rport->flags & DISABLED)) { + ustmsc_t ustmsc; + rport->hwstate = HW_RUNNING; + li_activate_dma(&rport->chan); + li_read_USTMSC(&rport->chan, &ustmsc); + rport->MSC_offset = ustmsc.msc; + } + } + if (wport) { + if (wport->hwbuf_max > wport->swbuf_size) + wport->hwbuf_max = wport->swbuf_size; + wport->flags &= ~ERFLOWN; + wport->swb_u_avail = wport->swbuf_size; + wport->swb_i_avail = 0; + wport->swstate = SW_RUN; + li_setup_dma(&wport->chan, + &li_comm2, + &devc->lith, + wport->hwbuf_paddr, + HWBUF_SHIFT, + wport->hw_fragshift, + wport->sw_channels, + wport->sample_size); + ad1843_setup_dac(&devc->lith, + wport->sw_framerate, + wport->sw_samplefmt, + wport->sw_channels); + li_enable_interrupts(&devc->lith, WRITE_INTR_MASK); + } + DBGRV(); + return 0; +} + +/* + * pcm_shutdown_port - shut down one port (direction) for PCM I/O. + * Only called from pcm_shutdown. + */ + +static void pcm_shutdown_port(vwsnd_dev_t *devc, + vwsnd_port_t *aport, + unsigned int mask) +{ + unsigned long flags; + vwsnd_port_hwstate_t hwstate; + DECLARE_WAITQUEUE(wait, current); + + aport->swstate = SW_INITIAL; + add_wait_queue(&aport->queue, &wait); + current->state = TASK_UNINTERRUPTIBLE; + while (1) { + spin_lock_irqsave(&aport->lock, flags); + { + hwstate = aport->hwstate; + } + spin_unlock_irqrestore(&aport->lock, flags); + if (hwstate == HW_STOPPED) + break; + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&aport->queue, &wait); + li_disable_interrupts(&devc->lith, mask); + if (aport == &devc->rport) + ad1843_shutdown_adc(&devc->lith); + else /* aport == &devc->wport) */ + ad1843_shutdown_dac(&devc->lith); + li_shutdown_dma(&aport->chan); + vfree(aport->swbuf); + aport->swbuf = NULL; + aport->byte_count = 0; +} + +/* + * pcm_shutdown undoes what pcm_setup did. + * Also sets the ports' swstate to newstate. + */ + +static void pcm_shutdown(vwsnd_dev_t *devc, + vwsnd_port_t *rport, + vwsnd_port_t *wport) +{ + DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport); + + if (rport && rport->swbuf) { + DBGPV("shutting down rport\n"); + pcm_shutdown_port(devc, rport, READ_INTR_MASK); + } + if (wport && wport->swbuf) { + DBGPV("shutting down wport\n"); + pcm_shutdown_port(devc, wport, WRITE_INTR_MASK); + } + DBGRV(); +} + +static void pcm_copy_in(vwsnd_port_t *rport, int swidx, int hwidx, int nb) +{ + char *src = rport->hwbuf + hwidx; + char *dst = rport->swbuf + swidx; + int fmt = rport->sw_samplefmt; + + DBGPV("swidx = %d, hwidx = %d\n", swidx, hwidx); + ASSERT(rport->hwbuf != NULL); + ASSERT(rport->swbuf != NULL); + ASSERT(nb > 0 && (nb % 32) == 0); + ASSERT(swidx % 32 == 0 && hwidx % 32 == 0); + ASSERT(swidx >= 0 && swidx + nb <= rport->swbuf_size); + ASSERT(hwidx >= 0 && hwidx + nb <= rport->hwbuf_size); + + if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) { + + /* See Sample Format Notes above. */ + + char *end = src + nb; + while (src < end) + *dst++ = *src++ ^ 0x80; + } else + memcpy(dst, src, nb); +} + +static void pcm_copy_out(vwsnd_port_t *wport, int swidx, int hwidx, int nb) +{ + char *src = wport->swbuf + swidx; + char *dst = wport->hwbuf + hwidx; + int fmt = wport->sw_samplefmt; + + ASSERT(nb > 0 && (nb % 32) == 0); + ASSERT(wport->hwbuf != NULL); + ASSERT(wport->swbuf != NULL); + ASSERT(swidx % 32 == 0 && hwidx % 32 == 0); + ASSERT(swidx >= 0 && swidx + nb <= wport->swbuf_size); + ASSERT(hwidx >= 0 && hwidx + nb <= wport->hwbuf_size); + if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) { + + /* See Sample Format Notes above. */ + + char *end = src + nb; + while (src < end) + *dst++ = *src++ ^ 0x80; + } else + memcpy(dst, src, nb); +} + +/* + * pcm_output() is called both from baselevel and from interrupt level. + * This is where audio frames are copied into the hardware-accessible + * ring buffer. + * + * Locking note: The part of this routine that figures out what to do + * holds wport->lock. The longer part releases wport->lock, but sets + * wport->flags & HW_BUSY. Afterward, it reacquires wport->lock, and + * checks for more work to do. + * + * If another thread calls pcm_output() while HW_BUSY is set, it + * returns immediately, knowing that the thread that set HW_BUSY will + * look for more work to do before returning. + * + * This has the advantage that port->lock is held for several short + * periods instead of one long period. Also, when pcm_output is + * called from base level, it reenables interrupts. + */ + +static void pcm_output(vwsnd_dev_t *devc, int erflown, int nb) +{ + vwsnd_port_t *wport = &devc->wport; + const int hwmax = wport->hwbuf_max; + const int hwsize = wport->hwbuf_size; + const int swsize = wport->swbuf_size; + const int fragsize = wport->hw_fragsize; + unsigned long iflags; + + DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb); + spin_lock_irqsave(&wport->lock, iflags); + if (erflown) + wport->flags |= ERFLOWN; + (void) __swb_inc_u(wport, nb); + if (wport->flags & HW_BUSY) { + spin_unlock_irqrestore(&wport->lock, iflags); + DBGPV("returning: HW BUSY\n"); + return; + } + if (wport->flags & DISABLED) { + spin_unlock_irqrestore(&wport->lock, iflags); + DBGPV("returning: DISABLED\n"); + return; + } + wport->flags |= HW_BUSY; + while (1) { + int swptr, hwptr, hw_avail, sw_avail, swidx; + vwsnd_port_hwstate_t hwstate = wport->hwstate; + vwsnd_port_swstate_t swstate = wport->swstate; + int hw_unavail; + ustmsc_t ustmsc; + + hwptr = li_read_hwptr(&wport->chan); + swptr = li_read_swptr(&wport->chan); + hw_unavail = (swptr - hwptr + hwsize) % hwsize; + hw_avail = (hwmax - hw_unavail) & -fragsize; + sw_avail = wport->swb_i_avail & -fragsize; + if (sw_avail && swstate == SW_RUN) { + if (wport->flags & ERFLOWN) { + wport->flags &= ~ERFLOWN; + } + } else if (swstate == SW_INITIAL || + swstate == SW_OFF || + (swstate == SW_DRAIN && + !sw_avail && + (wport->flags & ERFLOWN))) { + DBGP("stopping. hwstate = %d\n", hwstate); + if (hwstate != HW_STOPPED) { + li_deactivate_dma(&wport->chan); + wport->hwstate = HW_STOPPED; + } + wake_up(&wport->queue); + break; + } + if (!sw_avail || !hw_avail) + break; + spin_unlock_irqrestore(&wport->lock, iflags); + + /* + * We gave up the port lock, but we have the HW_BUSY flag. + * Proceed without accessing any nonlocal state. + * Do not exit the loop -- must check for more work. + */ + + swidx = wport->swb_i_idx; + nb = hw_avail; + if (nb > sw_avail) + nb = sw_avail; + if (nb > hwsize - swptr) + nb = hwsize - swptr; /* don't overflow hwbuf */ + if (nb > swsize - swidx) + nb = swsize - swidx; /* don't overflow swbuf */ + ASSERT(nb > 0); + if (nb % fragsize) { + DBGP("nb = %d, fragsize = %d\n", nb, fragsize); + DBGP("hw_avail = %d\n", hw_avail); + DBGP("sw_avail = %d\n", sw_avail); + DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr); + DBGP("swsize = %d, swidx = %d\n", swsize, swidx); + } + ASSERT(!(nb % fragsize)); + DBGPV("copying swb[%d..%d] to hwb[%d..%d]\n", + swidx, swidx + nb, swptr, swptr + nb); + pcm_copy_out(wport, swidx, swptr, nb); + li_write_swptr(&wport->chan, (swptr + nb) % hwsize); + spin_lock_irqsave(&wport->lock, iflags); + if (hwstate == HW_STOPPED) { + DBGPV("starting\n"); + li_activate_dma(&wport->chan); + wport->hwstate = HW_RUNNING; + li_read_USTMSC(&wport->chan, &ustmsc); + ASSERT(wport->byte_count % wport->frame_size == 0); + wport->MSC_offset = ustmsc.msc - wport->byte_count / wport->frame_size; + } + __swb_inc_i(wport, nb); + wport->byte_count += nb; + wport->frag_count += nb / fragsize; + ASSERT(nb % fragsize == 0); + wake_up(&wport->queue); + } + wport->flags &= ~HW_BUSY; + spin_unlock_irqrestore(&wport->lock, iflags); + DBGRV(); +} + +/* + * pcm_input() is called both from baselevel and from interrupt level. + * This is where audio frames are copied out of the hardware-accessible + * ring buffer. + * + * Locking note: The part of this routine that figures out what to do + * holds rport->lock. The longer part releases rport->lock, but sets + * rport->flags & HW_BUSY. Afterward, it reacquires rport->lock, and + * checks for more work to do. + * + * If another thread calls pcm_input() while HW_BUSY is set, it + * returns immediately, knowing that the thread that set HW_BUSY will + * look for more work to do before returning. + * + * This has the advantage that port->lock is held for several short + * periods instead of one long period. Also, when pcm_input is + * called from base level, it reenables interrupts. + */ + +static void pcm_input(vwsnd_dev_t *devc, int erflown, int nb) +{ + vwsnd_port_t *rport = &devc->rport; + const int hwmax = rport->hwbuf_max; + const int hwsize = rport->hwbuf_size; + const int swsize = rport->swbuf_size; + const int fragsize = rport->hw_fragsize; + unsigned long iflags; + + DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb); + + spin_lock_irqsave(&rport->lock, iflags); + if (erflown) + rport->flags |= ERFLOWN; + (void) __swb_inc_u(rport, nb); + if (rport->flags & HW_BUSY || !rport->swbuf) { + spin_unlock_irqrestore(&rport->lock, iflags); + DBGPV("returning: HW BUSY or !swbuf\n"); + return; + } + if (rport->flags & DISABLED) { + spin_unlock_irqrestore(&rport->lock, iflags); + DBGPV("returning: DISABLED\n"); + return; + } + rport->flags |= HW_BUSY; + while (1) { + int swptr, hwptr, hw_avail, sw_avail, swidx; + vwsnd_port_hwstate_t hwstate = rport->hwstate; + vwsnd_port_swstate_t swstate = rport->swstate; + + hwptr = li_read_hwptr(&rport->chan); + swptr = li_read_swptr(&rport->chan); + hw_avail = (hwptr - swptr + hwsize) % hwsize & -fragsize; + if (hw_avail > hwmax) + hw_avail = hwmax; + sw_avail = rport->swb_i_avail & -fragsize; + if (swstate != SW_RUN) { + DBGP("stopping. hwstate = %d\n", hwstate); + if (hwstate != HW_STOPPED) { + li_deactivate_dma(&rport->chan); + rport->hwstate = HW_STOPPED; + } + wake_up(&rport->queue); + break; + } + if (!sw_avail || !hw_avail) + break; + spin_unlock_irqrestore(&rport->lock, iflags); + + /* + * We gave up the port lock, but we have the HW_BUSY flag. + * Proceed without accessing any nonlocal state. + * Do not exit the loop -- must check for more work. + */ + + swidx = rport->swb_i_idx; + nb = hw_avail; + if (nb > sw_avail) + nb = sw_avail; + if (nb > hwsize - swptr) + nb = hwsize - swptr; /* don't overflow hwbuf */ + if (nb > swsize - swidx) + nb = swsize - swidx; /* don't overflow swbuf */ + ASSERT(nb > 0); + if (nb % fragsize) { + DBGP("nb = %d, fragsize = %d\n", nb, fragsize); + DBGP("hw_avail = %d\n", hw_avail); + DBGP("sw_avail = %d\n", sw_avail); + DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr); + DBGP("swsize = %d, swidx = %d\n", swsize, swidx); + } + ASSERT(!(nb % fragsize)); + DBGPV("copying hwb[%d..%d] to swb[%d..%d]\n", + swptr, swptr + nb, swidx, swidx + nb); + pcm_copy_in(rport, swidx, swptr, nb); + li_write_swptr(&rport->chan, (swptr + nb) % hwsize); + spin_lock_irqsave(&rport->lock, iflags); + __swb_inc_i(rport, nb); + rport->byte_count += nb; + rport->frag_count += nb / fragsize; + ASSERT(nb % fragsize == 0); + wake_up(&rport->queue); + } + rport->flags &= ~HW_BUSY; + spin_unlock_irqrestore(&rport->lock, iflags); + DBGRV(); +} + +/* + * pcm_flush_frag() writes zero samples to fill the current fragment, + * then flushes it to the hardware. + * + * It is only meaningful to flush output, not input. + */ + +static void pcm_flush_frag(vwsnd_dev_t *devc) +{ + vwsnd_port_t *wport = &devc->wport; + + DBGPV("swstate = %d\n", wport->swstate); + if (wport->swstate == SW_RUN) { + int idx = wport->swb_u_idx; + int end = (idx + wport->hw_fragsize - 1) + >> wport->hw_fragshift + << wport->hw_fragshift; + int nb = end - idx; + DBGPV("clearing %d bytes\n", nb); + if (nb) + memset(wport->swbuf + idx, + (char) wport->zero_word, + nb); + wport->swstate = SW_DRAIN; + pcm_output(devc, 0, nb); + } + DBGRV(); +} + +/* + * Wait for output to drain. This sleeps uninterruptibly because + * there is nothing intelligent we can do if interrupted. This + * means the process will be delayed in responding to the signal. + */ + +static void pcm_write_sync(vwsnd_dev_t *devc) +{ + vwsnd_port_t *wport = &devc->wport; + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + vwsnd_port_hwstate_t hwstate; + + DBGEV("(devc=0x%p)\n", devc); + add_wait_queue(&wport->queue, &wait); + current->state = TASK_UNINTERRUPTIBLE; + while (1) { + spin_lock_irqsave(&wport->lock, flags); + { + hwstate = wport->hwstate; + } + spin_unlock_irqrestore(&wport->lock, flags); + if (hwstate == HW_STOPPED) + break; + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&wport->queue, &wait); + DBGPV("swstate = %d, hwstate = %d\n", wport->swstate, wport->hwstate); + DBGRV(); +} + +/*****************************************************************************/ +/* audio driver */ + +/* + * seek on an audio device always fails. + */ + +static void vwsnd_audio_read_intr(vwsnd_dev_t *devc, unsigned int status) +{ + int overflown = status & LI_INTR_COMM1_OVERFLOW; + + if (status & READ_INTR_MASK) + pcm_input(devc, overflown, 0); +} + +static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status) +{ + int underflown = status & LI_INTR_COMM2_UNDERFLOW; + + if (status & WRITE_INTR_MASK) + pcm_output(devc, underflown, 0); +} + +static void vwsnd_audio_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) dev_id; + unsigned int status; + + DBGEV("(irq=%d, dev_id=0x%p, regs=0x%p)\n", irq, dev_id, regs); + + status = li_get_clear_intr_status(&devc->lith); + vwsnd_audio_read_intr(devc, status); + vwsnd_audio_write_intr(devc, status); +} + +static loff_t vwsnd_audio_llseek(struct file *file, loff_t offset, int whence) +{ + DBGEV("(file=0x%p, offset=%Ld, whence=%d)\n", file, offset, whence); + return -ESPIPE; +} + +static ssize_t vwsnd_audio_do_read(struct file *file, + char *buffer, + size_t count, + loff_t *ppos) +{ + vwsnd_dev_t *devc = file->private_data; + vwsnd_port_t *rport = ((file->f_mode & FMODE_READ) ? + &devc->rport : NULL); + int ret, nb; + + DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n", + file, buffer, count, ppos); + + if (!rport) + return -EINVAL; + + if (rport->swbuf == NULL) { + vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? + &devc->wport : NULL; + ret = pcm_setup(devc, rport, wport); + if (ret < 0) + return ret; + } + + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + ret = 0; + while (count) { + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&rport->queue, &wait); + current->state = TASK_INTERRUPTIBLE; + while ((nb = swb_inc_u(rport, 0)) == 0) { + DBGPV("blocking\n"); + if (rport->flags & DISABLED || + file->f_flags & O_NONBLOCK) { + current->state = TASK_RUNNING; + remove_wait_queue(&rport->queue, &wait); + return ret ? ret : -EAGAIN; + } + schedule(); + if (signal_pending(current)) { + current->state = TASK_RUNNING; + remove_wait_queue(&rport->queue, &wait); + return ret ? ret : -ERESTARTSYS; + } + } + current->state = TASK_RUNNING; + remove_wait_queue(&rport->queue, &wait); + pcm_input(devc, 0, 0); + /* nb bytes are available in userbuf. */ + if (nb > count) + nb = count; + DBGPV("nb = %d\n", nb); + copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb); + (void) swb_inc_u(rport, nb); + buffer += nb; + count -= nb; + ret += nb; + } + DBGPV("returning %d\n", ret); + return ret; +} + +static ssize_t vwsnd_audio_read(struct file *file, + char *buffer, + size_t count, + loff_t *ppos) +{ + vwsnd_dev_t *devc = file->private_data; + ssize_t ret; + + down(&devc->io_sema); + ret = vwsnd_audio_do_read(file, buffer, count, ppos); + up(&devc->io_sema); + return ret; +} + +static ssize_t vwsnd_audio_do_write(struct file *file, + const char *buffer, + size_t count, + loff_t *ppos) +{ + vwsnd_dev_t *devc = file->private_data; + vwsnd_port_t *wport = ((file->f_mode & FMODE_WRITE) ? + &devc->wport : NULL); + int ret, nb; + + DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n", + file, buffer, count, ppos); + + if (!wport) + return -EINVAL; + + if (wport->swbuf == NULL) { + vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? + &devc->rport : NULL; + ret = pcm_setup(devc, rport, wport); + if (ret < 0) + return ret; + } + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + ret = 0; + while (count) { + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&wport->queue, &wait); + current->state = TASK_INTERRUPTIBLE; + while ((nb = swb_inc_u(wport, 0)) == 0) { + if (wport->flags & DISABLED || + file->f_flags & O_NONBLOCK) { + current->state = TASK_RUNNING; + remove_wait_queue(&wport->queue, &wait); + return ret ? ret : -EAGAIN; + } + schedule(); + if (signal_pending(current)) { + current->state = TASK_RUNNING; + remove_wait_queue(&wport->queue, &wait); + return ret ? ret : -ERESTARTSYS; + } + } + current->state = TASK_RUNNING; + remove_wait_queue(&wport->queue, &wait); + /* nb bytes are available in userbuf. */ + if (nb > count) + nb = count; + DBGPV("nb = %d\n", nb); + copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb); + pcm_output(devc, 0, nb); + buffer += nb; + count -= nb; + ret += nb; + } + DBGPV("returning %d\n", ret); + return ret; +} + +static ssize_t vwsnd_audio_write(struct file *file, + const char *buffer, + size_t count, + loff_t *ppos) +{ + vwsnd_dev_t *devc = file->private_data; + ssize_t ret; + + down(&devc->io_sema); + ret = vwsnd_audio_do_write(file, buffer, count, ppos); + up(&devc->io_sema); + return ret; +} + +static unsigned int vwsnd_audio_poll(struct file *file, + struct poll_table_struct *wait) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; + vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? + &devc->rport : NULL; + vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? + &devc->wport : NULL; + unsigned int mask = 0; + + DBGEV("(file=0x%p, wait=0x%p)\n", file, wait); + + ASSERT(rport || wport); + if (rport) { + poll_wait(file, &rport->queue, wait); + if (swb_inc_u(rport, 0)) + mask |= (POLLIN | POLLRDNORM); + } + if (wport) { + poll_wait(file, &wport->queue, wait); + if (wport->swbuf == NULL || swb_inc_u(wport, 0)) + mask |= (POLLOUT | POLLWRNORM); + } + + DBGPV("returning 0x%x\n", mask); + return mask; +} + +static int vwsnd_audio_do_ioctl(struct inode *inode, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; + vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? + &devc->rport : NULL; + vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? + &devc->wport : NULL; + vwsnd_port_t *aport = rport ? rport : wport; + struct audio_buf_info buf_info; + struct count_info info; + unsigned long flags; + int ival; + + + DBGEV("(inode=0x%p, file=0x%p, cmd=0x%x, arg=0x%lx)\n", + inode, file, cmd, arg); + switch (cmd) { + case OSS_GETVERSION: /* _SIOR ('M', 118, int) */ + DBGX("OSS_GETVERSION\n"); + ival = SOUND_VERSION; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_GETCAPS: /* _SIOR ('P',15, int) */ + DBGX("SNDCTL_DSP_GETCAPS\n"); + ival = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_GETFMTS: /* _SIOR ('P',11, int) */ + DBGX("SNDCTL_DSP_GETFMTS\n"); + ival = (AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | + AFMT_U8 | AFMT_S8); + return put_user(ival, (int *) arg); + break; + + case SOUND_PCM_READ_RATE: /* _SIOR ('P', 2, int) */ + DBGX("SOUND_PCM_READ_RATE\n"); + ival = aport->sw_framerate; + return put_user(ival, (int *) arg); + + case SOUND_PCM_READ_CHANNELS: /* _SIOR ('P', 6, int) */ + DBGX("SOUND_PCM_READ_CHANNELS\n"); + ival = aport->sw_channels; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_SPEED: /* _SIOWR('P', 2, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_SPEED %d\n", ival); + if (ival) { + if (aport->swstate != SW_INITIAL) { + DBGX("SNDCTL_DSP_SPEED failed: swstate = %d\n", + aport->swstate); + return -EINVAL; + } + if (ival < MIN_SPEED) + ival = MIN_SPEED; + if (ival > MAX_SPEED) + ival = MAX_SPEED; + if (rport) + rport->sw_framerate = ival; + if (wport) + wport->sw_framerate = ival; + } else + ival = aport->sw_framerate; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_STEREO: /* _SIOWR('P', 3, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_STEREO %d\n", ival); + if (ival != 0 && ival != 1) + return -EINVAL; + if (aport->swstate != SW_INITIAL) + return -EINVAL; + if (rport) + rport->sw_channels = ival + 1; + if (wport) + wport->sw_channels = ival + 1; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_CHANNELS: /* _SIOWR('P', 6, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_CHANNELS %d\n", ival); + if (ival != 1 && ival != 2) + return -EINVAL; + if (aport->swstate != SW_INITIAL) + return -EINVAL; + if (rport) + rport->sw_channels = ival; + if (wport) + wport->sw_channels = ival; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_GETBLKSIZE: /* _SIOWR('P', 4, int) */ + ival = pcm_setup(devc, rport, wport); + if (ival < 0) { + DBGX("SNDCTL_DSP_GETBLKSIZE failed, errno %d\n", ival); + return ival; + } + ival = 1 << aport->sw_fragshift; + DBGX("SNDCTL_DSP_GETBLKSIZE returning %d\n", ival); + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_SETFRAGMENT: /* _SIOWR('P',10, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n", + ival >> 16, ival & 0xFFFF); + if (aport->swstate != SW_INITIAL) + return -EINVAL; + { + int sw_fragshift = ival & 0xFFFF; + int sw_subdivshift = aport->sw_subdivshift; + int hw_fragshift = sw_fragshift - sw_subdivshift; + int sw_fragcount = (ival >> 16) & 0xFFFF; + int hw_fragsize; + if (hw_fragshift < MIN_FRAGSHIFT) + hw_fragshift = MIN_FRAGSHIFT; + if (hw_fragshift > MAX_FRAGSHIFT) + hw_fragshift = MAX_FRAGSHIFT; + sw_fragshift = hw_fragshift + aport->sw_subdivshift; + hw_fragsize = 1 << hw_fragshift; + if (sw_fragcount < MIN_FRAGCOUNT(hw_fragsize)) + sw_fragcount = MIN_FRAGCOUNT(hw_fragsize); + if (sw_fragcount > MAX_FRAGCOUNT(hw_fragsize)) + sw_fragcount = MAX_FRAGCOUNT(hw_fragsize); + DBGPV("sw_fragshift = %d\n", sw_fragshift); + DBGPV("rport = 0x%p, wport = 0x%p\n", rport, wport); + if (rport) { + rport->sw_fragshift = sw_fragshift; + rport->sw_fragcount = sw_fragcount; + } + if (wport) { + wport->sw_fragshift = sw_fragshift; + wport->sw_fragcount = sw_fragcount; + } + ival = sw_fragcount << 16 | sw_fragshift; + } + DBGX("SNDCTL_DSP_SETFRAGMENT returns %d:%d\n", + ival >> 16, ival & 0xFFFF); + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_SUBDIVIDE: /* _SIOWR('P', 9, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_SUBDIVIDE %d\n", ival); + if (aport->swstate != SW_INITIAL) + return -EINVAL; + { + int subdivshift; + int hw_fragshift, hw_fragsize, hw_fragcount; + switch (ival) { + case 1: subdivshift = 0; break; + case 2: subdivshift = 1; break; + case 4: subdivshift = 2; break; + default: return -EINVAL; + } + hw_fragshift = aport->sw_fragshift - subdivshift; + if (hw_fragshift < MIN_FRAGSHIFT || + hw_fragshift > MAX_FRAGSHIFT) + return -EINVAL; + hw_fragsize = 1 << hw_fragshift; + hw_fragcount = aport->sw_fragcount >> subdivshift; + if (hw_fragcount < MIN_FRAGCOUNT(hw_fragsize) || + hw_fragcount > MAX_FRAGCOUNT(hw_fragsize)) + return -EINVAL; + if (rport) + rport->sw_subdivshift = subdivshift; + if (wport) + wport->sw_subdivshift = subdivshift; + } + return 0; + + case SNDCTL_DSP_SETFMT: /* _SIOWR('P',5, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_SETFMT %d\n", ival); + if (ival != AFMT_QUERY) { + if (aport->swstate != SW_INITIAL) { + DBGP("SETFMT failed, swstate = %d\n", + aport->swstate); + return -EINVAL; + } + switch (ival) { + case AFMT_MU_LAW: + case AFMT_A_LAW: + case AFMT_U8: + case AFMT_S8: + case AFMT_S16_LE: + if (rport) + rport->sw_samplefmt = ival; + if (wport) + wport->sw_samplefmt = ival; + break; + default: + return -EINVAL; + } + } + ival = aport->sw_samplefmt; + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_GETOSPACE: /* _SIOR ('P',12, audio_buf_info) */ + DBGXV("SNDCTL_DSP_GETOSPACE\n"); + if (!wport) + return -EINVAL; + ival = pcm_setup(devc, rport, wport); + if (ival < 0) + return ival; + ival = swb_inc_u(wport, 0); + buf_info.fragments = ival >> wport->sw_fragshift; + buf_info.fragstotal = wport->sw_fragcount; + buf_info.fragsize = 1 << wport->sw_fragshift; + buf_info.bytes = ival; + DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n", + buf_info.fragments, buf_info.fragstotal, + buf_info.fragsize, buf_info.bytes); + return copy_to_user((void *) arg, &buf_info, sizeof buf_info); + + case SNDCTL_DSP_GETISPACE: /* _SIOR ('P',13, audio_buf_info) */ + DBGX("SNDCTL_DSP_GETISPACE\n"); + if (!rport) + return -EINVAL; + ival = pcm_setup(devc, rport, wport); + if (ival < 0) + return ival; + ival = swb_inc_u(rport, 0); + buf_info.fragments = ival >> rport->sw_fragshift; + buf_info.fragstotal = rport->sw_fragcount; + buf_info.fragsize = 1 << rport->sw_fragshift; + buf_info.bytes = ival; + DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n", + buf_info.fragments, buf_info.fragstotal, + buf_info.fragsize, buf_info.bytes); + return copy_to_user((void *) arg, &buf_info, sizeof buf_info); + + case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */ + DBGX("SNDCTL_DSP_NONBLOCK\n"); + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */ + DBGX("SNDCTL_DSP_RESET\n"); + /* + * Nothing special needs to be done for input. Input + * samples sit in swbuf, but it will be reinitialized + * to empty when pcm_setup() is called. + */ + if (wport && wport->swbuf) { + wport->swstate = SW_INITIAL; + pcm_output(devc, 0, 0); + pcm_write_sync(devc); + } + pcm_shutdown(devc, rport, wport); + return 0; + + case SNDCTL_DSP_SYNC: /* _SIO ('P', 1) */ + DBGX("SNDCTL_DSP_SYNC\n"); + if (wport) { + pcm_flush_frag(devc); + pcm_write_sync(devc); + } + pcm_shutdown(devc, rport, wport); + return 0; + + case SNDCTL_DSP_POST: /* _SIO ('P', 8) */ + DBGX("SNDCTL_DSP_POST\n"); + if (!wport) + return -EINVAL; + pcm_flush_frag(devc); + return 0; + + case SNDCTL_DSP_GETIPTR: /* _SIOR ('P', 17, count_info) */ + DBGX("SNDCTL_DSP_GETIPTR\n"); + if (!rport) + return -EINVAL; + spin_lock_irqsave(&rport->lock, flags); + { + ustmsc_t ustmsc; + if (rport->hwstate == HW_RUNNING) { + ASSERT(rport->swstate == SW_RUN); + li_read_USTMSC(&rport->chan, &ustmsc); + info.bytes = ustmsc.msc - rport->MSC_offset; + info.bytes *= rport->frame_size; + } else { + info.bytes = rport->byte_count; + } + info.blocks = rport->frag_count; + info.ptr = 0; /* not implemented */ + rport->frag_count = 0; + } + spin_unlock_irqrestore(&rport->lock, flags); + return copy_to_user((void *) arg, &info, sizeof info); + + case SNDCTL_DSP_GETOPTR: /* _SIOR ('P',18, count_info) */ + DBGX("SNDCTL_DSP_GETOPTR\n"); + if (!wport) + return -EINVAL; + spin_lock_irqsave(&wport->lock, flags); + { + ustmsc_t ustmsc; + if (wport->hwstate == HW_RUNNING) { + ASSERT(wport->swstate == SW_RUN); + li_read_USTMSC(&wport->chan, &ustmsc); + info.bytes = ustmsc.msc - wport->MSC_offset; + info.bytes *= wport->frame_size; + } else { + info.bytes = wport->byte_count; + } + info.blocks = wport->frag_count; + info.ptr = 0; /* not implemented */ + wport->frag_count = 0; + } + spin_unlock_irqrestore(&wport->lock, flags); + return copy_to_user((void *) arg, &info, sizeof info); + + case SNDCTL_DSP_GETODELAY: /* _SIOR ('P', 23, int) */ + DBGX("SNDCTL_DSP_GETODELAY\n"); + if (!wport) + return -EINVAL; + spin_lock_irqsave(&wport->lock, flags); + { + int fsize = wport->frame_size; + ival = wport->swb_i_avail / fsize; + if (wport->hwstate == HW_RUNNING) { + int swptr, hwptr, hwframes, hwbytes, hwsize; + int totalhwbytes; + ustmsc_t ustmsc; + + hwsize = wport->hwbuf_size; + swptr = li_read_swptr(&wport->chan); + li_read_USTMSC(&wport->chan, &ustmsc); + hwframes = ustmsc.msc - wport->MSC_offset; + totalhwbytes = hwframes * fsize; + hwptr = totalhwbytes % hwsize; + hwbytes = (swptr - hwptr + hwsize) % hwsize; + ival += hwbytes / fsize; + } + } + spin_unlock_irqrestore(&wport->lock, flags); + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_PROFILE: /* _SIOW ('P', 23, int) */ + DBGX("SNDCTL_DSP_PROFILE\n"); + + /* + * Thomas Sailer explains SNDCTL_DSP_PROFILE + * (private email, March 24, 1999): + * + * This gives the sound driver a hint on what it + * should do with partial fragments + * (i.e. fragments partially filled with write). + * This can direct the driver to zero them or + * leave them alone. But don't ask me what this + * is good for, my driver just zeroes the last + * fragment before the receiver stops, no idea + * what good for any other behaviour could + * be. Implementing it as NOP seems safe. + */ + + break; + + case SNDCTL_DSP_GETTRIGGER: /* _SIOR ('P',16, int) */ + DBGX("SNDCTL_DSP_GETTRIGGER\n"); + ival = 0; + if (rport) { + spin_lock_irqsave(&rport->lock, flags); + { + if (!(rport->flags & DISABLED)) + ival |= PCM_ENABLE_INPUT; + } + spin_unlock_irqrestore(&rport->lock, flags); + } + if (wport) { + spin_lock_irqsave(&wport->lock, flags); + { + if (!(wport->flags & DISABLED)) + ival |= PCM_ENABLE_OUTPUT; + } + spin_unlock_irqrestore(&wport->lock, flags); + } + return put_user(ival, (int *) arg); + + case SNDCTL_DSP_SETTRIGGER: /* _SIOW ('P',16, int) */ + get_user_ret(ival, (int *) arg, -EFAULT); + DBGX("SNDCTL_DSP_SETTRIGGER %d\n", ival); + + /* + * If user is disabling I/O and port is not in initial + * state, fail with EINVAL. + */ + + if (((rport && !(ival & PCM_ENABLE_INPUT)) || + (wport && !(ival & PCM_ENABLE_OUTPUT))) && + aport->swstate != SW_INITIAL) + return -EINVAL; + + if (rport) { + vwsnd_port_hwstate_t hwstate; + spin_lock_irqsave(&rport->lock, flags); + { + hwstate = rport->hwstate; + if (ival & PCM_ENABLE_INPUT) + rport->flags &= ~DISABLED; + else + rport->flags |= DISABLED; + } + spin_unlock_irqrestore(&rport->lock, flags); + if (hwstate != HW_RUNNING && ival & PCM_ENABLE_INPUT) { + + if (rport->swstate == SW_INITIAL) + pcm_setup(devc, rport, wport); + else + li_activate_dma(&rport->chan); + } + } + if (wport) { + vwsnd_port_flags_t pflags; + spin_lock_irqsave(&wport->lock, flags); + { + pflags = wport->flags; + if (ival & PCM_ENABLE_OUTPUT) + wport->flags &= ~DISABLED; + else + wport->flags |= DISABLED; + } + spin_unlock_irqrestore(&wport->lock, flags); + if (pflags & DISABLED && ival & PCM_ENABLE_OUTPUT) { + if (wport->swstate == SW_RUN) + pcm_output(devc, 0, 0); + } + } + return 0; + + default: + DBGP("unknown ioctl 0x%x\n", cmd); + return -EINVAL; + } + DBGP("unimplemented ioctl 0x%x\n", cmd); + return -EINVAL; +} + +static int vwsnd_audio_ioctl(struct inode *inode, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; + int ret; + + down(&devc->io_sema); + ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg); + up(&devc->io_sema); + return ret; +} + +/* No mmap. */ + +static int vwsnd_audio_mmap(struct file *file, struct vm_area_struct *vma) +{ + DBGE("(file=0x%p, vma=0x%p)\n", file, vma); + return -ENODEV; +} + +/* + * Open the audio device for read and/or write. + * + * Returns 0 on success, -errno on failure. + */ + +static int vwsnd_audio_open(struct inode *inode, struct file *file) +{ + vwsnd_dev_t *devc; + dev_t minor = MINOR(inode->i_rdev); + int sw_samplefmt; + + DBGE("(inode=0x%p, file=0x%p)\n", inode, file); + + INC_USE_COUNT; + for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) + if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) + break; + + if (devc == NULL) { + DEC_USE_COUNT; + return -ENODEV; + } + + down(&devc->open_sema); + while (devc->open_mode & file->f_mode) { + up(&devc->open_sema); + if (file->f_flags & O_NONBLOCK) { + DEC_USE_COUNT; + return -EBUSY; + } + interruptible_sleep_on(&devc->open_wait); + if (signal_pending(current)) { + DEC_USE_COUNT; + return -ERESTARTSYS; + } + down(&devc->open_sema); + } + devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + up(&devc->open_sema); + + /* get default sample format from minor number. */ + + sw_samplefmt = 0; + if ((minor & 0xF) == SND_DEV_DSP) + sw_samplefmt = AFMT_U8; + else if ((minor & 0xF) == SND_DEV_AUDIO) + sw_samplefmt = AFMT_MU_LAW; + else if ((minor & 0xF) == SND_DEV_DSP16) + sw_samplefmt = AFMT_S16_LE; + else + ASSERT(0); + + /* Initialize vwsnd_ports. */ + + down(&devc->io_sema); + { + if (file->f_mode & FMODE_READ) { + devc->rport.swstate = SW_INITIAL; + devc->rport.flags = 0; + devc->rport.sw_channels = 1; + devc->rport.sw_samplefmt = sw_samplefmt; + devc->rport.sw_framerate = 8000; + devc->rport.sw_fragshift = DEFAULT_FRAGSHIFT; + devc->rport.sw_fragcount = DEFAULT_FRAGCOUNT; + devc->rport.sw_subdivshift = DEFAULT_SUBDIVSHIFT; + devc->rport.byte_count = 0; + devc->rport.frag_count = 0; + } + if (file->f_mode & FMODE_WRITE) { + devc->wport.swstate = SW_INITIAL; + devc->wport.flags = 0; + devc->wport.sw_channels = 1; + devc->wport.sw_samplefmt = sw_samplefmt; + devc->wport.sw_framerate = 8000; + devc->wport.sw_fragshift = DEFAULT_FRAGSHIFT; + devc->wport.sw_fragcount = DEFAULT_FRAGCOUNT; + devc->wport.sw_subdivshift = DEFAULT_SUBDIVSHIFT; + devc->wport.byte_count = 0; + devc->wport.frag_count = 0; + } + } + up(&devc->io_sema); + + file->private_data = devc; + DBGRV(); + return 0; +} + +/* + * Release (close) the audio device. + */ + +static int vwsnd_audio_release(struct inode *inode, struct file *file) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; + vwsnd_port_t *wport = NULL, *rport = NULL; + int err = 0; + + down(&devc->io_sema); + { + DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); + + if (file->f_mode & FMODE_READ) + rport = &devc->rport; + if (file->f_mode & FMODE_WRITE) { + wport = &devc->wport; + pcm_flush_frag(devc); + pcm_write_sync(devc); + } + pcm_shutdown(devc, rport, wport); + if (rport) + rport->swstate = SW_OFF; + if (wport) + wport->swstate = SW_OFF; + } + up(&devc->io_sema); + + down(&devc->open_sema); + { + devc->open_mode &= ~file->f_mode; + } + up(&devc->open_sema); + wake_up(&devc->open_wait); + DBGDO(if (IN_USE)) /* see hack in vwsnd_mixer_release() */ + DEC_USE_COUNT; + DBGR(); + return err; +} + +static struct file_operations vwsnd_audio_fops = { + &vwsnd_audio_llseek, + &vwsnd_audio_read, + &vwsnd_audio_write, + NULL, /* readdir */ + &vwsnd_audio_poll, + &vwsnd_audio_ioctl, + &vwsnd_audio_mmap, + &vwsnd_audio_open, + NULL, /* flush */ + &vwsnd_audio_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/*****************************************************************************/ +/* mixer driver */ + +/* open the mixer device. */ + +static int vwsnd_mixer_open(struct inode *inode, struct file *file) +{ + vwsnd_dev_t *devc; + + DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); + + INC_USE_COUNT; + for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) + if (devc->mixer_minor == MINOR(inode->i_rdev)) + break; + + if (devc == NULL) { + DEC_USE_COUNT; + return -ENODEV; + } + file->private_data = devc; + return 0; +} + +/* release (close) the mixer device. */ + +static int vwsnd_mixer_release(struct inode *inode, struct file *file) +{ + DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); + + /* + * hack -- opening/closing the mixer device zeroes use count + * so driver can be unloaded. + * Use only while debugging module, and then use it carefully. + */ + + DBGDO(while (IN_USE)) + DEC_USE_COUNT; + return 0; +} + +/* seek is illegal on mixer. */ + +static loff_t vwsnd_mixer_llseek(struct file *file, loff_t offset, int whence) +{ + return -ESPIPE; +} + +/* mixer_read_ioctl handles all read ioctls on the mixer device. */ + +static int mixer_read_ioctl(vwsnd_dev_t *devc, unsigned int nr, caddr_t arg) +{ + int val = -1; + + DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg); + + switch (nr) { + case SOUND_MIXER_CAPS: + val = SOUND_CAP_EXCL_INPUT; + break; + + case SOUND_MIXER_DEVMASK: + val = (SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV); + break; + + case SOUND_MIXER_STEREODEVS: + val = (SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV); + break; + + case SOUND_MIXER_OUTMASK: + val = (SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_MIC | SOUND_MASK_CD); + break; + + case SOUND_MIXER_RECMASK: + val = (SOUND_MASK_PCM | SOUND_MASK_LINE | + SOUND_MASK_MIC | SOUND_MASK_CD); + break; + + case SOUND_MIXER_PCM: + val = ad1843_get_gain(&devc->lith, &ad1843_gain_PCM); + break; + + case SOUND_MIXER_LINE: + val = ad1843_get_gain(&devc->lith, &ad1843_gain_LINE); + break; + + case SOUND_MIXER_MIC: + val = ad1843_get_gain(&devc->lith, &ad1843_gain_MIC); + break; + + case SOUND_MIXER_CD: + val = ad1843_get_gain(&devc->lith, &ad1843_gain_CD); + break; + + case SOUND_MIXER_RECLEV: + val = ad1843_get_gain(&devc->lith, &ad1843_gain_RECLEV); + break; + + case SOUND_MIXER_RECSRC: + val = ad1843_get_recsrc(&devc->lith); + break; + + case SOUND_MIXER_OUTSRC: + val = ad1843_get_outsrc(&devc->lith); + break; + + default: + return -EINVAL; + } + return put_user(val, (int *) arg); +} + +/* mixer_write_ioctl handles all write ioctls on the mixer device. */ + +static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, caddr_t arg) +{ + int val; + int err; + + DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg); + + err = get_user(val, (int *) arg); + if (err) + return -EFAULT; + switch (nr) { + case SOUND_MIXER_PCM: + val = ad1843_set_gain(&devc->lith, &ad1843_gain_PCM, val); + break; + + case SOUND_MIXER_LINE: + val = ad1843_set_gain(&devc->lith, &ad1843_gain_LINE, val); + break; + + case SOUND_MIXER_MIC: + val = ad1843_set_gain(&devc->lith, &ad1843_gain_MIC, val); + break; + + case SOUND_MIXER_CD: + val = ad1843_set_gain(&devc->lith, &ad1843_gain_CD, val); + break; + + case SOUND_MIXER_RECLEV: + val = ad1843_set_gain(&devc->lith, &ad1843_gain_RECLEV, val); + break; + + case SOUND_MIXER_RECSRC: + if (devc->rport.swbuf || devc->wport.swbuf) + return -EBUSY; /* can't change recsrc while running */ + val = ad1843_set_recsrc(&devc->lith, val); + break; + + case SOUND_MIXER_OUTSRC: + val = ad1843_set_outsrc(&devc->lith, val); + break; + + default: + return -EINVAL; + } + if (val < 0) + return val; + return put_user(val, (int *) arg); +} + +/* This is the ioctl entry to the mixer driver. */ + +static int vwsnd_mixer_ioctl(struct inode *ioctl, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; + const unsigned int nrmask = _IOC_NRMASK << _IOC_NRSHIFT; + const unsigned int nr = (cmd & nrmask) >> _IOC_NRSHIFT; + int retval; + + DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg); + + down(&devc->mix_sema); + { + if ((cmd & ~nrmask) == MIXER_READ(0)) + retval = mixer_read_ioctl(devc, nr, (caddr_t) arg); + else if ((cmd & ~nrmask) == MIXER_WRITE(0)) + retval = mixer_write_ioctl(devc, nr, (caddr_t) arg); + else + retval = -EINVAL; + } + up(&devc->mix_sema); + return retval; +} + +static struct file_operations vwsnd_mixer_fops = { + &vwsnd_mixer_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &vwsnd_mixer_ioctl, + NULL, /* mmap */ + &vwsnd_mixer_open, + NULL, /* flush */ + &vwsnd_mixer_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/*****************************************************************************/ +/* probe/attach/unload */ + +/* driver probe routine. Return nonzero if hardware is found. */ + +static int probe_vwsnd(struct address_info *hw_config) +{ + lithium_t lith; + int w; + unsigned long later; + + DBGEV("(hw_config=0x%p)\n", hw_config); + + /* XXX verify lithium present (to prevent crash on non-vw) */ + + if (li_create(&lith, hw_config->io_base) != 0) { + printk(KERN_WARNING "probe_vwsnd: can't map lithium\n"); + return 0; + } + later = jiffies + 2; + li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE); + do { + w = li_readl(&lith, LI_HOST_CONTROLLER); + } while (w == LI_HC_LINK_ENABLE && jiffies < later); + + li_destroy(&lith); + + DBGPV("HC = 0x%04x\n", w); + + if ((w == LI_HC_LINK_ENABLE) || (w & LI_HC_LINK_CODEC)) { + + /* This may indicate a beta machine with no audio, + * or a future machine with different audio. + * On beta-release 320 w/ no audio, HC == 0x4000 */ + + printk(KERN_WARNING "probe_vwsnd: audio codec not found\n"); + return 0; + } + + if (w & LI_HC_LINK_FAILURE) { + printk(KERN_WARNING "probe_vwsnd: can't init audio codec\n"); + return 0; + } + + printk(KERN_INFO "probe_vwsnd: lithium audio found\n"); + + return 1; +} + +/* + * driver attach routine. Initialize driver data structures and + * initialize hardware. A new vwsnd_dev_t is allocated and put + * onto the global list, vwsnd_dev_list. + * + * Return +minor_dev on success, -errno on failure. + */ + +static int attach_vwsnd(struct address_info *hw_config) +{ + vwsnd_dev_t *devc = NULL; + int err = -ENOMEM; + + DBGEV("(hw_config=0x%p)\n", hw_config); + + devc = kmalloc(sizeof (vwsnd_dev_t), GFP_KERNEL); + if (devc == NULL) + goto fail0; + + err = li_create(&devc->lith, hw_config->io_base); + if (err) + goto fail1; + + init_waitqueue(&devc->open_wait); + + devc->rport.hwbuf_size = HWBUF_SIZE; + devc->rport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER); + if (!devc->rport.hwbuf_vaddr) + goto fail2; + devc->rport.hwbuf = (caddr_t) devc->rport.hwbuf_vaddr; + devc->rport.hwbuf_paddr = virt_to_phys(devc->rport.hwbuf); + + /* + * Quote from the NT driver: + * + * // WARNING!!! HACK to setup output dma!!! + * // This is required because even on output there is some data + * // trickling into the input DMA channel. This is a bug in the + * // Lithium microcode. + * // --sde + * + * We set the input side's DMA base address here. It will remain + * valid until the driver is unloaded. + */ + + li_writel(&devc->lith, LI_COMM1_BASE, + devc->rport.hwbuf_paddr >> 8 | 1 << (37 - 8)); + + devc->wport.hwbuf_size = HWBUF_SIZE; + devc->wport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER); + if (!devc->wport.hwbuf_vaddr) + goto fail3; + devc->wport.hwbuf = (caddr_t) devc->wport.hwbuf_vaddr; + devc->wport.hwbuf_paddr = virt_to_phys(devc->wport.hwbuf); + DBGP("wport hwbuf = 0x%p\n", devc->wport.hwbuf); + + DBGDO(shut_up++); + err = ad1843_init(&devc->lith); + DBGDO(shut_up--); + if (err) + goto fail4; + + /* install interrupt handler */ + + err = request_irq(hw_config->irq, vwsnd_audio_intr, 0, "vwsnd", devc); + if (err) + goto fail5; + + /* register this device's drivers. */ + + devc->audio_minor = register_sound_dsp(&vwsnd_audio_fops, -1); + if ((err = devc->audio_minor) < 0) { + DBGDO(printk(KERN_WARNING + "attach_vwsnd: register_sound_dsp error %d\n", + err)); + goto fail6; + } + devc->mixer_minor = register_sound_mixer(&vwsnd_mixer_fops, + devc->audio_minor >> 4); + if ((err = devc->mixer_minor) < 0) { + DBGDO(printk(KERN_WARNING + "attach_vwsnd: register_sound_mixer error %d\n", + err)); + goto fail7; + } + + /* Squirrel away device indices for unload routine. */ + + hw_config->slots[0] = devc->audio_minor; + + /* Initialize as much of *devc as possible */ + + devc->open_sema = MUTEX; + devc->io_sema = MUTEX; + devc->mix_sema = MUTEX; + devc->open_mode = 0; + devc->rport.lock = SPIN_LOCK_UNLOCKED; + init_waitqueue(&devc->rport.queue); + devc->rport.swstate = SW_OFF; + devc->rport.hwstate = HW_STOPPED; + devc->rport.flags = 0; + devc->rport.swbuf = NULL; + devc->wport.lock = SPIN_LOCK_UNLOCKED; + init_waitqueue(&devc->wport.queue); + devc->wport.swstate = SW_OFF; + devc->wport.hwstate = HW_STOPPED; + devc->wport.flags = 0; + devc->wport.swbuf = NULL; + + /* Success. Link us onto the local device list. */ + + devc->next_dev = vwsnd_dev_list; + vwsnd_dev_list = devc; + return devc->audio_minor; + + /* So many ways to fail. Undo what we did. */ + + fail7: + unregister_sound_dsp(devc->audio_minor); + fail6: + free_irq(hw_config->irq, devc); + fail5: + fail4: + free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER); + fail3: + free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER); + fail2: + li_destroy(&devc->lith); + fail1: + kfree(devc); + fail0: + return err; +} + +static int unload_vwsnd(struct address_info *hw_config) +{ + vwsnd_dev_t *devc, **devcp; + + DBGE("()\n"); + + if (IN_USE) + return -EBUSY; + devcp = &vwsnd_dev_list; + while ((devc = *devcp)) { + if (devc->audio_minor == hw_config->slots[0]) { + *devcp = devc->next_dev; + break; + } + devcp = &devc->next_dev; + } + + if (!devc) + return -ENODEV; + + unregister_sound_mixer(devc->mixer_minor); + unregister_sound_dsp(devc->audio_minor); + free_irq(hw_config->irq, devc); + free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER); + free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER); + li_destroy(&devc->lith); + kfree(devc); + + return 0; +} + +/*****************************************************************************/ +/* initialization and loadable kernel module interface */ + +static struct address_info the_hw_config = { + 0xFF001000, /* lithium phys addr */ + CO_IRQ(CO_APIC_LI_AUDIO) /* irq */ +}; + +#ifdef MODULE + +MODULE_DESCRIPTION("SGI Visual Workstation sound module"); +MODULE_AUTHOR("Bob Miller <kbob@sgi.com>"); + +extern int init_module(void) +{ + int err; + + DBGXV("\n"); + DBGXV("sound::vwsnd::init_module()\n"); + + if(!probe_vwsnd(&the_hw_config)) + return -ENODEV; + err = attach_vwsnd(&the_hw_config); + if (err < 0) + return err; + return 0; +} + +extern void cleanup_module(void) +{ + DBGX("sound::vwsnd::cleanup_module()\n"); + + unload_vwsnd(&the_hw_config); +} + +#else + +extern void init_vwsnd(void) +{ + DBGX("sound::vwsnd::init_vwsnd()\n"); + if (probe_vwsnd(&the_hw_config)) + (void) attach_vwsnd(&the_hw_config); +} + +#endif /* !MODULE */ + +/* + * Local variables: + * compile-command: "cd ../..; make modules SUBDIRS=drivers/sound" + * c-basic-offset: 8 + * End: + */ |