DOS32 Version 3.0 beta Released on 10th March 1995 A 32 bit DOS extender package Copyright (C) 1994 Adam Seychell, All Rights Reserved. This document should explain everything about the DOS extender DOS32 V3.0 This program may only be of use to people who have some knowledge of assembly language, however, I'll try to make this document easy for the beginners. Anyone who is sick of programming with pathetic 64KB segments or can no longer stand the 640Kb barrier and wants to use the full power of their computer then use DOS32 for protected mode programming. AGREEMENT This program is free software only and may not be sold other than the cost of the disk or physical handling. You can redistribute it only in the same form as you have received it and all files must be left unmodified. The exception to this rule is if you choose to develop an application that requires the file DOS32.EXE then you may freely distribute it with the application. All programs and source code are distributed WITHOUT ANY WARRANTY and no responsibility will be accepted for damage of computer software and/or hardware. The DOS32 project has been developed entirely in my spare time and I've been working on it for about two years now. It's only fair for me to ask that any programs that use the DOS32 dos-extender must include full credit for it's use. Of course I have no control on what people do with it so I am just relying your honesty. So please, help support free software. Registering DOS32 This program is the unregistered version and operates identical to the registered version. The DOS32 dos-extender may be used without royalties or registration fees on non- profitable software only. That is, software in which the author of the application will not receive any money for it. Commercial use of the DOS32 dos-extender (i.e any software that is to be sold ) is not allowed on this beta version. Please wait until the final V3.0 is released for the rules on developing commercial software using DOS32. The Registration fee is US$35 and includes a copy of the complete source code to DOS32.EXE. The source code is about 170KB in size and may be compiled with either MASM (Microsoft Macro Assembler) or TASM (Turbo Assembler), it is also very well commented and so it should be easy to follow and learn from. Address all correspondence to the author at the following address; Adam Seychell 16 Avion Place Westmeadows, VIC. 3049 AUSTRALIA internet: s921880@minyos.xx.rmit.edu.au Please ensure you enclose your return address! If you wish to register then write out your cheque in the name of Adam Seychell. WHAT IS A DOS EXTENDER ? The 386 has been around since 1987 and to this day DOS is still running in real mode. Since nobody has bothered to design a protected mode DOS, programs called 'DOS extenders' were written. A DOS extender is basically a program that will switch the CPU into protected mode so that it can then execute a protected mode application under DOS. If you don't know the difference between real mode and protected mode then have a go at reading the file PMODE.DOC or better still get a proper book before reading to much further. I think that it is much easier to program in protected mode than in real mode ( 8086 architecture ) because you can use only one big segment for the entire application. You could say a DOS extender is a separate program that handles all the setting up needed for protected mode under DOS. You let the DOS extender worry about all of the protected mode initialising. So you write programs in plain and pure protected mode. Since DOS runs in real mode ( or V86 mode ) a protected mode program can no longer execute DOS calls directly. The DOS extender should have services that allow your protected mode program to call real mode code and will either enter V86 mode or return to real mode when doing so. Usually a DOS extender has many more services than just real mode calls. For example, setting interrupt vectors, memory allocation, disk I/O routines and possibly a debugger. DOS32 Version 3.0 Introduction DOS32 V3.0 is a public domain 32bit DOS-extender package for the development of true 32bit DOS executable. The actual extender is a real mode DOS executable called DOS32.EXE. This tiny 7K file is the heart of the hole package. DOS32.EXE will load and execute a custom 32bit executable. To make one of these 32bit executable you must use the linker, DLINK which is distributed in this package. My main aims when developing DOS32 was to make a DOS- extender that is very easy to use, has powerful features and small in size. I have also tried to make the extender as close as possible to programming under conventional real mode DOS, and yet have full 32bit power. This should make it easier for people to start programming in protected mode. The debugger that is distributed with DOS32 should also help you become more familiar with the workings of protected mode. I have released my work so people can stop programming in a 8086 architecture, a CPU produced back in 1978. What is DLINK? The program DLINK is a linker supporting the Intel standard Object Module Format (OMF). DLINK is distributed with the DOS32 package and is required to produce the customary executable file that's used by the DOS32 dos-extender. This means you will need both DOS32.EXE and DLINK.EXE to make a protected mode application. The main difference between DLINK and a conventional DOS linker such as Borland Turbo Linker (TLINK.EXE) or Microsoft Link (LINK.EXE), is that DLINK is produces a special 32bit executable format made specifically for flat memory model programs. When DLINK is ran it will begin processing the OBJ files specified on the command line. The information inside these OBJ files (object modules) is then used to create the executable file of your application, and may simply be executed under DOS. Here are some of DOS32 main features * Complies with the following specifications; Dos Protected Mode Interface ( DPMI v0.9 ) Virtual Control Program Interface ( VCPI v1.0 ) Extended Memory Specification ( XMS v2.0 and v3.0 ) Int 15h Top-Down extended memory management * Unlimited executable size. * Supports up to 4Gb of RAM * Paged memory enabling true flat memory. * Functions for allocating/freeing memory and DMA buffers * Contains a complete set of 32bit DOS file I/O services ( open/close/create/read/write/chdir/rename, ect) * Services for interfacing to Real Mode programs * Capable of terminating and staying resident. * Uses only 40K total memory. * Only 7837 bytes of disk space * Distributed with a debugger and it's own 'smart' linker. Not so great features * Can run with zero extended memory * Handles all errors during initialising * Load time selector fixups in executable. * DOS32 can be integrated in the main .EXE file * Runtime termination for CPU exceptions 0,1,3,6,13 & 14 * Uses VCPI if available even when a DPMI server is present * No overhead on hardware interrupts (expect under DPMI) * Detects VCPI even with Microsoft's EMM386.EXE NOEMS * Hooks XMS driver to stop disabling of the A20 gate. * Hooks INT 23h for correct (Ctrl+C) terminatation * Not a single 4KB block is wasted on the machine * Fast starting and exiting. Less than 0.2 sec on a 386SX16 * Stops DOS32 trying to be loaded into upper memory because the system resets when doing so. * Guards from returning to protected mode from a real mode switch when under a XMS or raw systems and the 386 is in V86 mode. DOS32 MANAGEMENT This is the main section of this document and will explain the workings of DOS32. This is a flat memory model DOS extender. Flat memory means that the entire program is operating in one big block of linear memory. Or in other words there is only one big segment, 4GByte big. There is still a data and code segment but they have the same base addresses so effectively there is no difference. This allows you to mix data variables and code in any place you wish. Also, as the segment limits are 4GB in size it means that the entire CPU address space can be accessed with a single 32bit offset. That means there is no need for your programs to ever again use multiple segment registers. These are the reasons why I wrote DOS32. In protected mode the segments are defined by descriptors in the CPU desctriptor tables. If you are unfamiliar with descriptors and segments then have a go at reading the files PMODE.DOC and PMODE2.DOC. These files will explain some basics of protected mode operation. DOS32 sets up three descriptors for the application, one code segment and two data segments. The code segment and one of the data segments have equal base addresses and are used for the entire applications code and data. Since these two segments are on top of each other in memory I will call them the program segment. The base address of the program segment (or if you like, the programs code and data segments) can be obtained from function AX=EE02h INT 31h. The other data segment has a fixed base address of zero and may be used to access physical addresses such as video memory, BIOS data area, ect. Most of the time the application may never need to use this data segment because the entire CPU address space can already be accessed from a 32bit offset. The selector value for this zero based data segment can be obtained from function AX=EE00h INT 31h ( see API.DOC ). So basically there are three different descriptors (segments) available to your program, all have limits of 4GB. 1) data segment 2) code segment 3) zero base data segment Please note that the first 1 MB of linear address space is mapped to physical address space. This means that for locations 0..100000h the linear address equals the physical address. This allows you to access physical address in the lower 1 MB. Remembering that the Linear Address = Offset + Segment Base Address. So the offset in the program segment to access the physical memory is; offset = Physical address in first MByte - Base address of segment. You can also use the zero based segment to access the physical memory. In this case if the offset is below 1MB then the Offset = linear = physical. You will probably only need physical memory locations for the video memory at 0A0000h - 0BFFFFh. If your program dos not need the zero base segment then you can ignore this selector value and keep all of the segment registers ( DS,ES,FS,GS,SS ) loaded with the program data selector. This is what makes protected mode so powerful, you can access all of your data,code, video memory or whatever just by using the 32bit offset. If you are still not clear on what I am saying here then try having a look the example files. When the application is first started at the program entry point all *data* segment registers (DS,ES,SS,FS & GS) will be equal to the programs data selector and interrupts will be enabled. The code segment register, CS, will of course be equal to the programs code selector. The DOS32 A.P.I The DOS32 extender supplies many useful services for the application. The complete list of each service and programming details are described in the file API.DOC. I've put all the API documentation in a separate file so it may be printed as a handy reference. Format of the executable and loading process. The information here will explain how DOS32 and DLINK work together and exactly what happens when the executable is first ran from DOS to when the application's first instruction is executed. Please note that it is not essential for you to know these details but will be described here for those of you who are interested. Format of a DOS32 executable (.EXE) produced by DLINK. Offset Size Description ---------------------------------------------------- 0 n A stub loader or DOS32.EXE of n bytes n+0 4 Signature "Adam" n+4 2 DLINK version (BCD format) n+6 2 Minimum DOS32 version required (BCD) n+8 4 Number of bytes remaining after the stub n+0Ch 4 Start of executable image after the stub n+10h 4 Length of executable image ( see below ). n+14h 4 Minimum memory required for application. n+18h 4 Initial EIP n+1Ch 4 Initial ESP n+20h 4 Number of entries in selector fixup table. Each entry in the table contains a 32bit offset relative to the start of the executable image of a WORD that must be set to the programs data selector at load time. The table immediately follows the executable image. ------ more entries can be added in future ------------- At the front of the .EXE is the stub loader or DOS32.EXE file and must be a normal DOS executable ( i.e start with a 'MZ' signature ). When the .EXE is executed, DOS will only load and execute the 'MZ' executable at the front of the file and ignore the rest of the file. The stub loader is a small program that will simply execute DOS32.EXE. I have distributed a sample stub loader, STUB.ASM. This actual program is stored internally in DLINK and is automatically used as the stub if the -S option is not used ( see 'Using DLINK' on how to use the -S switch ). When the program DOS32.EXE is executed it will first initialise for protected mode and try an load in the 32bit application. It does this by first checking at the end of the it's self for the 'Adam' signature. If found it will then assume that it is a DOS32 32bit executable and will begin to load it into memory. If no 'Adam' signature was found it will then look at parent program which had executed DOS32.EXE. If the parent program has the 'Adam' signature then it will begin loading the executing the DOS32 executable. If the parent does not contain the signature then the following error will be displayed. DOS32 Version 3.0 beta 32bit DOS-extender and loader Copyright (c) Adam Seychell, 1994. All rights reserved. File name: C:\DOS32.EXE Error: Bad DOS32 executable With this set up it allows DOS32.EXE to be used in place of the stub loader. If a stub loader is used, and the user runs the .EXE, the stub file will be executed which in turn will execute DOS32.EXE. DOS32 will then begin it's work, by first initialising for protected mode operation and allocate a memory block for the application. The executable image is then loaded into the memory block. Finally the stack pointer (SS:ESP) and instruction pointer (CS:EIP) are set to start the application up and running. PROGRAMMING The section explains, in general, on how to write protected mode applications. It will explain about the initial stack, entry point, selectors, segments definitions and examples of basic ASM file structure. Segment Definitions There may be some confusion with segments defined in the ASM file to the protected mode CPU segments. In real mode if you declared a segment that is not grouped to the main segment then a segment register must be loaded with the segment value if any data/code is to access it. For example, if the application had more than 64KB of code then multiple code segments would need to be defined and far calls would be required to call across the segments. The CPU segment registers have to be altered each time a the CPU accessed a new segment. In a flat memory things work completely different. Segments defined in the ASM file (or in modules from a C compiler) have nothing to do with segments defined in the CPU descriptor tables. As described earlier, flat memory is when only one segment in memory exists for the entire application. Segments defined in the ASM file are like segments or sections within the actual program segment in memory. The object modules ( OBJ files) contain information of all the segments that have been defined in the source code. The linker will place all the code/data from a particular segment name and group it into one section in the program segment in memory. For example, all data/code that has been defined in the segments named 'blabla' will be grouped to together and stored in the executable. The Object Module Format ( format of OBJ files ) are capable of containing all sorts of information about a segment definition. Some of these include public or private, Alignment in memory and Group definitions. However for flat memory most of them can be ignored. Rules on how DLINK handles segments. * DLINK can support up to 100 segment definitions. * Each segment is automatically made public. The public field in the segment definition is ignored. * Each segment is aligned on a eight byte boundary. The alignment field in the segment definition is ignored. * The occurrence of each segment definition in the executable will be same order as they are defined in the object modules. * Each segment will automatically be grouped together. The assembler GROUP directive is ignored. * The code and data defined in segments of the same name will be next to each other in the executable. It is possible to define data in a segment that is not initialised. In this case the actual segment size greater than the total size of code and data that is defined in it. In assembler, non-initialised data can be defined with the ? operator. The following examples will define a 1Kb array of data that is not initialised to any value. My_Array DB 1024 DUP (?) ; Assembly language char My_Array[1024]; /* C language */ The thing about non-initialised data is that it does not matter what information it contains when the application is loaded. Therefore if the end of the executable contains data that is not to be initialised then there is no need for it to be loaded into memory or stored in the .EXE file. DLINK takes advantage this and will not include any non- initialised data in the executable file which has been declared at the end of the program segment. This is how the initial stack area is set up. A segment is defined with an array and the stack pointer will point to the last dword of the segment. Defining the initial stack When the program is first loaded the initial stack area is defined by the last segment with it's class name equal to 'STACK'. The initial value of ESP will point to the last dword of this segment. Make sure ESP is on a 4 byte boundary or else your program will run slower. This is because in 32bit mode, the stack transfers in double words and the CPU takes several extra clocks for every misaligned memory reference. Please also note that DOS32 should have a stack size of 128 bytes to play with. Add to this what ever stack your program is going to use. Example: To define a 128Kb stack My_Stack SEGMENT 'STACK' DB 20000h DUP (?) My_Stack ENDS If you are using the assembler quick segment definitions ( e.g .model .code .data .stack ) then the stack may be defined with the .STACK [size] assembler directive. Example: To define a 128Kb stack .386 .MODEL FLAT .STACK 20000h Defining the program entry point The entry point of the program is defined exactly the same way as writing a conventional assembler program. The start address will equal to the label at the assembler END directive. For example, the following code shows how to identify a program's starting instruction with the label 'start'. .CODE ; define code segment using ; quick segment definitions. start: .. .. .. END start Please note that the start address will only be set to the first module to contain a start address. Starting addresses defined in following modules will be ignored and the linker will report with a warning message. The program must terminate with INT 21h AH=4Ch, just like in good old DOS. Reading the program data selector In a real mode program the segment value could be obtained by referencing a segment name. E.G MOV AX,_TEXT will load AX with the real mode segment value of the _TEXT segment. In protected mode only selectors are used so loading AX with a real mode segment value is useless not to mention impossible if it's above 1MB. Whenever a segment name is referenced (like in the above instruction ) the value of the programs data selector is read. It does not matter what segment name or group definition is referenced, the value read will *allways* be the programs data selector. This feature is handy for interrupt handlers as the program data selector may be required. For example, the following code will set both DS and FS segment registers to the programs data selector. First_Seg SEGMENT First_Seg ENDS The_Seg SEGMENT mov ax,The_Seg mov ds,ax mov ax,First_Seg mov fs,ax The_Seg ENDS USING THE LINKER Since the DOS32 package is mainly for assembly language programming I will assume you are familiar and have used a conventional linker before. Remember DLINK has been designed specifically for flat memory model programs so there is no need to worry about all the modules and segments combining to produce one large executable. If you wish to stop DLINK while it is linking then press the CTRL+BREAK keys. DLINK should stop what it's doing and return to the DOS prompt. DLINK is controlled entirely by the command line so you will need to know what each command line switch does. The format of the command line is; DLINK [@ResponceFiles] OBJ file list [, EXE file] The OBJ file list is a list of the Object Modules that DLINK is required to link. Each file name is separated by spaces. If executable file name is not specified then it will be equal to the name of the first file in the OBJ file list. The default file name extension of the Object Module file list and executable file is .OBJ and .EXE respectively. DLINK will also accept command line response files. The response file is a text file containing the input DLINK expects on the command line and has the exact same format as the Turbo linker (TLINK.EXE) or the Microsoft linker (LINK.EXE) response files. The response file can be used to overcome the 128 character limit of the command line or is sometimes used by compiler make utilities. DLINK Options The linker options can go anywhere on the command line and must start with - or / characters. Below is a description of each option. Option Description @xx Where xx is the file name of a response file. Multiple response files are allowed and can be placed anywhere on the command line. /v Verbose linking information. This will display all sorts ofinformation that the linker is currently processing. /c Case sensitive symbol matching. All external symbols that are to be matched with public symbols in other object modules will be compared case sensitive. When this switch is not used, matching is case insensitive. /Sx Use alternate stub file x. The stub loader which is placed at the front of the executable file will be the file x. If no file extension is specified the extension '.EXE' will be used. E.G dlink -Sdos32 ,will use the file dos32.exe as the stub loader. THE DEBUGGER This DOS extender comes with a complete debugger for the debugging your 32bit protected mode programs. The whole debugger is the file DEBUG.OBJ and must be to be linked in with the program that you wish to debug. The debugger is started by executing a near call to the external procedure named "debug" or "debug_run". The debugging will immediately begin after this call. You have probably already ran the debugger example program, EG10.EXE. You will find that it's similar to a conventional debugger except it's for 32bit protected mode. The debugger will not debug when in V86 mode or in real mode. If your program calls real mode (or V86) then debugger will be disabled until it returns to the program in protected mode. The main feature of the debugger is single-stepping. Single-stepping allows the user to execute one instruction at time and able to see the values of each register. There are two types of stepping available. Pressing the F7 key will step on every instruction except for INT xx. Pressing F8 will step on all instructions except for CALL, INT xx, LOOP and instructions with the REP prefix. For these instructions that are not stepped through, the debugger will begin normal execution of the instruction and return back to debugging mode on the following instruction. When stepping through, the debugger saves the value of each register. The debugger has back stepping feature, which allows the user to load every register to the same values as in the previous step. The back stepping keys are ALT+F4 and can only go back up to 40 times. You can also insert breakpoints anywhere in the code simply by pressing F2. This will insert (or delete) an opcode 0CCh which is an single byte to cause an interrupt 3. You will see the instruction highlighted red. When the program is run ( F9 key ), it will stop at the breakpoint instruction and return to the debugger. You can also assemble your programs with an INT 3 instruction at a location you wish to break. For example, if you have a procedure that hangs your system, you could assemble the program with an INT 3 somewhere inside the procedure. The program may then simply be executed ( F9) and the debugger will take charge soon as the INT 3 is executed. Another feature of the debugger is toggling between the user screen and debuggers screen by ALT+F5. When switching to the users screens, the video mode, palette, cursor location, font memory, text mode screen memory, and all of the standard VGA registers are restored. Non standard VGA registers are not restored so you may have some problems in SVGA modes. The video memory is saved and restored when switching between the users screen and the debuggers screen. This video memory is saved in a 16KB block of allocated memory using the "Allocate_memory" service of DOS32. This means that if the program allocates all of the available memory before the debugger is started then there would not any available for the debuggers video buffers. It is recommended to start the debugger before the program attempts to allocate the entire available free memory. The debugger also has it's own keyboard handler. This means the debugger is independent of the BIOS's keyboard handler. Programs can grab IRQ 1 for their own keyboard handlers and do not need to be redirect back to the BIOS. At any time the program is running you may return to the debugger by pressing CTRL+BREAK. When stepping through certain instructions a temporary switch to the users screen is made. The instructions that will cause a video switch include, LOOP, INT xx ,CALL, REP prefix, and any access to the VGA ports. This makes sure that the VGA card is properly programmed while in the debugger. You may start the debugger by either calling the external procedure 'debug' and the debugger will immediately start. Another method of starting the debugger is to call the procedure 'debug_run'. This will only initialise the debugger and only start on any CPU exception or with CTRL+BREAK. Calling 'debug_run' is exactly the same as calling 'debug' and pressing the F9 key to continue executing. This debugger directly uses the 386's debug registers so don't try running it under DPMI. Windows DPMI seems to handle single-stepping and the software breakpoints, but it's not very reliable and OS/2 hangs with blank screen, yes OS/2 can crash. I have tried using the DPMI services for setting the debug registers but have not had much luck. In my next version I might add support for DPMI but at the moment I cannot be bothered with it. As it is DEBUG.ASM is already over 140KB of assembler...( yuck ) Advanced Debugging As well as software breakpoints ( opcode 0CCh) and single stepping, the 386 has a set of special debug registers. There are four breakpoint registers each of which hold a 32bit linear breakpoint address ( registers DR0..DR3 ). Another debug register ( DR7 ) sets the type of breakpoint for each of the four breakpoint addresses. There is also a debug status register ( DR6 ) which contains information for the exception 1 handler. See the Intel documentation for a complete description of the debug registers. The debuggers exception 1 handler will read DR6 to see what was the caused of the exception. If the exception was caused from one of the four breakpoint addresses then a message will be displayed on the screen telling you which breakpoint it was and if it was an instruction or data breakpoint. At any time the user can hold down the CONTROL key to display the values of the four linear breakpoint addresses and the W, R, and LEN fields from DR7. The debugger does not set any of the debug registers however the program that you are debugging can. Your program can load any of the breakpoint addresses and control fields (e.g. Ri,Ei,LENi & Gi ) and the debugger will report the breakpoint so you can then analyse the program. DOS32 NOTES DOS32 will run under a DPMI ( Dos Protected Mode Interface ) server if one is installed. DPMI is a bunch of services developed so that DOS programs can run in protected mode in a multitasking environment. Windows in enhanced mode and OS/2 supply a DPMI server when executing a DOS program. All of the services in DOS32 will work the same way wether it is using a DPMI server, VCPI server, XMS driver or plain raw DOS. The VCPI ( Virtual Program Control Interface) is what Expanded Memory Managers provide to allow dos extenders to switch into and protected mode. Any Expanded Memory Manager, for example EMM386.EXE, QEMM386.SYS, 386MAX, runs the CPU in V86 mode so that it can use the 386 paging hardware to swap expanded memory pages for DOS. If DOS32 is run when the CPU is already in V86 mode and there isn't a DPMI or VCPI server available then it will exit with a error message because there is no way for DOS32 to switch into protected mode. Exceptions ( with non DPMI systems ) DOS32 will handle the exceptions interrupts 0 to 31 by displaying a message on the screen of the type of exception, then it exits to DOS. Your program can hook any of these interrupts but it is usually not required. The allocate memory service will build page tables as the memory is allocated. This means that if you try to access memory that was not allocated you may end up with a page fault exception. When running under DPMI, all exceptions will be handled by the DPMI server. Hardware Interrupt Handlers All hardware interrupts IRQ's 0..15 can be hooked in protected mode by using the interrupt services. When you program starts DOS32 will handle all the IRQ interrupt vectors ( including the NMI ) so that they all will be redirected to the original real mode interrupts. For example, when ever you push a key it will be calling INT 9 in Real/V86 mode. IMPORTANT Never assume what will be in the segment registers in a hardware interrupt handler. You should always preserve the segment registers used and then load them with the desired selector. The interrupt handler may obtain the programs data selector by referencing any segment definiton name. This was explained before under 'Reading the program Data Selector'. The other important thing to remember is that when operating under a DPMI server ALL modified interrupt vectors (INTs 0 .. 255) should be returned to their original values before the application terminates. When under Raw/XMS or VCPI this is not necessary to do but should always be done for compatibility with DPMI. Oh I almost forgot, in protected mode you cannot write to the code segment otherwise it will cause the famous General Protection Exception. However reading data is allowed by using the program code selector. So a MOV CS:[0],EAX is a no no. bugs, bugs and more bugs A word about program bugs. Of course the more complicated a program is the more likely it's going to have bugs. This is by far the biggest assembler program I have ever written and so I am sure it will have a bug or two or three , ect. So I would appreciate it if you would contact me on finding any bugs. A program like DOS32 or any DOS extender fiddles a lot around with drivers and hardware, which means compatibility problems across the hundreds of different IBM compatible computers available. I don't have access to very many different types of PCs so it is hard for me to find these bugs. Of course it works flawlessly on my computer. The continuation of DOS32 I wrote this DOS extender for myself and have customised it to my preferences. If I get enough replies from people asking for extra features or changes to DOS32, then I might include these features in my next version. If there are lots of people who are interested in this DOS extender, it may end up becoming a big project. If there are people who are willing to improve DOS32 or help with libraries then we may even be able to get a team of people working on the project. Remember DOS32 is freeware so it's there for everyone to use. Anyone who is interested then please contact me! Future Versions of DLINK This is the first version of DLINK and is only capable of linking files of the Intel standard Object Module Format (.OBJ extension). In future versions of DLINK I plan on supporting the Microsoft MS-DOS Library Format (.LIB extension). I also would like to have DLINK support the object modules that are produced by the 32bit GNU C compiler. A feature I would really like DLINK to have is compression of the .EXE file. My knowledge of compression algorithms do not go mush further than the simple run-length encoding so I was unable to put this feature in the first version of DLINK. If any one would like to help me out on this one then, again, don't be afraid to call me. Known Problems and limitations * When under Raw/XMS systems and another application has been executed ( e.g using INT21h AH=4Bh ) which switches the 386 into V86 mode and the DOS32 application has hooked a protected mode IRQ or a real mode call back then this protected mode IRQ handler or Call Back procedure will not be called but rather a IRET or RETF will be executed. This avoids DOS32 trying to do a raw switch into protected mode while the 386 is already in control of another protected mode program and thus causing an exception to it. * When under raw/XMS/VCPI systems and the application has hooked interrupt vectors 13 or 14 (IRQs 5 or 6 ) then general exceptions and page faults will no longer be handled and may cause a triple fault ( CPU reset ) if one of these exceptions occur. * If the application has terminated and stayed resident and the system in under XMS and any IRQ other than IRQ 1 has been hooked then Windows cannot be loaded. This should not be too much of a problem since most people who use Windows are fools and run a EMS driver, thinking they are increasing available memory!. Limitations of DLINK Description Maximum limit -------------------------------------------------------------- Number of externals 1024 per module Number of publics - Number of object files 1024 Number of library files 256 Number of segments 100 Size of response file 6K Size of executable 4068 Mbytes Time to create a 500 byte executable 0.8 seconds Time to create a 1Mb executable 2.2 seconds Time to create a 16Mb executable 19 seconds Memory required to link approx 102Kbytes + total size of OBJs ( Tested on my computer which is a 386DX-33Mhz with 5MB RAM, 420Mb WD HDD in ISA Bus ) THE END After reading all this doc, I hope you have made at least some sense out of it. I know my english is not the best but you cant complain if your getting it for free. I am also probably missing some very important notes about DOS32. So all in all I think ( I hope ) that this DOS extender works out to be a very useful program all the programmers out there. If you are new to the 80x86 and what to jump straight into 32bit power (flat memory) without getting to involved with the 386's architecture then this DOS extender is probably what your after. For people who have only ever used real mode assembler I bet that they will be hooked to protected mode programming once got the hang of it. The way I see it, there is no reason why people should ever again write real mode assembler programs when they can use DOS32. Best of luck, and remember to support free software ! Adam Seychell. References used for the development of DOS32; 1 Ralf Brown Interrupt listings, Release 41, 6/5/1994 2 DPMI Specification, Version 0.9, 26 July 1990 3 VCPI Specification, Version 1.0, 12 June 1989 4 eXtended Memory Specification (XMS), Version 3.0, Microsoft Corporation, Lotus Development Corporation, Intel Corporation,and AST Research, Inc. January 1991. 5 Microprocessors Vol 1 & 2, Intel Corporation, 1993 6 "Undocumented DOS" 7 S.P.Morse, E.J.Isaacson and D.J.Albert, "The 80386/387 Architecture", Jhon Wiley & Sons, Inc. 1987 8 Microsoft Products Support Services Application Note (Text file) SS0288: Relocatable Object Module Format. Revision 5/92. 9 HelpPC, quick reference utility, David Jurgens, 1991 MASM & LINK are a trademark of Microsoft corporation. TASM & TLINK are a trademark of Borland International.