Short: PCI driver for all bridge boards Author: thomas.richter@alumni.tu-berlin.de (Thomas Richter) Uploader: thomas richter alumni tu-berlin de (Thomas Richter) Type: driver/other Version: 40.2 Architecture: m68k-amigaos >= 2.0.4 ----------------------------------------------------------------------------- Changes since release 2.0: - Fixed defects in the list management of PCI boards. - Forgot to map the legacy IO window through via the MMU. - Added a preferences file ("ENVARC:PCI-Configuration"). - Fixed code if run on an MMU-less system. - Tested successfully on a Firestorm and A4000 Mediator, more tests welcome. - Apparently, the PCIInit tool that came with the previous version was broken. This got fixed as well. ----------------------------------------------------------------------------- Changes for release 2.2: - Added functions for allocating, releasing and announcing PCI memory for DMA bounce buffers. - Added an emulation of the prometheus.library. - Added commands to reserve IO space and memory space. ----------------------------------------------------------------------------- Changes for release 3.2: - The functions for bounce buffer allocation have been debugged. - Added two new tags for FindBoardTagList() to find a board by a memory range. This allows P96 to identify an OpenPCI handled board from the frame buffer address. - Added development files such as the .fd file and the includes. ----------------------------------------------------------------------------- Changes for release 4.2: - This release adds support for PCI-2-PCI or PCI-2-PCIe bridges. However, such bridges require additional hardware support to allow accessing devices behind such bridges. At the time of writing, only the Firestorm PCI bridge is able to generate such extended PCI configuration cycles and thus, this is the only bridge that supports bridges. Support is currently limited to bridges that offer a single PCI bus behind the bridge. This should apply to the majority of PCI plug-in cards. - Added functionality to remove the cybpci.library from the system to stop interfering with the openpci.library. ----------------------------------------------------------------------------- Changes for release 4.3: - The PCI scanning functions were broken and could not continue correctly from a middle of a scan, i.e. if the previous device passed in was non-NULL. - The Grex detection algorithm was a bit uncareful can could have hung machines. It now tests for the presence of the ID tags of the corresponding boards. - The Grex interrupt server did not test all flags necessary to ensure that an interrupt was triggered. - Grex boars board detection now also includes the CVisionPPC if it is present, and the early PCI bridges. - Grex detection now also includes the PCI reset sequence that might have been missing if the PCI firmware was not initialized. - PCIInit no longer fails with an Alert if no PCI bridge boards were detected. ----------------------------------------------------------------------------- Changes for release 4.7: - A new command SetCacheLineSize was added to the PCI-Configuration file. This command sets the cache line size field in the PCI config area. Typically, it should be set to 0. - Support for G-Rex was finalized. The G-Rex board is now fully initialized and PCI configuration cycles now also generate parity correctly. - The G-Rex PCI configuration code now also detects the legacy PCI bridge which connects to the CVisionPPC. This potentially requires an update of the CVisionPPC graphics card driver as it may now use the openpci.library as an optional component. - The G-Rex interrupt handler is now fully debugged and working. - Mediator A1200 device detection has been verified on real hardware. Still missing confirmation that the MMU window handling works not only under emulation. ----------------------------------------------------------------------------- Changes for release 5.2: - A couple of new tags to GetBoardAttrs() allow to retrieve the interrupt line, the legacy IO space or the offset from the PCI address space to 68K virtual addresses. - The G-Rex support functions did not fill in the device number correctly. - Includes for assembler developers were included. - Added sources and binaries for an lspci example binary that lists the devices on the PCI bus(es). ----------------------------------------------------------------------------- Changes for release 5.3: - FindBoardTagList() had a defect and crashed if it was called. This got fixed. - The cybpci.library is now removed immediately after detecting a G-Rex, avoiding a conflict when the PCI configuration is changed under the feed of cybpci. - The include files still misdocumented one field ("master") incorrectly as 32-bit whereas it is just 16 bit, also under the version 1 of openpci. - Forgot to include an assembler lvo file defining the library offsets. ----------------------------------------------------------------------------- Changes for release 5.4: - The Grex board installs now its own DMA memory provider which allocates RAM from the board RAM. This should work as PCI devices on the GRex can do DMA into the CPU RAM, unlike other boards. - Fixed a wrong pointer reference when removing cybpci. ----------------------------------------------------------------------------- Changes for release 5.5: - The code now also removes the P5 PCI ConfigDevs from autoconf as they should not be used anymore. Instead, PCI access should be routed through the openpci.library and its expansion nodes. ----------------------------------------------------------------------------- Changes for release 6.2: - Due to a defect in a header file, creating MMU tables for the A1200 mediator boards did not work. - In case the MMU table setup did not work, the code did not clear device flags requesting MMU window processing. - Creating expansion library ConfigDevs did not check whether some of the BARs have not been initialized. ----------------------------------------------------------------------------- Changes for release 6.3: - During preferences parsing, a structure to hold the parsed arguments was not released, causing a mild memory loss. - A new command was added to the PCI-Configuration file, namely "EMULATE". This command allows to enable emulation of third party libraries, for example "Emulate Prometheus" will enable the prometheus emulation layer, including a "fake" configDev structure pointing to the legacy IO region. This works regardless of the actual PCI board installed. Note that while previous releases always enabled the Prometheus emulation, this emulation now requires explicit user interaction by editing "ENVARC:PCI-Configuration". - When initializing PCI devices for one of the 1200 Mediators, the code overwrote parts of the device structure, implicitly allocating the device. This got fixed. - The SetBoardAttrs() function now expects a "struct Node *" as argument to PRM_BoardOwner, and GetBoardAttrs() returns one. Unfortunately, the prometheus library documentation was not very clear on what the expected argument should be. Similarly, the library stores now its own base address (and thus a struct Node *) as owner on pci_obtain_card(). ----------------------------------------------------------------------------- Changes for release 6.5: - This version now fixes the interrupt routing through PCI bridges and also configures the InterruptLine PCI configuration register to include the interrupt the device is actually generating. ----------------------------------------------------------------------------- Changes for release 6.6: - Interrupt enabling and disabling now not only happens at bridge level, but also at PCI device level through the device command register. ----------------------------------------------------------------------------- Changes for release 6.7: - Interrupt management has been improved further by disabling the interrupt at bridge level only if there is no additional interrupt server queued to listen to the interrupt. This prevents problems if multiple interrupt servers for multiple devices are installed, but one of the servers is removed. - Fixed the include files, the arguments should be TagItem *, not TagList *, and the FindBoard() function follows now the convention of the remaining tag based calls by using an A as appendix for the regular function, and the function name without the appendix for the varadic function. ----------------------------------------------------------------------------- Changes for release 7.2: - Memory and IO base and limit generation for PCI-to-PCI bridges was wrong because it set the upper limit to the exclusive, not the inclusive largest address, thus requesting the bridge to map more than the absolute minimum address range through the bridge. - Bridge memory and IO limits were not rounded correctly to the granularity of the bridge registers. - The bridge subordinate bus configuration byte was set incorrectly in case more than a single bus was behind the bridge; in fact, bridges could not detect more than a single bus behind them at all. This was fixed. - Installation of the interrupt line on the Mediator A1200 closed the PCI configuration bank and thus prevented configuration of any but the first PCI device. - In case a VGA device is found behind the bridge, the code now ensures that access to the legacy VGA registers is mapped through the bridge. - This release disables memory prefetching at the bridge level. There is probably little to be gained as the 68K and the Zorro bus dominates the access time, and prefetching may interact badly with memory mapped IO registers. ----------------------------------------------------------------------------- Changes for release 7.2.1: - The library remained unchanged, but the archive got reorganized a bit. This version includes an installer script and also a guide. ----------------------------------------------------------------------------- Changes for release 7.2.2: - This release fixed the default source directory of the installer. ----------------------------------------------------------------------------- Changes for release 8.2: - The emulate command in PCI-Configuration was extended. ----------------------------------------------------------------------------- Changes for release 9.2: - The built-in DMA memory provider for the G-Rex host bridge now also allocates cache-disabled memory by going through the PCI library, and resets the caching mode as soon as the memory is released. - This version adds experimental support for PCI to PCI bridges on the Mediator bridges. This is experimental and to some degree based on guesswork, so feedback is required. ----------------------------------------------------------------------------- Changes for release 9.3: - The PCI device scanner for the mediator bridges bypassed PCI bridges early and thus could have never supported bridges in first place. Nevertheless, most mediator boards are not capable to support bridges, unfortunately. - The IO and memory regions for PCI devices are now only enabled after BAR registers have been loaded with the final addresses. ----------------------------------------------------------------------------- Changes for release 10.2: - Preferences are now parsed before BAR registers are sized. This has the effect that the IGNORE command for BARs will also prevent that the ignored BARs are even written to. - Matching a PCI by class code in PCI-configuration could have trashed memory. - The SetInterrupt command in PCI-Configuration failed to reroute interrupts and thus was mostly useless. - SetInterrupt and SetPri may have failed to configure PCI devices correctly on the A1200 mediator. - In PCI-Configuration, the device function is now separated by a dot from the device ID to mirror the syntax of lspci. - Added a new SLOT keyword to most commands for PCI-Configuration to identify a device by its bus number, slot number and (optionally) function number. ----------------------------------------------------------------------------- Changes for release 10.3: - Bridge configuration was refactored again. Bridge and parent device are now passed already into the constructor of a PCI device, and not only when it is added. - Fixed a trashed register in the Mediator board scan. - The Mediator scan did not pass the parent device correctly into the device creator, thus giving devices behind bridges wrong bus IDs. - For some strange reason, the Mediator does not seem to decode the address bits for selecting a device behind a PCI bridge correctly; it seems to ignore them. Therefore, the Mediator currently supports only a single device behind a bridge. - Some bridges take apparently several milliseconds to accept a configuration. Now the library inserts a 50ms delay after having installed the target busses after setting up a PCI bridge. - The time delay function was broken and passed in the wrong command to the timer.device. ----------------------------------------------------------------------------- Changes for release 10.4: - The algorithm for finding an address space window for the A1200 mediators has been changed. It no longer looks behind the last memory segment, but uses the largest hole from the 24bit limit up. - The installer script has been updated. It now checks whether the archive is corrupt, and also backs up the PCI-Configuration file if it existed. - PCIInit no longer checks whether the version of openpci is larger or equal than its own version. Version 3 of openpci is now sufficient since that version introduced the MMU initialization API. ----------------------------------------------------------------------------- Changes for release 10.5: - When tearing down the library due to an Expunge, the code trashed memory due to an incorrectly loaded memory. - When scanning for devices, the scan no longer stops after the first device of a multi-function device that claims not be of multi-function type. ----------------------------------------------------------------------------- Changes for release 11.2: - GetBoardAttrs() and SetBoardAttrs() could loop forever on unknown tags, the end marker for the known tags was incorrect. - The PCI BAR register parser did not compute the parity correctly for some boards. - Two new tags were added for GetBoardAttr(), namely PRM_PCIMemWindowLow and PRM_PCIMemWindowHigh, which provide the PCI address range available for a device at config time, or the PCI address range a device is mapped into later. These are PCI addresses, not 68K addresses. - SetBoardAttr() can now write PRM_MemorySizeX and PRM_MemoryFlagsX at config time to dynamically size PCI devices. This is useful for tools called from within the PCI-Configuration file. - Fixed a missing register initialization when unloading tools from LIBS:PCI. - Added example source code for an init tool for sizing PCI devices dynamically. - Fixed the description of the autoconf vendor IDs in the autodoc file. ----------------------------------------------------------------------------- Changes for release 12.2: - The "lspci" program accepts now an additional argument, namely "NUMERIC". If set, then it does not attempt to resolve the PCI vendor and device ID to human-readable numbers but rather prints their hex values. - Dynamic PCI initialization through external segments was augmented. Init functions receive now one additional argument in a1, and may return a (non-NULL) pointer. Initially, Init functions are called with this argument set to NULL, and receive in register a0 a pointer to a RDArgs structure for command line parsing. If they return a non-NULL pointer and not a small number as error code, they are called *once again* the PCI environment is completely setup. They then receive NULL as RDArgs in a0, but its own (previous) return code in a1 to complete a potential initialization of a device. ----------------------------------------------------------------------------- Changes for release 12.3: - lspci sources included the wrong header, is BSD-only, should be which is POSIX. - Fixed a defect in the mediator emulation setup. ----------------------------------------------------------------------------- Changes for release 12.4: - This version fixes a race condition in initializing the emulated library bases. - As side effect, emulated libraries are now already showing within exec once openpci has been loaded. MMU initialization is now also performed by opening one of the emulated pci libraries. ----------------------------------------------------------------------------- Changes for release 12.5: - The GetPhysicalAddress() and GetVirtualAddress() of the prometheus emulation library expected the input address in register a0 instead of d0. This got fixed. ----------------------------------------------------------------------------- Changes for release 12.6: - When PCI BAR sizes are defined through SetBoardAttrs(), the library no longer attempts to read back the corresponding BAR as it assumes that the corresponding BAR is non-standard and does not allow read-access. Instead, the defined BAR size is assumed to be correct. ----------------------------------------------------------------------------- Changes for release 12.7: - The ReserveMemSpace function in PCI-Configuration could hang forever if a bridge does not support access to the low memory PCI area and reservation failed. - In case address space allocation for a BAR fails, the corresponding device is disabled, excluded from further reservations and removed from the listed device list now. - Translation between 68K addresses and PCI addresses is now aware of the memory region reserved by ReserveMemSpace and maps addresses below the reservation limit through, regardless whether any BAR actually uses the region. ----------------------------------------------------------------------------- Changes for release 12.8: - The legacy VGA window, made accessible by ReserveMemSpace was not properly mapped by the MMU, and neither received an Expansion ConfigDev node. This has now been fixed. The product ID for this region is now 7 (see also openpci.doc). - The PCI address space algorithm was updated to make better use of a non-aligned upper PCI memory window. Now, smaller PCI BARs are placed there first to make best use of the available address space. - The guide was updated to describe the legacy VGA window. ----------------------------------------------------------------------------- Changes for release 12.9: - The pci_logic_to_physic_addr() and related functions were actually broken because one of the used instructions did not (as expected) generate condition codes for determine error conditions. This has been fixed. ----------------------------------------------------------------------------- Changes for release 13.2: - Added the "VirtualMapping" command for PCI-Configuration. If this is enabled - which is the default - the PCI address space of the A1200 mediator boards is enlarged by dynamically (virtually) mapping addresses of the 68K to the small PCI window. Can be turned off to always have physically mapped PCI addresses, though only few devices then fit into the relatively small address space. - Flushing the library now restores the original ConfigDev structures. - If the emulation code was flushed, the code forgot to remove the emulated expansion structures and thus could have crashed the machines. - If the PCI bus was rescanned after flushing the library, the MMU blocked access to non-existing devices and thus caused the code to trigger MuForce hits - for devices that are not present. The library now bypasses the MMU for scanning. It already did for Firestorm and G-Rex. ----------------------------------------------------------------------------- Changes for release 13.3: - The mediator emulation code did not pass the device/function offset correctly to the lower level config space accessor functions and therefore failed to read or write configuration registers at all. - DMA memory handling for mediator emulation was unfortunately broken. While this is fixed, DMA memory is only available through the emulation if the underlying bridge maps 68K addresses directly to PCI addresses, without any offset. ----------------------------------------------------------------------------- Changes for release 13.4: - The alloc_dma_mem() function returned nonsense instead of NULL if no DMA memory provider is available. - The emulation functions now call (as much as possible) through the openpci API. ----------------------------------------------------------------------------- Changes for release 14.2: - The PCI address space/BAR allocation algorithm was revisited again. It is now some kind of "buddy" allocation scheme that should be (nearly) optimal and should be able to squeeze in BARs even if top and bottom end of the window are not allocated. - The lower PCI memory area end for the Prometheus was not properly indicated, thus potentially causing BARs to leak into the I/O or config areas. - The upper end of the PCI memory area for the firestorm was extended a little bit to make more room. This requires testing whether real hardware behaves as documented. - Added two new functions to the API, ObtainPCIRegion() and ReleasePCIRegion() which temporarily can provide access to any area in the PCI config space. The typical use case for these functions is to write to legacy VGA space. Not all PCI host adapters will support such accesses. Included are currently the firestorm and the Mediators (potentially). Example source is included (ObtainExample.c) to demonstrate the API. - As the API is extended, pragmas and headers have been regenerated. ----------------------------------------------------------------------------- Changes for release 14.3: - Fixed bridge allocation (again, hopefully). ----------------------------------------------------------------------------- Changes for release 14.4: - The granularity of which bridge limits are allocated now also depends on the devices behind the bridge (and, recursively, behind bridges behind the bridge). This should also make bridge limit allocation almost optimal. - Enlarged the delay to move out of reset to 100ms, and the delay to start scanning behind a bridge to 100ms. ----------------------------------------------------------------------------- Changes for release 14.5: - openpci now installs a patch into AllocMem if one of the emulated libraries is opened and by that provides DMA memory to drivers that ask for DMA memory this way. The allocation then goes directly down to P96 without requiring a memory pool in exec. This method has the advantage that DMA memory cannot be allocated "by accident" if the system runs low on memory because such memory might be incompatible to forms of Zorro DMA as it may be virtually mapped. The patch is removed again once the emulation is closed again. ----------------------------------------------------------------------------- Changes for release 14.6: - This release fixes a crash when attempting to remove one of the emulation libraries. ----------------------------------------------------------------------------- Changes for release 15.2: - The PCI-Configuration file offers a new command, namely "Hint". With this command, openpci can be hinted which BARs of a PCI device contain memory-mapped registers and which contain video RAM. The purpose of this command is that it allows openpci to support VGA graphics cards even in restricted configurations with only two small PCI windows accessible from the 68K side without using a virtual MMU mapping window. If such a hint is found, openpci makes the first 4MB of the IO window and another 4MB window into vdeo RAM accessible to the 68K side. This makes some graphics cards such as the Voodoo workable without MMU tricks in such limited environments, but also restricts the usable video RAM to 4MB. Driver developers need to take care that they clamp the video RAM to the size delivered from the pci_dev structure and do not attemp to read them from hardware. Furthermore, MMIO registers are in such setups not reachable by DMA - this should hopefully be not a restriction. - lspci received a new command line option "PCIADDRS" to print the addresses of the PCI bar registers as seen from the PCI space. The default is to print the addresses as used by the 68K side. - The DMA memory provider is now more careful and checks whether PCI and 68K addresses differ for memory allocated for some emulation modules that cannot handle such translations. ----------------------------------------------------------------------------- Changes for release 16.2: - When allocating DMA memory from a G-Rex, and no suitable memory was found, the previous release crashed with a bad memory alert. The fixed code just does not deliver any memory. - The emulation code now also accepts G-Rex memory as DMA memory and provides it as such under emulation. - The memory allocation patch for the emulation will now also request G-Rex memory if DMA memory is desired through AllocMem(). - A new command was added to PCI-Configuration, namely DMAMemSource. This command allows to select the board from which DMA memory is taken if requested through the (old) openpci interface that does not take a target board for which the memory is desired. For example "DMAMemSource G-Rex" designates the G-Rex board in a multi- PCI setup as source board for DMA memory, asuming that DMA-requesting devices are plugged into this board. ----------------------------------------------------------------------------- Changes for release 17.2: - Added a command to disable the second PCI window on some boards as it is not always working, in some configurations. Alternatively, the board should be jumpered to 4MB only. ----------------------------------------------------------------------------- Changes for release 17.3: - Due to a left-over debugging switch, the 17.2 version always handled mediator bridge boards as if they had an 8MB window. ----------------------------------------------------------------------------- Changes for release 17.4: - Interrupt handling on the mediator bridges improved and should now be able to handle multiple simultaneous interrupts at once. ----------------------------------------------------------------------------- Changes for release 17.5: - At most 512MB are reserved for the MMU window of the small mediators as the window management of the hardware cannot handle larger windows. ----------------------------------------------------------------------------- Changes for release 17.6: - When reading BAR registers, the scanner now disregards those registers that are not negatives of powers of 2 and thus likely corrupt. - One mediator emulation function had to keep CPU registers intact. - Fixed computation of the announced Mediator window mask. ----------------------------------------------------------------------------- Changes for release 17.7: - The algorithm for determining whether devices of a bridge fit into an MMU window was a bit too conservative and did not attempt to place BARs ideally, i.e. failed to mirror the actual generic allocation algorithm of the bridge. This could have caused failure to allocate devices within an MMU window at all. ----------------------------------------------------------------------------- Changes for release 17.8: - Due to an oversight, the G-Rex emulation was always enabled, even if not requested. This has been fixed. ----------------------------------------------------------------------------- Changes for release 17.9: - Interrupt handling was reworked. Even if an interrupt handler signaled that it was responsible for an interrupt, the interrupt is passed on as the server cannot exclude that another device triggered an interrupt simultaenously. - Fixed the algorithm to determine invalid BARs. ----------------------------------------------------------------------------- Changes for release 17.10: - Interrupt handling for mediator was reworked again. Interrupts are now acknowledged by writing into the interrupt enable register once the interrupt source has been detected. - The "find PCI device by class" function in the mediator emulation was broken and got fixed. ----------------------------------------------------------------------------- Changes for release 17.11: - The mediator interrupt mask computation was still not correct. ----------------------------------------------------------------------------- Changes for release 17.12: - The logic to refuse invalid BAR registers unfortunately also refused to accept 16 bit I/O registers. This was fixed. ----------------------------------------------------------------------------- Changes for release 17.13: - Window allocation changed; a supervisor allocated window takes now priority and is not mapped out unless an overlapping window access requires so. ----------------------------------------------------------------------------- Changes for release 17.14: - Added support for emulation of interrupt probing. ----------------------------------------------------------------------------- Changes for release 40.2: - Added a workaround for a defect in PatchControl. This program is, however, not recommended due to defects when patching the exec memory allocation functions. It is recommended to replace it by TRSaferPtch.lha. ----------------------------------------------------------------------------- This archive contains an implementation of the openpci.library following the API defined by Benjamin Vernoux, ported to AmigaOs 4 by St?phane Guillard. Unlike the former implementation by Benjamin and St?phane, this version does not depend on an underlying bridge-board specific library but operates on top of the hardware directly. It is also compatible to the mmu.library and uses its services for banking PCI windows. This version also avoids unnecessary long MMU table setup times implied by some PCI bridge boards that drill unnecessarily large wholes into the 68K address space. This version supports the following PCI bridge boards: - The original Prometheus board - The Prometheus Firestorm board - The Grex bridge board - The A4000 Mediator boards (all variants) - The A1200 Mediator boards (all variants) Restrictions: - The A4000 Mediator board does not support MMU mapping and is restricted to a 512MB PCI window (see below for the rationale). - The mechanism to allocate memory from RTG graphic boards as buffer for PCI DMA memory transactions requires at least version 3.5.0 of the P96 software. At the time of writing, this version is not yet available. It is likely going to be published in approximately December 2024. Some of these restrictions will be lifted in the future. The future of this library depends on you - please help its autor by providing test results. ------------------------------------------------------------------------------ Installation: - Run the installer included in the archive. Alternatively: - Make a backup of your current openpci.library, if you use it. - Copy the openpci.library to LIBS:, replacing other versions. - Third-party PCI bridge libraries are no longer needed. They can be kept or removed. - Install "PCIInit" to LIBS:mmu. - Edit the "ENVARC:MMU-Configuration" file and add the following line at its end: PCIInit This MMU tool loads the openpci.library into RAM, locks it and restricts the MMU table building to the areas actually occupied by PCI components. This will speed up MMU table build-up dramatically. Now reboot. PCI implementations based on openpci based PCI implementations will continue to work. ------------------------------------------------------------------------------ The THOR-Software Licence (v3, January 2nd 2021) This License applies to the computer programs known as the "openpci.library" and its sources. The "Program", below, refers to such program. The "Archive" refers to the package of distribution, as prepared by the author of the Program, Thomas Richter. Each licensee is addressed as "you". The Program and the data in the archive are freely distributable under the restrictions stated below, but are also Copyright (c) Thomas Richter. Distribution of the Program, the Archive and the data in the Archive by a commercial organization without written permission from the author to any third party is prohibited if any payment is made in connection with such distribution, whether directly (as in payment for a copy of the Program) or indirectly (as in payment for some service related to the Program, or payment for some product or service that includes a copy of the Program "without charge"; these are only examples, and not an exhaustive enumeration of prohibited activities). However, the following methods of distribution involving payment shall not in and of themselves be a violation of this restriction: (i) Distributing the Program on a physical data carrier (e.g. CD-ROM, DVD, USB-Stick, Disk...) provided that: a) the Archive is reproduced entirely and verbatim on such data carrier, including especially this licence agreement; b) the data carrier is made available to the public for a nominal fee only, i.e. for a fee that covers the costs of the data carrier, and shipment of the data carrier; c) a data carrier with the Program installed is made available to the author for free except for shipment costs, and d) provided further that all information on said data carrier is redistributable for non-commercial purposes without charge. Redistribution of a modified version of the Archive, the Program or the contents of the Archive is prohibited in any way, by any organization, regardless whether commercial or non-commercial. Everything must be kept together, in original and unmodified form. Limitations. THE PROGRAM IS PROVIDED TO YOU "AS IS", WITHOUT WARRANTY. THERE IS NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IF YOU DO NOT ACCEPT THIS LICENCE, YOU MUST DELETE THE PROGRAM, THE ARCHIVE AND ALL DATA OF THIS ARCHIVE FROM YOUR STORAGE SYSTEM. YOU ACCEPT THIS LICENCE BY USING OR REDISTRIBUTING THE PROGRAM. Thomas Richter ----------------------------------------------------------------------------- So long, Thomas (March 2025)