2
* Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
4
* Permission to use, copy, modify, distribute, and sell this software and its
5
* documentation for any purpose is hereby granted without fee, provided that
6
* the above copyright notice appear in all copies and that both that copyright
7
* notice and this permission notice appear in supporting documentation, and
8
* that the name of Marc Aurele La France not be used in advertising or
9
* publicity pertaining to distribution of the software without specific,
10
* written prior permission. Marc Aurele La France makes no representations
11
* about the suitability of this software for any purpose. It is provided
12
* "as-is" without express or implied warranty.
14
* MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
16
* EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20
* PERFORMANCE OF THIS SOFTWARE.
34
#include "atimach64io.h"
36
#include "atiwonderio.h"
41
* Display various parts of the BIOS when the server is invoked with -verbose.
47
const unsigned int Length /* A multiple of 512 */
50
unsigned char *Char = NULL;
52
unsigned char Printable[17];
54
if (xf86GetVerbosity() <= 4)
57
(void)memset(Printable, 0, SizeOf(Printable));
59
xf86ErrorFVerb(5, "\n BIOS image:");
61
for (Index = 0; Index < Length; Index++)
63
if (!(Index & (4U - 1U)))
65
if (!(Index & (16U - 1U)))
68
xf86ErrorFVerb(5, " |%s|", Printable);
70
xf86ErrorFVerb(5, "\n 0x%08X: ", Index);
72
xf86ErrorFVerb(5, " ");
74
xf86ErrorFVerb(5, "%02X", BIOS[Index]);
75
if (isprint(BIOS[Index]))
76
*Char++ = BIOS[Index];
81
xf86ErrorFVerb(5, " |%s|\n", Printable);
87
* ATIPrintIndexedRegisters --
89
* Display a set of indexed byte-size registers when the server is invoked with
93
ATIPrintIndexedRegisters
95
const unsigned long Port,
96
const CARD8 StartIndex,
99
const unsigned long GenS1
104
xf86ErrorFVerb(4, "\n %s register values:", Name);
105
for (Index = StartIndex; Index < EndIndex; Index++)
107
if (!(Index & (4U - 1U)))
109
if (!(Index & (16U - 1U)))
110
xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
111
xf86ErrorFVerb(4, " ");
114
(void)inb(GenS1); /* Reset flip-flop */
115
xf86ErrorFVerb(4, "%02X", GetReg(Port, Index));
120
(void)inb(GenS1); /* Reset flip-flop */
121
outb(ATTRX, 0x20U); /* Turn on PAS bit */
124
xf86ErrorFVerb(4, "\n");
127
#endif /* AVOID_CPIO */
130
* ATIMach64PrintRegisters --
132
* Display a Mach64's main register bank when the server is invoked with
136
ATIMach64PrintRegisters
140
const char *Description
144
CARD8 dac_read, dac_mask, dac_data, dac_write;
151
#endif /* AVOID_CPIO */
153
xf86ErrorFVerb(4, "\n Mach64 %s register values:", Description);
158
Limit = DWORD_SELECT;
160
Limit = MM_IO_SELECT;
162
for (Index = 0; Index <= Limit; Index += UnitOf(MM_IO_SELECT))
164
if (!(Index & SetBits(3, MM_IO_SELECT)))
165
xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
166
if (Index == (DAC_REGS & DWORD_SELECT))
168
dac_read = in8(DAC_REGS + 3);
170
dac_mask = in8(DAC_REGS + 2);
172
dac_data = in8(DAC_REGS + 1);
174
dac_write = in8(DAC_REGS + 0);
177
xf86ErrorFVerb(4, " %02X%02X%02X%02X",
178
dac_read, dac_mask, dac_data, dac_write);
180
out8(DAC_REGS + 2, dac_mask);
182
out8(DAC_REGS + 3, dac_read);
187
IOValue = inm(Index);
189
if ((Index == (CRTC_GEN_CNTL & DWORD_SELECT)) &&
190
(IOValue & CRTC_EXT_DISP_EN))
191
*crtc = ATI_CRTC_MACH64;
193
xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
197
#else /* AVOID_CPIO */
199
Limit = ATIIOPort(IOPortTag(0x1FU, 0x3FU));
200
Step = ATIIOPort(IOPortTag(0x01U, 0x01U)) - pATI->CPIOBase;
201
for (Index = pATI->CPIOBase; Index <= Limit; Index += Step)
203
if (!(((Index - pATI->CPIOBase) / Step) & 0x03U))
204
xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
205
if (Index == (int)ATIIOPort(DAC_REGS))
207
dac_read = in8(DAC_REGS + 3);
209
dac_mask = in8(DAC_REGS + 2);
211
dac_data = in8(DAC_REGS + 1);
213
dac_write = in8(DAC_REGS + 0);
216
xf86ErrorFVerb(4, " %02X%02X%02X%02X",
217
dac_read, dac_mask, dac_data, dac_write);
219
out8(DAC_REGS + 2, dac_mask);
221
out8(DAC_REGS + 3, dac_read);
226
IOValue = inl(Index);
228
if ((Index == (int)ATIIOPort(CRTC_GEN_CNTL)) &&
229
(IOValue & CRTC_EXT_DISP_EN))
230
*crtc = ATI_CRTC_MACH64;
232
xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
236
#endif /* AVOID_CPIO */
238
xf86ErrorFVerb(4, "\n");
242
* ATIMach64PrintPLLRegisters --
244
* Display an integrated Mach64's PLL registers when the server is invoked with
248
ATIMach64PrintPLLRegisters
254
CARD8 PLLReg[MaxBits(PLL_ADDR) + 1];
256
for (Limit = 0; Limit < SizeOf(PLLReg); Limit++)
257
PLLReg[Limit] = ATIMach64GetPLLReg(Limit);
259
/* Determine how many PLL registers there really are */
260
while ((Limit = Limit >> 1))
261
for (Index = 0; Index < Limit; Index++)
262
if (PLLReg[Index] != PLLReg[Index + Limit])
267
xf86ErrorFVerb(4, "\n Mach64 PLL register values:");
268
for (Index = 0; Index < Limit; Index++)
273
xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
274
xf86ErrorFVerb(4, " ");
276
xf86ErrorFVerb(4, "%02X", PLLReg[Index]);
279
xf86ErrorFVerb(4, "\n");
283
* ATIRGB514PrintRegisters --
285
* Display IBM RGB 514 registers when the server is invoked with -verbose.
288
ATIRGB514PrintRegisters
293
CARD32 crtc_gen_cntl, dac_cntl;
294
CARD8 index_lo, index_hi, index_ctl;
297
/* Temporarily switch to Mach64 CRTC */
298
crtc_gen_cntl = inr(CRTC_GEN_CNTL);
299
if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
300
outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);
302
/* Temporarily switch to IBM RGB 514 registers */
303
dac_cntl = inr(DAC_CNTL);
304
outr(DAC_CNTL, (dac_cntl & ~DAC_EXT_SEL_RS3) | DAC_EXT_SEL_RS2);
306
index_lo = in8(M64_DAC_WRITE);
307
index_hi = in8(M64_DAC_DATA);
308
index_ctl = in8(M64_DAC_READ);
310
out8(M64_DAC_WRITE, 0x00U);
311
out8(M64_DAC_DATA, 0x00U);
312
out8(M64_DAC_READ, 0x01U); /* Auto-increment */
314
xf86ErrorFVerb(4, "\n IBM RGB 514 registers:");
315
for (Index = 0; Index < 0x0800; Index++)
321
xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
323
/* Need to rewrite index every so often... */
324
if ((Index == 0x0100) || (Index == 0x0500))
326
out8(M64_DAC_WRITE, 0x00U);
327
out8(M64_DAC_DATA, Index >> 8);
331
xf86ErrorFVerb(4, " ");
334
xf86ErrorFVerb(4, "%02X", in8(M64_DAC_MASK));
337
/* Restore registers */
338
out8(M64_DAC_WRITE, index_lo);
339
out8(M64_DAC_DATA, index_hi);
340
out8(M64_DAC_READ, index_ctl);
341
outr(DAC_CNTL, dac_cntl);
342
if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
343
outr(CRTC_GEN_CNTL, crtc_gen_cntl);
345
xf86ErrorFVerb(4, "\n");
349
* ATIPrintRegisters --
351
* Display various registers when the server is invoked with -verbose.
360
CARD32 lcd_index, tv_out_index, lcd_gen_ctrl;
361
CARD8 dac_read, dac_mask, dac_write;
370
if (pATI->VGAAdapter)
372
xf86ErrorFVerb(4, "\n Miscellaneous output register value: 0x%02X.\n",
373
genmo = inb(R_GENMO));
377
if (pATI->Chip == ATI_CHIP_264LT)
379
lcd_gen_ctrl = inr(LCD_GEN_CTRL);
381
outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
382
ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
383
"Non-shadow colour CRT controller", 0);
385
outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
386
ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
387
"Shadow colour CRT controller", 0);
389
outr(LCD_GEN_CTRL, lcd_gen_ctrl);
391
else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
392
(pATI->Chip == ATI_CHIP_264XL) ||
393
(pATI->Chip == ATI_CHIP_MOBILITY))
395
lcd_index = inr(LCD_INDEX);
396
lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
398
ATIMach64PutLCDReg(LCD_GEN_CNTL,
399
lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
400
ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
401
"Non-shadow colour CRT controller", 0);
403
ATIMach64PutLCDReg(LCD_GEN_CNTL,
404
(lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
405
ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
406
"Shadow colour CRT controller", 0);
408
ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
409
outr(LCD_INDEX, lcd_index);
413
ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
414
"Colour CRT controller", 0);
417
ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
418
GENS1(ColourIOBase));
422
if (pATI->Chip == ATI_CHIP_264LT)
424
lcd_gen_ctrl = inr(LCD_GEN_CTRL);
426
outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
427
ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
428
"Non-shadow monochrome CRT controller", 0);
430
outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
431
ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
432
"Shadow monochrome CRT controller", 0);
434
outr(LCD_GEN_CTRL, lcd_gen_ctrl);
436
else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
437
(pATI->Chip == ATI_CHIP_264XL) ||
438
(pATI->Chip == ATI_CHIP_MOBILITY))
440
lcd_index = inr(LCD_INDEX);
441
lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
443
ATIMach64PutLCDReg(LCD_GEN_CNTL,
444
lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
445
ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
446
"Non-shadow monochrome CRT controller", 0);
448
ATIMach64PutLCDReg(LCD_GEN_CNTL,
449
(lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
450
ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
451
"Shadow monochrome CRT controller", 0);
453
ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
454
outr(LCD_INDEX, lcd_index);
458
ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
459
"Monochrome CRT controller", 0);
462
ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
463
GENS1(MonochromeIOBase));
466
ATIPrintIndexedRegisters(GRAX, 0, 16, "Graphics controller", 0);
467
ATIPrintIndexedRegisters(SEQX, 0, 8, "Sequencer", 0);
469
if (pATI->CPIO_VGAWonder)
470
ATIPrintIndexedRegisters(pATI->CPIO_VGAWonder, 0x80U, 0xC0U,
471
"ATI extended VGA", 0);
474
#endif /* AVOID_CPIO */
476
if (pATI->Chip == ATI_CHIP_264LT)
478
lcd_gen_ctrl = inr(LCD_GEN_CTRL);
480
outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
481
ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");
483
outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
484
ATIMach64PrintRegisters(pATI, &crtc, "shadow");
486
outr(LCD_GEN_CTRL, lcd_gen_ctrl);
488
ATIMach64PrintPLLRegisters(pATI);
490
else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
491
(pATI->Chip == ATI_CHIP_264XL) ||
492
(pATI->Chip == ATI_CHIP_MOBILITY))
494
lcd_index = inr(LCD_INDEX);
495
lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
497
ATIMach64PutLCDReg(LCD_GEN_CNTL,
498
lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
499
ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");
501
ATIMach64PutLCDReg(LCD_GEN_CNTL,
502
(lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
503
ATIMach64PrintRegisters(pATI, &crtc, "shadow");
505
if (pATI->Chip != ATI_CHIP_264XL)
507
ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl | CRTC_RW_SELECT);
508
ATIMach64PrintRegisters(pATI, &crtc, "secondary");
511
ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
513
ATIMach64PrintPLLRegisters(pATI);
515
xf86ErrorFVerb(4, "\n LCD register values:");
516
for (Index = 0; Index < 64; Index++)
519
xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
520
xf86ErrorFVerb(4, " %08X", ATIMach64GetLCDReg(Index));
523
outr(LCD_INDEX, lcd_index);
525
tv_out_index = inr(TV_OUT_INDEX);
527
xf86ErrorFVerb(4, "\n\n TV_OUT register values:");
528
for (Index = 0; Index < 256; Index++)
531
xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
532
xf86ErrorFVerb(4, " %08X", ATIMach64GetTVReg(Index));
535
outr(TV_OUT_INDEX, tv_out_index);
537
xf86ErrorFVerb(4, "\n");
544
ATIMach64PrintRegisters(pATI, &crtc, "MMIO");
546
#else /* AVOID_CPIO */
548
ATIMach64PrintRegisters(pATI, &crtc,
549
(pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block");
551
#endif /* AVOID_CPIO */
553
if (pATI->Chip >= ATI_CHIP_264CT)
554
ATIMach64PrintPLLRegisters(pATI);
556
if (pATI->DAC == ATI_DAC_IBMRGB514)
557
ATIRGB514PrintRegisters(pATI);
562
dac_read = in8(M64_DAC_READ);
564
dac_write = in8(M64_DAC_WRITE);
566
dac_mask = in8(M64_DAC_MASK);
569
xf86ErrorFVerb(4, "\n"
570
" DAC read index: 0x%02X\n"
571
" DAC write index: 0x%02X\n"
572
" DAC mask: 0x%02X\n\n"
573
" DAC colour lookup table:",
574
dac_read, dac_write, dac_mask);
576
out8(M64_DAC_MASK, 0xFFU);
578
out8(M64_DAC_READ, 0x00U);
581
for (Index = 0; Index < 256; Index++)
584
xf86ErrorFVerb(4, "\n 0x%02X:", Index);
585
xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
587
xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
589
xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
593
out8(M64_DAC_MASK, dac_mask);
595
out8(M64_DAC_READ, dac_read);
598
#else /* AVOID_CPIO */
600
ATISetDACIOPorts(pATI, crtc);
602
dac_read = inb(pATI->CPIO_DAC_READ);
604
dac_write = inb(pATI->CPIO_DAC_WRITE);
606
dac_mask = inb(pATI->CPIO_DAC_MASK);
609
xf86ErrorFVerb(4, "\n"
610
" DAC read index: 0x%02X\n"
611
" DAC write index: 0x%02X\n"
612
" DAC mask: 0x%02X\n\n"
613
" DAC colour lookup table:",
614
dac_read, dac_write, dac_mask);
616
outb(pATI->CPIO_DAC_MASK, 0xFFU);
618
outb(pATI->CPIO_DAC_READ, 0x00U);
621
for (Index = 0; Index < 256; Index++)
624
xf86ErrorFVerb(4, "\n 0x%02X:", Index);
625
xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
627
xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
629
xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
633
outb(pATI->CPIO_DAC_MASK, dac_mask);
635
outb(pATI->CPIO_DAC_READ, dac_read);
638
#endif /* AVOID_CPIO */
641
xf86ErrorFVerb(4, "\n\n PCI configuration register values:");
642
for (Index = 0; Index < 256; Index+= 4)
644
pciVideoPtr pVideo = pATI->PCIInfo;
647
PCI_READ_LONG(pVideo, &data, Index);
650
xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
651
xf86ErrorFVerb(4, " 0x%08X", data);
655
xf86ErrorFVerb(4, "\n");
660
xf86ErrorFVerb(4, "\n Banked aperture at 0x%0lX.",
661
(unsigned long)pATI->pBank);
663
xf86ErrorFVerb(4, "\n No banked aperture.");
665
#endif /* AVOID_CPIO */
669
xf86ErrorFVerb(4, "\n Linear aperture at %p.\n", pATI->pMemory);
674
xf86ErrorFVerb(4, " Block 0 aperture at %p.\n", pATI->pBlock[0]);
675
if (inr(CONFIG_CHIP_ID) == pATI->config_chip_id)
676
xf86ErrorFVerb(4, " MMIO registers are correctly mapped.\n");
678
xf86ErrorFVerb(4, " MMIO mapping is in error!\n");
680
xf86ErrorFVerb(4, " Block 1 aperture at %p.\n",
685
xf86ErrorFVerb(4, " No MMIO aperture.\n");
688
if (pATI->pCursorImage)
689
xf86ErrorFVerb(4, " Hardware cursor image aperture at %p.\n",
692
xf86ErrorFVerb(4, " No hardware cursor image aperture.\n");
694
xf86ErrorFVerb(4, "\n");
698
* A table to associate mode attributes with character strings.
700
static const SymTabRec ModeAttributeNames[] =
702
{V_PHSYNC, "+hsync"},
703
{V_NHSYNC, "-hsync"},
704
{V_PVSYNC, "+vsync"},
705
{V_NVSYNC, "-vsync"},
706
{V_PCSYNC, "+csync"},
707
{V_NCSYNC, "-csync"},
708
{V_INTERLACE, "interlace"},
709
{V_DBLSCAN, "doublescan"},
710
{V_CSYNC, "composite"},
711
{V_DBLCLK, "dblclk"},
712
{V_CLKDIV2, "clkdiv2"},
719
* This function displays a mode's timing information.
727
const SymTabRec *pSymbol = ModeAttributeNames;
728
int flags = pMode->Flags;
729
double mClock, hSync, vRefresh;
731
mClock = (double)pMode->SynthClock;
732
if (pMode->HSync > 0.0)
733
hSync = pMode->HSync;
735
hSync = mClock / pMode->HTotal;
736
if (pMode->VRefresh > 0.0)
738
vRefresh = pMode->VRefresh;
742
vRefresh = (hSync * 1000.0) / pMode->VTotal;
743
if (flags & V_INTERLACE)
745
if (flags & V_DBLSCAN)
747
if (pMode->VScan > 1)
748
vRefresh /= pMode->VScan;
751
xf86ErrorFVerb(4, " Dot clock: %7.3f MHz\n", mClock / 1000.0);
752
xf86ErrorFVerb(4, " Horizontal sync: %7.3f kHz\n", hSync);
753
xf86ErrorFVerb(4, " Vertical refresh: %7.3f Hz (%s)\n", vRefresh,
754
(flags & V_INTERLACE) ? "I" : "NI");
755
if ((pMode->ClockIndex >= 0) && (pMode->ClockIndex < MAXCLOCKS))
756
xf86ErrorFVerb(4, " Clock index: %d\n", pMode->ClockIndex);
757
xf86ErrorFVerb(4, " Horizontal timings: %4d %4d %4d %4d\n"
758
" Vertical timings: %4d %4d %4d %4d\n",
759
pMode->HDisplay, pMode->HSyncStart, pMode->HSyncEnd, pMode->HTotal,
760
pMode->VDisplay, pMode->VSyncStart, pMode->VSyncEnd, pMode->VTotal);
765
xf86ErrorFVerb(4, " Horizontal skew: %4d\n", pMode->HSkew);
768
if (pMode->VScan >= 1)
769
xf86ErrorFVerb(4, " Vertical scan: %4d\n", pMode->VScan);
771
xf86ErrorFVerb(4, " Flags: ");
772
for (; pSymbol->token; pSymbol++)
774
if (flags & pSymbol->token)
776
xf86ErrorFVerb(4, " %s", pSymbol->name);
777
flags &= ~pSymbol->token;
783
xf86ErrorFVerb(4, "\n");