A fat binary (or multiarchitecture binary) is a computer executable program or library which has been expanded (or "fattened") with code native to multiple instruction sets which can consequently be run on multiple processor types. [1] This results in a file larger than a normal one-architecture binary file, thus the name.
The usual method of implementation is to include a version of the machine code for each instruction set, preceded by a single entry point with code compatible with all operating systems, which executes a jump to the appropriate section. Alternative implementations store different executables in different forks, each with its own entry point that is directly used by the operating system.
The use of fat binaries is not common in operating system software; there are several alternatives to solve the same problem, such as the use of an installer program to choose an architecture-specific binary at install time (such as with Android multiple APKs), selecting an architecture-specific binary at runtime (such as with Plan 9's union directories and GNUstep's fat bundles), [2] [3] distributing software in source code form and compiling it in-place, or the use of a virtual machine (such as with Java) and just-in-time compilation.
In 1988, Apollo Computer's Domain/OS SR10.1 introduced a new file type, "cmpexe" (compound executable), that bundled binaries for Motorola 680x0 and Apollo PRISM executables. [4]
A fat-binary scheme smoothed the Apple Macintosh's transition, beginning in 1994, from 68k microprocessors to PowerPC microprocessors. Many applications for the old platform ran transparently on the new platform under an evolving emulation scheme, but emulated code generally runs slower than native code. Applications released as "fat binaries" took up more storage space, but they ran at full speed on either platform. This was achieved by packaging both a 68000-compiled version and a PowerPC-compiled version of the same program into their executable files. [5] [6] The older 68K code (CFM-68K or classic 68K) continued to be stored in the resource fork, while the newer PowerPC code was contained in the data fork, in PEF format. [7] [8] [9]
Fat binaries were larger than programs supporting only the PowerPC or 68k, which led to the creation of a number of utilities that would strip out the unneeded version. [5] [6] In the era of small hard drives, when 80 MB hard drives were a common size, these utilities were sometimes useful, as program code was generally a large percentage of overall drive usage, and stripping the unneeded members of a fat binary would free up a significant amount of space on a hard drive.
Fat binaries were a feature of NeXT's NeXTSTEP/OPENSTEP operating system, starting with NeXTSTEP 3.1. In NeXTSTEP, they were called "Multi-Architecture Binaries". Multi-Architecture Binaries were originally intended to allow software to be compiled to run both on NeXT's Motorola 68k-based hardware and on Intel IA-32-based PCs running NeXTSTEP, with a single binary file for both platforms. [10] It was later used to allow OPENSTEP applications to run on PCs and the various RISC platforms OPENSTEP supported. Multi-Architecture Binary files are in a special archive format, in which a single file stores one or more Mach-O subfiles for each architecture supported by the Multi-Architecture Binary. Every Multi-Architecture Binary starts with a structure (struct fat_header
) containing two unsigned integers. The first integer ("magic") is used as a magic number to identify this file as a Fat Binary. The second integer (nfat_arch) defines how many Mach-O Files the archive contains (how many instances of the same program for different architectures). After this header, there are nfat_arch number of fat_arch structures (struct fat_arch
). This structure defines the offset (from the start of the file) at which to find the file, the alignment, the size and the CPU type and subtype which the Mach-O binary (within the archive) is targeted at.
The version of the GNU Compiler Collection shipped with the Developer Tools was able to cross-compile source code for the different architectures on which NeXTStep was able to run. For example, it was possible to choose the target architectures with multiple '-arch' options (with the architecture as argument). This was a convenient way to distribute a program for NeXTStep running on different architectures.
It was also possible to create libraries (e.g. using NeXTStep's libtool) with different targeted object files.
Apple Computer acquired NeXT in 1996 and continued to work with the OPENSTEP code. Mach-O became the native object file format in Apple's free Darwin operating system (2000) and Apple's Mac OS X (2001), and NeXT's Multi-Architecture Binaries continued to be supported by the operating system. Under Mac OS X, Multi-Architecture Binaries can be used to support multiple variants of an architecture, for instance to have different versions of 32-bit code optimized for the PowerPC G3, PowerPC G4, and PowerPC 970 generations of processors. It can also be used to support multiple architectures, such as 32-bit and 64-bit PowerPC, or PowerPC and x86, or x86-64 and ARM64. [11]
In 2005, Apple announced another transition, from PowerPC processors to Intel x86 processors. Apple promoted the distribution of new applications that support both PowerPC and x86 natively by using executable files in Multi-Architecture Binary format. [12] Apple calls such programs "Universal applications" and calls the file format "Universal binary" as perhaps a way to distinguish this new transition from the previous transition, or other uses of Multi-Architecture Binary format.
Universal binary format was not necessary for forward migration of pre-existing native PowerPC applications; from 2006 to 2011, Apple supplied Rosetta, a PowerPC (PPC)-to-x86 dynamic binary translator, to play this role. However, Rosetta had a fairly steep performance overhead, so developers were encouraged to offer both PPC and Intel binaries, using Universal binaries. The obvious cost of Universal binary is that every installed executable file is larger, but in the years since the release of the PPC, hard-drive space has greatly outstripped executable size; while a Universal binary might be double the size of a single-platform version of the same application, free-space resources generally dwarf the code size, which becomes a minor issue. In fact, often a Universal-binary application will be smaller than two single-architecture applications because program resources can be shared rather than duplicated. If not all of the architectures are required, the lipo and ditto command-line applications can be used to remove versions from the Multi-Architecture Binary image, thereby creating what is sometimes called a thin binary.
In addition, Multi-Architecture Binary executables can contain code for both 32-bit and 64-bit versions of PowerPC and x86, allowing applications to be shipped in a form that supports 32-bit processors but that makes use of the larger address space and wider data paths when run on 64-bit processors.
In versions of the Xcode development environment from 2.1 through 3.2 (running on Mac OS X 10.4 through Mac OS X 10.6), Apple included utilities which allowed applications to be targeted for both Intel and PowerPC architecture; universal binaries could eventually contain up to four versions of the executable code (32-bit PowerPC, 32-bit x86, 64-bit PowerPC, and 64-bit x86). However, PowerPC support was removed from Xcode 4.0 and is therefore not available to developers running Mac OS X 10.7 or greater.
In 2020, Apple announced another transition, this time from Intel x86 processors to Apple silicon (ARM64 architecture). To smooth the transition Apple added support for the Universal 2 binary format; Universal 2 binary files are Multi-Architecture Binary files containing both x86-64 and ARM64 executable code, allowing the binary to run natively on both 64-bit Intel and 64-bit Apple silicon. Additionally, Apple introduced Rosetta 2 dynamic binary translation for x86 to Arm64 instruction set to allow users to run applications that do not have Universal binary variants.
In 2006, Apple switched from PowerPC to Intel CPUs, and replaced Open Firmware with EFI. However, by 2008, some of their Macs used 32-bit EFI and some used 64-bit EFI. For this reason, Apple extended the EFI specification with "fat" binaries that contained both 32-bit and 64-bit EFI binaries. [13]
CP/M-80, MP/M-80, Concurrent CP/M, CP/M Plus, Personal CP/M-80, SCP and MSX-DOS executables for the Intel 8080 (and Zilog Z80) processor families use the same .COM file extension as DOS-compatible operating systems for Intel 8086 binaries. [nb 1] In both cases programs are loaded at offset +100h and executed by jumping to the first byte in the file. [14] [15] As the opcodes of the two processor families are not compatible, attempting to start a program under the wrong operating system leads to incorrect and unpredictable behaviour.
In order to avoid this, some methods have been devised to build fat binaries which contain both a CP/M-80 and a DOS program, preceded by initial code which is interpreted correctly on both platforms. [15] The methods either combine two fully functional programs each built for their corresponding environment, or add stubs which cause the program to exit gracefully if started on the wrong processor. For this to work, the first few instructions (sometimes also called gadget headers [16] ) in the .COM file have to be valid code for both 8086 and 8080 processors, which would cause the processors to branch into different locations within the code. [16] For example, the utilities in Simeon Cran's emulator MyZ80 start with the opcode sequence EBh, 52h, EBh. [17] [18] An 8086 sees this as a jump and reads its next instruction from offset +154h whereas an 8080 or compatible processor goes straight through and reads its next instruction from +103h. A similar sequence used for this purpose is EBh, 03h, C3h. [19] [20] John C. Elliott's FATBIN [21] [22] [23] is a utility to combine a CP/M-80 and a DOS .COM file into one executable. [17] [24] His derivative of the original PMsfx modifies archives created by Yoshihiko Mino's PMarc to be self-extractable under both, CP/M-80 and DOS, starting with EBh, 18h, 2Dh, 70h, 6Dh, 73h, 2Dh to also include the "-pms-" signature for self-extracting PMA archives, [25] [17] [24] [18] thereby also representing a form of executable ASCII code.
Another method to keep a DOS-compatible operating system from erroneously executing .COM programs for CP/M-80 and MSX-DOS machines [15] is to start the 8080 code with C3h, 03h, 01h, which is decoded as a "RET" instruction by x86 processors, thereby gracefully exiting the program, [nb 2] while it will be decoded as "JP 103h" instruction by 8080 processors and simply jump to the next instruction in the program. Similar, the CP/M assembler Z80ASM+ by SLR Systems would display an error message when erroneously run on DOS. [17]
Some CP/M-80 3.0 .COM files may have one or more RSX overlays attached to them by GENCOM. [26] If so, they start with an extra 256-byte header (one page). In order to indicate this, the first byte in the header is set to magic byte C9h, which works both as a signature identifying this type of COM file to the CP/M 3.0 executable loader, as well as a "RET" instruction for 8080-compatible processors which leads to a graceful exit if the file is executed under older versions of CP/M-80. [nb 2]
C9h is never appropriate as the first byte of a program for any x86 processor (it has different meanings for different generations, [nb 3] but is never a meaningful first byte); the executable loader in some versions of DOS rejects COM files that start with C9h, avoiding incorrect operation.
Similar overlapping code sequences have also been devised for combined Z80/6502, [17] 8086/68000 [17] or x86/MIPS/ARM binaries. [16]
CP/M-86 and DOS do not share a common file extension for executables. [nb 1] Thus, it is not normally possible to confuse executables. However, early versions of DOS had so much in common with CP/M in terms of its architecture that some early DOS programs were developed to share binaries containing executable code. One program known to do this was WordStar 3.2x, which used identical overlay files in their ports for CP/M-86 and MS-DOS, [27] and used dynamically fixed-up code to adapt to the differing calling conventions of these operating systems at runtime. [27]
Digital Research's GSX for CP/M-86 and DOS also shares binary identical 16-bit drivers. [28]
DOS device drivers (typically with file extension .SYS) start with a file header whose first four bytes are FFFFFFFFh by convention, although this is not a requirement. [29] This is fixed up dynamically by the operating system when the driver loads (typically in the DOS BIOS when it executes DEVICE statements in CONFIG.SYS). Since DOS does not reject files with a .COM extension to be loaded per DEVICE and does not test for FFFFFFFFh, it is possible to combine a COM program and a device driver into the same file [30] [29] by placing a jump instruction to the entry point of the embedded COM program within the first four bytes of the file (three bytes are usually sufficient). [29] If the embedded program and the device driver sections share a common portion of code, or data, it is necessary for the code to deal with being loaded at offset +0100h as a .COM style program, and at +0000h as a device driver. [30] For shared code loaded at the "wrong" offset but not designed to be position-independent, this requires an internal address fix-up [30] similar to what would otherwise already have been carried out by a relocating loader, except for that in this case it has to be done by the loaded program itself; this is similar to the situation with self-relocating drivers but with the program already loaded at the target location by the operating system's loader.
Under DOS, some files, by convention, have file extensions which do not reflect their actual file type. [nb 4] For example, COUNTRY.SYS [31] is not a DOS device driver, [nb 5] but a binary NLS database file for use with the CONFIG.SYS COUNTRY directive and the NLSFUNC driver. [31] Likewise, the PC DOS and DR-DOS system files IBMBIO.COM and IBMDOS.COM are special binary images loaded by bootstrap loaders, not COM-style programs. [nb 5] Trying to load COUNTRY.SYS with a DEVICE statement or executing IBMBIO.COM or IBMDOS.COM at the command prompt will cause unpredictable results. [nb 4] [nb 6]
It is sometimes possible to avoid this by utilizing techniques similar to those described above. For example, DR-DOS 7.02 and higher incorporate a safety feature developed by Matthias R. Paul: [32] If these files are called inappropriately, tiny embedded stubs will just display some file version information and exit gracefully. [33] [32] [34] [31] Additionally, the message is specifically crafted to follow certain "magic" patterns recognized by the external NetWare & DR-DOS VERSION file identification utility. [31] [32] [nb 7]
A similar protection feature was the 8080 instruction C7h ("RST 0") at the very start of Jay Sage's and Joe Wright's Z-System type-3 and type-4 "Z3ENV" programs [35] [36] as well as "Z3TXT" language overlay files, [37] which would result in a warm boot (instead of a crash) under CP/M-80 if loaded inappropriately. [35] [36] [37] [nb 2]
In a distantly similar fashion, many (binary) file formats by convention include a 1Ah byte (ASCII ^Z) near the beginning of the file. This control character will be interpreted as "soft" end-of-file (EOF) marker when a file is opened in non-binary mode, and thus, under many operating systems (including the PDP-6 monitor [38] and RT-11, VMS, TOPS-10, [39] CP/M, [40] [41] DOS, [42] and Windows [43] ), it prevents "binary garbage" from being displayed when a file is accidentally printed at the console.
FatELF [44] was a fat binary implementation for Linux and other Unix-like operating systems. Technically, a FatELF binary was a concatenation of ELF binaries with some meta data indicating which binary to use on what architecture. [45] Additionally to the CPU architecture abstraction (byte order, word size, CPU instruction set, etc.), there is the advantage of binaries with support for multiple kernel ABIs and versions.
FatELF has several use-cases, according to developers: [44]
A proof-of-concept Ubuntu 9.04 image is available. [47] As of 2021 [update] , FatELF has not been integrated into the mainline Linux kernel.[ citation needed ] [48] [49]
Although the Portable Executable format used by Windows does not allow assigning code to platforms, it is still possible to make a loader program that dispatches based on architecture. This is because desktop versions of Windows on ARM have support for 32-bit x86 emulation, making it a useful "universal" machine code target. Fatpack is a loader that demonstrates the concept: it includes a 32-bit x86 program that tries to run the executables packed into its resource sections one by one. [50]
When developing Windows 11 ARM64, Microsoft introduced a new way to extend the Portable Executable format called Arm64X. [51] An Arm64X binary contains all the content that would be in separate x64/Arm64EC and Arm64 binaries, but merged into one more efficient file on disk. Visual C++ toolset has been upgraded to support producing such binaries. And when building Arm64X binaries are technically difficult, developers can build Arm64X pure forwarder DLLs instead. [52]
The following approaches are similar to fat binaries in that multiple versions of machine code of the same purpose are provided in the same file.
Since 2007, some specialized compilers for heterogeneous platforms produce code files for parallel execution on multiple types of processors, i.e. the CHI (C for Heterogeneous Integration) compiler from the Intel EXOCHI (Exoskeleton Sequencer) development suite extends the OpenMP pragma concept for multithreading to produce fat binaries containing code sections for different instruction set architectures (ISAs) from which the runtime loader can dynamically initiate the parallel execution on multiple available CPU and GPU cores in a heterogeneous system environment. [53] [54]
Introduced in 2006, Nvidia's parallel computing platform CUDA (Compute Unified Device Architecture) is a software to enable general-purpose computing on GPUs (GPGPU). Its LLVM-based compiler NVCC can create ELF-based fat binaries containing so called PTX virtual assembly (as text) which the CUDA runtime driver can later just-in-time compile into some SASS (Streaming Assembler) binary executable code for the actually present target GPU. The executables can also include so called CUDA binaries (aka cubin files) containing dedicated executable code sections for one or more specific GPU architectures from which the CUDA runtime can choose from at load-time. [55] [56] [57] [58] [59] [60] Fat binaries are also supported by GPGPU-Sim , a GPU simulator introduced in 2007 as well. [61] [62]
Multi2Sim (M2S), an OpenCL heterogeneous system simulator framework (originally only for either MIPS or x86 CPUs, but later extended to also support ARM CPUs and GPUs like the AMD/ATI Evergreen & Southern Islands as well as Nvidia Fermi & Kepler families) [63] supports ELF-based fat binaries as well. [64] [63]
GNU Compiler Collection (GCC) and LLVM do not have a fat binary format, but they do have fat object files for link-time optimization (LTO). Since LTO involves delaying the compilation to link-time, the object files must store the intermediate representation (IR), but on the other hand machine code may need to be stored too (for speed or compatibility). An LTO object containing both IR and machine code is known as a fat object. [65]
Even in a program or library intended for the same instruction set architecture, a programmer may wish to make use of some newer instruction set extensions while keeping compatibility with an older CPU. This can be achieved with function multi-versioning (FMV): versions of the same function are written into the program, and a piece of code decides which one to use by detecting the CPU's capabilities (such as through CPUID). Intel C++ Compiler, GCC, and LLVM all have the ability to automatically generate multi-versioned functions. [66] This is a form of dynamic dispatch without any semantic effects.
Many math libraries feature hand-written assembly routines that are automatically chosen according to CPU capability. Examples include glibc, Intel MKL, and OpenBLAS. In addition, the library loader in glibc supports loading from alternative paths for specific CPU features. [67]
A similar, but byte-level granular approach originally devised by Matthias R. Paul and Axel C. Frinke is to let a small self-discarding, relaxing and relocating loader embedded into the executable file alongside any number of alternative binary code snippets conditionally build a size- or speed-optimized runtime image of a program or driver necessary to perform (or not perform) a particular function in a particular target environment at load-time through a form of dynamic dead code elimination (DDCE). [68] [69] [70] [71]
COUNTRY.SYS
file formats supported by the MS-DOS/PC DOS and the DR-DOS families of operating systems contain similar data but are organized differently and incompatible. Since the entry points into the data structures are at different offsets in the file it is possible to create "fat" COUNTRY.SYS
databases, which could be used under both DOS families. [b] However, DR-DOS 7.02 and its NLSFUNC 4.00 (and higher) include an improved parser capable of reading both types of formats (and variants), even at the same time, so that Janus-headed files are not necessary. [c] [d] The shipped files are nevertheless "fat" for including a tiny executable stub just displaying an embedded message when invoked inappropriately. [d] [b] In computing, the Executable and Linkable Format is a common standard file format for executable files, object code, shared libraries, and core dumps. First published in the specification for the application binary interface (ABI) of the Unix operating system version named System V Release 4 (SVR4), and later in the Tool Interface Standard, it was quickly accepted among different vendors of Unix systems. In 1999, it was chosen as the standard binary file format for Unix and Unix-like systems on x86 processors by the 86open project.
In computer programming, machine code is computer code consisting of machine language instructions, which are used to control a computer's central processing unit (CPU). Although decimal computers were once common, the contemporary marketplace is dominated by binary computers; for those computers, machine code is "the binary representation of a computer program which is actually read and interpreted by the computer. A program in machine code consists of a sequence of machine instructions ."
Turbo Pascal is a software development system that includes a compiler and an integrated development environment (IDE) for the programming language Pascal running on the operating systems CP/M, CP/M-86, and DOS. It was originally developed by Anders Hejlsberg at Borland, and was notable for its very fast compiling. Turbo Pascal, and the later but similar Turbo C, made Borland a leader in PC-based development tools.
CP/M, originally standing for Control Program/Monitor and later Control Program for Microcomputers, is a mass-market operating system created in 1974 for Intel 8080/85-based microcomputers by Gary Kildall of Digital Research, Inc. CP/M is a disk operating system and its purpose is to organize files on a magnetic storage medium, and to load and run programs stored on a disk. Initially confined to single-tasking on 8-bit processors and no more than 64 kilobytes of memory, later versions of CP/M added multi-user variations and were migrated to 16-bit processors.
The Portable Executable (PE) format is a file format for executables, object code, DLLs and others used in 32-bit and 64-bit versions of Windows operating systems, and in UEFI environments. The PE format is a data structure that encapsulates the information necessary for the Windows OS loader to manage the wrapped executable code. This includes dynamic library references for linking, API export and import tables, resource management data and thread-local storage (TLS) data. On NT operating systems, the PE format is used for EXE, DLL, SYS, MUI and other file types. The Unified Extensible Firmware Interface (UEFI) specification states that PE is the standard executable format in EFI environments.
86-DOS is a discontinued operating system developed and marketed by Seattle Computer Products (SCP) for its Intel 8086-based computer kit.
x86-64 is a 64-bit version of the x86 instruction set, first announced in 1999. It introduced two new modes of operation, 64-bit mode and compatibility mode, along with a new 4-level paging mode.
The A20, or address line 20, is one of the electrical lines that make up the system bus of an x86-based computer system. The A20 line in particular is used to transmit the 21st bit on the address bus.
A COM file is a type of simple executable file. On the Digital Equipment Corporation (DEC) VAX operating systems of the 1970s, .COM
was used as a filename extension for text files containing commands to be issued to the operating system. With the introduction of Digital Research's CP/M, the type of files commonly associated with COM extension changed to that of executable files. This convention was later carried over to DOS. Even when complemented by the more general EXE file format for executables, the compact COM files remained viable and frequently used under DOS.
IBMBIO.COM is a system file in many DOS operating systems. It contains the system initialization code and all built-in device drivers. It also loads the DOS kernel (IBMDOS.COM) and optional pre-loadable system components, displays boot menus, processes configuration files and launches the shell.
Virtual DOS machines (VDM) refer to a technology that allows running 16-bit/32-bit DOS and 16-bit Windows programs when there is already another operating system running and controlling the hardware.
Relocation is the process of assigning load addresses for position-dependent code and data of a program and adjusting the code and data to reflect the assigned addresses. Prior to the advent of multiprocess systems, and still in many embedded systems, the addresses for objects are absolute starting at a known location, often zero. Since multiprocessing systems dynamically link and switch between programs it became necessary to be able to relocate objects using position-independent code. A linker usually performs relocation in conjunction with symbol resolution, the process of searching files and libraries to replace symbolic references or names of libraries with actual usable addresses in memory before running a program.
A source-to-source translator, source-to-source compiler, transcompiler, or transpiler is a type of translator that takes the source code of a program written in a programming language as its input and produces an equivalent source code in the same or a different programming language. A source-to-source translator converts between programming languages that operate at approximately the same level of abstraction, while a traditional compiler translates from a higher level programming language to a lower level programming language. For example, a source-to-source translator may perform a translation of a program from Python to JavaScript, while a traditional compiler translates from a language like C to assembly or Java to bytecode. An automatic parallelizing compiler will frequently take in a high level language program as an input and then transform the code and annotate it with parallel code annotations or language constructs.
MSX-DOS is a discontinued disk operating system developed by Microsoft's Japan subsidiary for the 8-bit home computer standard MSX, and is a cross between MS-DOS v1.25 and CP/M-80 v2.2.
A volume boot record (VBR) is a type of boot sector introduced by the IBM Personal Computer. It may be found on a partitioned data storage device, such as a hard disk, or an unpartitioned device, such as a floppy disk, and contains machine code for bootstrapping programs stored in other parts of the device. On non-partitioned storage devices, it is the first sector of the device. On partitioned devices, it is the first sector of an individual partition on the device, with the first sector of the entire device being a Master Boot Record (MBR) containing the partition table.
.sys is a filename extension used in MS-DOS applications and Microsoft Windows operating systems. They are system files that contain device drivers or hardware configurations for the system.
In computer programming, a self-relocating program is a program that relocates its own address-dependent instructions and data when run, and is therefore capable of being loaded into memory at any address. In many cases, self-relocating code is also a form of self-modifying code.
MS-DOS is an operating system for x86-based personal computers mostly developed by Microsoft. Collectively, MS-DOS, its rebranding as IBM PC DOS, and a few operating systems attempting to be compatible with MS-DOS, are sometimes referred to as "DOS". MS-DOS was the main operating system for IBM PC compatibles during the 1980s, from which point it was gradually superseded by operating systems offering a graphical user interface (GUI), in various generations of the graphical Microsoft Windows operating system.
DOS is a family of disk-based operating systems for IBM PC compatible computers. The DOS family primarily consists of IBM PC DOS and a rebranded version, Microsoft's MS-DOS, both of which were introduced in 1981. Later compatible systems from other manufacturers include DR-DOS (1988), ROM-DOS (1989), PTS-DOS (1993), and FreeDOS (1998). MS-DOS dominated the IBM PC compatible market between 1981 and 1995.
The FAT file system is a file system used on MS-DOS and Windows 9x family of operating systems. It continues to be used on mobile devices and embedded systems, and thus is a well suited file system for data exchange between computers and devices of almost any type and age from 1981 through the present.
[…] DOS protection feature […] The idea is based on the utilities in Simeon Cran's MYZ80 emulator; the DOS-protection header in those goes one better by not changing any Z80 registers. The magic sequence is EB 52 EB: […] XCHG […] MOV D,D […] XCHG […] but that means the DOS code ends up quite a way away from the start of the program. […] More fun can be had with self-extract PMArc archives. Start one with […] defb 0EBh, 018h, '-pms-' […] and it's treated as a valid archive by the PMA utilities, sends 8086 processors to 011Ah, and Z80 processors to 0130h. […]
[…] byte sequence […] EB 03 C3 yy xx […] If you create a .COM file with those 5 bytes as the first ones […] you'll see 'JMP SHORT 3', followed by 3 garbage bytes. […] If you look at a Z80 disassembly […] that translates to 'EX DE,HL; INC BC;' […] The 3rd byte is 'JUMP' followed by the 16-bit address specified as yy xx […] you'll have a .COM file that runs on MS-DOS and […] CP/M […](NB. While the author speaks about the Z80, this sequence also works on the 8080 and compatible processors.)
[…] FATBIN 1.00 - combine a CP/M .COM file and a DOS .COM file to create one which runs on both platforms. […] It was used to create: […] MSODBALL 2.05 - convert floppy discs between Amstrad 706k format and a DOS 706k format. […] Both the programs run under CP/M-80 and DOS. […]
[…] DSKWRITE.Z80 contains source for the CP/M version. […] DSKWRITE.ASM contains source for the DOS version. […] To get the single .COM file, you need to use FBMAKE: […](NB. Mentions FBMAKE from the FATBNSEA.COM package.)
[…] Self-extracting archives are .COM files containing a number of smaller files. When you run one, it will create its smaller files […] The self-extract archive programs will run under DOS (2 or later) or CP/M, with identical effects. To extract them under Unix, you can use ZXCC […] FATBNSEA.COM […] FATBIN combines a CP/M-80 .COM file and a DOS .COM file to produce one that will work on both systems. […] M3C4SEA.COM […] M3CONV version 4 - converts Spectrum snapshots in the .Z80 or .SNA format to or from Multiface 3 format (Multiface 3 -> Z80 only on a PC). […] PMSFX21X.COM […] PMSFX is the program that was used to generate these self-unpacking archives. This version (2.11) can generate archives which unpack themselves under CP/M or DOS. You will need PMARC to use PMSFX. New: Under DOS, it supports exact file sizes. […] SP2BMSEA.COM […] Converts a Stop Press Canvas file to a Windows .BMP […]
[…] I've written a version of PMSFX that produces .COM files unpackable under DOS and CP/M (the first three bytes are both legal Z80 code, legal 8086 code and legal PMA header) […] as a self-extracting archive. […]
[…] The reason to suspect such difference is that version 3.2x also supported CP/M-86 (the overlays are identical between DOS and CP/M-86, only the main executable is different) […] the .OVR files are 100% identical between DOS and CP/M-86, with a flag (clearly shown in the WordStar 3.20 manual) switching between them at runtime […] the OS interface in WordStar is quite narrow and well abstracted […] the WordStar 3.2x overlays are 100% identical between the DOS and CP/M-86 versions. There is a runtime switch which chooses between calling INT 21h (DOS) and INT E0h (CP/M-86). WS.COM is not the same between DOS and CP/M-86, although it's probably not very different either. […]
[…] FreeKEYB is […] a true .COM and .SYS driver (tiny model) in one. You can safely overwrite the first JMP, that's part of what I meant by "tricky header". […] you can replace the FFFFh:FFFFh by a 3-byte jump and a pending DB FFh. It works with MS-DOS, PC DOS, DR-DOS, and most probably any other DOS issue as well. […]
[…] Add a SYS device driver header to the driver, so that CTMOUSE could be both in one, a normal TSR and a device driver - similar to our FreeKEYB advanced keyboard driver. […] This is not really needed under DR DOS because INSTALL= is supported since DR DOS 3.41+ and DR DOS preserves the order of [D]CONFIG.SYS directives […] but it would […] improve the […] flexibility on MS-DOS/PC DOS systems, which […] always execute DEVICE= directives prior to any INSTALL= statements, regardless of their order in the file. […] software may require the mouse driver to be present as a device driver, as mouse drivers have always been device drivers back in the old times. These mouse drivers have had specific device driver names depending on which protocol they used ("PC$MOUSE" for Mouse Systems Mode for example), and some software may search for these drivers in order to find out the correct type of mouse to be used. […] Another advantage would be that device drivers usually consume less memory (no environment, no PSP) […] It's basically a tricky file header, a different code to parse the command line, a different entry point and exit line, and some segment magics to overcome the ORG 0 / ORG 100h difference. Self-loadhighing a device driver is a bit more tricky as you have to leave the driver header where it is and only relocate the remainder of the driver […]
Für ein zukünftiges Update für Calderas OpenDOS 7.01 habe ich den Startcode von IBMBIO.COM so modifiziert, daß er - falls fälschlicherweise als normales Programm gestartet - ohne Absturz zur Kommandozeile zurückkehrt. Wann diese Sicherheitsfunktion in die offizielle Version Einzug halten wird, ist jedoch noch nicht abzusehen.(NB. NWDOSTIP.TXT is a comprehensive work on Novell DOS 7 and OpenDOS 7.01, including the description of many undocumented features and internals. It is part of the author's yet larger
MPDOSTIP.ZIP
collection maintained up to 2001 and distributed on many sites at the time. The provided link points to a HTML-converted older version of the NWDOSTIP.TXT
file.) […] there was an opcode of "RST 0", which, if executed, would result in a warm boot. A file containing a Z3TXT module should never be executed, but at a cost of one byte we could protect ourself against that outside chance. The header also contained the string of characters "Z3TXT" followed by a null (0) byte. Many Z-System modules include such identifiers. In this category are resident command packages (RCPs), flow command packages (FCPs), and environment descriptor modules (Z3ENVs). Programs, such as Bridger Mitchell's […] JETLDR.COM, that load these modules from files into memory can use the ID string to validate the file, that is, to make sure that it is the kind of module that the user has stated it to be. User mistakes and damaged files can thus be detected. […] The header, thus, now stands as follows: […] rst […] db 'Z3TXT',0 ; null-terminated ID […] ; 12345678 ; must be 8 characters, […] db 'PROGNAME' ; pad with spaces […] ; 123 ; must be 3 characters […] db 'ENG' ; name of language […] dw LENGTH ; length of module […]
[…] The end of an ASCII file is denoted by a control-Z character (1AH) or a real end of file, returned by the CP/M read operation. Control-Z characters embedded within machine code files (e.g., COM files) are ignored, however, and the end of file condition returned by CP/M is used to terminate read operations. […](56 pages)
[…] CP/M marks the end of an ASCII file by placing a CONTROL-Z character in the file after the last data character. If the file contains an exact multiple of 128 characters, in which case adding the CONTROL-Z would waste 127 characters, CP/M does not do so. Use of the CONTROL-Z character as the end-of-file marker is possible because CONTROL-Z is seldom used as data in ASCII files. In a non-ASCII file, however, CONTROL-Z is just as likely to occur as any other character. Therefore, it cannot be used as the end-of-file marker. CP/M uses a different method to mark the end of a non-ASCII file. CP/M assumes it has reached the end of the file when it has read the last record (basic unit of disk space) allocated to the file. The disk directory entry for each file contains a list of the disk records allocated to that file. This method relies on the size of the file, rather than its content, to locate the end of the file. […]
[…] FreeKEYB builds the driver's runtime image at initialization time depending on the type of machine it is being loaded on, the type of keyboard, layout, country and code page used, the type of mouse and video adapter(s) installed, the other drivers loaded on that system, the operating system and the load and relocation method(s) used, the individual features included, and the configuration options specified in the command line. Due to the large number of command line switches and options supported […] (around fifty switches […] with multiple possible settings) there is a high number of feature combinations with uncountable dependencies […] resulting in […] endless number of […] different target images. FreeKEYB's Dynamic Dead Code Elimination technique manages to resolve […] these […] dependencies and […] remove dead code and data […] is not restricted to […] include or exclude a somewhat limited number of modules or whole sub-routines and fix up some dispatch tables as in classical TSR programming, but […] works […] at […] byte level […] able to remove […] individual instructions in the middle of larger routines […] distributed all over the code to handle a particular case or support a specific feature […] special tools are used to analyze the code […] and create […] fixup tables […] automated […] using conditional defines […] to declare the various cases […] not only optional at assembly time but at initialization time […] without the […] overhead of having at least some amount of dead code left in the runtime image […] to keep track of all the dependencies between […] these conditionals, dynamically build and relocate the runtime image, fix up all the references between these small, changing, and moving binary parts […] still allowing to use the tiny .COM/.SYS style […] model […] is done at initialization time […]
[…] a […] unique feature […] we call dynamic dead code elimination, so you can at installation time […] specify which components of the driver you want and which you don't. This goes to an extent of dynamic loadable modularization and late linkage I have not seen under DOS so far. If you do not like the screen saver, macros, the calculator, or mouse support, or <almost anything else>, you can specify this at the command line, and FreeKEYB, while taking all the dependencies between the routines into account, will completely remove all the code fragments, which deal with that feature and are not necessary to provide the requested functionality, before the driver relocates the image into the target location and makes itself resident. […]
[…] brandneue[s] Feature, der dynamischen Dead-Code-Elimination, die die jeweils notwendigen Bestandteile des Treibers erst zum Installationszeitpunkt zusammenbastelt und reloziert, so daß keine ungenutzten Code- oder Datenbereiche mehr resident bleiben (z.B. wenn jemand ein bestimmtes FreeKEYB-Feature nicht benötigt). […]