|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: BitBlt.c ! 8: ! 9: Abstract: ! 10: ! 11: This module hooks DrvBitBlt and DrvCopyBits for the Jaguar VXL board. ! 12: ! 13: The following operations are supported for DrvBitBlt: ! 14: SRCCOPY from screen to screen ! 15: BLACKNESS ! 16: WHITNESS ! 17: PATCOPY when the Brush pattern is a solid color ! 18: NOTPATCOPY when the Brush pattern is a solid color ! 19: ! 20: DrvCopyBits copies the data if source and dest surfaces are the ! 21: frame buffer. ! 22: ! 23: Environment: ! 24: ! 25: User mode. ! 26: ! 27: Revision History: ! 28: ! 29: --*/ ! 30: ! 31: #include "driver.h" ! 32: #include "jzvxl484.h" ! 33: ! 34: // ! 35: //Tmp savescreenbits vars ! 36: // ! 37: ! 38: ! 39: BOOL ! 40: DrvpIntersectRect( ! 41: IN PRECTL Rectl1, ! 42: IN PRECTL Rectl2, ! 43: OUT PRECTL DestRectl ! 44: ) ! 45: ! 46: /*++ ! 47: ! 48: Routine Description: ! 49: ! 50: This routine checks to see if the two specified retangles intersect. ! 51: ! 52: N.B. This routine is adopted from a routine written by darrinm. ! 53: ! 54: Arguments: ! 55: ! 56: Rectl1 - Supplies the coordinates of the first rectangle. ! 57: ! 58: Rectl2 - Supplies the coordinates of the second rectangle. ! 59: ! 60: DestRectl - Supplies the coordinates of the utput rectangle. ! 61: ! 62: Return Value: ! 63: ! 64: A value of TRUE is returned if the rectangles intersect. Otherwise, ! 65: a value of FALSE is returned. ! 66: ! 67: --*/ ! 68: ! 69: ! 70: { ! 71: ! 72: // ! 73: // Compute the maximum left edge and the minimum right edge. ! 74: // ! 75: ! 76: DestRectl->left = max(Rectl1->left, Rectl2->left); ! 77: DestRectl->right = min(Rectl1->right, Rectl2->right); ! 78: ! 79: // ! 80: // If the minimum right edge is greater than the maximum left edge, ! 81: // then the rectanges may intersect. Otherwise, they do not intersect. ! 82: // ! 83: ! 84: if (DestRectl->left < DestRectl->right) { ! 85: ! 86: // ! 87: // Compute the maximum top edge and the minimum bottom edge. ! 88: // ! 89: ! 90: DestRectl->top = max(Rectl1->top, Rectl2->top); ! 91: DestRectl->bottom = min(Rectl1->bottom, Rectl2->bottom); ! 92: ! 93: // ! 94: // If the minimum bottom edge is greater than the maximum top ! 95: // edge, then the rectanges intersect. Otherwise, they do not ! 96: // intersect. ! 97: // ! 98: ! 99: if (DestRectl->top < DestRectl->bottom) { ! 100: return TRUE; ! 101: } ! 102: } ! 103: ! 104: return FALSE; ! 105: } ! 106: ! 107: VOID ! 108: DrvpFillRectangle( ! 109: IN PRECTL DstRect, ! 110: IN ULONG Color ! 111: ) ! 112: /*++ ! 113: ! 114: Routine Description: ! 115: ! 116: Place a solid color fill command into the FIFO ! 117: ! 118: Arguments: ! 119: ! 120: DestRect - Rectangle to fill ! 121: Color - Fill color ! 122: ! 123: Return Value: ! 124: ! 125: Status of operation. ! 126: ! 127: --*/ ! 128: { ! 129: ! 130: ULONG X,Y; ! 131: ULONG XYCmd; ! 132: ULONG DstAdr; ! 133: ! 134: // ! 135: // calculate size of the fill. ! 136: // ! 137: ! 138: X = (ULONG)(DstRect->right - DstRect->left); ! 139: Y = (ULONG)(DstRect->bottom - DstRect->top); ! 140: Y &= 0x3FF; ! 141: ! 142: XYCmd=(JAGUAR_SOLID_FILL << XYCMD_CMD_SHIFT) | (Y << XYCMD_Y_SHIFT) | X; ! 143: ! 144: DstAdr= Vxl.JaguarScreenX*DstRect->top + (DstRect->left << Vxl.ColorModeShift); ! 145: ! 146: // ! 147: // Write command to the FIFO. ! 148: // ! 149: ! 150: FifoWrite(DstAdr,Color,XYCmd); ! 151: ! 152: } ! 153: ! 154: VOID ! 155: DrvpSolidFill( ! 156: IN PRECTL DstRect, ! 157: IN CLIPOBJ *pco, ! 158: IN ULONG Color ! 159: ) ! 160: /*++ ! 161: ! 162: Routine Description: ! 163: ! 164: This routine fills the unclipped areas of the destination rectangle with ! 165: the given color. ! 166: ! 167: Arguments: ! 168: ! 169: DstRect - Destination Rectangle ! 170: pco - Clipping area. ! 171: Color - Color to fill with. ! 172: ! 173: Return Value: ! 174: ! 175: None. ! 176: ! 177: --*/ ! 178: { ! 179: RECTL BltRectl; ! 180: ENUMRECTLIST ClipEnum; ! 181: BOOL MoreClipRects; ! 182: ULONG ClipRegions; ! 183: BYTE FixedComplexity; ! 184: ! 185: // ! 186: // Figure out the real clipping complexity ! 187: // ! 188: if (pco == (CLIPOBJ *)NULL) { ! 189: FixedComplexity = DC_TRIVIAL; ! 190: } else { ! 191: FixedComplexity = pco->iDComplexity; ! 192: } ! 193: switch (FixedComplexity) { ! 194: ! 195: // ! 196: // Entire destination is to be updated. ! 197: // Proceed with the Solid Fill. ! 198: // ! 199: case DC_TRIVIAL: ! 200: ! 201: DrvpFillRectangle(DstRect, // Target rectangle ! 202: Color); // Color ! 203: ! 204: break; ! 205: ! 206: // ! 207: // Only one clip region. ! 208: // ! 209: ! 210: case DC_RECT: ! 211: // ! 212: // only do the Fill if there is an intersection ! 213: // ! 214: ! 215: if (DrvpIntersectRect(DstRect,&pco->rclBounds,&BltRectl)) { ! 216: ! 217: DrvpFillRectangle(&BltRectl, // Target rectangle ! 218: Color); // Color ! 219: } ! 220: break; ! 221: ! 222: // ! 223: // Multiple clip regions. ! 224: // ! 225: ! 226: case DC_COMPLEX: ! 227: ! 228: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,CD_ANY,BB_RECT_LIMIT); ! 229: do { ! 230: ! 231: // ! 232: // Get list of clip rectangles. ! 233: // ! 234: ! 235: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum); ! 236: ! 237: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) { ! 238: ! 239: // ! 240: // If the rectangles intersect do the fill ! 241: // ! 242: if (DrvpIntersectRect(DstRect, ! 243: &ClipEnum.arcl[ClipRegions], ! 244: &BltRectl)) { ! 245: DrvpFillRectangle(&BltRectl, // Target rectangle ! 246: Color); // Color ! 247: ! 248: } ! 249: } ! 250: } while (MoreClipRects); ! 251: break; ! 252: ! 253: } // end switch complexity ! 254: } ! 255: ! 256: VOID ! 257: DrvpBitBlt( ! 258: IN PRECTL DstRect, ! 259: IN PPOINTL SrcPoint, ! 260: IN BOOL BltDir ! 261: ) ! 262: /*++ ! 263: ! 264: Routine Description: ! 265: ! 266: Place a BitBlt command into the FIFO ! 267: ! 268: Arguments: ! 269: ! 270: DstRect - Destination Rectangle ! 271: SrcPoint - Source Point ! 272: BltDir - FALSE = Left to Right Top to Bottom. ! 273: TRUE = Right to Left Bottom to Top ! 274: ! 275: Return Value: ! 276: ! 277: None. ! 278: ! 279: --*/ ! 280: { ! 281: ! 282: ULONG X,Y; ! 283: ULONG XYCmd; ! 284: ULONG SrcAdr; ! 285: ULONG DstAdr; ! 286: ! 287: X = DstRect->right - DstRect->left; ! 288: Y = DstRect->bottom - DstRect->top; ! 289: if (BltDir) { ! 290: ! 291: // ! 292: // This is a Right To Left Bottom to Top BitBlt ! 293: // Src and Dest adr are the first byte of the pixel to ! 294: // be moved. That is the most significant byte of the pixel. ! 295: // The Rectangle excludes the bottom right corner which ! 296: // is the start address for these sort of bitblts. ! 297: // One is substracted from the Y to exclude the last line. ! 298: // One is substracted from the X after addjusting it to the ! 299: // size of the pixel. So the address of the next pixel is computed ! 300: // and then one is substracted which gives the address of the ! 301: // most significant byte of the previous pixel. ! 302: // ! 303: ! 304: DstAdr=Vxl.JaguarScreenX*(DstRect->bottom-1) + ((DstRect->right) << Vxl.ColorModeShift) -1; ! 305: SrcAdr=Vxl.JaguarScreenX*(SrcPoint->y+Y-1) + ((SrcPoint->x+X) << Vxl.ColorModeShift) -1; ! 306: XYCmd=JAGUAR_BITBLT_RIGHTLEFT << XYCMD_CMD_SHIFT; ! 307: ! 308: } else { ! 309: ! 310: // ! 311: // This is a Left To Right Top to Bottom. ! 312: // ! 313: ! 314: DstAdr=Vxl.JaguarScreenX*DstRect->top + (DstRect->left << Vxl.ColorModeShift); ! 315: SrcAdr=Vxl.JaguarScreenX*SrcPoint->y + (SrcPoint->x << Vxl.ColorModeShift); ! 316: XYCmd=JAGUAR_BITBLT_LEFTRIGHT << XYCMD_CMD_SHIFT; ! 317: ! 318: } ! 319: Y &= 0x3FF; ! 320: ! 321: XYCmd = XYCmd | (Y << XYCMD_Y_SHIFT) | X; ! 322: FifoWrite(DstAdr,SrcAdr,XYCmd); ! 323: } ! 324: ! 325: BOOL ! 326: DrvBitBlt( ! 327: IN SURFOBJ *psoDst, // Target surface ! 328: IN SURFOBJ *psoSrc, // Source surface ! 329: IN SURFOBJ *psoMask, // Mask ! 330: IN CLIPOBJ *pco, // Clip through this ! 331: IN XLATEOBJ *pxlo, // Color translation ! 332: IN PRECTL prclDst, // Target offset and extent ! 333: IN PPOINTL pptlSrc, // Source offset ! 334: IN PPOINTL pptlMask, // Mask offset ! 335: IN BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush) ! 336: IN PPOINTL pptlBrush, // Brush offset (origin) ! 337: IN ROP4 rop4 // Raster operation ! 338: ) ! 339: ! 340: /*++ ! 341: ! 342: Routine Description: ! 343: ! 344: Code for "hooking" Bit Blt functions for Jaguar VXL. ! 345: ! 346: Arguments: ! 347: ! 348: ! 349: Return Value: ! 350: ! 351: ! 352: --*/ ! 353: ! 354: { ! 355: ! 356: FLONG BltDir; ! 357: BOOL JaguarDir; ! 358: RECTL BltRectl; ! 359: ENUMRECTLIST ClipEnum; ! 360: BOOL MoreClipRects; ! 361: ULONG ClipRegions; ! 362: POINTL SrcPoint; ! 363: PPDEV ppdev = (PPDEV) psoDst->dhpdev; ! 364: BYTE FixedComplexity; ! 365: ! 366: // ! 367: // Check that there is no color translation. ! 368: // ! 369: ! 370: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { ! 371: ! 372: // ! 373: // Check that the blt operation has the screen as target surface. ! 374: // ! 375: ! 376: if (psoDst->pvBits == (PVOID)Vxl.ScreenBase) { ! 377: ! 378: // ! 379: // Check for rops that Jaguar handles. ! 380: // Solid Fills, ! 381: // SRCCOPPY ! 382: // ! 383: ! 384: switch(rop4) { ! 385: case 0x00000000: // DDx (BLACKNESS) ! 386: DrvpSolidFill(prclDst,pco,0); ! 387: return(TRUE); ! 388: ! 389: case 0x0000FFFF: // DDxn (WHITENESS) ! 390: DrvpSolidFill(prclDst,pco,0xFFFFFF); ! 391: return(TRUE); ! 392: ! 393: case 0x0000F0F0: // P (PATCOPY) ! 394: case 0x00000F0F: // Pn (NOTPATCOPY) ! 395: ! 396: // ! 397: // This is a pattern fill. Check if the brush pattern ! 398: // is just a plain color, in this case procede with the ! 399: // Solid Color Fill. ! 400: // ! 401: ! 402: if (pdbrush->iSolidColor != 0xFFFFFFFF) { ! 403: DrvpSolidFill(prclDst, ! 404: pco, ! 405: (rop4 == 0xF0F) ? ~(pdbrush->iSolidColor) : pdbrush->iSolidColor); ! 406: return(TRUE); ! 407: } ! 408: ! 409: break; ! 410: ! 411: // ! 412: // Source copy ! 413: // ! 414: ! 415: case 0x0000CCCC: ! 416: ! 417: // ! 418: // Check that Source and Destination Surfaces are the same. ! 419: // This is enough as we already checked that the dst is the frame buffer ! 420: // ! 421: ! 422: if (psoDst->pvBits == psoSrc->pvBits) { ! 423: ! 424: // ! 425: // check BLT direction for setting up clip regions ! 426: // And for Jaguar BitBlt Commands as follows: ! 427: // - If BltDir is UPWARDS do the BitBlt RightToLeft Bottom ! 428: // to Top except when Src & Dst are in the same scan line ! 429: // and BltDir is not LEFTWARDS ! 430: // ! 431: ! 432: BltDir = 0; ! 433: JaguarDir = FALSE; ! 434: if (pptlSrc->y <= prclDst->top) { ! 435: BltDir = CD_UPWARDS; ! 436: JaguarDir = TRUE; ! 437: } ! 438: ! 439: if (pptlSrc->x <= prclDst->left) { ! 440: BltDir |= CD_LEFTWARDS; ! 441: } else { ! 442: if ((JaguarDir) && (pptlSrc->y == prclDst->top)) { ! 443: JaguarDir = FALSE; ! 444: } ! 445: } ! 446: ! 447: // ! 448: // Figure out the real clipping complexity ! 449: // ! 450: ! 451: if (pco == (CLIPOBJ *)NULL) { ! 452: FixedComplexity = DC_TRIVIAL; ! 453: } else { ! 454: FixedComplexity = pco->iDComplexity; ! 455: } ! 456: ! 457: switch (FixedComplexity) { ! 458: ! 459: // ! 460: // Entire destination is to be updated. ! 461: // Proceed with the BitBlt. ! 462: // ! 463: ! 464: case DC_TRIVIAL: ! 465: ! 466: DrvpBitBlt(prclDst, // Target rectangle ! 467: pptlSrc, // Source offset ! 468: JaguarDir // Direction ! 469: ); ! 470: return(TRUE); ! 471: ! 472: // ! 473: // Only one clip region. ! 474: // ! 475: ! 476: case DC_RECT: ! 477: ! 478: // ! 479: // only do the BLT if there is an intersection ! 480: // ! 481: ! 482: if (DrvpIntersectRect(prclDst,&pco->rclBounds,&BltRectl)) { ! 483: ! 484: // ! 485: // Adjust the Source for the intersection rectangle. ! 486: // ! 487: ! 488: pptlSrc->x += BltRectl.left - prclDst->left; ! 489: pptlSrc->y += BltRectl.top - prclDst->top; ! 490: ! 491: DrvpBitBlt(&BltRectl, // Target rectangle ! 492: pptlSrc, // Source offset ! 493: JaguarDir // Direction ! 494: ); ! 495: } ! 496: ! 497: return(TRUE); ! 498: ! 499: // ! 500: // Multiple clip regions. ! 501: // ! 502: ! 503: case DC_COMPLEX: ! 504: ! 505: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,BltDir,BB_RECT_LIMIT); ! 506: do { ! 507: ! 508: // ! 509: // Get list of clip rectangles. ! 510: // ! 511: ! 512: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum); ! 513: ! 514: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) { ! 515: ! 516: // ! 517: // If the rectangles intersect calculate the offset to the ! 518: // source start location to match and do the BitBlt. ! 519: // ! 520: if (DrvpIntersectRect(prclDst, ! 521: &ClipEnum.arcl[ClipRegions], ! 522: &BltRectl)) { ! 523: SrcPoint.x = pptlSrc->x + BltRectl.left - prclDst->left; ! 524: SrcPoint.y = pptlSrc->y + BltRectl.top - prclDst->top; ! 525: DrvpBitBlt(&BltRectl, // Target rectangle ! 526: &SrcPoint, // Source offset ! 527: JaguarDir // Direction ! 528: ); ! 529: } ! 530: } ! 531: } while (MoreClipRects); ! 532: ! 533: return(TRUE); ! 534: ! 535: // ! 536: // Unknown Clip complexity ! 537: // ! 538: ! 539: default: ! 540: break; ! 541: } // end switch complexity ! 542: } // end if Src surface = Dst surface ! 543: } // end switch rop4 ! 544: } ! 545: } ! 546: ! 547: // ! 548: // Call GDI to do the Blt for us. No need to syncrhonize here since ! 549: // EngXXX routines call DrvSynchronize. ! 550: // ! 551: ! 552: return(EngBitBlt(psoDst, // Target surface ! 553: psoSrc, // Source surface ! 554: psoMask, // Mask ! 555: pco, // Clip through this ! 556: pxlo, // Color translation ! 557: prclDst, // Target offset and extent ! 558: pptlSrc, // Source offset ! 559: pptlMask, // Mask offset ! 560: pdbrush, // Brush data (from cbRealizeBrush) ! 561: pptlBrush, // Brush offset (origin) ! 562: rop4 // Raster operation ! 563: ) ! 564: ); ! 565: } ! 566: ! 567: BOOL ! 568: DrvCopyBits( ! 569: SURFOBJ *psoDst, ! 570: SURFOBJ *psoSrc, ! 571: CLIPOBJ *pco, ! 572: XLATEOBJ *pxlo, ! 573: RECTL *prclDst, ! 574: POINTL *pptlSrc) ! 575: ! 576: /*++ ! 577: ! 578: Routine Description: ! 579: ! 580: Code for "hooking" CopyBits function for Jaguar VXL. ! 581: ! 582: Arguments: ! 583: ! 584: ! 585: Return Value: ! 586: ! 587: ! 588: --*/ ! 589: ! 590: { ! 591: RECTL BltRectl; ! 592: ENUMRECTLIST ClipEnum; ! 593: BYTE FixedComplexity; ! 594: BOOL MoreClipRects; ! 595: FLONG BltDir; ! 596: BOOL JaguarDir; ! 597: ULONG ClipRegions; ! 598: POINTL SrcPoint; ! 599: ! 600: ! 601: ! 602: // ! 603: // Check that there is no color translation. ! 604: // ! 605: ! 606: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { ! 607: ! 608: // ! 609: // Check that source and destination surfaces are the frame buffer. ! 610: // ! 611: ! 612: if ((psoSrc->pvBits == (PVOID)Vxl.ScreenBase) && ! 613: (psoDst->pvBits == (PVOID)Vxl.ScreenBase)) { ! 614: ! 615: // ! 616: // check BLT direction for setting up clip regions ! 617: // And for Jaguar BitBlt Commands as follows: ! 618: // - If BltDir is UPWARDS do the BitBlt RightToLeft Bottom ! 619: // to Top except when Src & Dst are in the same scan line ! 620: // and BltDir is not LEFTWARDS ! 621: // ! 622: ! 623: BltDir = 0; ! 624: JaguarDir = FALSE; ! 625: if (pptlSrc->y <= prclDst->top) { ! 626: BltDir = CD_UPWARDS; ! 627: JaguarDir = TRUE; ! 628: } ! 629: ! 630: if (pptlSrc->x <= prclDst->left) { ! 631: BltDir |= CD_LEFTWARDS; ! 632: } else { ! 633: if ((JaguarDir) && (pptlSrc->y == prclDst->top)) { ! 634: JaguarDir = FALSE; ! 635: } ! 636: } ! 637: ! 638: // ! 639: // Figure out the real clipping complexity ! 640: // ! 641: ! 642: if (pco == (CLIPOBJ *)NULL) { ! 643: FixedComplexity = DC_TRIVIAL; ! 644: } else { ! 645: FixedComplexity = pco->iDComplexity; ! 646: } ! 647: ! 648: switch (FixedComplexity) { ! 649: ! 650: // ! 651: // Entire destination is to be updated. ! 652: // Proceed with the BitBlt. ! 653: // ! 654: ! 655: case DC_TRIVIAL: ! 656: ! 657: DrvpBitBlt(prclDst, // Target rectangle ! 658: pptlSrc, // Source offset ! 659: JaguarDir // Direction ! 660: ); ! 661: return(TRUE); ! 662: ! 663: // ! 664: // Only one clip region. ! 665: // ! 666: ! 667: case DC_RECT: ! 668: ! 669: // ! 670: // only do the BLT if there is an intersection ! 671: // ! 672: ! 673: if (DrvpIntersectRect(prclDst,&pco->rclBounds,&BltRectl)) { ! 674: ! 675: // ! 676: // Adjust the Source for the intersection rectangle. ! 677: // ! 678: ! 679: pptlSrc->x += BltRectl.left - prclDst->left; ! 680: pptlSrc->y += BltRectl.top - prclDst->top; ! 681: ! 682: DrvpBitBlt(&BltRectl, // Target rectangle ! 683: pptlSrc, // Source offset ! 684: JaguarDir // Direction ! 685: ); ! 686: } ! 687: ! 688: return(TRUE); ! 689: ! 690: // ! 691: // Multiple clip regions. ! 692: // ! 693: ! 694: case DC_COMPLEX: ! 695: ! 696: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,BltDir,BB_RECT_LIMIT); ! 697: do { ! 698: ! 699: // ! 700: // Get list of clip rectangles. ! 701: // ! 702: ! 703: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum); ! 704: ! 705: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) { ! 706: ! 707: // ! 708: // If the rectangles intersect calculate the offset to the ! 709: // source start location to match and do the BitBlt. ! 710: // ! 711: if (DrvpIntersectRect(prclDst, ! 712: &ClipEnum.arcl[ClipRegions], ! 713: &BltRectl)) { ! 714: SrcPoint.x = pptlSrc->x + BltRectl.left - prclDst->left; ! 715: SrcPoint.y = pptlSrc->y + BltRectl.top - prclDst->top; ! 716: DrvpBitBlt(&BltRectl, // Target rectangle ! 717: &SrcPoint, // Source offset ! 718: JaguarDir // Direction ! 719: ); ! 720: } ! 721: } ! 722: } while (MoreClipRects); ! 723: ! 724: return(TRUE); ! 725: ! 726: // ! 727: // Unknown Clip complexity ! 728: // ! 729: ! 730: default: ! 731: break; ! 732: } // end switch complexity ! 733: } ! 734: ! 735: } ! 736: ! 737: // ! 738: // If the copy operation could be performed by the accelerator, ! 739: // this routine has already returned. ! 740: // If execution falls here, call the Engine routine. ! 741: // No need to Synchronize here since the Eng routine will call DrvSyncrhonize. ! 742: // ! 743: ! 744: return EngCopyBits(psoDst, ! 745: psoSrc, ! 746: pco, ! 747: pxlo, ! 748: prclDst, ! 749: pptlSrc); ! 750: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.