diff -uNr a/dos32a/ChangeLog b/dos32a/ChangeLog --- a/dos32a/ChangeLog false +++ b/dos32a/ChangeLog 805dfe2f1e4e5b312178e659424e80835770e13bdf2e958ae6d7a22e2434579ddde0f93ef162314aa8ffa5beaefba2ebe5a833d7d60c9bda34952eacf599f37e @@ -0,0 +1,769 @@ + ***************************************** + *** DOS/32A DOS Extender -- ChangeLog *** + ***************************************** + + +[2006-04-20] +DOS/32 Advanced DOS Extender, version 9.1.2 +=========================================== + +DOS Extender (DOS32A.EXE): +-------------------------- ++ Bugfix: Int 21h function 3Fh refused to return when reading from STDIN + (reported by Gianni Gallucci) + ++ Bugfix: in irq_fail fn, hardware exception #9 doesn't have exception code + (reported by Charles Hyde) + ++ applied mode.asm patch (also by Charles Hyde from Infineon) with minor + formatting changes; I'm rather ambivalent about implementing the others + into the mainstream builds (in particular the PAE one), will make those + available from the development (beta) page... + + + + + +[2005-12-12] +DOS/32 Advanced DOS Extender, version 9.1.1 +=========================================== + +DOS Extender (DOS32A.EXE): +-------------------------- ++ improved memory allocation under Clean system: INT 15h, AX=0E801h is used + if AX=0E820h fails (based on patch provided by Arthur Kalliokoski) + + + + + +[2005-11-08] +DOS/32 Advanced DOS Extender, version 9.1.0 +=========================================== + +DOS Extender (DOS32A.EXE): +-------------------------- ++ added support for SSE/SSE2/SSE3 capable processors + ++ added preliminary support for PE file format (recognized but not yet implemented) + ++ with verbose mode turned on the DOS Extender will pause prompting to press a key; + this gives a chance to read loader info before the app kicks in + ++ internal debugger has been dropped, CLIENT/debug.asm has been heavily rewritten + ++ INT 1 and INT 3 op-codes are now treated by DOS/32A as no-ops, this works around + some lame anti-debugging protections (Null-pointer protection works as expected) + ++ "VCPI/DPMI Detection Order" option has been removed, DOS/32A unconditionally + favours VCPI over DPMI, if and when possible + ++ "Internal Exception Control" option has been removed, DOS/32A is always in control + of the exception handling + ++ "Trap and Report Emulated IRQs" option has been removed, this simplifies IRQ + handling + ++ "Extended Memory Blocks Checking" option has been removed, DOS/32A unconditionally + checks EMB integrity + ++ DPMITST environment option is no longer supported; it is still recognized but is + now a no-op + ++ whenever possible, DOS/32A will favour INT 15h/XMS systems over VCPI/DPMI, + (thanks wd) + ++ INT 31h DPMI last function entry is cached so that subsequent calls with the same + function number do no search the lookup table + ++ INT 31h DPMI functions 0E00h & 0E01h no longer virtualize FPU EM & MP flags + ++ additional PIC constraint: slave PIC may not be mapped onto INT 8 + ++ slightly reduced run-time complexity of the IRQ handling code + ++ exception handlers are now invoked with the correct stack frame (as mandated + by DPMI v0.9 spec) + ++ all the exception vectors are now hooked under external DPMI (symmetric with + built-in DPMI and using the same exception handlers) + + +SUNSYS Setup Utility (SS.EXE): +------------------------------ ++ the following options in the Kernel menu have been deprecated: + + "VCPI/DPMI Detection Order" + "Internal Exception Control" + "Trap and Report Emulated IRQs" + "Extended Memory Blocks Checking" + + it is still possible to toggle the state of these options, but the changes have + no effect on the DOS Extender + + +SUNSYS Debugger (SD.EXE): +------------------------- ++ R.I.P. + + + + + +[2005-05-19] +DOS/32 Advanced DOS Extender, version 7.35 +========================================== + +DOS Extender (DOS32A.EXE): +-------------------------- ++ mouse callback code cleanup ++ allocation of up to 2Gig under Clean system (Int 15h, AX=E820h) ++ with verbose mode active and not under external DPMI the entry point + of application will trap to internal debugger + + + + + +[2005-01-12] +DOS/32 Advanced DOS Extender version 7.33 +========================================= + +DOS Extender (DOS32A.EXE): +-------------------------- ++ Bugfix: exec loader could crash the DOS Extender during startup in rare situations ++ Bugfix: DPMI function 0301h can not transfer data on stack to real mode procedure ++ Int 21h functions 4402h, 4403h, 4404h, 4405h, (DOS IOCTL) have been extended ++ Int 21h functions 3Fh & 40h (DOS IO) have been rewritten ++ mouse callback can now handle non-standard stack frames + + +SUNSYS Bind Utility (SB.EXE): +----------------------------- ++ Bugfix: minor binding problems with unbound LE/LX execs ++ removed check for DOS32A environment string + + +SUNSYS Compress Utility (SC.EXE): +--------------------------------- ++ removed check for DOS32A environment string + + +SUNSYS Setup Utility (SS.EXE): +------------------------------ ++ removed Lock and Version checks + + + + + +******************************************************************************* +Release 8 +DOS/32 Advanced DOS Extender version 7.1 +======================================== + +News: +----- ++ This release of DOS/32A is distributed under a new license. See "license.txt" + for more information. + ++ The complete source code of the DOS Extender and its tools is included with + this release. + +DOS Extender: +------------- ++ Fixed bug in DPMI function 0503h when in certain cases the contents of the + memory block being reallocated was not copied to the new location. + ++ Minor fix: DOS/32A environment configuration option /NOWARN can now accept + several warnings separated by a comma (eg /NOWARN:9003,9004). + +Other: +------ ++ Minor updates to the documentation manuals, mainly to reflect the new + licensing issues. + + + + + +******************************************************************************* +Service Pack 1 (Revision [C]) +DOS/32 Advanced DOS Extender version 7.0 +======================================== + +News: +----- ++ SVER Utility program. This utility can be used to find out the version + of DOS/32A, STUB/32A or STUB/32C and to display the OEM Information + appended to the LC-style executables by Original Equipment Vendors. + +DOS Extender: +------------- ++ Fixed problem in DOS/32A DPMI kernel causing the DOS Extender not being + able to properly callback the IRQs of the second PIC to the protected mode + handlers. + +SUNSYS Setup Utility: +--------------------- ++ Fixed minor problem when in Kernel Config window setting VCPI PhysTables + to 0 and switching to Hex mode caused the number to flash red incorrectly + indicating an errorneously enered value. + + + + + +******************************************************************************* +Release 7 +DOS/32 Advanced DOS Extender version 7.0 +======================================== + +News +---- ++ A new high performance D32A C/C++ Run-Time Library is now included with + DOS/32 Advanced DOS Extender. The Library is located in .\L32 directory + and its C/C++ header in .\H32 directory. + ++ The documentation manuals supplied with DOS/32 Advanced DOS Extender are + now in the HTML format. The plain-text based manuals have been dropped. To + view the new HTML based manuals use an internet browser (Netscape Navigator + is highly recommended although Explorer will also do fine), select "File -> + Open File" from the browser's menu and open "manual.htm" file located in the + .\DOCS directory. + +DOS Extender +------------ ++ Year 2000 compliance has been added for DOS/32 Advanced DOS Extender and + all of the utilities accompanying it. + ++ When running under _external_ DPMI host, DOS/32A will remove its own DPMI + Kernel from memory, thus freeing up up to 10KB of conventional DOS memory. + ++ Added exception handling under _external_ DPMI, DOS/32A will trap exceptions + #0, #6, #13 and #14 (ie the most common) and report the complete machine + state; DOS/32A will now also report where the exception came from by + specifying "KERNEL" for ADPMI Kernel, "CLIENT" for DOS/32A Client, "APP/32" + for the currently running application and "APP/??" if exception's origin is + unknown. + ++ Added support for "Performance Counters" which monitor the number of mode + switches for INTs, IRQs, and Callbacks; a new Extended DPMI API function + (AX=0A00h, then AL=09h) provides access to these. + ++ Added support for protected mode TSRs installed with INT 21h, AH=31h + function; contents of DX register passed to this function are ignored + when called from protected mode. + ++ Added new warning (9006): "incompatible version of DOS/32A already running" + issued when the parent and the child applications are running under + different versions of DOS/32A (when spawn() programs). + ++ Added new environment option "/NOWARN:xxxx" to disable particular warnings, + ie /NOWARN:9003. + ++ Added new environment option "/NOC" to disable explictly the copyright + banner. The warnings are still displayed on the screen. + ++ Increased the maximum of loadable Objects from 32 to 64 per application. + ++ Improved CTRL-C and CTRL-Break handling in the DOS Extender's Client code, + which solves problems with these key combinations not properly detected when + running under some external DPMI hosts (in particular Windows). + ++ Improved Interrupt switching algorithm in DOS/32A DPMI Kernel, also improved + algorithm enabling A20 gate when running in Clean system. + ++ Improved error checking in Extended DOS functions 0FF95h and 0FF97h: they + will now fail calls that allocate 0 bytes or >1MB. + ++ Improved support for VCPI system software; fixed bug in VCPI initialization + code which caused the DOS Extender's kernel to fail to free all the + allocated PageTables on exit in some situations. You are now also allowed to + set VCPI PhysTables value to zero to save some conventional memory if not + using physical memory mapping DPMI functions 0800h and 0801h. + ++ Minor fix: DPMI function 0001h (Free Selector) will now fail any calls that + try to free the current CS (Kernel) or SS (App. stack) selectors. + ++ Minor fix: Extended DOS function 4Ch (Terminate) will release ZERO selector + before exiting to DOS. + ++ Minor improvements in the LC-style file format loader: uncompressed Objects + are loaded slightly faster. + ++ Fixed bug in Extended DOS function AH=40h (Write to file) when DOS/32A would + crash when running under external DPMI and writing to disk with no free + space left. + ++ Fixed bug in DOS/32 Advanced environment configuration reading functions, + when the DOS Extender would sometimes at startup take off into "hyperspace" + reading the whole environment, instead of just one line (DOS32A=...). + ++ Removed check for invalid limits in DPMI function 0008h; DOS/32A will now + unconditionally perform auto-correction of selector's limit if it is out + of range. + ++ Removed support for bottom-up allocation scheme when running under Clean + (INT 15h) system software. Instead improved support for top-down allocation + scheme which yields better performance and more extended memory. + ++ Reduced the default number of Page Tables reserved for physical memory + mapping from 4 down to 2 (eq 8MB). + ++ Reduced the default size of DOS Transfer Buffer from 16KB down to 8KB, does + not affect disk I/O performance but brings the memory requirements down. + +SUNSYS Bind Utility: +-------------------- ++ Fixed all known problems. + ++ Added support for OEM title information for LC-style execs. + ++ Otherwise no major changes visible to the user. + +SUNSYS Compress Utility: +------------------------ ++ Fixed all known problems. + ++ Improved (rewritten) "Advanced Preprocessing" algorithm. + ++ Added support for OEM title information for LC-style execs. + ++ Otherwise no major changes visible to the user. + +SUNSYS Setup Utility: +--------------------- ++ Removed "Selector Invalid Limit Check" option. + ++ Otherwise no major changes visible to the user. + +SUNSYS Debugger: +---------------- ++ No major changes. + + + + + +******************************************************************************* +Release 6 +DOS/32 Advanced DOS Extender version 6.00 +========================================= + +News +---- ++ New SUNSYS Compress Utility program which allows compression of LE- and + LX-style Linear Executables into the new LC-style Linear Compressed file + format (see "sc.txt" help file located in .\DOCS directory). + ++ Configurable stub file STUB/32C which can be configured by SUNSYS Setup + Utility program, located in .\BINW directory and named "stub32c.exe". + +DOS Extender +------------ ++ Removed fatal error (0008): "configuration header corrupted", which was never + used unless the DOS Extender was linked incorrectly. + ++ Upon a crash (exception) in protected mode application the DOS Extender will + report the unrelocated crash address for _any_ Object, not the only one that + had entry point in it as it did before. + ++ DOS/32 Advanced now supports allocation of more than 64MB of memory without + using Virtual Memory. The maximum amount of memory the DOS Extender can + allocate is limited to 2GB when running under XMS and to 256MB under VCPI. + ++ Fixed problem with Verbose Mode when the DOS Extender would report the + incorrect size of DPMI memory when allocated >64MB. The DPMI memory size is + now reported in KB when below 64MB, and in MB when above. + ++ Added support for LC-style Linear Compressed protected mode executables. By + using SUNSYS Compress Utility the users can compress LE and LX applications + into the new LC file format. + ++ Added new run-time error (4007): "not enough DOS Transfer Buffer space to + load LC-exec" which is reported when loading Linear Compressed executables + and the size of DOS Transfer Buffer is set below 8KB. + ++ The Loader will skip allocation of selectors for subsequently loaded 32bit + Objects, and will make the application happy with only one 32bit CODE and + one 32bit DATA selectors respective. This will prevent wasting of selectors + in applications which contain more than two 32bit Objects. + ++ DPMI functions 0602h and 0603h are supported and will return with CF clear + without actually doing anything good. + +SUNSYS Bind Utility: +-------------------- ++ Added new commands and options "/BC", "/RC", "/BN", "/UN", "/Q", "/S" and + "/H" (or "/?"). Refer to "sb.txt" help file for more information. + +SUNSYS Compress Utility: +------------------------ ++ This one is new for this release. See "sc.txt" for help. + +SUNSYS Setup Utility: +--------------------- ++ Added support for configurable stubs, STUB/32C files. + ++ Added (actually documented) options "/INFO", "/LOCK", "/UNLOCK", "/QUIET", + "/SILENT" and "/H" (or "/?"). See "ss.txt" help file. + +SUNSYS Debugger: +---------------- ++ Minor changes, fixed mouse problem with some mouse drivers when the cursor + would disappear when moving it below the bottom of the screen. + + + + + +******************************************************************************* +Release 5 +DOS/32 Advanced DOS Extender version 5.00 +========================================= + +DOS Extender +------------ ++ Resolved problem with WATCOM Linker v11.0(a) when the DOS Extender was not + able to correctly recognize and load the LX-style executables. + ++ The DOS Extender now supports, and will correctly load Objects with the size + of zero. However, as such Objects will in most cases indicate an error in + the protected mode application (wlink dead code elimination should kill'em), + the DOS Extender will issue a new warning (9005) to inform the user about + this situation. + ++ The default size of the DOS Transfer Buffer is now 16KB instead of 64KB. + This not only reduced the DOS memory requirements, but also improved the + DOS Extender's disk I/O throughoutput. + ++ When showing information about Selectors in the exception report listing + the DOS Extender will no longer list the DPL of a Selector as it always + was equal to 0. Instead, DOS/32 Advanced will show a better explanation + of Selector's attributes (CODE/DATA and 16/32 bit). + ++ DPMI function 0008h, Set Segment Limit, will now report invalid limits as a + new run-time error (6006), which will result in application termination. You + can always turn off this feature, by using the SUNSYS Setup Utility. + ++ Fatal error (3005) will now report message "error in app exec" which means + that the application was corrupted or an error occurred at link time. + ++ With VERBOSE mode turned on the DOS Extender will now list the PSP_Sel, + Env_Sel and Env_Seg to provide additional information about PSP Selector, + Environment Selector and Environment real mode Segment allocated by the + DOS Extender for application. In addition, the DOS Extender will report + Process_ID and Module Name in the exception listing which can be useful + when spawning applications. + ++ Added new feature: "Start Full-Screen under Windows". DOS/32 Advanced will + switch the application to the full-screen mode when running under Windows in + a DOS-box window. Can be turned off (the default is off). + ++ Another new option in the DOS Extender: "Ignore DOS/4G API Extension Calls". + Documented in the "ss.txt" help file. Certain programs which otherwise use + DOS/4G API extensions can now be run under DOS/32 Advanced. + ++ The DOS Extender will now automatically deinstall the possibly installed + mouse ISR by issuing INT 33h with AX=000Ch and ES:EDI=0 on exit to DOS. + ++ New extended DOS functions 0FF94h..0FF97h are now supported for allocation + of DOS memory. These functions work in exactly the same way as functions + 0FF90h..0FF93h. Look into "Programmer's Reference" ("prog_ref.doc" file) + documentation for more information about those. + ++ The spawning techniques of DOS/32 Advanced have been greatly improved. The + required size of the "DOS Transfer Buffer" is now 1KB instead of 4KB when + using extended DOS function AH=4Bh to spawn. Read more about this in the + "Technical Reference" ("rech_ref.doc" file) documentation. + ++ Memory management ADPMI functions have been rewritten and now offer improved + performance and security. Allocated Extended Memory Blocks are now aligned + on Paragraph (16-byte) boundary and protection against EMB overwriting is + now 99% safe. + ++ Once again, DOS/32 Advanced DOS Extender requires no extended memory to load + and execute a protected mode program. The relocations are now loaded into + DOS memory first, only when not enough DOS memory, will they be loaded into + extended memory (a very rare situation). + ++ Fixed minor problem in DPMI functions 0800h/0801h when the last mapped page + was not marked as last. + ++ Fixed bug in extended DOS function AH=40h, Write to File, when truncation + of files (using ECX = 0) did not work as expected. + ++ Corrected DPMI function 050Ah, Get Base and Size of Memory Block. The base + reported now points to the actual address of memory block instead of block + header. + ++ Fixed problem with IRQ 7 which was not processed by DOS/32 Advanced built-in + DPMI correctly. + ++ Fixed a small problem when the DOS Extender could not load and execute the + "raw" LE/LX programs, ie applications not bound to any stub. + ++ The ADPMI function 0EEFFh now returns EAX with "D32A" ID-string instead of + "PMDW". This function has been pretty much standardized and can be used + for effective detection of the currently running DOS Extender. + ++ The Free Package version now supports DPMI functions 0800h and 0801h for + mapping of linear memory. + ++ Support for Win95 Long File Names has been included into this version of + DOS/32 Advanced. Look for information on these functions (INT 21h, AX=71xxh) + in the "Programmer's Reference" documentation ("prog_ref.doc" file). + +SUNSYS Setup Utility: +--------------------- ++ Two new options have been added: "Ignore DOS/4G API Extension Calls" in the + "Configure DOS/32A DPMI Kernel" menu, and "Start Full-Screen under Windows" + in the "Configure DOS/32A DOS Extender" menu. + ++ Several options have been renamed, and placed in a more proper (logical) + order. You really should not have problems with recognizing them though. + +SUNSYS Bind Utility: +-------------------- ++ Unbinding of LE/LX executables is now supported in the Free Package version. + +SUNSYS Debugger: +---------------- ++ Fully functional, except for the "System Interrupt History" which is + supported in the Pro version only. Otherwise no major changes. + + + + + +******************************************************************************* +Release 4 +DOS/32 Advanced DOS Extender version 4.30 +========================================= + +Install Program: +---------------- ++ The Install program will now automatically copy file "dos32a.lnk" into + WATCOM's BINW or BIN directory (depending on which version of WATCOM C/C++ + you have) if you select auto-system-update (which is strongly recommended). + ++ You can now install DOS/32 Advanced in any directory, not just "DRV:\DIR" as + it was before. You can install it for example in "C:\WATCOM\DOS32A" or + anything like that. + ++ File "dos4gw.exe" which was located in .\PCTEST directory has been removed + to reduce the size of Compressed Data File. + +DOS Extender: +------------- ++ Bug fixed in DPMI function 0500h when the reported information was written + to DS instead of ES selector (I know, I know...). + ++ The DOS Extender will now correctly recognize and execute all types of + DOS/4G(W) Professional bound applications. + ++ Mode switching routines have been optimized for Pentium MMX/II and AMD K6 + processors (or any CPU with multiple execution units supporting RISC86). + This does not really improve mode switching speed though. + ++ Bug fixed: the DOS Extender can now display decimal numbers greater than + 0x7FFF within strings containing "%d" option. + ++ DOS/32 Advanced now supports the "Verbose Mode". This one can be useful when + you need to know exactly what is going on while the DOS Extender is loading + your application, amount of allocated memory and so on. + ++ New environment option: /VERBOSE[:ON|OFF]. Refer to the "User's Reference" + ("user_ref.doc" file) documentation for more information. + ++ New "undocumented" DOS API function AX=Magic. This function is mentioned + somewhere in this package, but you will have to discover it yourself! + +SUNSYS Setup Utility: +--------------------- ++ The Setup Utility now supports new option: "Verbose Mode". + +SUNSYS Bind Utility: +-------------------- ++ The Bind Utility will now correctly recognize and process all types of + DOS/4G(W) Professional bound applications. + ++ Two new commands: "-BS", bind STUB/32A to a file, and "-RS" replace existing + stub with STUB/32A, now supported. + +SUNSYS Debugger: +---------------- ++ The Debugger will now correctly recognize and load all types of + DOS/4G(W) Professional bound applications. + ++ The Debugger shipped with the Free Package version of the DOS Extender now + supports all commands except "Here" (F4-key) and "Run" (F9-key). + + + + + +******************************************************************************* +Release 3 +DOS/32 Advanced DOS Extender version 4.00 +========================================= + +News: +----- ++ Installation program that installs DOS/32 Advanced DOS Extender on your + computer. + ++ New stub file, 538 bytes in size! + +DOS Extender: +------------- ++ DOS/32 Advanced DOS Extender does not check for 8086 anymore. This should not + be a problem since PC/XTs are quite dead nowdays. + ++ DOS API function AH=0Ah is no longer supported and has been removed. It is + not used in WATCOM libraries and nobody uses it anyway. + ++ Support for Slow Object Loading Scheme has been dropped. The DOS Extender + now requires some Extended memory in order to load application fixups, even + if the application itself is loaded in DOS memory. + ++ Error code (4004) has been changed: not enough extended memory to load + application fixups. + ++ Page Offset Shifts other than 0 are now supported by the loader for LX-style + executables. + ++ Fixed bug in startup code causing no errors being reported when protected + mode was not entered successfully. + ++ Fixed bug in exteded VBE API AX=4F00h when the CX register was not passed + down to the real mode. + ++ VBE API is now truly extended: function AX=4F00h now translates the pointers + returned in the VBE structure to protected mode values. + ++ New extended VBE functions have been added: AX=4F09h and AX=4F0Ah. + ++ Bug fixed: options /QUIET and /PRINT:OFF defined in the environment now + disable the copyright string (Pro version only) as well as warnings. + ++ Bug fixed: on exit under "Clean" system the DOS Extender will not disable + the A20 gate. This will solve problems when spawning programs with no + memory manager installed, but this will also produce a problem with A20 line + enabled after you run DOS/32 Advanced under "Clean" system. I guess we will + have to live with that, since there ain't many programs that rely on memory + wraparound under 1MB today, and you probably use a memory manager anyway. + ++ Fixed a little bug in DPMI API function AX=0300h when parameters pushed on + stack that were to be copied to the real mode stack were not being copied + properly. + ++ Bug fixed: extended DOS function AH=34h, get InDOS flag, will now work as + expected (no GPEs or crashes no more). + ++ Bug fixed: the loader was not able to correctly load the last object of the + protected mode application, especially when the application was linked with + debug info which was placed directly after the last object's data. An + incorrect amount of bytes was read causing the _BSS segment being trashed + while it should contain zeroes only (by default, WATCOM startup code will + clear only the first 4K of _BSS segment if it thinks it runs under DOS/4GW). + ++ Extended DOS API function AH=4Ch (terminate program), now will not restore + real mode environment segment in PSP at offset 002Ch to be compatible with + external DPMIs since they might need the protected mode selector at that + offset to perform their cleanup on the way to DOS,.. or some place else. + ++ Extended DOS API now supports new functions: AX=0FF8Ah, AX=0FF90h, AX=0FF91h, + ... and so on (see "prog_ref.doc" file). + +SUNSYS Setup Utility: +--------------------- ++ Option Use Fast Loading Object Scheme is no longer supported. + +SUNSYS Bind Utility: +-------------------- ++ No major changes. + +SUNSYS Debugger: +---------------- ++ No major changes. + + + + + +******************************************************************************* +Release 2 +DOS/32 Advanced DOS Extender version 3.00 +========================================= + +DOS Extender: +------------- ++ When a file name is specified at the command line, the DOS Extender will now + apply an ".exe" extension to it, if it could not open the original file. This + will solve some compatibility problems when replacing DOS/4GW DOS Extenders + with DOS/32 Advanced. + ++ The loader now supports Fast Object Loading Scheme. This feature allows the + DOS Extender to load protected mode applications much faster (as fast as + DOS/4GW does). Though it requires some extended memory to be allocated. Note + that if no extended memory was allocated by the DOS Extender at startup, + this feature will not be used, and the DOS Extender will automatically use + the old, slow Object Loading Scheme, rather than reporting an error. + ++ The loader now supports Paragraph (16 byte) alignment along with Page + alignment (4096 byte) for objects that are loaded into extended memory. + If a program has a large number of objects, this feature will greatly + increase the amount of free extended memory available after the application + was loaded. + ++ Invented new DOS function in the DOS Extender: AX=0FF89h - DOS/32 Advanced + Get Configuration Info (see "prog_ref.doc" file). + ++ Invented new DPMI API function (AX=0A00h): AL=06h - Get DOS/32 Advanced + Kernel Selectors (see "prog_ref.doc" file). + ++ When spawning DOS/32 Advanced from another (incompatible) DOS Extender + under VCPI, DOS/32 Advanced startup code will no longer cause the system + to crash. + ++ DPMI function 0500h will no longer return error 8013h when no extended + memory was allocated at startup. Instead it will simply fill all the + fields in the structure with zeroes. + ++ DPMI function 0500h will no longer return the incorrect size of the largest + available extended memory block as it did before in rare cases. + +SUNSYS Setup Utility: +--------------------- ++ Option Console Output has been replaced with two new options: Show Warnings + and Show Copyright Banner at Startup. + ++ New option in DOS Extender Configuration window: Use Fast Loading Object + Scheme. + ++ New option in DOS Extender Configuration window: Object Alignment when + Loaded High. + ++ New option in DOS Extender Configuration window: Show Copyright Banner at + Startup. This function replaces the old Console Output option, and allows + the user to separately disable warnings (with Show Warnings option) and + the copyright banner. + +SUNSYS Debugger: +---------------- ++ The Debugger now supports WATCOM-style assembly text screen along with + Borland's Turbo Debugger-style. Use key '1' to switch between TD and WD + text screens. + + + + + +******************************************************************************* +Release 1 +DOS/32 Advanced DOS Extender version 2.25 +========================================= + ++ The first publicly available version of DOS/32 Advanced DOS Extender. diff -uNr a/dos32a/LICENSE b/dos32a/LICENSE --- a/dos32a/LICENSE false +++ b/dos32a/LICENSE d82eaf75c9cf68f866ff7b565f4a4a6d74bd70299cf506cc2a79412ce6f0cf4f2ac72a9626a92db8b87d1132da2398e6dd17eecd4e2ed97f77e52601ab35b8b6 @@ -0,0 +1,39 @@ +DOS/32 Advanced DOS Extender Software License +============================================= + +Copyright (C) 1996-2006 by Narech K. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. The end-user documentation included with the redistribution, if any, +must include the following acknowledgment: + +"This product uses DOS/32 Advanced DOS Extender technology." + +Alternately, this acknowledgment may appear in the software itself, if +and wherever such third-party acknowledgments normally appear. + +4. Products derived from this software may not be called "DOS/32A" or +"DOS/32 Advanced". + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff -uNr a/dos32a/MANIFEST b/dos32a/MANIFEST --- a/dos32a/MANIFEST false +++ b/dos32a/MANIFEST 02d632e991f6d9f98083a9464c5078faa330d6ae45c483c27cd04ae9ac752237a9409dfa59ce131f61c824521d877fd551a6eb2c7924fb0ef22ebf6b31648ebe @@ -0,0 +1 @@ + 828710 dos32a-src "DOS/32 Advanced DOS Extender, version 9.1.2." diff -uNr a/dos32a/README b/dos32a/README --- a/dos32a/README false +++ b/dos32a/README d8eba3544618167de4e6c502efd69643db9b47fb96c9733e8f11ab03cf6634396d0b02e3784b1e3c449630a4516abf048d9e25f1bec3e347fd3a9c354f5b4dea @@ -0,0 +1,55 @@ +[2006-04-20] +DOS/32 Advanced DOS Extender, version 9.1.2 +Illis quorum meruere labores. + + +Contents: + 1.0 - Synopsis + 2.0 - System Requirements + 3.0 - Release Notes + 4.0 - FAQ + + + + +1.0 - Synopsis +============== +This is a DOS (Dead Operating System) Extender. It extends DOS. By how much +or for how long still remains a mystery. It lives in a refrigerator. It has +a wonderful ability to piss off one's dearest neighbors by sporadically +electrocuting their cats. Incidentally it also makes the farm sheep go bäää. + + + +2.0 - System Requirements +========================= +A puter and a pint of Guiness... Actually, you can replace puter with women. +Guiness, however, is mandatory. + + + +3.0 - Release Notes +=================== +Avril Lavigne rocks! Kent - ni är så j:a bra! Vitja Tsoy (Kino) - s ponikshej +golovoj, v tvoju pamjat'... + + + +4.0 - FAQ +========= +Q: What's new?! +A: Oh, not much. Just the same old shit wrapped up nicely in a new package. + +Q: I've found a bug, yippie! Now what? +A: Pin it on a wall. Alternatively send it in, I collect them! + +Q: WTF?! I can't build from your sources. +A: RTFM! Twice! Dumbass. Then download and install v7.1 SDK. + +Q: Eeeek! +A: Exactly! Ya said it, mate. + + +- his infinite evilness Narech "den livsfarlige" K. Over n' out! :=) + +[EOFF] diff -uNr a/dos32a/src/dos32a/dos32a.asm b/dos32a/src/dos32a/dos32a.asm --- a/dos32a/src/dos32a/dos32a.asm false +++ b/dos32a/src/dos32a/dos32a.asm a0373e242747f5cd54b18587f47445fdd236e769ea7be365307850e55e903622625c1375d0ceb763784f68f3554fd3682737c72e94e768d576d1c8552bf0444d @@ -0,0 +1,477 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +BUILDING_KERNEL = 0 +BUILDING_CLIENT = 1 + +;***************************************************************************** +; DOS/32 Advanced DOS Extender master Client file, implements program entry +; point and includes the necessary client files from .\TEXT\CLIENT\. +; +;***************************************************************************** + +STACKSIZE = 0080h ; size of stack (in para) +INTTABSIZE = 0040h ; size of copy of interrupt table (in para) + +_ID32 segment para public use16 'CODE0' +_ID32 ends +_KERNEL segment para public use16 'CODE1' +_KERNEL ends +_TEXT16 segment para public use16 'CODE2' +_TEXT16 ends +_STACK segment para stack use16 'STACK' +_STACK ends + +extrn pm32_info :far +extrn pm32_init :far +extrn pm32_data :byte + +include TEXT\include.asm + + + .386p + LOCALS + NOJUMPS +;============================================================================= +_ID32 segment para public use16 'CODE0' +_ID32_SIZE=16 ; size excluding 'ID32' signature +;----------------------------------------------------------------------------- +db 'ID32' ; ID signature +db 00111111b ; KERNEL misc. bits: + ; bit 0: **deprecated** + ; bit 1: **deprecated** + ; bit 2: 0=VCPI smart page alloc off, 1=on /1=def + ; bit 3: 0=VCPI+XMS alloc scheme off, 1=on /1=def + ; bit 4: **deprecated** + ; bit 5: **deprecated** + ; bit 6: reserved /0=def + ; bit 7: 0=ignore 4G extensions off, 1=on /0=def +db 64 ; Max. number of page tables under VCPI /256MB +db 2 ; Max. number of page tables mem_mapping /4MB +db 16 ; Max. number of real mode callbacks /16 +dw 256 ; Max. number of Selectors under VCPI/XMS/raw /256 +db 8 ; Real mode Stack nesting +db 8 ; Protected mode Stack nesting +dw 20h ; Real mode Stack length, (in para) +dw 20h ; Protected mode Stack length, (in para) +dd 0FFFFFFFFh ; Max. extended memory to allocate in bytes +;----------------------------------------------------------------------------- +db 00111111b ; DOS/32A misc. bits: + ; bit 0: 0=console output off, 1=on /1=def + ; bit 1: 0=sound generation off, 1=on /1=def + ; bit 2: 0=restore INT table off, 1=on /1=def + ; bit 3: 0=report modified INTs off, 1=on /1=def + ; bit 4: 0=load 16 in lowmem off, 1=on /1=def + ; bit 5: 0=force load 16 low off, 1=on /1=def + ; bit 6: 0=cls on exception off, 1=on /0=def + ; bit 7: 0=null-ptr protect off, 1=on /0=def +If EXEC_TYPE eq 0 +db 00001001b ; DOS/32A Pro second misc. bits +Else +db 10001001b ; DOS/32A Beta second misc. bits +Endif + ; bit 0: 0=config by enironment off, 1=on /1=def + ; bit 1: 0=focus on this VM off, 1=on /0=def + ; bit 2: 0=align objects on PARA, 1=PAGE /0=def + ; bit 3: 0=show copyright off, 1=on /1=def + ; bit 4: 0=verbose mode off, 1=on /0=def + ; bit 5: reserved /0=def + ; bit 6: 0=lock configuration off, 1=on /* + ; bit 7: 0=Professional, 1=Beta /* +dw 0200h ; DOS INT 21h buffer in low memory (in para) /8 KB +dw 090Ch ; Internal Version of DOS/32A: db low,high +dw 0000h ; Reserved (v7.0+) +;----------------------------------------------------------------------------- +include TEXT\oemtitle.asm +_ID32 ends + + + + + + + + + +;============================================================================= +_TEXT16 segment para public use16 'CODE2' + assume cs:_TEXT16, ds:_TEXT16 + org 0 + +@text16_beg label byte + +include TEXT\CLIENT\config.asm +include TEXT\CLIENT\strings.asm +include TEXT\CLIENT\misc.asm +include TEXT\CLIENT\debug.asm +include TEXT\CLIENT\int10h.asm +include TEXT\CLIENT\int21h.asm +include TEXT\CLIENT\int33h.asm +include loader.asm +include loadlc.asm +include loadpe.asm + + + .8086 + Align 4 + +start: push cs ; DS = CS + pop ds + mov _seg_ds,ds ; save SEG regs + mov _seg_es,es + mov _seg_ss,ss + mov ax,es:[002Ch] + mov _seg_env,ax + sti + cld + + call get_default_config ; configure using defaults + call get_environ_config ; configure using environment + call copyright ; show copyright message + mov ax,ss ; get end of program + mov si,es:[0002h] ; get free DOS memory (in para) + add ax,STACKSIZE+INTTABSIZE ; stacksize+inttable (in para) + mov _seg_buf,ax ; set base of INT 21h buffer segment + add ax,_lowmembuf ; +lowbuf (in para) + mov _membase,ax ; set base of memory for PMbuf + sub si,ax ; check if enough mem + jnc @@1 +@@err1: neg si + mov cl,6 + shr si,cl ; convert para to KB + mov ax,1001h + jmp report_error +@@err2: mov ax,1002h + jmp report_error + +@@1: sub ax,_seg_es ; (SS+STK+INT+DOS)-ES *NOTE*: no BUF + mov bx,ax ; resize DOS memory + mov ah,4Ah + int 21h + jc @@err2 + call far ptr pm32_info ; prepare and check for errors + jnc @@2 ; if error had occured, AX=error code + jmp report_error ; exit with error message +; +; No errors had occured, initialize kernel +; + .386p +@@2: mov wptr _buf_size,bx + mov wptr _cpu_type,cx + + call remove_kernel + + mov ax,_membase ; do second check for available memory + mov si,es:[0002h] ; (not really needed) + add ax,bx ; AX=base of free mem after PMbuf + sub si,ax + jc @@err1 + add bx,_membase ; resize DOS memory + sub bx,_seg_es ; (SS+STK+INT+DOS+BUF)-ES + mov ah,4Ah + int 21h + jc @@err2 + movzx eax,_seg_buf + mov edx,eax + sub ax,_seg_ds ; adjust for CS(sel):0000(offs) + shl edx,4 + shl eax,4 + mov _lobufbase,eax ; set INT 21h buf base relative to CS: + mov _lobufzero,edx ; set INT 21h buf base relative to 0 + movzx eax,_seg_ds + shl eax,4 + mov _seg_ds_base,eax ; set 32bit base of CS and DS segment + movzx eax,_lowmembuf + shl eax,4 + mov _lobufsize,eax ; set INT 21h buffer size in bytes + mov es,_membase + mov bx,_version + mov dx,offs critical_handler + call far ptr pm32_init ; enter Protected Mode + jc report_error + + cli + mov _sel_cs,cs ; save PM selectors + mov _sel_ds,ds + mov _sel_es,es + mov _sel_ss,ss + mov _sel_esp,esp + mov ax,es:[002Ch] + mov _sel_env,ax + mov _process_id,si + push di ecx + call init_system ; setup PM interrupts/buffers + call save_inttab ; now we can safely save inttab + call verbose_showsys + pop ecx di + sti + + call check_system ; check for, and issue any warnings + mov fs,_sel_ss ; FS: = selector of buffer (and stack) + mov gs,_sel_zero ; GS: = zero selector + call open_exec ; open executable file + call load_exec_header ; load exec header into memory + call check_command_line ; get command line info + cmp dx,0040h ; check if reloc-tab starts at 0040h + jnz @@6 ; if not, check command line for fname + mov edx,_exec_start ; get start of exec + test dx,dx ; check if application is bound + jnz load_bound_app ; if bound, load BOUND Application +@@6: test si,si ; check if command line is not empty + jnz load_extrn_app ; if cmd != 0, load EXTRN Application + call close_exec ; display help message + mov ax,8001h + jmp report_error + +load_extrn_app: + call close_exec + call open_extrn_exec + call load_extrn_exec_header + call update_environment + call remove_name_from_cmd + mov edx,_exec_start + +load_bound_app: + mov _err_code,3002h ; "error in app file" + call seek_from_start ; move file ptr to 32bit application + mov ecx,4 ; load 4 bytes (app signature) + xor edx,edx ; offset is zero + call load_fs_block ; load + mov ax,fs:[0000h] ; get file signature + mov bx,fs:[0002h] + test bx,bx + jnz @@1 + cmp ax,'EL' ; 'LE' type + jz load_le_app + cmp ax,'XL' ; 'LX' type + jz load_lx_app + cmp ax,'CL' ; 'LC' type (Linear Compressed) + jz load_lc_app + cmp ax,'EP' ; 'PE' type + jz load_pe_app +@@1: call close_exec + mov ax,3004h ; "app exec format not supported" + jmp file_error + + +;============================================================================= +; Jump to loaded 32-bit code +; +enter_32bit_code: + test cs:_misc_byte2,00010000b + jz @@0 + + sti + mov al,'>' ; "press any key to continue..." + call printc + xor ax,ax ; wait for a keypress + int 16h + call printcr + +@@0: cli ; disable interrupts + cld + call install_nullptr_protect ; install Null-Ptr Protection + mov ss,_sel32_ss ; SS = app 32bit data sel + mov esp,_app_esp ; ESP = application stack + + mov es,_sel_es ; ES = environment sel + mov fs,_sel_zero ; FS = 32bit zero sel + mov ds,_sel32_ss ; DS = app 32bit data sel + xor eax,eax ; clear registers + xor ebx,ebx + xor ecx,ecx + xor edx,edx + xor esi,esi + xor edi,edi + xor ebp,ebp + mov gs,ax + + pushfd ; push flags + push dptr cs:_sel32_cs ; push 32bit destination selector + push dptr cs:_app_eip ; push 32bit destination offset + or bptr ss:[esp+9],2 ; enable interrupts + sti + iretd + + + + + +;============================================================================= +init_system: + xor eax,eax ; reset temp variables to zero + mov _app_esp,eax + mov _app_num_objects,eax + mov _app_off_datapages,eax + call setup_selectors ; setup system selectors + call setup_dta_buffer ; allocate buffer for DTA and Mouse + call initialize_mouse ; initialize mouse + + mov ax,0204h ; get default PM interrupt handlers + mov bl,10h + int 31h + mov wptr _int10_cs,cx + mov dptr _int10_ip,edx + + mov bl,21h + int 31h + mov wptr _int21_cs,cx + mov dptr _int21_ip,edx + + mov bl,23h + int 31h + mov wptr _int23_cs,cx + mov dptr _int23_ip,edx + + mov bl,33h + int 31h + mov wptr _int33_cs,cx + mov dptr _int33_ip,edx + + mov ax,0202h ; get default PM exception handlers + xor ebx,ebx +@@0: int 31h + mov wptr _exc_tab[ebx*8+4],cx + mov dptr _exc_tab[ebx*8+0],edx + inc bl + cmp bl,15 + jb @@0 + + call install_client_ints ; install client PM interrupts + jc dpmi_error + + call win_focus_vm ; switch to full-screen under Windows + + cmp _sys_type,3 + jz @@done + cmp _process_id,0 ; do not reset PIT if we've been + jnz @@done ; spawned to avoid timing problems + + call restore_pit + +@@done: ret + + +;============================================================================= +check_system: + test di,di ; if no prev. DOS/32A in system + jz @@1 ; then jump + cmp di,_version ; check DOS/32A versions + jz @@1 ; if the same then jump + mov ax,9006h ; "incompatible version of DOS/32A" + call report_error +@@1: cmp _sys_type,3 ; if running under an external DPMI + jz @@2 ; then jump + test ecx,ecx ; if extended memory has been alloced + jnz @@2 ; then jump + mov ax,9001h ; "no ext mem has been allocated" + call report_error +@@2: mov ax,0400h ; get DPMI info + int 31h + cmp dh,08h ; warn if PICs have been remapped + jnz @@3 + cmp dl,70h + jz @@4 +@@3: movzx si,dh + movzx di,dl + mov ax,9002h ; "PICs have been relocated" + call report_error +@@4: ret + + +;============================================================================= +remove_kernel: + cmp _sys_type,3 + jnz @@done + + cli + pop bp + push es + mov es,_seg_kernel + mov si,offs @text16_beg + mov cx,(offs @text16_end - @text16_beg) / 2 + rep movsw + pop es + mov ax,dx + shr ax,4 + mov dx,ss + sub dx,ax + mov ss,dx + mov dx,ds + sub dx,ax + mov ds,dx + sub _seg_ds,ax + sub _seg_ss,ax + sub _seg_buf,ax + sub _membase,ax + push dx + push bp + sti + retf +@@done: ret + + + + + +;============================================================================= +; DATA + +include TEXT\CLIENT\data.asm + + +;============================================================================= +; BETA test code + +If EXEC_TYPE eq 2 +include TEXT\testbeta.asm +Endif + + Align 16 +@text16_end label byte +_TEXT16 ends + + + +;============================================================================= +; STACK +_STACK segment para stack use16 'STACK' + db STACKSIZE*16 dup(?) +_STACK ends +end start diff -uNr a/dos32a/src/dos32a/kernel.asm b/dos32a/src/dos32a/kernel.asm --- a/dos32a/src/dos32a/kernel.asm false +++ b/dos32a/src/dos32a/kernel.asm 0b15f492012406be562ee802d7cb6ea411687333661e1adf3fc0e9a9d95a9e2a6dc967df30ff884a966e2ca66a8a4857d2981ceccae8d77949b3fa88c572c41e @@ -0,0 +1,279 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +BUILDING_KERNEL = 1 +BUILDING_CLIENT = 0 + +;***************************************************************************** +; DOS/32 Advanced DOS Extender master Kernel file, includes kernel definitions +; data structures, and files from .\TEXT\KERNEL\ implementing the kernel. +; +; Created on: Oct-30-1996 +; +;***************************************************************************** + + .386p + .387 + LOCALS + NOJUMPS + +SELCODE = 08h ; KERNEL code selector +SELDATA = 10h ; KERNEL data selector +SELZERO = 18h ; ZERO data selector +SELVCPITSS = 20h ; TSS selector for VCPI +SELVCPICODE = 28h ; VCPI call code selector +SELVCPICOD2 = 30h ; VCPI internal selector #2 +SELVCPICOD3 = 38h ; VCPI internal selector #3 +SELBIOSDATA = 40h ; BIOS DATA Area 40h selector +SELCALLBACK = 48h ; Callback DS selector + +SYSSELECTORS = 10 ; number of system selectors in GDT + +INCLUDE TEXT\include.asm +PUBLIC pm32_info +PUBLIC pm32_init +PUBLIC pm32_data +PUBLIC @kernel_beg +PUBLIC @kernel_end + + +_KERNEL segment para public use16 'CODE1' + assume cs:_KERNEL, ds:_KERNEL +;============================================================================= +pm32_data label byte ; data area 12 bytes +pm32_mode db -1 ; mode bits: + ; bit0: 0=test DPMI/VCPI, 1=VCPI/DPMI + ; bit1: 0=exception control off, 1=on + ; bit2: 0=VCPI smart alloc pages off, 1=on + ; bit3: 0=VCPI+XMS alloc sheme off, 1=on + ; bit4: 0=trap software INTs off, 1=on + ; bit5: 0=check ext blocks off, 1=on + ; bit6: 0=invalid limit check off, 1=on + ; bit7: reserved +pm32_maxpages db -1 ; maximum number of VCPI page tables +pm32_maxfpages db -1 ; max. of physical mem. map pages +pm32_callbacks db -1 ; number of real mode callbacks +pm32_selectors dw -1 ; max selectors under VCPI/XMS/raw +pm32_rmstacks db -1 ; real mode stack nesting +pm32_pmstacks db -1 ; protected mode stack nesting +pm32_rmstacklen dw -1 ; real mode stack length, in para +pm32_pmstacklen dw -1 ; protected mode stack length, in para +pm32_maxextmem dd -1 ; maximum extended memory to allocate + + + +;============================================================================= +; GLOBAL DATA: +;============================================================================= + +;============================================================================= +;*** MEMORY DATA *** +mem_ptr equ @area1_dd+00h ;dd 0; pointer to next free mem block +mem_free equ @area1_dd+04h ;dd 0; size of largest free mem block +mem_top equ @area1_dd+08h ;dd 0 +mem_used equ @area1_dw+0Ch ;dw 0 +segmentbases equ @area1_dw+0Eh ;dw 16*2 dup(0); for function 0002h + + +;============================================================================= +;*** Interrupt Redirection DATA *** +temp_int equ @area1_db+4Fh ;db 0 +irqset_rm equ @area1_dw+50h ;dw 0 ; installed Real Mode IRQ Vectors +irqset_pm equ @area1_dw+52h ;dw 0 ; installed Prot. Mode IRQ Vectors +irqtab_rm equ @area1_dd+56h ;dd 16 dup(0) ; 16 Real Mode IRQ Vectors +irqtab_pm equ @area1_dd+96h ;dd 32 dup(0) ; 16 Prot. Mode IRQ Vectors +exctab_pm equ @area1_dd+116h ;dd 32 dup(0) ; 16 Exception Vectors + + +;============================================================================= +;*** Misc. *** +tempw0 equ @area1_dw+198h ;dw 0 +tempw1 equ @area1_dw+19Ah ;dw 0 +tempd1 equ @area1_dd+19Ch ;label dword +tempw2 equ @area1_dw+19Ch ;dw 0 +tempw3 equ @area1_dw+19Eh ;dw 0 + +oldcr0 equ @area1_dd+1A0h ;dd 0 ; preserved CR0 +oldint15h equ @area1_dd+1A4h ;dd 0 ; preserved INT 15h vector +oldint1Bh equ @area1_dd+1A8h ;dd 0 +oldint1Ch equ @area1_dd+1ACh ;dd 0 +oldint21h equ @area1_dd+1B0h ;dd 0 +oldint23h equ @area1_dd+1B4h ;dd 0 +oldint24h equ @area1_dd+1B8h ;dd 0 +oldint2Fh equ @area1_dd+1BCh ;dd 0 +newint1Bh equ @area1_dd+1C0h ;dd 0 +newint1Ch equ @area1_dd+1C4h ;dd 0 +newint23h equ @area1_dd+1C8h ;dd 0 +newint24h equ @area1_dd+1CCh ;dd 0 +id32_mem_free equ @area1_dd+1D0h +id32_mem_ptr equ @area1_dd+1D4h +id32_mem_vcpi equ @area1_dd+1D8h +id32_process_id equ @area1_dw+1DCh ; current process id when spawn +id32_spawned_id equ @area1_db+1E0h ; spawn mode flag (1=spawned) +id32_tsrmode_id equ @area1_db+1E2h ; TSR mode flag (1=TSR) +pagetablebase equ @area1_dd+1E4h ;dd 0; base of page table area +pagetabletop equ @area1_dd+1E8h ;dd 0; top of page table area +pagetablefree equ @area1_dd+1ECh ;dd 0; base of available pagetab area +phystablebase equ @area1_dd+1F0h ;dd 0 +phystabletop equ @area1_dd+1F4h ;dd 0 + +;============================================================================= +; *** Performance Counters *** +_pc_base equ @area1_db+200h +_pc_intrmtopm equ @area1_dd+200h ;dd 0; INT RM->PM switch counter +_pc_intpmtorm equ @area1_dd+204h ;dd 0; INT PM->RM switch counter +_pc_irqrmtopm equ @area1_dd+208h ;dd 0; IRQ RM->PM switch counter +_pc_irqpmtorm equ @area1_dd+20Ch ;dd 0; IRQ PM->RM switch counter +_pc_irqcbrmtopm equ @area1_dd+210h ;dd 0; IRQ Callback RM->PM counter +_pc_irqcbpmtorm equ @area1_dd+214h ;dd 0; IRQ Callback PM->RM counter +_pc_cbrmtopm equ @area1_dd+218h ;dd 0; Callback RM->PM counter +_pc_cbpmtorm equ @area1_dd+21Ch ;dd 0; Callback PM->RM counter +pmstacklen equ @area1_dd+220h ;dd 0; prot mode stack length in bytes +pmstackbase equ @area1_dd+224h ;dd 0; bottom of prot mode stack area +pmstacktop equ @area1_dd+228h ;dd 0; top of prot mode stack area +pmstacktop2 equ @area1_dd+22Ch ;dd 0 +rmstacklen equ @area1_dw+230h ;dw 0; real mode stack size in para +rmstackbase equ @area1_dw+232h ;dw 0; bottom of real mode stack area +rmstacktop equ @area1_dw+234h ;dw 0; top of real mode stack area +rmstacktop2 equ @area1_dw+236h ;dw 0 +rmstackesp equ @area1_dd+240h ;dd 0; for functions 0300h,0301h,0302h +rmstackss equ @area1_dw+244h ;dw 0 +callbackbase equ @area1_dd+248h ;dd 0; base of real mode callbacks +callbackseg equ @area1_dw+24Ch ;dw 0; segment of callbacks +irqcallbackptr equ @area1_dw+250h ;dw 0; ptr to IRQ callback ESP buffer + + evendata +client_call dw 0,0 ; client's critical handler offset +client_version dw 0 ; extender version +kernel_code dw 0 ; kernel CS: segment +cputype db 0 ; CPU type +fputype db 0 ; FPU type +pmodetype db 0 ; protected mode type +pagetables db 0 ; number of page tables under VCPI +picslave db 0 ; PIC slave base interrupt +picmaster db 0 ; PIC master base interrupt +__reserved_1 db 0 ; reserved +A20_state db 0 ; old A20 gate state +cpuidlvl dd 0 ; CPUID level + + evendata +codebase dd 0 ; _KERNEL linear address +dpmiepmode dd 0 ; DPMI enter pmode addx + +selzero dw SELZERO ; for immediate segreg loading +seldata dw SELDATA ; for immediate segreg loading +selcallback dw SELCALLBACK ; for immediate segreg loading +gdtseg dw 0 ; segment of GDT +gdtlimit dw 0 ; GDT limit +gdtbase dd 0 ; GDT base +idtseg dw 0 ; segment of IDT +idtlimit dw 7FFh ; IDT limit +idtbase dd 0 ; IDT base +rmidtlimit dw 3FFh ; real mode IDT limit +rmidtbase dd 0 ; real mode IDT base +rmtopmswrout dw offs v_rmtopmsw ; addx of real to protected routine +pmtormswrout dd offs v_pmtormsw ; addx of protected to real routine + + +;============================================================================= +;*** XMS DATA *** + evendata +xms_call dw 0,0 ; XMS driver offset, segment +xms_data dd 0 ; XMS 3.0 available memory +xms_handle dw 0 ; memory handle + + +;============================================================================= +;*** VCPI DATA *** + evendata ; VCPI structure, DO NOT MODIFY +vcpi_cr3 dd 0 ; VCPI CR3 value for protected mode +vcpi_gdtaddx dd offs gdtlimit ; linear addx of GDT limit and base +vcpi_idtaddx dd offs idtlimit ; linear addx of IDT limit and base +vcpi_selldt dw 0 ; LDT selector for protected mode +vcpi_seltss dw SELVCPITSS ; TSS selector for protected mode +vcpi_eip dd offs v_rmtopmswpm; destination EIP in protected mode +vcpi_cs dw SELCODE ; destination CS in protected mode + +vcpi_calleip dd 0 ; VCPI protected mode call offset +vcpi_callcs dw SELVCPICODE ; VCPI protected mode call selector +vcpi_allocmem dw 0 ; VCPI number of allocated pages +vcpistrucaddx dd offs vcpi_cr3 ; VCPI switch structure linear address +vcpiswitchstack dd 0 ; VCPI temporary mode switch stack + + +;============================================================================= +;*** DPMI DATA *** + evendata +int31h_cache label word + dw 0EEFFh ; last DPMI function # + dw int31h_EEFF ; last DPMI function target addr + + + + + +;============================================================================= +; PROTECTED MODE INIT/EXIT CODE + +include TEXT\KERNEL\detect.asm +include TEXT\KERNEL\init.asm +include TEXT\KERNEL\exit.asm +include TEXT\KERNEL\misc.asm + + +;============================================================================= +; PROTECTED MODE KERNEL CODE + +include TEXT\KERNEL\mode.asm +include TEXT\KERNEL\intr.asm +include TEXT\KERNEL\int31h.asm + + +;============================================================================= +; BETA test code + +If EXEC_TYPE eq 2 +include TEXT\testbeta.asm +Endif + + Align 16 +@kernel_end label byte + +_KERNEL ends +end diff -uNr a/dos32a/src/dos32a/loader.asm b/dos32a/src/dos32a/loader.asm --- a/dos32a/src/dos32a/loader.asm false +++ b/dos32a/src/dos32a/loader.asm 8da138308286a12155a21b6bdb313ced8d8daec83d7445340dee376cdc3baf18312072b818e0381dcac6a8d3f1b31c97881f720878e1aac2bd45f9e5278826d7 @@ -0,0 +1,670 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;***************************************************************************** +; DOS/32A 32-bit application loader (LE/LX style file formats) +; +;***************************************************************************** + +PushState + +APP_MAXOBJECTS = 64 + + +.386p +;============================================================================= +load_le_app: + mov _app_type,0 + jmp load_application + +load_lx_app: + mov _app_type,1 + jmp load_application + +load_lc_app: + mov _app_type,2 + + +;============================================================================= +load_application: + call load_header ; load 'LE'/'LX' exec header + call verbose_showloadhdr + mov ecx,1 ; start with Object #1 +@@1: call load_object ; load object + call create_selector ; allocate selector for loaded object + call verbose_showloadobj + push edx ; save Object Selector/Object Flags + push edi ; save Address of loaded Object + push esi ; save Page Table Index + push ebx ; save # Page Table Entries + inc cx ; increment Current_Object# + cmp cx,word ptr _app_num_objects + jbe @@1 ; loop until all objects are loaded + call preload_fixups ; preload fixup tables and records + mov ebp,esp ; base pointer to last loaded Object + mov ebx,_app_num_objects ; number of Objects + dec bx + shl bx,4 + mov _app_tmp_addr1,ebx +@@4: call relocate_object + sub bx,10h + jnc @@4 + call unload_fixups ; free allocated memory for fixups + call close_exec ; close file + mov esp,_sel_esp + call verbose_showstartup + jmp enter_32bit_code + + + +;----------------------------------------------------------------------------- +load_header: + mov ecx,0A8h ; load 'LE' header + mov edx,04h + mov _err_code,3002h ; "error in app file" + cmp _app_type,2 + jz load_lc_header + + call load_fs_block + mov edx,_exec_start + + mov ax,fs:[0010h] ; get Module Flags + and ax,2000h ; check if not-loadable;/no-fixups + mov ax,3005h + jnz file_error + mov ax,fs:[0044h] ; get # Objects + mov cx,ax + cmp ax,APP_MAXOBJECTS + mov ax,4001h ; "too many objects" + ja file_error + mov _app_num_objects,ecx + + mov eax,fs:[0040h] ; get Object Table Offset + add eax,edx + mov _app_off_objects,eax + mov eax,fs:[0048h] ; get Object PageTable Offset + add eax,edx + mov _app_off_objpagetab,eax + mov eax,fs:[0068h] ; get Fixup PageTable Offset + add eax,edx + mov _app_off_fixpagetab,eax + mov eax,fs:[006Ch] ; get Fixup Record Table Offset + add eax,edx + mov _app_off_fixrectab,eax + mov eax,fs:[0080h] ; get Data Pages Offset + add _app_off_datapages,eax + + mov eax,fs:[0018h] ; get EIP Object # + mov _app_eip_object,eax + mov eax,fs:[0020h] ; get ESP Object # + mov _app_esp_object,eax + mov eax,fs:[001Ch] ; get EIP + mov _app_eip,eax + mov eax,fs:[0024h] ; get ESP + mov _app_esp,eax + mov eax,fs:[0030h] ; get Fixup Records Size + mov _app_siz_fixrecstab,eax + mov eax,fs:[002Ch] ; get Bytes on Last Page (LE-only) + mov _app_siz_lastpage,eax + + mov eax,0FFFh + cmp _app_type,0 + jz @@done + mov ax,1 + mov cx,fs:[002Ch] ; get Page Offset Shift for LX-type + shl ax,cl ; max shift is 15 (8000h-1) + dec ax + +@@done: mov _app_off_pageshift,eax + ret + + + +;----------------------------------------------------------------------------- +load_object: + push ecx + cmp _app_type,2 + jz load_lc_object + + mov _err_code,3002h ; "error in app file" + mov edx,_app_off_objects + call seek_from_start ; move to object header + mov ecx,18h + xor edx,edx + call load_fs_block ; load object header + add _app_off_objects,eax + + mov edx,_app_off_datapages ; get Data_Pages_Offset + call seek_from_start ; move to object data + mov eax,fs:[0000h] ; get Virtual_Size[Object] + mov ebx,fs:[0010h] ; get # Page Table Entries + mov ecx,fs:[0008h] ; get Flags[Object] + mov esi,fs:[000Ch] ; get Page Table Index + + push ecx ; save Object Flags + call alloc_block ; allocate EAX memory block to EDI + mov ecx,eax ; ECX = bytes to read + mov ebp,eax ; EBP = preserve Virtual Size + mov edx,edi ; EDX = addres to read to + call fill_zero_pages ; fill allocated memory with zeroes + + mov eax,ebx + test eax,eax ; check if # Page Table Entries = 0 + jz @@5 ; if yes, skip loading + shl eax,12 ; convert # Page Table Entries to bytes + cmp eax,ecx ; check if # bytes >= bytes to load + jae @@1 ; if yes, jump + mov ecx,eax ; else adjust number of bytes to read + +@@1: mov ax,[esp+4] ; get Object # + cmp ax,word ptr _app_num_objects + jnz @@3 + cmp _app_type,0 + jnz @@2 + lea ecx,[ebx-1] ; load LE-style Last Object (BSS) + shl ecx,12 + add ecx,_app_siz_lastpage + jmp @@3 +@@2: mov ecx,ebx ; load LX-style Last Object (BSS) + shl ecx,12 + +@@3: mov _err_code,3002h ; "error in app file" + call load_gs_block ; load object data + mov eax,ecx + mov edx,_app_off_pageshift + test eax,edx + jz @@4 + mov ecx,edx + not edx + and eax,edx + lea eax,[eax+ecx+1] +@@4: add _app_off_datapages,eax + +@@5: pop edx ; restore Object Flags +@@done: pop ecx + ret + + + + +;============================================================================= +relocate_object: + xor eax,eax + cmp eax,[ebp+ebx+0] ; get # Page Table Entries[Object] + jnz @@0 ; if zero, done + ret +@@0: cmp _app_type,0 + jnz relocate_lx_object + +relocate_le_object: + mov ecx,[ebp+ebx+4] ; get Page Table Index + mov edx,_app_off_objpagetab ; get Object Page Table Offset in exec + lea edx,[ecx*4+edx-4] + mov _err_code,3002h ; "error in app file" + call seek_from_start ; *1) move file ptr +@@1: push eax ; EAX = counter + mov ecx,4 + xor edx,edx + mov _err_code,3002h ; "error in app file" + call load_fs_block ; load block + xor ecx,ecx ; get index into FixupPageTab + mov ch,fs:[0001h] + mov cl,fs:[0002h] + jcxz @@2 + mov eax,_app_off_fixpagetab ; get Fixup Page Table Offset + lea eax,[ecx*4+eax-4] + mov esi,gs:[eax+00h] ; get offset of 1st fixup table + mov ecx,gs:[eax+04h] ; get offset of 2nd fixup table + sub ecx,esi ; calculate size of 1st tab + jz @@2 ; if 1st == 2nd, no fixups + add esi,_app_off_fixrectab ; get Fixup Record Table Offset + mov edi,[esp] ; get current page number + shl edi,12 + add edi,[ebp+ebx+8] ; address of page target to fix in mem + add ecx,esi + call apply_fixups ; patch target with fixup data +@@2: pop eax + inc ax + cmp ax,word ptr [ebp+ebx+0] + jb @@1 + ret + +relocate_lx_object: + mov ecx,[ebp+ebx+4] ; get Page Table Index + mov edx,_app_off_fixpagetab ; get Fixup Page Table Offset + lea edx,[ecx*4+edx-4] +@@1: push eax edx ; EAX = counter + mov esi,gs:[edx+00h] ; get offset of 1st fixup table + mov ecx,gs:[edx+04h] ; get offset of 2nd fixup table + sub ecx,esi ; calculate size of 1st tab + jz @@2 ; if 1st == 2nd, no fixups + add esi,_app_off_fixrectab ; get Fixup Record Table Offset + mov edi,[esp+4] ; get current page number + shl edi,12 + add edi,[ebp+ebx+8] ; address of page target to fix in mem + add ecx,esi + call apply_fixups ; patch target with fixup data +@@2: pop edx eax + add edx,4 + inc ax + cmp ax,word ptr [ebp+ebx+0] + jb @@1 + ret + + + +;============================================================================= +apply_fixups: +@@0: push ecx edi + mov _err_code,4005h ; "unrecognized fixup data" + mov cx,gs:[esi+0] ; get SRC/FLAGS + movsx edx,word ptr gs:[esi+2] ; get SRCOFF + movzx eax,word ptr gs:[esi+4] ; get OBJNUM + add edi,edx ; calculate dest addr to be fixed + test cx,0F20h ; SrcLists/Imports not supported + jnz file_errorm ; jump if one of these + test cx,4000h ; test if 16bit object number + jnz @@1 ; if yes, jump + mov ah,0 + dec esi +@@1: add esi,6 + dec eax ; Object Number - 1 + shl eax,4 + mov edx,_app_tmp_addr1 + sub edx,eax + jc file_errorm + mov _app_tmp_addr2,edx + mov edx,[ebp+edx+8] ; EDX = Destination Object Address + mov al,cl + and al,0Fh + cmp al,02h ; check if 16bit Selector + jz @@3 ; if yes, jump + cmp al,08h + ja file_errorm + mov eax,gs:[esi] + test cx,1000h ; check for Alias flag + jnz @@2 ; if not, jump + movzx eax,ax + sub esi,2 +@@2: add esi,4 +@@3: cmp cl,07h + jnz @@4 + add eax,edx + mov gs:[edi+0],eax +@@5: pop edi ecx + cmp esi,ecx + jb @@0 + ret +@@4: push si + mov si,cx + and si,0Fh + add si,si + mov _err_code,4006h ; "16bit fixup overflow" + call fix_tab[si] + pop si + jmp @@5 + +; +; EAX = Data +; EDX = Address of Object +; EDI = Address to Fixup +; EBP:EBX = Ptr to Current Object Table +;----------------------------------------------------------------------------- +fix_byte: + mov gs:[edi+0],al + ret +fix_16off: + mov gs:[edi+0],ax + ret +fix_32off: + add eax,edx + mov gs:[edi+0],eax + ret +fix_32selfrel: + add eax,edx + lea ecx,[edi+4] + sub eax,ecx + test word ptr [ebp+ebx+12],2000h + jnz @@1 + lea ecx,[eax+8002h] + shr ecx,16 + jnz file_errorm + mov gs:[edi+0],ax + ret +@@1: mov gs:[edi+0],eax + ret +fix_16sel: + call check_range + mov gs:[edi+0],dx + ret +fix_1616ptr: + call check_range + mov gs:[edi+0],ax + mov gs:[edi+2],dx + ret +fix_1632ptr: + add eax,edx + mov gs:[edi+0],eax + call check_range + mov gs:[edi+4],dx + ret +fix_invalid: + mov ax,4005h ; "unrecognized fixup data" + jmp file_error + +check_range: + test word ptr [ebp+ebx+12],1000h ; check if 16:16 alias requird + jnz @@1 ; if yes, jump + test cl,10h + jnz @@1 +@@0: mov ecx,_app_tmp_addr2 + mov dx,[ebp+ecx+14] ; get selector + ret +@@1: test cl,10h + jz @@0 + mov ecx,_app_tmp_addr2 + mov dx,[ebp+ecx+14] ; get selector + test eax,0FFFF0000h ; check 64K range + jnz file_errorm + ret + + + evendata +fix_tab label word + dw fix_byte ; 00h + dw fix_invalid ; 01h + dw fix_16sel ; 02h + dw fix_1616ptr ; 03h + dw fix_invalid ; 04h + dw fix_16off ; 05h + dw fix_1632ptr ; 06h + dw fix_32off ; 07h + dw fix_32selfrel ; 08h + + + + + + + + +;----------------------------------------------------------------------------- +; In: ECX = size +; Out: EDI = address +; +fill_zero_pages: + push es dx eax ecx edi + push gs + pop es + mov dl,cl + shr ecx,2 + xor eax,eax + rep stos dword ptr es:[edi] + mov cl,dl + and cl,3 + rep stos byte ptr es:[edi] + pop edi ecx eax dx es + ret + + +;----------------------------------------------------------------------------- +; In: EAX = size +; Out: EDI = address +; +alloc_block: + push dx + test eax,eax ; if size of Object is zero + jz @@null ; then report a warning 9005 + mov dl,_misc_byte ; get misc byte + shr dx,4 ; get memory alloc bits in bit1,0 + and dx,3 ; mask them + jz @@00 ; if 00b alloc scheme, jump + dec dx + jz @@01 + dec dx + jz @@10 + dec dx + jz @@11 +@@done: pop dx + ret +@@null: push ax si + mov si,[esp+0Ch] + mov ax,9005h + call report_error + pop si ax dx + xor edi,edi + ret + +; +; load 16bit/32bit -> low, then high, then error +;--------------------------------------- +@@00: call alloc_dos_mem ; try to allocate DOS memory block + jnc @@done ; if allocated, jump + mov _err_code,4003h ; "not enough DPMI mem" + call alloc_dpmi_mem ; try to allocate DPMI memory block + jnc @@done ; if allocated, jump + jmp file_errorm ; if failed, error +; +; load 16bit -> low, then high, then error +; load 32bit -> high only, then error +;--------------------------------------- +@@01: test cx,2000h ; check if 32bit Object + jnz @@01_1 ; if yes, jump + mov _err_code,4002h ; "not enough DOS mem" + call alloc_dos_mem + jnc @@done ; if allocated, jump +@@01_1: mov _err_code,4003h ; "not enough DPMI mem" + call alloc_dpmi_mem + jnc @@done ; if allocated, jump + jmp file_errorm ; if failed, error +; +; load 16bit/32bit low, then error +;--------------------------------------- +@@10: mov _err_code,4002h ; "not enough DOS mem" + call alloc_dos_mem + jnc @@done + jmp file_errorm ; if failed, error +; +; load 16bit/32bit high, then error +;--------------------------------------- +@@11: mov _err_code,4003h ; "not enough DPMI mem" + call alloc_dpmi_mem + jnc @@done + jmp file_errorm ; if failed, error + + + + +;----------------------------------------------------------------------------- +alloc_dos_mem: + push eax ebp ; EAX = size to allocate + add eax,0Fh ; align size on para + shr eax,4 + test eax,0FFFF0000h ; check high word of EAX + stc + jnz @@done + sub esp,32h + mov ebp,esp + mov byte ptr [ebp+1Dh],48h ; DOS func: AH=48h + mov word ptr [ebp+10h],ax ; DOS BX=size + call int21h + movzx edi,word ptr [ebp+1Ch] ; get returned value in EAX + shl edi,4 ; NOTE: addres is relative to 0 + bt word ptr [ebp+20h],0 ; check for errors + lea esp,[esp+32h] +@@done: pop ebp eax + ret + +;----------------------------------------------------------------------------- +alloc_dpmi_mem: + push esi ebx ecx edx eax + mov ebx,eax + mov ax,0FF91h ; allocate DPMI memory + int 21h + jc @@done + mov eax,ebx + xor edx,edx + test _misc_byte2,00000100b ; check if para or page alignment + jnz @@l1 + test al,0Fh + jz @@1 + jmp @@l2 +@@l1: test ax,0FFFh ; check if returned addr aligned + jz @@1 ; on PAGE boundary, if yes, jump +@@l2: test _misc_byte2,00000100b + jnz @@l3 + add ebx,0Fh + and bl,0F0h + jmp @@l4 +@@l3: add ebx,0FFFh + and bx,0F000h ; align linear addr on PAGE boundary +@@l4: sub ebx,eax ; calculate difference + mov edx,ebx + add ebx,[esp] + mov ax,0FF93h ; resize DPMI memory block + int 21h + jc @@done +@@1: lea edi,[ebx+edx] ; adjust linear address + test _misc_byte2,00000100b + jnz @@l5 + test di,000Fh + jmp @@l6 +@@l5: test di,0FFFh +@@l6: stc + jnz @@done + clc +@@done: pop eax edx ecx ebx esi + ret + + + +;----------------------------------------------------------------------------- +create_selector: + push ebx ecx edx esi edi + mov ax,dx + mov ecx,ebp ; ECX = Virtual Size[Object] + mov dx,_acc_rights ; default: PAGE, USE32, DATA + test al,0004h ; check if object is executable + jz @@1 ; if not, jump + or dl,0008h ; set selector to Code +@@1: test ax,2000h ; check if object is 32bit + jz @@2 ; if not, jump + xor edi,edi ; set base to Zero + or ecx,-1 ; set limit to 4Gb + + test al,0004h ; check if code or data Object + mov ax,_sel32_cs ; AX = 32bit code selector + jnz @@0 ; if code, then jump + mov ax,_sel32_ss ; AX = 32bit data selector +@@0: test ax,ax ; check if already allocated + jnz @@4 ; if yes, use this selector + jmp @@3 + +@@2: and dx,0BFFFh ; set selector to 16bit +@@3: call set_descriptor ; allocate selector + jc dpmi_error +@@4: pop edi esi + mov [esp+2],ax ; store selector in high word of EDX + pop edx ecx ebx + mov _app_buf_allocsel[ecx*2],ax + mov _app_buf_allocbase[ecx*4],edi + + cmp cx,word ptr _app_eip_object; is Current_Object# == EIP_Object# + jnz @@l1 ; if not, jump + mov _sel32_cs,ax + mov _unreloc_eip,edi + test dx,2000h ; check if Object is 32bit + jz @@l1 ; if not, leave _APP_EIP as is + add _app_eip,edi + +@@l1: cmp cx,word ptr _app_esp_object; is Current_Object# == ESP_Object# + jnz @@l2 ; if not, jump + mov _sel32_ss,ax + mov _unreloc_esp,edi + add _app_esp,edi ; adjust ESP +@@l2: ret + + +preload_fixups: + cmp _app_type,2 + jz preload_lc_fixups + + mov ebx,_app_siz_fixrecstab ; allocate memory for fixups + mov _app_load,0 ; default load fixups low + mov ax,0FF95h + int 21h + jnc @@1 + mov _app_load,1 ; try load fixups hi + mov al,91h + int 21h + mov ax,4004h + jc file_error ; if not enough memory, error +@@1: mov _app_buf_fixrecstab,esi + + mov _err_code,3002h ; "error in app file" + mov edx,_app_off_fixpagetab ; move file ptr to fixups + call seek_from_start + mov edx,ebx + mov ecx,_app_siz_fixrecstab + call load_gs_block + + mov eax,_app_off_fixrectab + mov ebx,_app_off_fixpagetab + sub eax,ebx + add eax,edx + mov _app_off_fixpagetab,edx + mov _app_off_fixrectab,eax + ret + + +unload_fixups: + cmp _app_type,2 + jz unload_lc_fixups + + mov esi,_app_buf_fixrecstab + mov ax,0FF96h + cmp _app_load,0 + jz @@1 + mov al,92h +@@1: int 21h + ret + + +PopState + diff -uNr a/dos32a/src/dos32a/loadlc.asm b/dos32a/src/dos32a/loadlc.asm --- a/dos32a/src/dos32a/loadlc.asm false +++ b/dos32a/src/dos32a/loadlc.asm 3979a8df8c14218bd961e99f311e4449a00cc89ada60f8216334493104b91e43ac57eb46cc133b09964f9e2c9dc34af6b857f464cf1a8d8d6a42446d9f01faab @@ -0,0 +1,283 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;***************************************************************************** +; DOS/32A LC-style 32-bit (compressed) application loader +; +;***************************************************************************** + +;----------------------------------------------------------------------------- +; LC Header Format +; +; 0000 DD "LC" \0\0 +; 0004 DB # of Objects +; 0005 DB LC-flags +; bit0..3: LC implementation version +; bit4..7: reserved +; 0006 DB EIP Object # +; 0007 DB ESP Object # +; 0008 DD EIP Offset +; 000C DD ESP Offset +; 0010 ... ...Object #1 Header follows... +; +;----------------------------------------------------------------------------- +; Object Header Format +; +; 0000 DD Virtual Size (Uncompressed Size) +; bit31: 0=encoded, 1=not encoded +; 0004 DD Compressed Size +; 0008 DW Object Flags +; 000A DW Extended Object Flags +; 000C DW Page Table Index +; 000E DW # of Page Table Entries +; 0010 ... ...Object Data follows... +; +;----------------------------------------------------------------------------- +; +; Fixups Header Format +; +; 0000 DD Uncompresed Size +; bit31: 0=encoded, 1=not encoded +; 0004 DD Compressed Size +; 0008 DD Fixup Record Table Offset +; 000C ... ...Fixup Page Table Data ... +; 000C+[0008] ... ...Fixup Record Table Data ... +; + +LC_SPECVER equ 04h + +;============================================================================= +load_lc_header: + mov cl,0Ch ; load 'LC' header + call load_fs_block + xor eax,eax + mov al,fs:[0004h] ; get # Objects + mov _app_num_objects,eax + mov al,fs:[0006h] ; get EIP Object # + mov _app_eip_object,eax + mov al,fs:[0007h] ; get ESP Object # + mov _app_esp_object,eax + mov eax,fs:[0008h] ; get EIP + mov _app_eip,eax + mov eax,fs:[000Ch] ; get ESP + mov _app_esp,eax + mov al,fs:[0005h] + and al,0Fh + cmp al,LC_SPECVER ; check LC implementation version + mov ax,3006h ; "exec not supported" + jnz file_error + mov ax,4007h ; "not enough DOS Transfer Buffer" + cmp _lobufsize,2000h ; must be at least 8KB + jb file_error + ret + + + +;----------------------------------------------------------------------------- +load_lc_object: + mov ecx,10h + xor edx,edx + mov _err_code,3002h ; "error in app file" + call load_fs_block ; load object header + mov eax,fs:[0000h] ; get Virtual_Size[Object] + btr eax,31 ; check if encoded and clear bit "31" + setc _ic_byte ; if not encoded, set _ic_byte to "1" + push eax + call alloc_block ; allocate EAX memory block to EDI + mov ecx,eax ; ECX = bytes to read + mov edx,edi ; EDX = address to read to + call fill_zero_pages ; fill allocated memory with zeroes + mov _err_code,3002h ; "error in app file" + mov ebx,fs:[0004h] ; EBX = compressed data size + mov ecx,ebx + jecxz @@done ; skip null-size Objects + cmp _ic_byte,0 + jnz @@1 + mov ax,0FF91h + int 21h + mov ax,4003h ; "not enough extended memory" + jc file_error + mov _app_buf_fixrecstab,esi ; preserve memory block handle + mov edx,ebx + call decompress_data + mov ax,0FF92h + mov esi,_app_buf_fixrecstab + int 21h + jmp @@done +@@1: call load_gs_block +@@done: pop ebp ; get Virtual_Size[Object] + movzx ebx,word ptr fs:[000Eh] ; get # Page Table Entries + movzx edx,word ptr fs:[0008h] ; get Flags[Object] + movzx esi,word ptr fs:[000Ch] ; get Page Table Index + pop ecx + ret + + + +preload_lc_fixups: + mov ecx,0Ch + xor edx,edx + mov _err_code,3002h ; "error in app file" + call load_fs_block ; load LC Fixup Header + mov ax,0FF91h ; alloc memory for Decoded fixups + mov ebx,fs:[0000h] + btr ebx,31 ; check if encoded and clear bit "31" + setc _ic_byte ; if not encoded, set _ic_byte to "1" + mov ecx,ebx + inc ebx ; prevent error when EBX = 0 + int 21h + mov ax,4003h + jc file_error + mov edx,ebx + mov edi,ebx + mov _app_buf_fixrecstab,esi + call fill_zero_pages ; fill allocated memory with zeroes + mov ebx,fs:[0004h] + mov ecx,ebx + cmp _ic_byte,0 + jnz @@1 + mov ax,0FF91h ; alloc memory for Encoded fixups + inc ebx ; prevent error when EBX = 0 + int 21h + mov ax,4003h + jc file_error + mov edx,ebx + call decompress_data + mov ax,0FF92h + int 21h + jmp @@done +@@1: call load_gs_block +@@done: mov _app_off_fixpagetab,edi + add edi,fs:[0008h] + mov _app_off_fixrectab,edi + ret + +unload_lc_fixups: + mov ax,0FF92h + mov esi,_app_buf_fixrecstab + int 21h + ret + + + +;============================================================================= +; EBX = source address +; EDI = destination address +; ECX = size of source +; +decompress_data: + call load_gs_block + +decompress: + pushad + mov _xc_byte,0 + mov _srcaddr,ebx + mov _codesize,ecx + push edi + mov ecx,_lobufsize + mov esi,_lobufbase + mov edi,_lobufzero + call fill_zero_pages + pop edi + xor bx,bx + mov edx,0FEEh +@@3: shr bx,1 + and dx,0FFFh + test bh,01h + je @@6 +@@4: test bl,01h + je @@8 + call getbyte + js @@5 + mov [esi+edx],al + mov gs:[edi],al + inc dx + inc edi + jmp @@3 +@@5: mov _codesize,edi ; for INT 21h / AX=0FF8Dh function + popad + ret +@@6: call getbyte + js @@5 + or ah,-1 + mov bx,ax + jmp @@4 +@@8: call getbyte + js @@5 + mov cl,al + call getbyte + js @@5 + mov ch,al + shr ch,4 + and ax,0Fh + add al,02h + mov bp,ax + test ax,ax + jl @@3 +@@9: and cx,0FFFh + and dx,0FFFh + mov al,[esi+ecx] + mov [esi+edx],al + mov gs:[edi],al + inc cx + inc dx + inc edi + dec bp + jns @@9 + jmp @@3 + + +;----------------------------------------------------------------------------- +getbyte:mov eax,_srcaddr + mov al,gs:[eax] + xor al,_xc_byte + inc _srcaddr + mov _xc_byte,al + dec _codesize + ret + + + + +;----------------------------------------------------------------------------- +_ic_byte equ _int_number ;db 0 +_xc_byte equ _app_load ;db 0 +_srcaddr equ _app_tmp_addr1 ;dd 0 +_codesize equ _app_tmp_addr2 ;dd 0 + diff -uNr a/dos32a/src/dos32a/loadpe.asm b/dos32a/src/dos32a/loadpe.asm --- a/dos32a/src/dos32a/loadpe.asm false +++ b/dos32a/src/dos32a/loadpe.asm bf2d8275ddac10274d45bd45de2ffb7afb22062c51c20f70d3952ad0f1338b7b4e1369938fd82914559d224d250f17f985fab9c8dacade68b95bcd5414b3cd50 @@ -0,0 +1,56 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.386p +;============================================================================= +load_pe_app: + mov _app_type,3 +; +; Insert PE loader implementation here +; + mov ax,3004h ; "exec format not supported" + jmp file_error + + + +PopState + diff -uNr a/dos32a/src/dos32a/text/client/config.asm b/dos32a/src/dos32a/text/client/config.asm --- a/dos32a/src/dos32a/text/client/config.asm false +++ b/dos32a/src/dos32a/text/client/config.asm ae2cc92c2e1991a17b7f819da9cf16349de6bd01a82553d4c5795f59810040e313bfaf7258445bbd66280ed7ea639dba599fc9d39f1e41b0a8688a0dc437072e @@ -0,0 +1,433 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.8086 +;============================================================================= +; Get default configuration from _ID32 segment (buried in the program) +; and configure the both KERNEL and CLIENT +; +get_default_config: + push ds es + mov ax,_ID32 + mov dx,_KERNEL + mov _seg_id32,ax + mov _seg_kernel,dx + + push ax dx ; STUB/32C configuration code + mov ax,0FF87h + int 21h + cmp dx,'ID' + jnz @@1 + cmp ax,'32' + jnz @@1 + mov es,cs:_seg_id32 + xor di,di + mov cx,12 + rep movsw + mov ds,cs:_seg_ds + or _sys_misc,0001h ; indicate STUB/32C configuration +@@1: pop dx ax + + mov ds,ax + mov es,dx + xor si,si ; DS:SI=_ID32:0000 + mov di,offs pm32_data ; ES:DI=_KERNEL:PM32_DATA + lodsw ; check for 'ID32' signature + cmp ax,'DI' ; if not present, skip confuguration + jnz @@err + lodsw + cmp ax,'23' + jnz @@err + mov cx,_ID32_SIZE + rep movsb ; copy default config to KERNEL + mov es,cs:_seg_ds +If EXEC_TYPE eq 0 + and wptr ds:[si],7FFFh +Else + or wptr ds:[si],8800h +Endif + lodsw ; get DOS/32A config byte + mov wptr es:_misc_byte,ax + lodsw ; get DOS buffer size + mov wptr es:_lowmembuf,ax + lodsw ; get version + mov wptr es:_version,ax + clc + jmp @@done +@@err: stc +@@done: pop es ds + ret + + + evendata +@area2_db label byte +@area2_dw label word +@area2_dd label dword + +;============================================================================= +; Get environment configuration from the environment segment (at PSP:002C) +; and configure both KERNEL and DOS/32A +; +get_environ_config: + push ds es + jc @@done + test _misc_byte2,00000001b + jz @@done + mov es,_seg_env + xor di,di ; ES:DI=envirment + mov cx,-1 ; environment size, unlimited + xor ax,ax +@@0: push cx + mov cx,7 ; CX =length of 'DOS32A=' string + mov si,offs dos_str ; DS:SI=offset of 'DOS32A=' string + repe cmpsb + pop cx + jz @@1 ; quit loop if found + repne scasb + cmp al,es:[di] ; check for end of environment + jnz @@0 ; loop until found or end of environ. + jmp @@done ; no string found, exit +@@1: call skip_env_spaces ; skip any leading spaces + cmp bptr es:[di],0 ; if at the end of the line, exit + jz @@done ; (actually, just in case) + call get_env_word ; get word and configure + call skip_env_nonspaces ; skip anything else until space or 0 + cmp bptr es:[di],0 + jnz @@1 +@@done: pop es ds + ret + +get_env_word: + xor bx,bx ; BX=pointer to next argument in tab +@@0: mov si,dfn_tab[bx] ; DS:SI=string offset + cmp si,-1 ; check if at end of arg. list + jz @@1 ; if yes, terminate search + mov cx,dfn_tab[bx+2] ; CX=get string length + push di + repe cmpsb ; compare strings + pop di + jz @@2 ; if equ, process argument + add bx,6 ; loop until done + jmp @@0 +@@1: ret +@@2: add di,dfn_tab[bx+2] ; adjust env pointer by string length + jmp cs:dfn_tab[bx-2+6] ; goto appropriate argument handler + +skip_env_spaces: +@@1: mov al,es:[di] + test al,al + jz @@3 + cmp al,'/' + jz @@2 + cmp al,20h + jnz @@3 + inc di + jmp @@1 +@@2: inc di +@@3: ret + +skip_env_nonspaces: +@@1: mov al,es:[di] + test al,al + jz @@3 + cmp al,'/' + jz @@2 + cmp al,20h + jz @@3 + inc di + jmp @@1 +@@2: inc di +@@3: ret + + + +;============================================================================= +; Get switch in AX: 0, 1, ON, OFF (CF=1 if not found) +; +get_env_swc: + cmp bptr es:[di],':' ; skip ':' if present + jne @@1 + inc di +@@1: xor ax,ax ; if '0', return(0) + cmp bptr es:[di],'0' ; check for '0'=OFF + jz @@x1 + inc ax ; if '1', return(1) + cmp bptr es:[di],'1' ; check for '1'=ON + jz @@x1 + cmp wptr es:[di],'NO' ; check for 'ON' + jz @@x2 + dec ax + cmp wptr es:[di],'FO' ; check for 'OF'(F) + jnz @@x0 + cmp bptr es:[di+2],'F' ; check for (OF)'F' + jz @@x3 +@@x0: stc + ret +@@x3: inc di +@@x2: inc di +@@x1: inc di + test al,al + ret + + + +;============================================================================= +; Get number in AX: 0<=N(dec)<=65535 (CF=1 if not found) +; +get_env_num: + cmp bptr es:[di],':' ; skip ':' if present + jne @@1 + inc di +@@1: xor ax,ax + xor bx,bx + mov cx,10 + mov al,es:[di] + sub al,'0' + jb @@exit + cmp al,9 + ja @@exit + xchg bx,ax + mul cx + xchg bx,ax + add bx,ax +@@2: inc di + xor ax,ax + mov al,es:[di] + sub al,'0' + jb @@done + cmp al,9 + ja @@done + xchg bx,ax + mul cx + xchg bx,ax + add bx,ax + jmp @@2 +@@done: mov ax,bx + clc + ret +@@exit: stc + ret + + + + + +;============================================================================= +; /QUIET +; +cfg_env_quiet: +If EXEC_TYPE eq 0 + and wptr _misc_byte,1111011111111100b +Else + and wptr _misc_byte,1111111111111100b +Endif + ret + + + +;============================================================================= +; /PRINT:ON|OFF +; +cfg_env_print: + call get_env_swc + jc @@0 + jz @@1 + or wptr _misc_byte,0000100000000001b + ret +@@1: and wptr _misc_byte,1111011111111110b +@@0: ret + + + +;============================================================================= +; SOUND:ON|OFF +; +cfg_env_sound: + call get_env_swc + jc @@0 + jz @@1 + or _misc_byte,00000010b + ret +@@1: and _misc_byte,11111101b +@@0: ret + + + +;============================================================================= +; /EXTMEM:nnnn (KB) +; +cfg_env_extmem: + call get_env_num + jc @@0 + push ds + mov ds,_seg_kernel + assume ds:_KERNEL + push ax + mov bx,1024 ; make AX (Kb)-> DX:AX (bytes) + mul bx ; DX:AX= bytes + mov wptr ds:[pm32_data+12],ax ; set ext mem requirements + mov wptr ds:[pm32_data+14],dx + pop ax + add ax,00FFFh + and ax,0F000h + xor dx,dx + mov bx,1000h ; BX=Page size in KB + div bx ; MEM KB / Page Size KB + test al,al + jnz @@1 ; must alloc at least one + inc al +@@1: mov bptr ds:[pm32_data+1],al ; set max allowed pagetables + assume ds:_TEXT16 + pop ds +@@0: ret + + + +;============================================================================= +; /DOSBUF:nnnn (KB) +; +cfg_env_dosbuf: + call get_env_num + cmp ax,1 ; 1KB < ax < 64KB + jb @@0 + cmp ax,64 + ja @@0 + jnz @@2 + mov ax,0FFFh + jmp @@1 +@@2: mov cl,6 + shl ax,cl ; convert KB to para +@@1: mov _lowmembuf,ax +@@0: ret + + + +;============================================================================= +; /DPMITST:ON|OFF +; +cfg_env_test: + call get_env_swc +; jc @@0 +; push ds +; mov ds,_seg_kernel +; assume ds:_KERNEL +; jz @@1 +; or bptr ds:pm32_data[0],00000001b +; pop ds +; ret +;@@1: and bptr ds:pm32_data[0],11111110b +; assume ds:_TEXT16 +; pop ds +@@0: ret + + + +;============================================================================= +; /RESTORE:ON|OFF +; +cfg_env_restore: + call get_env_swc + jc @@0 + jz @@1 + or _misc_byte,00000100b + ret +@@1: and _misc_byte,11111011b +@@0: ret + + + +;============================================================================= +; /NULLP[:ON|OFF] +; +cfg_env_nullp: + call get_env_swc + jc @@0 + jz @@1 +@@0: or _misc_byte,10000000b + ret +@@1: and _misc_byte,01111111b + ret + + + +;============================================================================= +; /VERBOSE[:ON:OFF] +; +cfg_env_verbose: + call get_env_swc + jc @@0 + jz @@1 +@@0: or _misc_byte2,00010000b + ret +@@1: and _misc_byte2,11101111b + ret + + + +;============================================================================= +; /NOWARN:nnnn +; +cfg_env_nowarn: + call get_env_num + sub ax,9000 + jb @@0 + cmp al,6 + ja @@0 + add ax,ax + mov bx,ax + mov wptr errtab_90xx[bx],0 + cmp bptr es:[di],',' + jnz @@0 + inc di + jmp cfg_env_nowarn +@@0: ret + + + +;============================================================================= +; /NOC +; +cfg_env_noc: + and bptr _misc_byte2,11110111b + ret + +PopState diff -uNr a/dos32a/src/dos32a/text/client/data.asm b/dos32a/src/dos32a/text/client/data.asm --- a/dos32a/src/dos32a/text/client/data.asm false +++ b/dos32a/src/dos32a/text/client/data.asm 0cbd28472bf26fceae6e938ab39c52fa4825d619f76fba4e7d1011e17aec2d5d152371d84e5cbdd127764348141b8179c77b22778b16760b83c5ffac1cd34cef @@ -0,0 +1,397 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + +; table string /len/subroutine +;----------------------------------------------- + Align 2 +dfn_tab dw df1_str, 5, cfg_env_quiet + dw df2_str, 5, cfg_env_print + dw df3_str, 5, cfg_env_sound + dw df4_str, 6, cfg_env_extmem + dw df5_str, 6, cfg_env_dosbuf + dw df6_str, 7, cfg_env_test + dw df8_str, 7, cfg_env_restore + dw df9_str, 5, cfg_env_nullp + dw dfA_str, 7, cfg_env_verbose + dw dfB_str, 6, cfg_env_nowarn + dw dfC_str, 3, cfg_env_noc + dw -1 + + +; table errcode, errstatus, errtab +;------------------------------------------ + Align 2 +g_errtab db 00h, 0 + dw errtab_00xx + db 10h, 0 + dw errtab_10xx + db 20h, 0 + dw errtab_20xx + db 30h, 0 + dw errtab_30xx + db 40h, 0 + dw errtab_40xx + db 60h, 2 + dw errtab_60xx + db 80h, 0 + dw errtab_80xx + db 90h, 1 + dw errtab_90xx + dw -1 + +h_errtab dw errmsg1, errmsg2, errmsg3 + +errtab_00xx dw d_err0, d_err1, d_err2, d_err3, d_err4 + dw d_err5, d_err6, d_err7 +errtab_10xx dw n_msg, m_err1, m_err2 +errtab_20xx dw e_err0, e_err1, e_err2 +errtab_30xx dw n_msg, a_err1, a_err2, a_err3, a_err4, a_err2, a_err4 +errtab_40xx dw n_msg, l_err1, l_err2, l_err3, l_err4, l_err5, l_err6, l_err7 +errtab_60xx dw r_msg80,n_msg, r_msg81,r_msg82,r_msg83,r_msg84 +errtab_80xx dw n_msg, x_err1, x_err2, x_err3 +errtab_90xx dw n_msg, w_msg1, w_msg2, w_msg3, w_msg4, w_msg5, w_msg6 + +i_msg dw i_msg00, i_msg01, i_msg02, i_msg03 + dw i_msg04, i_msg05, i_msg06, i_msg07 + dw i_msg08, i_msg09, i_msg0A, i_msg0B + dw i_msg0C, i_msg0D, i_msg0E, n_msg + + + + + + +;============================================================================= + Align 4 +_misc_byte db 3 ; DOS/32A misc. bits ; +00 +_misc_byte2 db 7 ; +01 +_version dw 0 ; version ; +02 +_cpu_type db 0 ; CPU type: 80x86 ; +04 +_sys_type db 0 ; system type: raw/XMS/VCPI/DPMI ; +05 +_sys_misc dw 0 ; system misc. bits ; +06 +_buf_size dw 0 ; protected mode buffer size ; +08 + +; _sys_misc map: +;---------------- +; bit 0: 0=no stub32c present, 1=program started from stub32c +; bit 8: 0=no CTRL-C, 1=CTRL-C detected (run-time) + + +_pic_mask dw 0 ; PIC mask +_err_code dw 0 +_acc_rights dw 0 +_mus_size dd 0 +_mus_backoff dw 0 +_mus_backseg dw 0 +_mus_off dd 0 +_mus_sel dd 0 +_mus_data db 0,0 + +_seg_ds dw 0 ; real mode segment storage +_seg_es dw 0 +_seg_ss dw 0 +_seg_env dw 0 +_seg_buf dw 0 +_seg_dta dw 0 +_seg_mus dw 0 +_seg_id32 dw 0 +_seg_kernel dw 0 + +_sel_cs dw 0 ; protected mode selector storage +_sel_ds dw 0 +_sel_es dw 0 +_sel_esp dd 0 +_sel_ss dw 0 +_sel_zero dw 0 ; ZERO_32 Data selector +_sel_env dw 0 ; default environment selector +_process_id dw 0 + +_sel32_cs dw 0,0 ; CODE_32 Code selector +_sel32_ss dw 0,0 ; DATA_32 Data selector + +_membase dw 0 ; memory base after stk+int+buf +_lowmembuf dw 0 ; size of DOS INT 21h buffer +_lobufzero dd 0 +_lobufbase dd 0 +_lobufsize dd 0 +_seg_ds_base dd 0 ; 32bit base of DS (CS) segment +_dta_sel dw 0 +_dta_off dd 0 +_app_dta_sel dw 0 +_app_dta_off dd 0 + +;----------------------------------------------------------------------------- +_int10_ip dd 0 ; default INT 10h handler +_int10_cs dd 0 +_int21_ip dd 0 ; default INT 21h handler +_int21_cs dd 0 +_int23_ip dd 0 ; default INT 23h handler +_int23_cs dd 0 +_int33_ip dd 0 ; default INT 33h handler +_int33_cs dd 0 +_exc_tab dd 16 * 2 dup(0) + + +;----------------------------------------------------------------------------- +_exec_handle equ @area1_dw+00h ;dw 0 +_exec_start equ @area1_dd+04h ;dd 0 +_app_tmp_addr1 equ @area1_dd+08h ;dd 0 +_app_tmp_addr2 equ @area1_dd+0Ch ;dd 0 + +_app_num_objects equ @area1_dd+10h ;dd 0 +_app_off_objects equ @area1_dd+14h ;dd 0 + +_app_off_objpagetab equ @area1_dd+18h ;dd 0 +_app_off_fixpagetab equ @area1_dd+1Ch ;dd 0 +_app_off_fixrectab equ @area1_dd+20h ;dd 0 +_app_off_datapages equ @area1_dd+24h ;dd 0 +_app_off_pageshift equ @area1_dd+28h ;dd 0 + +_app_eip_object equ @area1_dd+2Ch ;dd 0 +_app_esp_object equ @area1_dd+30h ;dd 0 +_app_eip equ @area1_dd+34h ;dd 0 +_app_esp equ @area1_dd+38h ;dd 0 +_unreloc_eip equ @area1_dd+3Ch ;dd 0 +_unreloc_esp equ @area1_dd+40h ;dd 0 +_app_siz_fixrecstab equ @area1_dd+44h ;dd 0 +_app_buf_fixrecstab equ @area1_dd+48h ;dd 0 +_app_siz_lastpage equ @area1_dd+4Ch ;dd 0 + +_int_number equ @area1_db+50h ;db 0,0 +_int_temp equ @area1_dw+52h ;dw 0 +_int_errcode equ @area1_dd+54h ;dd 0 +_int_esp equ @area1_dd+58h ;dd 0 +_int_ss equ @area1_dd+5Ch ;dw 0 +_int_erravail equ @area1_db+5Eh ;db 0 + +_app_type equ @area1_db+60h ;db 0 +_app_load equ @area1_db+61h ;db 0 + +_mus_esp equ @area1_dd+64h ;dd 0 +_mus_ss equ @area1_dw+68h ;dw 0 + +; machine state +ms_reg_cr0 equ @area1_dd+ 80h ;dd 0 +ms_reg_cr2 equ @area1_dd+ 84h ;dd 0 +ms_reg_cr3 equ @area1_dd+ 88h ;dd 0 +ms_reg_dr6 equ @area1_dd+ 8Ch ;dd 0 +ms_eflags equ @area1_dd+ 90h ;dd 0 +ms_ec equ @area1_dd+ 94h ;dd 0 +ms_frame_esp equ @area1_dd+0A0h ;dd 0 ; exception handler's stack frame: ESP +ms_frame_ss equ @area1_dw+0A4h ;dw 0 ; exception handler's stack frame: SS +ms_reg_ds equ @area1_dw+0A8h ;dw 0 +ms_int equ @area1_dw+0ACh ;dw 0 ; INT # + +_app_buf_allocsel equ @area2_dw+00h ;dw 0 +_app_buf_allocbase equ @area2_dd+APP_MAXOBJECTS*2 ;dd APP_MAXOBJECTS*2 dup(00h) + + +;----------------------------------------------------------------------------- +n_msg db 0 +cpr_msg db 'DOS/32A -- DOS Extender ' +If EXEC_TYPE eq 2 + db 'BETA ' +EndIf + db 'version ' +ver_msg db 'x.x.x',cr + db 'Copyright (C) 1996-2006 by Narech K.',cr +cpr_end label byte + +errmsg1 db 'DOS/32A fatal (%w): ',0 +errmsg2 db 'DOS/32A warning (%w): ',0 +errmsg3 db 'DOS/32A run-time (%w): ',0 + +;----------------------------------------------------------------------------- +dos_str db 'DOS32A=' +df1_str db 'QUIET' ; print =OFF, sound =OFF -- +df2_str db 'PRINT' ; print (off=only errors reported) on/off +df3_str db 'SOUND' ; sound on error on/off +df4_str db 'EXTMEM' ; max Extended memory to alloc (KB) +df5_str db 'DOSBUF' ; lowmembuf, DOS INT 21h buffer (KB) +df6_str db 'DPMITST' ; test DPMI/VCPI or VCPI/DPMI on/off +df8_str db 'RESTORE' ; restore int vector table on exit on/off +df9_str db 'NULLP' ; install Null-Pointer protection on/off +dfA_str db 'VERBOSE' ; use verbose mode on/off +dfB_str db 'NOWARN' ; disable particular warning (NUM) +dfC_str db 'NOC' ; disable copyright banner -- + + Align 4 +@area1_db label byte +@area1_dw label word +@area1_dd label dword + + +; INIT errors 00xx +;============================================================================= +d_err0 db 'this program requires DOS 4.0 or higher' ,0 +d_err1 db '80386 processor or better required to run protected mode' ,0 +d_err2 db 'system software does not follow VCPI/DPMI specifications' ,0 +d_err3 db 'present DPMI host does not support 32bit applications' ,0 +d_err4 db 'incompatible VCPI PIC mappings' ,0 +d_err5 db 'could not enter 32bit protected mode' ,0 +d_err6 db 'could not allocate system selectors' ,0 +d_err7 db 'could not enable A20 line' ,0 + + +; MEMORY errors 10xx +;============================================================================= +m_err1 db 'not enough DOS memory, additional %dKB needed' ,0 +m_err2 db 'DOS reported insufficient memory' ,0 + + +; EXEC errors 20xx +;============================================================================= +e_err0 db 'invalid environment' ,0 +e_err1 db 'could not open exec file "%s"' ,0 +e_err2 db 'error in exec file "%s"' ,0 + + +; APPLICATION errors 30xx +;============================================================================= +a_err1 db 'could not open application file "%s"' ,0 +a_err2 db 'error in application file "%s"' ,0 +a_err3 db 'file "%s" does not contain any valid exec format' ,0 +a_err4 db 'exec format not supported in file "%s"' ,0 + + +; LOADER errors 40xx +;============================================================================= +l_err1 db 'too many objects in application exec "%s"' ,0 +l_err2 db 'not enough DOS memory to load application exec "%s"' ,0 +l_err3 db 'not enough extended memory to load application exec "%s"' ,0 +l_err4 db 'not enough extended memory to load fixups for exec "%s"' ,0 +l_err5 db 'unrecognized fixup data in application exec "%s"' ,0 +l_err6 db '16bit fixup overflow in application exec "%s"' ,0 +l_err7 db 'not enough DOS Transfer Buffer space to load LC-exec "%s"' ,0 + + +; MISC. errors 80xx +;============================================================================= +x_err1 db 'syntax is DOS32A ' ,0 +x_err2 db 'DOS reported an error (#%wh)' ,0 +x_err3 db 'DPMI host reported an error (#%wh)' ,0 + + +; WARNINGS 90xx +;============================================================================= +w_msg1 db 'no extended memory has been allocated' ,0 +w_msg2 db 'PICs have been relocated to INT %bh, INT %bh' ,0 +w_msg3 db 'real mode interrupt vector has been modified: INT %bh' ,0 +w_msg4 db 'mouse initialization failed' ,0 +w_msg5 db 'object #%d contains no data or code' ,0 +w_msg6 db 'incompatible version of DOS/32A already running' ,0 + + +; RUN-TIME errors 60xx +;============================================================================= +r_msg80 db 'unknown error code (#%bh)' ,0 +r_msg81 db 'out of real-mode virtual stacks' ,0 +r_msg82 db 'out of protected-mode virtual stacks' ,0 +r_msg83 db 'extended memory blocks have been corrupted (#%l)' ,0 +r_msg84 db 'DOS/4G API calls not supported' ,0 + + + +; Verbose messages +;============================================================================= +v_msg01 db 'Processor: %d, System: %s, Memory: DOS=%dKB, DPMI=%d%s',cre +v_msg02 db 'NONE',0, 'XMS',0,0, 'VCPI',0, 'DPMI',0 +v_msg03 db 'LE',0,'LX',0,'LC',0,'PE',0 +v_msg04 db 'KB',0 +v_msg05 db 'MB',0 +v_msg10 db 'Loading program "%s", %s-style',cre +v_msg11 db 'Object #%d loaded at %l, V/Psize: %l/%l, Flags=%w, Sel=%w',cre +v_msg12 db 'Startup CS:EIP=%w:%l, SS:ESP=%w:%l, %s EIP=%d:%l',cr + db 'Memory left: DOS=%dKB, DPMI=%d%s. PSP_Sel=%w, Env_Sel=%w, Env_Seg=%w',cre + + +;============================================================================= +excmsgE db 'exception',0 +excmsgI db 'unexpected interrupt',0 +excmsg1 db '%s %bh',cr + db 'Identity: %s at %w:%l',cre +excmsg2 db '%s crash address %d:%l',0 +excmsg4 db ', error code pushed on stack %l',0 + +excmsgA db 'Linear',0 +excmsgB db 'Unrelocated',0 +excmsgC db 'Module name: "%s", ProcessId=%w',cre + +nulmsg0 db 'Null-pointer protection at %w:%l',cre + +dbgmsg1 db 'EFLAGS = %l [%l.%l] ',0 +dbgmsg2 db 'CS:[EIP] = %b %b %b %b %b %b %b %b %b %b',0 +dbgmsg4 db 'EAX = %l ESI = %l DR6 = %l SS:[ESP+00] = %l',cre +dbgmsg5 db 'EBX = %l EDI = %l CR0 = %l SS:[ESP+04] = %l',cre +dbgmsg6 db 'ECX = %l EBP = %l CR2 = %l SS:[ESP+08] = %l',cre +dbgmsg7 db 'EDX = %l ESP = %l CR3 = %l SS:[ESP+0C] = %l',cre +dbgmsgA db 'Invalid selector',0 +dbgmsgB db 'NULL selector',0 + +selmsg1 db 'CS: = %w ',0 +selmsg2 db 'DS: = %w ',0 +selmsg3 db 'ES: = %w ',0 +selmsg4 db 'SS: = %w ',0 +selmsg5 db 'FS: = %w ',0 +selmsg6 db 'GS: = %w ',0 +selmsg0 db 'Base=%l Limit=%l Gr=%s Seg=%s/%dbit Type=%d Acc=%w',cre +selmsg9 db 'BYTE',0,'PAGE',0 +selmsg8 db 'DATA',0,'CODE',0 +selmsgX db 'KERNEL=',0 +selmsgY db 'CLIENT=',0 +selmsgZ db 'APP/32=',0 +selmsgW db 'APP/??=',0 + +i_msg00 db 'integer division by zero' ,0 +i_msg01 db 'hardware breakpoint' ,0 +i_msg02 db 'NMI' ,0 +i_msg03 db 'software breakpoint' ,0 +i_msg04 db 'overflow check fault' ,0 +i_msg05 db 'bounds check fault' ,0 +i_msg06 db 'invalid opcode fault' ,0 +i_msg07 db 'coprocessor not available' ,0 +i_msg08 db 'double fault' ,0 +i_msg09 db 'coprocessor segment overrun' ,0 +i_msg0A db 'invalid TSS fault' ,0 +i_msg0B db 'segment not present fault' ,0 +i_msg0C db 'stack fault' ,0 +i_msg0D db 'general protection fault' ,0 +i_msg0E db 'page fault' ,0 + diff -uNr a/dos32a/src/dos32a/text/client/debug.asm b/dos32a/src/dos32a/text/client/debug.asm --- a/dos32a/src/dos32a/text/client/debug.asm false +++ b/dos32a/src/dos32a/text/client/debug.asm 30b81317062b8362a8ea90927449f26088a98fb429ee5a931e0677e6a96d0fb4fe2489497d072015295a03b66cc78594fd1a98d197f00ee1c17b3757b58b4453 @@ -0,0 +1,767 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.386p +;============================================================================= +; IN: AL = interrupt number (if applicable) +; AH = kernel error code: +; +; 81h = unhandled interrupt/exception +; 82h = out of real-mode virtual stacks +; 83h = out of protected-mode virtual stacks +; 84h = extended memory blocks have been corrupted +; 85h = DOS/4G API calls not supported +; +;============================================================================= +critical_handler: + cli ; immediately disable interrupts + cld ; clear direction flag + mov ds,cs:_sel_ds ; restore client DS + lss esp,fptr _sel_esp ; restore client SS:ESP + + push ax ; push error code + mov al,20h ; send EOI codes to PICs + out 0A0h,al + out 020h,al + + mov ax,_pic_mask ; restore PIC masks + out 0A1h,al + mov al,ah + out 021h,al + + call restore_pit + call restore_inttab + call tone + call scr_on + pop dx ; DH = code, DL = int number + + mov ax,6001h ; error 6001: "unexpected interrupt" + cmp dh,81h + jz @@arg_dl + + mov al,02h ; error 6002: "out of real-mode virtual stacks" + cmp dh,82h + jz @@report + + mov al,03h ; error 6003: "out of protected-mode virtual stacks" + cmp dh,83h + jz @@report + + mov al,04h ; error 6004: "extended memory blocks have been corrupted" + cmp dh,84h + jz @@arg_esi + + mov al,05h ; error 6005: "DOS/4G API calls not supported" + cmp dh,85h + jz @@report + + mov al,00h ; error 6000: "unknown error code" + +@@arg_dl: + movzx si,dl ; load SI with DL + jmp @@report + +@@arg_esi: + rol esi,16 ; convert ESI to DI:SI + mov di,si + shr esi,16 + +@@report: + call report_error + mov al,0FFh ; exit with error code 0FFh + jmp exit386 + + + + +;============================================================================= +eh00: push 00h + jmp eh_common +eh01: push 01h + jmp eh_debug +eh02: push 02h + jmp eh_common +eh03: push 03h + jmp eh_debug +eh04: push 04h + jmp eh_common +eh05: push 05h + jmp eh_common +eh06: push 06h + jmp eh_common +eh07: push 07h + jmp eh_common +eh08: push 08h + jmp eh_common +eh09: push 09h + jmp eh_common +eh0A: push 0Ah + jmp eh_common +eh0B: push 0Bh + jmp eh_common +eh0C: push 0Ch + jmp eh_common +eh0D: push 0Dh + jmp eh_common +eh0E: push 0Eh + jmp eh_common + + +;============================================================================= +; Machine state at the point of exception: +; +; +; Stack Frame relative to ms_frame_ ss:esp +; +; 00:SS +1Ch +; ESP +18h +; EFL +14h +; 00:CS +10h +; EIP +0Ch +; ec +08h +; Ret: 00:CS +04h +; Ret: EIP +00h +; +;-------------------- +; Stack Frame relative to ss:esp at the point of eh_reporter +; +; DS +26h +; ES +24h +; FS +22h +; GS +20h +; EAX +1Ch +; ECX +18h +; EDX +14h +; EBX +10h +; ESP +0Ch +; EBP +08h +; ESI +04h +; EDI +00h +; +eh_debug: + cmp cs:_sys_type,3 + jz @@0 + + push eax + mov eax,dr6 ; check if breakpoint on one of DRs + and al,0Fh + pop eax + jnz eh_common ; if yes, jump + +@@0: add esp,2 ; pop INT # + and bptr [esp+15h],0FEh ; reset trap flag + db 66h ; do 32bit far ret + retf + + +;============================================================================= +;eh_debug_continue: +; popad +; pop gs fs es ds +; lss esp,fptr cs:ms_frame_esp ; restore app's SS:ESP +; and bptr [esp+15h],0FEh ; reset trap flag +; db 66h ; do 32bit far ret +; retf + +;============================================================================= +;eh_debug_trap: +; popad +; pop gs fs es ds +; lss esp,fptr cs:ms_frame_esp ; restore app's SS:ESP +; or bptr [esp+15h],01h ; set trap flag +; db 66h ; do 32bit far ret +; retf + + +;============================================================================= +eh_common: + cli + cld + + push ax ; save AX + mov ax,ds ; AX = app's DS + mov ds,cs:_sel_ds ; load DS with client's data selector + mov ms_reg_ds,ax ; machine state: save DS + pop ax ; restore AX + + pop ms_int ; machine state: save INT # + + mov ms_frame_ss,ss ; machine state: save eh frame SS + mov ms_frame_esp,esp ; machine state: save eh frame ESP + + lss esp,fptr _sel_esp ; switch to internal stack + + push ms_reg_ds + push es + push fs + push gs + pushad + + mov es,ms_frame_ss + mov ebp,ms_frame_esp + + mov eax,es:[ebp+08h] + mov ms_ec,eax ; machine state: save error code + mov eax,es:[ebp+14h] + mov ms_eflags,eax ; machine state: save EFLAGS +; +; make FS:ESI = app's CS:EIP +; make GS:EDI = app's SS:ESP +; + mov ax,es:[ebp+10h] ; load app CS + call check_selector ; validate app's CS + mov fs,ax ; FS = app CS + + mov ax,es:[ebp+1Ch] ; load app SS + call check_selector ; validate app's SS + mov gs,ax ; GS = app SS + + mov esi,es:[ebp+0Ch] ; load app EIP + mov edi,es:[ebp+18h] ; load app ESP +; +; copy CRx regs +; + xor eax,eax + mov ms_reg_cr0,eax ; machine state: reset CR0 + mov ms_reg_cr2,eax ; machine state: reset CR2 + mov ms_reg_cr3,eax ; machine state: reset CR3 + mov ms_reg_dr6,eax ; machine state: reset DR6 + + cmp _sys_type,3 + jz @@1 + mov eax,cr0 + mov ms_reg_cr0,eax ; machine state: save CR0 + mov eax,cr2 + mov ms_reg_cr2,eax ; machine state: save CR2 + mov eax,cr3 + mov ms_reg_cr3,eax ; machine state: save CR3 + mov eax,dr6 + mov ms_reg_dr6,eax ; machine state: save DR6 + +@@1: mov ebp,esp + + mov al,20h ; send EOI to PICs + out 0A0h,al + out 020h,al + + mov ax,_pic_mask ; restore PIC masks + out 0A1h,al + mov al,ah + out 021h,al + +eh_reporter: + call restore_pit + call restore_inttab + call tone + call scr_on + + call dump_description + call dump_description2 + + push _process_id + push offs start + mov dx,offs excmsgC + call prints + add sp,4 + + call dump_origin ; dump origin of exception + call dump_eflags ; dump EFLAGS + call dump_opcodes ; dump op-codes @ CS:EIP + + call dump_regs ; dump regs, CRs, stack + call dump_selectors ; dump selectors + + mov al,-1 + jmp exit386 + + + + + +;============================================================================= +dump_description: + mov eax,ms_reg_dr6 ; check if this is a breakpoint on one of DRs + and al,0Fh + jz @@0 ; if not, jump + + call check_faultsel ; check if CS is known code selector + push esi ; show EIP + push fs ; show CS + mov dx,offs nulmsg0 ; "Null-pointer protection..." + call prints + add sp,6 + ret + +@@0: push 6001h ; manually push error code + mov dx,offs errmsg3 ; 'DOS/32A run-time:' + call prints + pop ax ; remove arg from stack + + mov ebx,-2 ; FIXME: can crash + call loadl_cs_eip ; load 4 bytes at CS:[EIP-2] + + mov bl,0CDh ; check for INT # opcode + mov bh,bptr ms_int + cmp ax,bx + + mov cx,offs excmsgE ; "exception" + jnz @@1 + mov cx,offs excmsgI ; "unexpected interrupt" + +@@1: mov ax,ms_int ; machine state: get INT # + mov bx,ax + add bx,bx + + push esi ; show EIP + push fs ; show CS + push wptr i_msg[bx] ; int name + push ax ; int number + push cx ; "exception" + mov dx,offs excmsg1 ; main string + call prints + add sp,12 + + ret + + +;============================================================================= +dump_description2: + call check_faultsel ; check if CS is known code selector + push eax ; addr + push cx ; object # + mov ax,offs excmsgA ; "Linear" + jc @@1 + mov ax,offs excmsgB ; "Unrelocated" +@@1: push ax + mov dx,offs excmsg2 ; "...crash address..." + call prints + add sp,8 + + mov ax,ms_int + cmp al,08h ; if error code present, show it + jb @@3 + cmp al,09h + je @@2 + cmp al,0Eh + ja @@3 + +@@2: push ms_ec ; display error code + mov dx,offs excmsg4 + call prints + add sp,4 + +@@3: call printcr + + ret + + +;============================================================================= +; In: FS = app's CS +; +dump_origin: + mov al,'=' + mov cx,72 +@@0: call printc + loop @@0 + + mov ax,fs + cmp ax,0008h ; note: kernel selector hardcoded! + mov dx,offs selmsgX ; exception came from "KERNEL" + jz @@1 + cmp ax,_sel_cs + mov dx,offs selmsgY ; exception came from "CLIENT" + jz @@1 + cmp ax,_sel32_cs + mov dx,offs selmsgZ ; exception came from "APP/32" + jz @@1 + mov dx,offs selmsgW ; where do all they come from? +@@1: call prints + jmp printcr + + +;============================================================================= +dump_eflags: + mov cl,8 + mov ebx,ms_eflags + xor eax,eax + xor edx,edx +@@0: shr bl,1 + rcr eax,4 + shr bh,1 + rcr edx,4 + loop @@0 + push eax + push edx + push ms_eflags + mov dx,offs dbgmsg1 + call prints + add sp,12 + ret + + +;============================================================================= +; In: FS:ESI = app's CS:EIP +; +dump_opcodes: + mov cl,10 + mov ebx,9 +@@0: call loadb_cs_eip + push ax + dec ebx + loop @@0 + mov dx,offs dbgmsg2 + call prints + add sp,10*2 + jmp printcr + + +;============================================================================= +; In: SS:EBP = local stack frame +; FS:ESI = app's CS:EIP +; GS:EDI = app's SS:ESP +; +dump_regs: + xor ebx,ebx + call loadl_ss_esp + push eax ; STK[0] + push ms_reg_dr6 ; DR6 + push dptr [ebp+04h] ; ESI + push dptr [ebp+1Ch] ; EAX + mov dx,offs dbgmsg4 + call prints + add sp,16 + + add bx,4 + call loadl_ss_esp + push eax ; STK[4] + push ms_reg_cr0 ; CR0 + push dptr [ebp+00h] ; EDI + push dptr [ebp+10h] ; EBX + mov dx,offs dbgmsg5 + call prints + add sp,16 + + add bx,4 + call loadl_ss_esp + push eax ; STK[8] + push ms_reg_cr2 ; CR2 + push dptr [ebp+08h] ; EBP + push dptr [ebp+18h] ; ECX + mov dx,offs dbgmsg6 + call prints + add sp,16 + + add bx,4 + call loadl_ss_esp + push eax ; STK[12] + push ms_reg_cr3 ; CR3 + push edi ; ESP + push dptr [ebp+14h] ; EDX + mov dx,offs dbgmsg7 + call prints + add sp,16 + + ret + + +;============================================================================= +; In: SS:EBP = local stack frame +; FS:ESI = app's CS:EIP +; GS:EDI = app's SS:ESP +; +dump_selectors: + mov dx,offs selmsg1 + mov ax,fs ; CS selector + call describe_selector + + mov dx,offs selmsg2 + mov ax,[ebp+26h] ; DS selector + call describe_selector + + mov dx,offs selmsg3 + mov ax,[ebp+24h] ; ES selector + call describe_selector + + mov dx,offs selmsg4 + mov ax,gs ; SS selector + call describe_selector + + mov dx,offs selmsg5 + mov ax,[ebp+22h] ; FS selector + call describe_selector + + mov dx,offs selmsg6 + mov ax,[ebp+20h] ; GS selector + call describe_selector + + ret + + + + + +;============================================================================= +; In: AX = selector +; +describe_selector: + push ax + call prints + pop ax + test ax,ax ; check if NULL selector + jnz @@1 + mov dx,offs dbgmsgB + call prints + jmp printcr + +@@1: mov bx,ax + sub sp,8 ; get selector info + push ss + pop es + mov edi,esp + mov ax,000Bh + int 31h + jnc @@2 ; branch if selector is OK + add sp,8 ; invalid selector + mov dx,offs dbgmsgA + call prints + jmp printcr + +@@2: mov ax,wptr es:[edi+5] ; describe selector + mov dx,ax + push ax ; Acc + + shr al,1 + and ax,07h + push ax ; Type + + mov cl,dh + shr cl,6 + and cl,1 + mov ax,16 + shl ax,cl + push ax ; Seg: USE16/USE32 + + mov al,dl + shr al,3 + and eax,01h + lea eax,selmsg8[eax*4+eax] + push ax ; Seg: DATA/CODE + + mov al,dh + shr al,7 + and eax,01h + lea eax,selmsg9[eax+eax*4] + push ax ; Granularity + + mov al,dh + and eax,0Fh + shl eax,16 + mov ax,wptr es:[edi+0] + push eax ; Limit + mov ah,bptr es:[edi+7] + mov al,bptr es:[edi+4] + shl eax,16 + mov ax,wptr es:[edi+2] + push eax ; Base + mov dx,offs selmsg0 + call prints + add sp,26 + ret + + +;============================================================================= +; In: FS:ESI = app CS:EIP +; +; Out: if FS = known selector: +; CF clear +; CX:EAX = N:unrelocated_addr +; else +; CF set +; CX:EAX = 0:linear_addr +check_faultsel: + mov ax,6 ; get base of app's CS + mov bx,fs + int 31h + shl ecx,16 + mov cx,dx ; ECX = base of app's CS + lea eax,[ecx+esi] ; EAX = linear addr (eg CS.base + EIP) + mov ecx,_app_num_objects + jcxz @@err +@@0: cmp bx,_app_buf_allocsel[ecx*2] + jz @@ok + loop @@0 +@@err: stc + ret +@@ok: sub eax,_app_buf_allocbase[ecx*4] ; EAX = unrelocated addr + clc + ret + + +;============================================================================= +; In: AX = selector +; +; Out: if valid selector AX.out == AX.in +; else AX = 0 (Null selector) +; +check_selector: + lar bx,ax ; get access rights + jnz @@0 ; if sel not a valid selector, jump + verr ax ; verify selector read access + jnz @@0 ; if non-readable, jump + not bx ; invert Present bit + test bh,80h ; test Present bit + jnz @@0 ; if segment not present, jump + ret +@@0: xor ax,ax ; return Null selector + ret + + +;============================================================================= +; In: FS:ESI = app's CS:EIP +; EBX = offset +; +; Out: AL +; +loadb_cs_eip: + mov ax,fs + test ax,ax + jnz @@0 + xor eax,eax + ret +@@0: movzx eax,bptr fs:[esi+ebx] + ret + +;============================================================================= +; In: FS:ESI = app's CS:EIP +; EBX = offset +; +; Out: EAX +; +loadl_cs_eip: + mov ax,fs + test ax,ax + jnz @@0 + xor eax,eax + ret +@@0: mov eax,fs:[esi+ebx] + ret + +;============================================================================= +; In: GS:EDI = app's SS:ESP +; EBX = offset +; +; Out: EAX +; +loadl_ss_esp: + mov ax,gs + test ax,ax + jnz @@0 + xor eax,eax + ret +@@0: mov eax,gs:[edi+ebx] + ret + + + + + +.8086 +;============================================================================= +tone: push ax cx + mov ax,0500h + mov cx,0110h + call beep + mov ax,0300h + call beep + pop cx ax + ret + +;============================================================================= +beep: test cs:_misc_byte,00000010b + jnz @@0 + ret + +@@0: push cx dx ax ; AX=frequency, CX=time + mov al,0B6h ; set frequency + out 43h,al + pop ax + out 42h,al ; fLow + mov al,ah + out 42h,al ; fHigh + in al,61h ; beep on + or al,03h + out 61h,al +@@loop: in al,40h + in al,40h + mov ah,al +@@1: in al,40h + in al,40h + cmp ah,al + je @@1 + loop @@loop + in al,61h ; beep off + and al,not 03h + out 61h,al + pop dx cx + ret + +;============================================================================= +scr_on: push ax bx cx dx + test cs:_misc_byte,01000000b + jz @@0 + + mov ax,0003h + int 10h ; set default videomode + +@@0: mov dx,03C4h ; turn on VGA screen + mov al,01 + out dx,al + inc dx + in al,dx + and al,0DFh + out dx,al + pop dx cx bx ax + ret + + +PopState + diff -uNr a/dos32a/src/dos32a/text/client/int10h.asm b/dos32a/src/dos32a/text/client/int10h.asm --- a/dos32a/src/dos32a/text/client/int10h.asm false +++ b/dos32a/src/dos32a/text/client/int10h.asm 0b05fb9f373a0aca408114f975bc50f6e833e25b564e43b3fe14ce7a8d832e4ea6a9dd40b77a4bc9a2f847f6d986d1782fc4657933bf95afc50fd9984b92c021 @@ -0,0 +1,377 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.386p +;============================================================================= +_int10: cld + push ds es + pushad + + cmp ah,1Bh + jz @v_1Bh + cmp ah,1Ch + jz @v_1Ch + cmp ax,4F00h + jz @v_4F00h + cmp ax,4F01h + jz @v_4F01h + cmp ax,4F04h + jz @v_4F04h + cmp ax,4F09h + jz @v_4F09h + cmp ax,4F0Ah + jz @v_4F0Ah + + popad + pop es ds + db 66h + jmp cs:_int10_ip + + + +;============================================================================= +; VGA: Read Functionality Information +; In: BX = implementation type +; ES:EDI = 64 byte buffer +; Out: AL = 1Bh if function supported by VGA BIOS +; BX = implementation type +; ES:EDI = 64 byte buffer +; +@v_1Bh: sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax ; store AX + mov [ebp+10h],bx ; store BX + mov ds,cs:_sel_ds + mov ax,_seg_buf + mov wptr [ebp+22h],ax ; store ES + mov wptr [ebp+00h],0 ; store DI + call int10h + mov ecx,16 + mov esi,_lobufbase + rep movs dword ptr es:[edi],[esi] + movzx eax,wptr [ebp+1Ch] ; get AX + movzx ebx,wptr [ebp+10h] ; get BX + add esp,32h + mov [esp+1Ch],eax ; return EAX + mov [esp+10h],ebx ; return EBX + jmp @__ok + + +;============================================================================= +; VGA: Save/Restore VGA Video State +; In: AL = subfunction: +; 00h - get state buffer size +; Return: EBX = number of 64-byte blocks needed +; 01h - save video states +; 02h - restore video states +; ECX = states to save/restore +; ES:EBX = pointer to save/restore buffer +; Out: AL = 1Ch if function supported by VGA BIOS +; +@v_1Ch: test al,al + jz @v_1Ch_00 + cmp al,01h + jz @v_1Ch_01 + cmp al,02h + jz @v_1Ch_02 + jmp @v_err + +@v_1Ch_00: + pushfd + db 66h + call cs:_int10_ip + movzx eax,ax + movzx ebx,bx + mov [esp+1Ch],eax + mov [esp+10h],ebx + jmp @__ok + +@v_1Ch_01: + sub esp,32h + mov ebp,esp + call @v_std + call int10h + mov esi,_lobufbase + mov edi,ebx + mov ax,1C00h + xor bx,bx + int 10h + mov ecx,ebx + shl ecx,4 + rep movs dptr es:[edi],[esi] + jmp @v_ok + +@v_1Ch_02: + sub esp,32h + mov ebp,esp + call @v_std + mov esi,ebx + mov edi,_lobufbase + mov ax,1C00h + xor bx,bx + int 10h + mov ecx,ebx + shl ecx,4 + push ds es + pop ds es + rep movs dptr es:[edi],[esi] + call int10h + jmp @v_ok + + +;============================================================================= +; VESA: Get SuperVGA Information +; In: ES:EDI = 512 byte buffer +; Out: AL = 4Fh if function supported by VESA BIOS +; AH = 00h if function was successful +; ES:EDI = 512 byte buffer +; +;============================================================================= +; VESA: Get SuperVGA Mode Information +; In: CX = VideoMode +; ES:EDI = 256 byte buffer +; Out: AL = 4Fh if function supported by VESA BIOS +; AH = 00h if function was successful +; ES:EDI = 256 byte buffer +; +@v_4F00h: +@v_4F01h: + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax ; store AX + mov [ebp+18h],cx ; store CX + mov dx,ax + mov ds,cs:_sel_ds + mov ax,_seg_buf + mov wptr [ebp+22h],ax ; store ES + mov wptr [ebp+00h],0 ; store DI + call int10h + mov esi,_lobufbase + test dl,dl + mov ecx,64 + jnz @@1 + + lea ebx,[esi+06h] ; offset of OEM Str + call @@mod + lea ebx,[esi+0Eh] ; offset of VideoMode Ptr + call @@mod + lea ebx,[esi+16h] ; offset of OEM Version Ptr + call @@mod + lea ebx,[esi+1Ah] ; offset of OEM Name Ptr + call @@mod + lea ebx,[esi+1Eh] ; offset of OEM Revision Ptr + call @@mod + mov ecx,128 +@@1: rep movs dptr es:[edi],[esi] + jmp @v_ok + +@@mod: movzx edx,wptr [ebx+00h] ; get low word (offset) + movzx eax,wptr [ebx+02h] ; get high word (segment) + shl eax,4 ; convert real mode seg:off + add eax,edx ; to linear ptr relative to zero + mov dx,[ebx+02h] + cmp dx,_seg_buf + jnz @@ok + sub eax,_lobufzero ; since the structure will be moved + add eax,edi ; from buffer, we must adjust ptr +@@ok: mov [ebx+00h],eax + ret + + +;============================================================================= +; VESA: Save/Restore SuperVGA Video State +; In: DL = subfunction: +; 00h - get state buffer size +; Return: BX = number of 64-byte blocks needed +; 01h - save video states +; 02h - restore video states +; ECX = states to save/restore +; ES:EBX = pointer to save/restore buffer +; Out: AL = 4Fh if function supported by VESA BIOS +; AH = 00h if function was successful +; +@v_4F04h: + test dl,dl + jz @v_1Ch_00 + cmp dl,01h + jz @v_4F04h_01 + cmp dl,02h + jz @v_4F04h_02 + jmp @v_err + +@v_4F04h_01: + sub esp,32h + mov ebp,esp + call @v_std + call int10h + mov esi,_lobufbase + mov edi,ebx + mov ax,4F04h + xor dl,dl + xor bx,bx + int 10h + mov ecx,ebx + shl ecx,4 + rep movs dptr es:[edi],[esi] + jmp @v_ok + +@v_4F04h_02: + sub esp,32h + mov ebp,esp + call @v_std + mov esi,ebx + mov edi,_lobufbase + mov ax,4F04h + xor dl,dl + xor bx,bx + int 10h + mov ecx,ebx + shl ecx,4 + push ds es + pop ds es + rep movs dptr es:[edi],[esi] + call int10h + jmp @v_ok + + +;============================================================================= +; VESA: Load/Unload Palette Data +; In: BL = subfunction: +; 00h - set palette data +; 01h - get palette data +; 02h - set 2nd palette data +; 03h - get 2nd palette data +; 80h - set palette data during VR +; ECX = number of palette registers to update +; EDX = first palette register to update +; ES:EDI = pointer to buffer +; Out: AL = 4Fh if function supported by VESA BIOS +; AH = 00h if function was successful +; +@v_4F09h: + cmp bl,03h + jbe @@0 + cmp bl,80h + jnz @v_err +@@0: sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov [ebp+18h],cx + mov [ebp+14h],dx + mov [ebp+10h],bx + mov ds,cs:_sel_ds + mov ax,_seg_buf + mov wptr [ebp+22h],ax + mov wptr [ebp+00h],0 + test bl,bl + jz @@1 + dec bl + jz @@2 + dec bl + jz @@1 + dec bl + jz @@2 +@@1: mov esi,edi + mov edi,_lobufbase + push ds es + pop ds es + rep movs dptr es:[edi],[esi] + call int10h + jmp @v_ok +@@2: call int10h + mov esi,_lobufbase + rep movs dptr es:[edi],[esi] + jmp @v_ok + + +;============================================================================= +; VESA: Get Protected Mode Interface +; In: BL = 00h - return protected mode table +; Out: AL = 4Fh if function supported by VESA BIOS +; AH = 00h if function was successful +; ES = protected mode selector of table +; EDI = offset of table +; ECX = length of table +; +@v_4F0Ah: + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov [ebp+10h],bx + call int10h + movzx eax,wptr [ebp+1Ch] ; get AX + movzx ecx,wptr [ebp+18h] ; get CX + movzx edx,wptr [ebp+22h] ; get ES segment + movzx edi,wptr [ebp+00h] ; get DI pointer + cmp ax,004Fh ; check that there was no error + jnz @v_ok + shl edx,4 + add edi,edx ; convert seg:off to linear addr + add esp,32h + mov [esp+1Ch],eax ; set EAX + mov [esp+18h],ecx ; set ECX + mov [esp+00h],edi ; set EDI + mov ax,cs:_sel_zero + mov [esp+20h],ax ; set ES + jmp @__ok + + + + +;----------------------------------------------------------------------------- +@v_std: mov [ebp+1Ch],ax ; store AX + mov [ebp+18h],cx ; store CX + mov [ebp+14h],dx ; store DX + mov ds,cs:_sel_ds + mov ax,_seg_buf + mov wptr [ebp+22h],ax ; store ES + mov wptr [ebp+10h],0 ; store BX + ret +@v_ok: movzx eax,wptr [ebp+1Ch] + add esp,32h + mov [esp+1Ch],eax + jmp @__ok +@v_err: mov dptr [esp+1Ch],-1 + jmp @__ok + + +PopState diff -uNr a/dos32a/src/dos32a/text/client/int21h.asm b/dos32a/src/dos32a/text/client/int21h.asm --- a/dos32a/src/dos32a/text/client/int21h.asm false +++ b/dos32a/src/dos32a/text/client/int21h.asm df7fa6c8d493b3af578b3fa23121b5f17ec4c7382afc2347f993bebeba50fdfa75769761174b7b892a61d95c351b5a654c8ed93cb5347973c43fe6961ecca592 @@ -0,0 +1,1493 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.386p +;============================================================================= +_int21: cld + test cs:_sys_misc,0100h ; check for CTRL-C flag + jnz _ctrl_c + + push ds es + pushad + + cmp ah,09h ; Print string: DS:EDX + jz @__09h + + cmp ah,1Ah ; Set DTA buffer: DS:EDX + jz @__1Ah + cmp ah,1Bh ; Get DefDrive Info: -> AL, DS:EBX, ECX EDX + jz @__1Bh + cmp ah,1Ch ; Get Drive Info: AL, (-> ---//---) + jz @__1Ch + cmp ah,1Fh ; Get DefDrive PB: -> AL, DS:EBX + jz @__1Fh + + cmp ah,25h ; Set INT vector: AL, DS:EDX + jz @__25h + + cmp ah,2Fh ; Get DTA buffer: -> ES:EBX + jz @__2Fh + cmp ah,31h ; Go TSR AL + jz @__31h + cmp ah,32h ; Get Drive PB: AL, (-> DS:EBX) + jz @__32h + cmp ah,34h ; Get InDOS flag: -> ES:EBX + jz @__34h + + cmp ah,35h ; Get INT vector: AL, ES:EBX + jz @__35h + + cmp ah,39h ; Create DIR: DS:EDX + jz @__39h + cmp ah,3Ah ; Remove DIR: DS:EDX + jz @__3Ah + cmp ah,3Bh ; Change DIR: DS:EDX + jz @__3Bh + + cmp ah,3Ch ; Create file: CX, DS:EDX + jz @__3Ch + cmp ah,3Dh ; Open file: AL, DS:EDX + jz @__3Dh + cmp ah,3Fh ; Read file: BX, ECX, DS:EDX + jz @__3Fh + cmp ah,40h ; Write file: BX, ECX, DS:EDX + jz @__40h + cmp ah,41h ; Delete file: DS:EDX + jz @__41h + cmp ah,42h ; Move file ptr: AL, BX, EDX, (->EAX) + jz @__42h + cmp ah,43h ; Change file attr: CX, DS:EDX + jz @__43h + + cmp ax,4402h ; IOCTL Read: BX, ECX, DS:EDX + jz @__4402h + cmp ax,4403h ; IOCTL Write: BX, ECX, DS:EDX + jz @__4403h + cmp ax,4404h ; IOCTL Read: BX, ECX, DS:EDX + jz @__4404h + cmp ax,4405h ; IOCTL Write: BX, ECX, DS:EDX + jz @__4405h + + cmp ah,47h ; Get DIR: DL, DS:ESI + jz @__47h + + cmp ah,48h ; Alloc mem: BX (->AX) + jz @__48h + cmp ah,49h ; Dealloc mem: ES + jz @__49h + cmp ah,4Ah ; Realloc mem: BX + jz @__4Ah + + cmp ah,4Bh ; Execute Prog: AL, DS:EDX, ES:EBX + jz @__4Bh + cmp ah,4Ch ; Terminate Prog: AL + jz @__4Ch + + cmp ah,4Eh ; Find file: CX, DS:EDX + jz @__4Eh + cmp ah,4Fh ; Find next file: - + jz @__4Fh + cmp ah,51h ; Get PSP segment: (->BX) + jz @__51h + cmp ah,56h ; Rename file: DS:EDX, ES:EDI + jz @__56h + cmp ah,5Ah ; Create temp file: CX, DS:EDX + jz @__5Ah + cmp ah,5Bh ; Create new file: CX, DS:EDX + jz @__5Bh + cmp ah,62h ; Get PSP selector: (->BX) + jz @__62h + + cmp ah,0FFh ; Rational DOS/4G call + jz @__FFh + + cmp ah,71h ; Windows 95 long filename extensions + jnz @__go21 + cmp al,39h ; Win95 Create DIR: DS:EDX + jz @__39h + cmp al,3Ah ; Win95 Remove DIR: DS:EDX + jz @__3Ah + cmp al,3Bh ; Win95 Change DIR: DS:EDX + jz @__3Bh + cmp al,41h ; Win95 Delete file: DS:EDX, CX, SI + jz @__41h + cmp al,43h ; Win95 Change attr: DS:EDX, BL, CX + jz @__43h + cmp al,47h ; Win95 Get curr DIR: DS:ESI, DL + jz @__47h + cmp al,56h ; Win95 Rename file: DS:EDX, ES:EDI + jz @__56h + cmp al,60h ; Win95 True name: + jz @_7160 + cmp al,6Ch ; Win95 C/Open file: + jz @_716C + +@__go21:popad + pop es ds + db 66h + jmp cs:_int21_ip + + +_ctrl_c:mov ax,4CFFh ; exit on CTRL-C with code 255 + jmp @__4Ch + + + + +;============================================================================= +; Print String +; In: DS:EDX = offset of string +; Out: - +; +@__09h: push ds + pop es + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov esi,edx + mov edi,edx + mov al,'$' + or ecx,-1 + repne scas bptr es:[edi] + not ecx + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + rep movs bptr es:[edi],[esi] + stos bptr es:[edi] + mov ax,cs:_seg_buf + mov wptr [ebp+24h],ax + mov wptr [ebp+14h],00h + call int21h + add esp,32h + jmp @__ok + + + +;============================================================================= +; Set DTA buffer +; In: DS:EDX = sel:offs +; Out: - +; +@__1Ah: mov es,cs:_sel_ds + mov es:_app_dta_sel,ds + mov es:_app_dta_off,edx + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov ax,cs:_seg_dta + mov wptr [ebp+24h],ax + mov wptr [ebp+14h],0 + call int21h + add esp,32h + jmp @__ok + + + +;============================================================================= +; Get Default Drive Info +; In: - +; Out: AL = sectors per cluster +; DS:EBX = addr of FAT +; ECX = bytes per sector +; EDX = number of clusters on drive +; +@__1Bh: +@__1Ch: call @__all + mov [esp+1Ch],al + cmp al,0FFh + jz @@done + mov [esp+14h],edx + mov [esp+18h],ecx + shl esi,4 + add ebx,esi + mov [esp+10h],ebx + mov ax,cs:_sel_zero + mov [esp+22h],ax +@@done: jmp @__ok + + + +;============================================================================= +; Get Drive Info +; In: DL = Drive number +; Out: AL = sectors per cluster +; DS:EBX = addr of FAT +; ECX = bytes per sector +; EDX = number of clusters on drive +; +;@__1Ch: jmp @__1Bh + + + +;============================================================================= +; Get DefDrive Parameter Block +; In: - +; Out: AL = status +; DS:EBX = addr of DPB +; +@__1Fh: +@__32h: call @__all + mov [esp+1Ch],al + cmp al,0FFh + jz @@done + shl esi,4 + add ebx,esi + mov [esp+10h],ebx + mov ax,cs:_sel_zero + mov [esp+22h],ax +@@done: jmp @__ok + + + +;============================================================================= +; Set INT vector +; In: AL = INT vector, DS:EDX = sel:offs +; Out: - +; +@__25h: mov bl,al + mov cx,ds + mov ax,0205h + int 31h + jc @__err + jmp @__ok + + + +;============================================================================= +; Get DTA buffer +; In: - +; Out: ES:EBX = addr of DTA +; +@__2Fh: mov ax,cs:_app_dta_sel + mov [esp+20h],ax + mov eax,cs:_app_dta_off + mov [esp+10h],eax + jmp @__ok + + + +;============================================================================= +; Go TSR +; In: AL = exit code +; Out: - +; +@__31h: sub esp,32h + mov ebp,esp + + mov bx,cs:_membase + add bx,cs:_buf_size + sub bx,cs:_seg_es + mov [ebp+1Ch],ax + mov [ebp+14h],bx + call int21h + + add esp,32h + jmp @__ok + + + +;============================================================================= +; Get Drive Parameter Block +; In: DL = drive number +; Out: AL = status +; DS:EBX = addr of DPB +; +;@__32h: jmp @__1Fh + + + +;============================================================================= +; Get InDOS flag address +; In: - +; Out: ES:EBX = addr of InDOS flag +; +@__34h: call @__all + shl edi,4 + add ebx,edi + mov [esp+10h],ebx + mov ax,cs:_sel_zero + mov [esp+20h],ax + jmp @__ok + + + +;============================================================================= +; Get INT vector +; In: AL = INT vector +; Out: ES:EBX = sel:offs +; +@__35h: mov bl,al + mov ax,0204h + int 31h + mov [esp+20h],cx + mov [esp+10h],edx + jmp @__ok + + + +;============================================================================= +; Create Directory +; In: DS:EDX = directory name +; Out: - +; +@__39h: +@__3Ah: +@__3Bh: +@__41h: +@__5Ah: +@__5Bh: + call @__std + jz @__ok + mov [esp+1Ch],eax + jmp @__err + + + +;============================================================================= +; Remove Directory +; In: DS:EDX = directory name +; Out: - +; +;@__3Ah: jmp @__39h + + + +;============================================================================= +; Change Directory +; In: DS:EDX = directory name +; Out: - +; +;@__3Bh: jmp @__39h + + + +;============================================================================= +; Create File +; In: DS:EDX = file name, ECX = attributes +; Out: EAX = file handle +; +@__3Ch: +@__3Dh: call @__std + mov [esp+1Ch],eax + jz @__ok + jmp @__err + + + +;============================================================================= +; Open File +; In: DS:EDX = file name, AL = access mode +; Out: EAX = file handle +; +;@__3Dh: jmp @__3Ch + + + +;============================================================================= +; Read from File +; In: DS:EDX = addr, ECX = size, EBX = handle +; Out: EAX = bytes read +; +@__4402h: +@__4404h: +@__3Fh: + push ds + pop es + mov ds,cs:_sel_ds ; DS=_TEXT16 + sub esp,32h + mov ebp,esp + mov [ebp+10h],bx ; store handle in structure + + mov edi,edx ; ES:EDI=destination + mov ebx,ecx ; EBX=bytes to read + xor edx,edx ; EDX=counter bytes read + +@@loop: mov [ebp+1Ch],ax ; store AX in structure + mov ax,_seg_buf + mov [ebp+24h],ax ; store DS in structure + mov wptr [ebp+14h],0 ; store DX in structure + + mov eax,ebx + cmp eax,_lobufsize + jbe @@1 + mov eax,_lobufsize +@@1: mov [ebp+18h],ax ; store CX in structure + + call int21h ; DOS read + movzx eax,wptr [ebp+1Ch] ; EAX=bytes read + test bptr [ebp+20h],1 ; check for error + jnz @@err + + test ax,ax ; if read 0 bytes + jz @@done ; then we're done + + mov esi,_lobufbase ; DS:ESI=source + call @__cp2 ; copy buffer to destination + + add edx,eax ; adjust bytes read + + cmp wptr [ebp+10h],0 ; if was reading from stdin + jz @@done ; then we're done + + sub ebx,eax ; adjust bytes to read + mov ax,[ebp+1Ch+32h] + ja @@loop + +@@done: add esp,32h + mov [esp+1Ch],edx ; store bytes count + jmp @__ok +@@err: add esp,32h + mov [esp+1Ch],eax ; error reading, store errcode + jmp @__err + + + +;============================================================================= +; Write to File +; In: DS:EDX = addr, ECX = size, EBX = handle +; Out: EAX = bytes written +; +@__4403h: +@__4405h: +@__40h: mov es,cs:_sel_ds + sub esp,32h + mov ebp,esp + mov [ebp+10h],bx ; store handle in structure + + mov esi,edx ; DS:ESI=source + mov ebx,ecx ; EBX=bytes to write + xor edx,edx ; EDX=counter bytes written + +@@loop: mov [ebp+1Ch],ax ; store AX in structure + mov ax,cs:_seg_buf + mov [ebp+24h],ax ; store DS in structure + mov wptr [ebp+14h],0 ; store DX in structure + + mov eax,ebx + cmp eax,cs:_lobufsize + jbe @@1 + mov eax,cs:_lobufsize +@@1: mov [ebp+18h],ax ; store CX in structure + + mov edi,cs:_lobufbase + call @__cp2 ; copy source into buffer + + call int21h ; DOS write to file + movzx eax,wptr [ebp+1Ch] ; EAX=bytes written + test bptr [ebp+20h],1 ; check for error + jnz @@err + + test ax,ax + jz @@done ; if 0 bytes written, we're done + + add edx,eax ; adjust bytes written + sub ebx,eax ; adjust bytes to write + mov ax,[ebp+1Ch+32h] + ja @@loop ; loop until done + +@@done: add esp,32h + mov [esp+1Ch],edx ; store bytes count + jmp @__ok +@@err: add esp,32h + mov [esp+1Ch],eax ; error writing, store errcode + jmp @__err + + + +;============================================================================= +; Delete File +; In: DS:EDX = file name +; Out: - +; +;@__41h: jmp @__39h + + + +;============================================================================= +; Move File Ptr +; In: ECX:EDX = ptr, AL = mode +; Out: EDX:EAX = ptr +; +@__42h: call @__all + mov [esp+1Ch],eax + jnz @__err + mov [esp+14h],edx + jmp @__ok + + + +;============================================================================= +; Change File Attributes +; In: DS:EDX = file name +; Out: - +; +@__43h: call @__std + jz @@1 + mov [esp+1Ch],eax + jmp @__err +@@1: mov [esp+18h],ecx + jmp @__ok + + + +;============================================================================= +; Get Directory +; In: DL = drive +; DS:ESI = buffer +; Out: - +; +@__47h: sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov [ebp+14h],dx + mov ax,cs:_seg_buf + mov [ebp+24h],ax + mov wptr [ebp+04h],0 + call int21h + test bptr [ebp+20h],1 + jnz @@err + push ds + pop es + mov edi,esi + mov ds,cs:_sel_ds + mov esi,_lobufbase +@@1: lods bptr ds:[esi] + stos bptr es:[edi] + test al,al + jnz @@1 + add esp,32h + jmp @__ok +@@err: movzx eax,wptr [ebp+1Ch] + add esp,32h + mov [esp+1Ch],eax + jmp @__err + + + +;============================================================================= +; Allocate DOS Memory +; In: EBX = bytes to allocate +; Out: EAX = selector +; +@__48h: mov ax,0100h + int 31h + jc @@1 + movzx edx,dx + mov [esp+1Ch],edx + jmp @__ok +@@1: movzx eax,ax + movzx ebx,bx + mov [esp+1Ch],eax + mov [esp+10h],ebx + jmp @__err + + + +;============================================================================= +; Deallocate DOS Memory +; In: ES = selector +; Out: - +; +@__49h: mov ax,0101h + mov dx,es + int 31h + jnc @@0 + movzx eax,ax + mov [esp+1Ch],eax + jmp @__err +@@0: mov wptr [esp+20h],0 + jmp @__ok + + + +;============================================================================= +; Resize DOS Memory +; In: ES = selector, EBX = new size +; Out: - +; +@__4Ah: mov ax,0102h + mov dx,es + int 31h + jnc @__ok + movzx eax,ax + movzx ebx,bx + mov [esp+1Ch],eax + mov [esp+10h],ebx + jmp @__err + + + +;============================================================================= +; Execute Program (sub-func AL=00h) +; In: AL = 00h +; DS:EDX = path name +; ES:EBX = parameter block +; Out: - +; +@__4Bh: test al,al ; only subfunction AL=00h supported + jnz @__err + cmp cs:_lobufsize,0400h ; buffer size must be at least 1Kb + jb @__err ; if less, return -1 + + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax ; put AX in structure + + push es + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + mov esi,edx + add edi,100h +@@1: lods bptr ds:[esi] ; copy Path\Name into buffer + stos bptr es:[edi] + test al,al + jnz @@1 + pop es + + push ds es + mov esi,es:[ebx+06h] + mov edi,cs:_lobufbase + mov ds,es:[ebx+0Ah] + mov es,cs:_sel_ds + add edi,180h + movzx ecx,bptr ds:[esi] + inc cx + inc cx + rep movs bptr es:[edi],[esi] ; copy command line + pop es ds + + push ds es + mov edi,es:[ebx+00h] ; get environment + mov ax,es:[ebx+04h] + test ax,ax ; check env selector is 0 + jz @@3 ; if yes, jump + mov es,ax + xor ax,ax + mov esi,edi + or ecx,-1 +@@2: repne scas bptr es:[edi] + dec ecx + scas bptr es:[edi] + jnz @@2 + not ecx + mov ax,0100h ; allocate mem for environment + mov bx,cx + shr bx,4 + inc bx + int 31h + jc @@4 + push es + pop ds + mov es,dx + xor edi,edi + rep movs bptr es:[edi],[esi] ; copy environment +@@3: mov ds,cs:_sel_ds + mov edi,_lobufbase + mov wptr [edi+00h],ax + mov ax,_seg_buf + mov wptr [edi+02h],180h + mov wptr [edi+04h],ax + mov ax,_seg_es + mov wptr [edi+06h],5Ch + mov wptr [edi+08h],ax + mov wptr [edi+0Ah],6Ch + mov wptr [edi+0Ch],ax +@@4: pop es ds + jc @@err + + push dx ; save env selector + mov ds,cs:_sel_ds + mov ax,_seg_buf + mov wptr [ebp+22h],ax + mov wptr [ebp+24h],ax + mov wptr [ebp+10h],0000h + mov wptr [ebp+14h],0100h + + cmp _sys_type,3 + jz @@5 + mov eax,cr0 + mov edi,eax + and al,0FBh + mov cr0,eax +@@5: call uninstall_client_ints + call int21h + call install_client_ints + cmp _sys_type,3 + jz @@6 + mov cr0,edi + +@@6: pop dx ; restore env sel + mov ax,0101h + int 31h + + movzx eax,wptr [ebp+1Ch] ; get return code + test bptr [ebp+20h],01h ; check carry flag + lea esp,[esp+32h] + mov [esp+1Ch],eax ; put return code in AX + jnz @__err ; if error, set carry on ret + jmp @__ok + +@@err: add esp,32h + mov dptr [esp+1Ch],-1 + jmp @__err + + + +;============================================================================= +; Terminate Program +; In: AL = error code +; Out: - +; +@__4Ch: cli ; disable interrupts + cld + mov ds,cs:_sel_ds ; restore SEG registers + mov es,_sel_es + lss esp,fptr _sel_esp ; set default stack + push ax + mov ax,_sel_env + mov es:[002Ch],ax ; restore default environment + + cmp _sys_type,3 ; if under DPMI, do not clear DRx + jz @@1 + xor eax,eax + mov dr7,eax + +@@1: push es ; undefine Mouse ISR + mov ax,000Ch + xor edx,edx + mov cx,dx + mov es,dx + int 33h + pop es + + mov dx,_mus_backoff ; free mouse callback + mov cx,_mus_backseg + mov ax,cx + or ax,dx + jz @@2 + mov ax,0304h + int 31h + +@@2: mov ecx,_app_num_objects ; deallocate selectors + jcxz @@4 +@@3: mov ax,0001h + mov bx,_app_buf_allocsel[ecx*2] + int 31h + loop @@3 + +@@4: call check_inttab + call restore_inttab + call uninstall_client_ints + +@@5: mov ax,0001h ; free ZERO selector + mov bx,cs:_sel_zero + int 31h + + xor ax,ax + mov fs,ax + mov gs,ax + pop ax + db 66h ; 32-bit jump + jmp cs:_int21_ip ; exit with errorcode in AL + + + +;============================================================================= +; Find First File +; In: CX = file attributes +; DS:EDX = file name +; Out: - +; +@__4Eh: call @__std + jnz @@err + mov ds,cs:_dta_sel + mov esi,cs:_dta_off + mov es,cs:_app_dta_sel + mov edi,cs:_app_dta_off + mov ecx,2Bh + rep movs bptr es:[edi],[esi] + jmp @__ok +@@err: mov [esp+1Ch],eax + jmp @__err + + + +;============================================================================= +; Find Next File +; In: - +; Out: - +; +@__4Fh: mov ds,cs:_app_dta_sel + mov esi,cs:_app_dta_off + mov es,cs:_dta_sel + mov edi,cs:_dta_off + mov ecx,2Bh + rep movs bptr es:[edi],[esi] + call @__all + jnz @@err + mov ds,cs:_dta_sel + mov esi,cs:_dta_off + mov es,cs:_app_dta_sel + mov edi,cs:_app_dta_off + mov ecx,2Bh + rep movs bptr es:[edi],[esi] + jmp @__ok +@@err: mov [esp+1Ch],eax + jmp @__err + + + +;============================================================================= +; Get PSP Segment +; In: - +; Out: EBX = PSP segment +; +@__51h: movzx eax,cs:_seg_es + mov [esp+10h],eax + jmp @__ok + + + +;============================================================================= +; Rename File +; In: DS:EDX = old filename +; ES:EDI = new filename +; Out: - +; +@__56h: sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + or ecx,-1 + xor al,al + repne scas bptr es:[edi] + not ecx + sub edi,ecx + mov esi,edi + push ds + push es + pop ds + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + rep movs bptr es:[edi],[esi] + pop ds + mov ecx,edi + mov ebx,cs:_lobufbase + sub ecx,ebx + xchg ecx,ebx + push ds + pop es + mov esi,edx + xchg esi,edi + or ecx,-1 + xor al,al + repne scas bptr es:[edi] + not ecx + sub edi,ecx + xchg esi,edi + mov es,cs:_sel_ds + rep movs bptr es:[edi],[esi] + mov ax,cs:_seg_buf + mov [ebp+24h],ax + mov [ebp+22h],ax + mov wptr [ebp+00h],0 + mov [ebp+14h],bx + call int21h + jmp @__tst + + + +;============================================================================= +; Create Temp File +; In: DS:EDX = file name +; Out: - +; +;@__5Ah: jmp @__39h + + + +;============================================================================= +; Create New File +; In: CX = attributes +; DS:EDX = file name +; Out: - +; +;@__5Bh: jmp @__39h + + + +;============================================================================= +; Get PSP Selector +; In: - +; Out: BX = PSP selector +; +@__62h: movzx eax,cs:_sel_es + mov [esp+10h],eax + jmp @__ok + + + +;============================================================================= +; Win95 Get Short (8.3) filename +; In: CL = 00/01/02h +; CH = SUBST expansion flag +; DS:ESI = ASCIIZ long filename or path +; ES:EDI = 261/128/261-byte buffer for short name +; Out: - +; +@_7160: sub esp,32h + mov ebp,esp + push es edi + mov [ebp+1Ch],ax + mov [ebp+18h],cx + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + add edi,0200h +@@1: lods bptr ds:[esi] + stos bptr es:[edi] + test al,al + jnz @@1 + mov ax,cs:_seg_buf + mov wptr [ebp+24h],ax + mov wptr [ebp+22h],ax + mov wptr [ebp+04h],0200h + mov wptr [ebp+00h],0000h + call int21h + push es + pop ds + mov esi,cs:_lobufbase + pop edi es + test bptr [ebp+20h],1 + jnz @@err +@@2: lods bptr ds:[esi] + stos bptr es:[edi] + test al,al + jnz @@2 + add esp,32h + jmp @__ok +@@err: movzx eax,wptr [ebp+1Ch] + add esp,32h + mov [esp+1Ch],eax + jmp @__err + + + +;============================================================================= +; Win95 Create or Open File +; In: BX = access mode +; CX = attributes +; DX = action +; DI = alias hint +; DS:ESI = ASCIIZ long filename +; Out: AX = file handle +; CX = action taken +; +@_716C: sub esp,32h + mov ebp,esp + mov [ebp+00h],di + mov [ebp+10h],bx + mov [ebp+14h],dx + mov [ebp+18h],cx + mov [ebp+1Ch],ax + mov ax,cs:_seg_buf + mov wptr [ebp+24h],ax + mov wptr [ebp+04h],0 + mov es,cs:_sel_ds + mov edi,cs:_lobufbase +@@0: lods bptr ds:[esi] + stos bptr es:[edi] + test al,al + jnz @@0 + call int21h + movzx eax,wptr [ebp+1Ch] + movzx ecx,wptr [ebp+18h] + test bptr [ebp+20h],1 + lea esp,[esp+32h] + mov [esp+1Ch],eax + jnz @__err + mov [esp+18h],ecx + jmp @__ok + + + + + +;============================================================================= +; DOS/4G Identification call +; In: AX = 0FF00h, DX = 0078h +; Out: EAX = 0FFFF3447h '..4G' +; +@__FFh: cmp al,88h ; AX=0FF88h - DOS/32A functional call + jz @_FF88 + cmp al,89h ; AX=0FF89h - DOS/32A get config + jz @_FF89 + cmp al,8Ah ; AX=0FF8Ah - DOS/32A get info + jz @_FF8A + cmp al,8Dh ; AX=0FF8Dh - DOS/32A decompress data + jz @_FF8D + cmp al,8Eh ; AX=0FF8Eh - DOS/32A get Client ptrs + jz @_FF8E + cmp al,8Fh ; AX=0FF8Fh - DOS/32A resize DOS buf + jz @_FF8F + + cmp al,80h ; AX=0FF80h - DOS/32A prints (magic) + jz @_FF80 + cmp al,90h ; AX=0FF90h - DOS/32A get hi mem + jz @_FF90 + cmp al,91h ; AX=0FF91h - DOS/32A alloc hi mem + jz @_FF91 + cmp al,92h ; AX=0FF92h - DOS/32A free hi mem + jz @_FF92 + cmp al,93h ; AX=0FF93h - DOS/32A resize hi mem + jz @_FF93 + + cmp al,94h ; AX=0FF94h - DOS/32A get lo mem + jz @_FF94 + cmp al,95h ; AX=0FF95h - DOS/32A alloc lo mem + jz @_FF95 + cmp al,96h ; AX=0FF96h - DOS/32A free lo mem + jz @_FF96 + cmp al,97h ; AX=0FF97h - DOS/32A resize lo mem + jz @_FF97 + + cmp al,98h ; AX=0FF98h - DOS/32A map phys mem + jz @_FF98 + cmp al,99h ; AX=0FF99h - DOS/32A free phys mem + jz @_FF99 + cmp al,9Ah ; AX=0FF9Ah - DOS/32A alloc selector + jz @_FF9A + + cmp dx,0078h ; DX=0078h - DOS/4G detection + jnz @__go21 + mov gs,cs:_sel_ds + mov dptr [esp+1Ch],4734FFFFh + jmp @__ok + + +;============================================================================= +; DOS/32A Identification call +; In: AX = 0FF88h +; Out: EAX = 'ID32' +; EBX = DOS Extender version +; +@_FF88: sub esp,32h ; DOS/32A internal function + mov ebp,esp + mov [ebp+1Ch],ax + call int21h + mov eax,'ID32' + movzx ebx,cs:_version + mov ecx,[ebp+18h] + mov edx,[ebp+14h] + mov esi,[ebp+04h] + mov edi,[ebp+00h] + mov ebp,[esp+3Ah] + add esp,52h + jmp @__exi + +;============================================================================= +; DOS/32A Get Client Configuration +; In: AX = 0FF89h +; Out: EAX = 'ID32' +; EBX = DOS Extender version +; ECX = size of low buffer +; EDX = configuration bits +; ESI = pointer to ID32 config header +; FS = zero selector +; +@_FF89: mov eax,'ID32' + movzx esi,cs:_seg_id32 + shl esi,4 + mov fs,cs:_sel_zero + movzx ebx,cs:_version + mov ecx,cs:_lobufsize + movzx edx,wptr cs:_misc_byte + add esp,20h + jmp @__exi + +;============================================================================= +; DOS/32A Get Kernel Configuration +; In: AX = 0FF8Ah +; Out: EAX = 'ID32' +; EBX = DOS Extender version +; CL = CPU type +; CH = System software +; DL = Kernel configuration bits +; ESI = pointer to Kernel config header +; FS = zero selector +; +@_FF8A: mov eax,'ID32' + movzx esi,cs:_seg_kernel + shl esi,4 + add esi,offs pm32_data + mov fs,cs:_sel_zero + movzx ebx,cs:_version + mov cl,cs:_cpu_type + mov ch,cs:_sys_type + mov dl,fs:[esi+00h] + add esp,20h + jmp @__exi + +;============================================================================= +; DOS/32A Decompress data +; In: AX = 0FF8Dh +; DS:EBX = source address +; DS:EDI = destination address +; ECX = source size +; Out: EAX = destination size +; +@_FF8D: push gs ds + pop gs + mov ds,cs:_sel_ds + call decompress + mov eax,_codesize + sub eax,edi + pop gs + mov [esp+1Ch],eax + jmp @__ok + +;============================================================================= +; DOS/32A Return pointers to Client variables +; In: AX = 0FF8Eh +; Out: GS = Client data selector +; EDX = pointer to "start" == module file name +; ESI = pointer to loaded application sel/base table +; EDI = pointer to Client variables structure +; +@_FF8E: mov gs,cs:_sel_ds + mov edx,offs start + mov esi,offs _app_buf_allocsel + mov edi,offs _misc_byte + add esp,20h + jmp @__exi + +;============================================================================= +; DOS/32A Resize DOS transfer buffer +; In: AX = 0FF8Fh +; EBX = new size of DOS transfer buffer in bytes +; Out: EBX = old size of DOS transfer buffer in bytes +; +@_FF8F: mov ds,cs:_sel_ds + xchg _lobufsize,ebx + mov [esp+10h],ebx + jmp @__ok + + +;============================================================================= +; DOS/32A Print String (Magic) +; In: AX = 0FF80h +; EBX = value +; DS:EDX = pointer to string +; Out: - +; +@_FF80: mov es,cs:_sel_ds + mov edi,cs:_lobufbase + mov esi,edx + mov dx,di +@@1: lods bptr ds:[esi] + stosb + test al,al + jnz @@1 + push es + pop ds + mov _int_ss,ss + mov _int_esp,esp + lss esp,fptr _sel_esp + push ecx + push ebx + call prints + lss esp,fptr _int_esp + jmp @__ok + + +;============================================================================= +; DOS/32A Get Free Extended Memory Information +; In: AX = 0FF90h +; Out: EAX = largest free memory block +; +@_FF90: push ss + pop es + sub esp,30h + mov edi,esp + mov ax,0500h + int 31h + mov eax,[esp] + add esp,30h + mov [esp+1Ch],eax + jmp @__ok + +;============================================================================= +; DOS/32A Allocate Extended Memory +; In: AX = 0FF91h +; EBX = size of block +; Out: EBX = linear address of block +; ESI = handle of block +; +@_FF91: call @_FF9x1 + mov ax,0501h + int 31h + jmp @_FF9x2 + +;============================================================================= +; DOS/32A Free Extended Memory +; In: AX = 0FF92h +; ESI = handle of block +; Out: - +; +@_FF92: call @_FF9x1 + mov ax,0502h + int 31h + jc @__err + jmp @__ok + +;============================================================================= +; DOS/32A Resize Extended Memory +; In: AX = 0FF93h +; EBX = new size of block +; ESI = handle of block +; Out: EBX = new linear address of block +; ESI = new handle of block +; +@_FF93: call @_FF9x1 + mov ax,0503h + int 31h + jmp @_FF9x2 + +;============================================================================= +; DOS/32A Get Free DOS Memory Information +; In: AX = 0FF94h +; Out: EAX = largest free memory block +; +@_FF94: mov ah,48h + mov bx,-1 + call @__all + shl ebx,4 + mov [esp+1Ch],ebx + jmp @__ok + +;============================================================================= +; DOS/32A Allocate DOS Memory +; In: AX = 0FF94h +; EBX = size of block +; Out: EBX = linear address of block +; ESI = handle of block +; +@_FF95: add ebx,0Fh + shr ebx,4 + test ebx,0FFFF0000h + jnz @__err + test bx,bx + jz @__err + mov ah,48h + call @__all + jnz @__err + mov [esp+04h],eax + shl eax,4 + mov [esp+10h],eax + jmp @__ok + +;============================================================================= +; DOS/32A Free DOS Memory +; In: AX = 0FF96h +; ESI = handle of block +; Out: - +; +@_FF96: sub esp,32h + mov ebp,esp + mov bptr [ebp+1Dh],49h + mov wptr [ebp+22h],si + call int21h + test bptr [ebp+20h],1 + lea esp,[esp+32h] + jnz @__err + jmp @__ok + +;============================================================================= +; DOS/32A Resize DOS Memory +; In: AX = 0FF97h +; EBX = new size of block +; ESI = handle of block +; Out: EBX = new linear address of block +; ESI = new handle of block +; +@_FF97: add ebx,0Fh + shr ebx,4 + test ebx,0FFFF0000h + jnz @__err + test bx,bx + jz @__err + sub esp,32h + mov ebp,esp + mov bptr [ebp+1Dh],4Ah + mov wptr [ebp+10h],bx + mov wptr [ebp+22h],si + call int21h + test bptr [ebp+20h],1 + lea esp,[esp+32h] + jnz @__err + jmp @__ok + +;============================================================================= +; DOS/32A Map Physical Memory +; In: AX = 0FF98h +; EBX = base of physical memory +; ESI = size of region +; Out: EBX = linear address of memory +; +@_FF98: call @_FF9x1 + mov ax,0800h + int 31h + jc @__err + jmp @_FF9x3 + +;============================================================================= +; DOS/32A Unmap Physical Memory +; In: AX = 0FF99h +; EBX = linear address of memory +; Out: - +; +@_FF99: call @_FF9x1 + mov ax,0801h + int 31h + jc @__err + jmp @__ok + +;============================================================================= +; DOS/32A Allocate Selector +; In: AX = 0FF94h +; EBX = selector base +; ECX = selector limit +; DX = selector access rights +; Out: AX = selector +; +@_FF9A: mov edi,ebx + call set_descriptor + jc @__err + mov [esp+1Ch],ax + jmp @__ok + + + + +;----------------------------------------------------------------------------- +@_FF9x1:mov cx,bx ; convert BX:CX to EBX + shr ebx,16 + mov di,si ; convert SI:DI to EDI + shr esi,16 + ret +@_FF9x2:jc @__err + shl esi,16 + mov si,di + mov [esp+04h],esi +@_FF9x3:shl ebx,16 + mov bx,cx + mov [esp+10h],ebx + jmp @__ok + + + + +;***************************************************************************** +@__cpy: push ds ; copy NULL-terminated string to buffer + pop es + xor ax,ax + mov esi,edx + mov edi,edx + or ecx,-1 + repne scas bptr es:[edi] + not ecx + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + rep movs bptr es:[edi],[esi] + mov ax,cs:_seg_buf + mov wptr [ebp+24h],ax + mov wptr [ebp+14h],0 + jmp int21h +@__cp2: mov ecx,eax ; copy buffer + shr cx,2 + rep movs dptr es:[edi],[esi] + mov cl,al + and cl,03h + rep movs bptr es:[edi],[esi] + ret +@__std: sub esp,32h + mov ebp,esp + mov [ebp+04h],si ; these two pass-downs are + mov [ebp+10h],bx ; for Win95 longfilenames + mov [ebp+18h],cx + mov [ebp+1Ch],ax + call @__cpy + movzx eax,wptr [ebp+1Ch] + movzx ecx,wptr [ebp+18h] + test bptr [ebp+20h],1 + lea esp,[esp+32h] ; restore stack + ret +@__all: sub esp,32h + mov ebp,esp + mov [ebp+10h],bx + mov [ebp+14h],dx + mov [ebp+18h],cx + mov [ebp+1Ch],ax + call int21h + movzx eax,wptr [ebp+1Ch] + movzx ecx,wptr [ebp+18h] + movzx edx,wptr [ebp+14h] + movzx ebx,wptr [ebp+10h] + movzx edi,wptr [ebp+22h] ; ES + movzx esi,wptr [ebp+24h] ; DS + test bptr [ebp+20h],1 + lea esp,[esp+32h] ; restore stack + ret +@__tst: movzx eax,wptr [ebp+1Ch] ; get error number + test bptr [ebp+20h],1 ; check if CF is set + lea esp,[esp+32h] ; restore stack + mov [esp+1Ch],eax ; put EAX (error) on stack + jnz @__err +@__ok: popad ; return ok +@__exi: pop es ds + and bptr [esp+8],0FEh + iretd +@__err: popad ; return with error + pop es ds + or bptr [esp+8],01h + iretd + + +PopState diff -uNr a/dos32a/src/dos32a/text/client/int33h.asm b/dos32a/src/dos32a/text/client/int33h.asm --- a/dos32a/src/dos32a/text/client/int33h.asm false +++ b/dos32a/src/dos32a/text/client/int33h.asm e2e31c006ffe4d231b2e02177072205f810923779ead9bd8a618345596f7b1f7915a1519c93eadfac862649fda724b46840c26c6fb1e4bce1664fb6ee45eac75 @@ -0,0 +1,285 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.386p +;============================================================================= +_int33: cld + push ds es + pushad + + cmp ax,0009h + jz @__0009h + cmp ax,000Ch + jz @__000Ch + cmp ax,0014h + jz @__0014h + cmp ax,0016h + jz @__0016h + cmp ax,0017h + jz @__0017h + cmp ax,0018h + jz @__0018h + cmp ax,0019h + jz @__0019h + cmp ax,0020h + jz @__0020h + + popad + pop es ds + db 66h + jmp cs:_int33_ip + + + + +;============================================================================= +; Define Graphics Cursor +; In: BX = column of cursor hotspot in bitmap +; CX = row of cursor hotspot in bitmap +; ES:EDX = mask bitmap +; +@__0009h: + push es + pop ds + sub esp,32h + mov ebp,esp + mov esi,edx + mov es,cs:_sel_zero + movzx edi,cs:_seg_mus + mov wptr [ebp+1Ch],ax + mov wptr [ebp+18h],cx + mov wptr [ebp+10h],bx + mov wptr [ebp+22h],di + mov wptr [ebp+14h],0 + shl edi,4 + mov ecx,10h + rep movs dptr es:[edi],[esi] + call int33h + add esp,32h + jmp @__ok + + + +;============================================================================= +; Define Interrupt Subroutine +; In: CX = call mask +; ES:EDX = far pointer to routine +; +@__000Ch: + call _mus_int_def + jmp @__ok + + +;============================================================================= +; Exchange Defined Interrupt Subroutine +; In: CX = call mask +; ES:EDX = far pointer to routine +; Out: CX = call mask +; ES:EDX = far pointer to routine +; +@__0014h: + mov si,wptr cs:_mus_sel + mov edi,dptr cs:_mus_off + call _mus_int_def + mov [esp+14h],edi + mov [esp+20h],si + jmp @__ok + + +;============================================================================= +; Define Interrupt Subroutine +; In: CX = call mask +; ES:EDX = far pointer to routine +; +@__0018h: + call _mus_int_def + mov [esp+1Ch],eax + jmp @__ok + + +;============================================================================= +; Return Defined Interrupt Subroutine +; In: CX = call mask +; Out: BX:EDX = far pointer to routine +; +@__0019h: + mov ax,wptr cs:_mus_sel + mov edx,dptr cs:_mus_off + mov [esp+14h],edx + mov [esp+10h],ax + jmp @__ok + + + +;----------------------------------------------------------------------------- +_mus_int_def: + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov [ebp+18h],cx + mov ds,cs:_sel_ds + xor eax,eax + mov _mus_off,edx + mov _mus_sel,es + mov ax,es + or eax,edx + jz @@1 + mov ax,_seg_ds + mov dx,offs _mus_int_rm +@@1: mov wptr [ebp+14h],dx + mov wptr [ebp+22h],ax + cli + call int33h + movzx eax,wptr [ebp+1Ch] + add esp,32h + sti + ret + +_mus_int_rm: + cmp cs:_mus_data,0 + mov cs:_mus_data,1 + jnz @@1 + jmp dword ptr cs:_mus_backoff +@@1: retf + +_mus_int_pm: + cld + pushad + push ds es fs gs + xor eax,eax + + mov ax,ds + mov ds,cs:_sel_ds + mov ds:_mus_esp,esp + mov ds:_mus_ss,ss + mov ds,ax + + mov ax,ss + lar eax,eax + shr eax,23 + jc @@1 + movzx esp,sp + +@@1: mov ax,cs:_seg_ds + mov wptr es:[edi+2Ch],ax + mov wptr es:[edi+2Ah],offs @@done + + movzx eax,wptr es:[edi+1Ch] + movzx ecx,wptr es:[edi+18h] + movzx edx,wptr es:[edi+14h] + movzx ebx,wptr es:[edi+10h] + movzx esi,wptr es:[edi+04h] + movzx edi,wptr es:[edi+00h] + pushfd + call fword ptr cs:_mus_off + + lss esp,fword ptr cs:_mus_esp + + pop gs fs es ds + popad + iretd +@@done: mov cs:_mus_data,0 + retf + + + +;============================================================================= +; Save Driver State +; In: BX = size of buffer +; ES:EDX = buffer for driver state +; +@__0016h: + sub esp,32h + mov ebp,esp + mov edi,edx + mov [ebp+1Ch],ax + mov ax,cs:_seg_buf + mov wptr [ebp+22h],ax + mov wptr [ebp+14h],0 + call int33h + mov ds,cs:_sel_ds + mov esi,_lobufbase + mov ecx,_mus_size + rep movs bptr es:[edi],[esi] + add esp,32h + jmp @__ok + + +;============================================================================= +; Restore Driver State +; In: BX = size of buffer +; ES:EDX = buffer containing saved state +; +@__0017h: + push es + pop ds + sub esp,32h + mov ebp,esp + mov esi,edx + mov [ebp+1Ch],ax + mov ax,cs:_seg_buf + mov wptr [ebp+22h],ax + mov wptr [ebp+14h],0 + mov es,cs:_sel_ds + mov edi,cs:_lobufbase + mov ecx,cs:_mus_size + rep movs bptr es:[edi],[esi] + call int33h + add esp,32h + jmp @__ok + + +;============================================================================= +; Enable Mouse Driver +; In: - +; +@__0020h: + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + call int33h + add esp,32h + mov wptr [esp+1Ch],-1 + jmp @__ok + + +PopState diff -uNr a/dos32a/src/dos32a/text/client/misc.asm b/dos32a/src/dos32a/text/client/misc.asm --- a/dos32a/src/dos32a/text/client/misc.asm false +++ b/dos32a/src/dos32a/text/client/misc.asm 96d599e5fc3078fec775f2f42f73df63de1632aedeec54fc496edaf561c64d6dc4fedd361d2b4eae35ff102c8074cb1b652c2b4127cc911fd9e1fadc368ca067 @@ -0,0 +1,975 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.8086 +;============================================================================= +; Real mode exit routine, using 8086 instructions +; +exit86: cli + cld + mov ds,cs:_seg_ds ; restore SEG regs + mov es,_seg_es + mov ss,_seg_ss + mov sp,STACKSIZE*16 ; set stack to default size + mov ax,_seg_env + mov es:[002Ch],ax + mov ax,4CFFh ; exit with error code -1 + int 21h ; NOTE: DOS 1.0 will hang + +.386p +;============================================================================= +; Protected mode exit routine, using 80386 instructions +; +exit386:cli + cld + mov ds,cs:_sel_ds ; restore SEG regs + mov es,_sel_es + lss esp,fptr _sel_esp ; set stack to default size + xor dx,dx + mov fs,dx + mov gs,dx + mov ah,4Ch ; exit with error code in AL + int 21h + +;============================================================================= +save_inttab: ; save real mode interrupts + push cx si di ds es + xor si,si + mov di,STACKSIZE*16 + mov ds,cs:_sel_zero + mov es,cs:_sel_ss + mov cx,0200h + cld + rep movsw + in al,21h ; save PIC mask + mov ah,al + in al,0A1h + pop es ds di si cx + mov _pic_mask,ax + ret + +;============================================================================= +restore_inttab: ; restore real mode interrupts + test cs:_misc_byte,00000100b + jz @@done + cmp cs:_sys_type,3 + jz @@1 + xor eax,eax ; reset Null-Pointer protection + mov dr7,eax +@@1: pushf + cli + push si di ds es + xor di,di + mov si,STACKSIZE*16 + mov es,cs:_sel_zero + mov ds,cs:_sel_ss + mov cx,0200h + cld + rep movsw + mov ax,cs:_pic_mask ; restore PIC mask + out 0A1h,al + mov al,ah + out 21h,al + pop es ds di si + popf +@@done: ret + +;============================================================================= +check_inttab: + test cs:_misc_byte,00001000b + jz @@done + pushad + push ds es + xor bx,bx + mov ds,cs:_sel_ss + mov es,cs:_sel_zero + mov esi,STACKSIZE*16 + xor edi,edi + cld +@@1: cmps dptr ds:[esi],[edi] + jnz @@2 +@@3: inc bx + cmp bx,256 + jb @@1 + pop es ds + popad +@@done: ret +@@2: mov ax,9003h + push bx si + mov si,bx + call report_error + pop si bx + jmp @@3 + +;============================================================================= +restore_pit: + push ax + mov al,36h ; reprogram PIT to DOS freq + out 43h,al + mov al,00h + out 40h,al + out 40h,al + pop ax + ret + +;============================================================================= +set_descriptor: ; EDI=base, ECX=limit, DX=access + push ebx ecx edx ebp + mov ebp,ecx + xor ax,ax ; allocate descriptor + mov cx,1 + int 31h + jc @@err + mov bx,ax + mov ax,0009h ; set access rights + mov cx,dx + int 31h + jc @@err + dec ax ; set limit + mov ecx,ebp + mov dx,cx + shr ecx,16 + int 31h + jc @@err + dec ax ; set base + mov ecx,edi + mov dx,cx + shr ecx,16 + int 31h + jc @@err + mov ax,bx +@@err: pop ebp edx ecx ebx + ret + +;============================================================================= +_int23: push ds ; handle CTRL-C INT 23h + mov ds,cs:_sel_ds + or _sys_misc,0100h + pop ds + iretd + +;============================================================================= +int10h: push bx ; simulate INT 10h (VGA API) + mov bx,10h + jmp intxxh + +int33h: push bx ; simulate INT 33h (Mouse API) + mov bx,33h + jmp intxxh + +int21h: push bx ; simulate INT 21h (DOS API) + mov bx,21h + +intxxh: push cx edi es + xor eax,eax + mov [ebp+20h],ax ; clear Flags + mov [ebp+2Eh],eax ; clear SS:SP + xor cx,cx + push ss + pop es + mov edi,ebp + mov ax,0300h + int 31h + pop es edi cx bx + jc dpmi_error + ret + + +;============================================================================= +setup_dta_buffer: + sub esp,32h + mov ebp,esp + mov ax,_seg_ss + add ax,0010h + mov _seg_dta,ax ; DTA at offset STK_TOP + 0100h + mov wptr [ebp+24h],ax + add ax,0008h + mov _seg_mus,ax ; MOUSE at offset STK_TOP + 0180h + mov ax,ss + mov _dta_sel,ax + mov _app_dta_sel,ax + mov eax,0100h + mov _dta_off,eax + mov _app_dta_off,eax + mov bptr [ebp+1Dh],1Ah + mov wptr [ebp+14h],0 + call int21h ; set up new DTA buffer + add esp,32h + ret + +;============================================================================= +initialize_mouse: + push ds + mov ds,_sel_zero + cmp dptr ds:[4*33h],0 ; check if mouse INT 33h is installed + pop ds + jz @@err ; if not, report warning + mov ax,0021h ; software reset mouse handler + int 33h + cmp ax,0021h ; check if function supported + jnz @@1 ; if yes, go on + xor ax,ax ; try hardware reset + int 33h + inc ax ; if failed, report warning + jnz @@err +@@1: mov ax,0015h ; get mouse buffer size + int 33h + movzx eax,bx + cmp eax,_lobufsize + jae @@err + mov _mus_size,eax + push ds es + push cs + pop ds + push ss + pop es + mov esi,offs _mus_int_pm + mov edi,STACKSIZE*16-40h + mov ax,0303h + int 31h + pop es ds + jc dpmi_error + mov _mus_backoff,dx + mov _mus_backseg,cx + ret +@@err: mov wptr _int33,0CF66h + mov ax,9004h + jmp report_error ; "mouse init failed" + +;============================================================================= +install_client_ints: + mov ax,0205h + mov cx,cs + + mov bl,10h + mov edx,offs _int10 + int 31h + jc @@err + + mov bl,21h + mov dx,offs _int21 + int 31h + jc @@err + + mov bl,23h + mov dx,offs _int23 + int 31h + jc @@err + + mov bl,33h + mov dx,offs _int33 + int 31h + jc @@err + + + mov ax,0203h + + mov bl,00h + mov dx,offs eh00 + int 31h + jc @@err + + mov bl,01h + mov dx,offs eh01 + int 31h + jc @@err + + mov bl,02h + mov dx,offs eh02 + int 31h + jc @@err + + mov bl,03h + mov dx,offs eh03 + int 31h + jc @@err + + mov bl,04h + mov dx,offs eh04 + int 31h + jc @@err + + mov bl,05h + mov dx,offs eh05 + int 31h + jc @@err + + mov bl,06h + mov dx,offs eh06 + int 31h + jc @@err + + mov bl,07h + mov dx,offs eh07 + int 31h + jc @@err + + mov bl,08h + mov dx,offs eh08 + int 31h + jc @@err + + mov bl,09h + mov dx,offs eh09 + int 31h + jc @@err + + mov bl,0Ah + mov dx,offs eh0A + int 31h + jc @@err + + mov bl,0Bh + mov dx,offs eh0B + int 31h + jc @@err + + mov bl,0Ch + mov dx,offs eh0C + int 31h + jc @@err + + mov bl,0Dh + mov dx,offs eh0D + int 31h + jc @@err + + mov bl,0Eh + mov dx,offs eh0E + int 31h + + clc +@@err: ret + + +;============================================================================= +uninstall_client_ints: + mov ax,0205h + + mov bl,10h + mov cx, wptr cs:_int10_cs + mov edx,dptr cs:_int10_ip + int 31h + + mov bl,21h + mov cx, wptr cs:_int21_cs + mov edx,dptr cs:_int21_ip + int 31h + + mov bl,23h + mov cx, wptr cs:_int23_cs + mov edx,dptr cs:_int23_ip + int 31h + + mov bl,33h + mov cx, wptr cs:_int33_cs + mov edx,dptr cs:_int33_ip + int 31h + + mov ax,0203h ; restore default PM exception handlers + xor ebx,ebx +@@0: mov cx,wptr cs:_exc_tab[ebx*8+4] + mov edx,dptr cs:_exc_tab[ebx*8+0] + int 31h + inc bl + cmp bl,15 + jb @@0 + + clc +@@done: ret + +;============================================================================= +install_nullptr_protect: + cmp _sys_type,3 + jz @@done + test _misc_byte,10000000b + jz @@done + + xor eax,eax ; install null-pointer protection + mov dr6,eax + mov dr0,eax + add al,04h + mov dr1,eax + add al,04h + mov dr2,eax + add al,04h + mov dr3,eax + mov eax,0DDDD03FFh + mov dr7,eax +@@done: ret + +;============================================================================= +setup_selectors: + xor edi,edi ; base = 0 + or ecx,-1 ; limit = 4GB + mov ax,cs ; get CS selector + lar dx,ax + mov dl,0C0h + xchg dh,dl + and dl,60h + or dl,92h + mov _acc_rights,dx ; set std selector access rights + call set_descriptor ; allocate descriptor + jc @@err + mov _sel_zero,ax + mov ax,0008h ; resize DS limit to 4GB + mov bx,ds ; this might be needed to access + mov cx,0FFFFh ; DOS buffer which is it self 64KB + mov dx,cx + int 31h + jc @@err + ret +@@err: mov ax,4CFFh + int 21h + + + + + +;============================================================================= +check_command_line: + mov di,80h + movzx cx,es:[di] ; get length of command line + jcxz @@err ; if zero, error + inc di ; offset to start of command line + mov al,20h + repe scasb ; look for non-space character + jz @@err ; if not found, error + dec di + inc cx + mov bx,di +@@1: mov al,es:[di] + cmp al,09h ; look for TAB character + jz @@2 + cmp al,0Dh ; look for CR character + jz @@2 + cmp al,20h ; look for ' ' character + jz @@2 + inc di + loop @@1 +@@2: mov cx,di + mov si,bx ; SI = pointer to file name + mov di,bx ; DI = pointer to file name + sub cx,bx ; CX = file name length +@@done: ret +@@err: xor si,si + ret + +;============================================================================= +remove_name_from_cmd: + call check_command_line + jz @@done + mov al,20h + rep stosb +@@done: ret + +;============================================================================= +check_if_fullname: + push ds es + call check_command_line + jz @@done + mov al,'\' + mov bx,cx + repne scasb + jcxz @@done + push ds es + pop ds es + mov cx,bx + mov di,offs start+40h + rep movsb + xor al,al + stosb +@@full: pop es ds + stc + ret +@@done: pop es ds + clc + ret + +;============================================================================= +update_environment: + push ds es + call check_if_fullname ; check if full path provided + jc @@skip ; if yes, skip copying + mov ah,19h + int 21h ; get drive letter + mov dl,al + add al,'A' + mov bptr [start+40h],al ; set drive + mov wptr [start+41h],'\:' + inc dx + mov ah,47h + mov esi,offs start+43h + int 21h ; get current directory + push ds + pop es + xor al,al + mov di,si + mov cx,64 + repne scasb ; get length of dir string + cmp bptr [di-2],'\' + jnz @@0 + dec di +@@0: mov bptr [di-1],'\' + mov si,offs start + mov cx,64 +@@1: lodsb + stosb + test al,al + loopne @@1 +@@skip: push ds + pop es + xor al,al + mov cx,-1 + mov di,offs start+40h + repne scasb + not cx + mov bx,cx + pop es + push es + mov ax,es:[002Ch] ; get environment selector + test ax,ax ; check if selector is NULL + jz @@err ; if yes, jump to error + lar cx,ax + jnz @@err + mov es,ax + xor al,al + xor di,di + mov cx,-1 +@@2: repne scasb + scasb + jnz @@2 + inc di + inc di + mov cx,-1 + mov dx,di + repne scasb + not cx + cmp bx,cx + ja create_new_environment + mov cx,bx + mov di,dx + mov si,offs start+40h + rep movsb + pop es ds + ret +@@err: mov ax,2000h + jmp report_error + +create_new_environment: + push bx + mov cx,-1 + xor di,di +@@1: repne scasb ; get size of environment + dec cx + scasb + jnz @@1 + not cx + inc cx + inc cx + push cx + add bx,cx + shr bx,4 + inc bx + mov ax,0100h + int 31h + pop cx + jc @@err + push es + pop ds + mov es,dx + xor si,si + xor di,di + rep movsb + pop cx + mov si,offs start+40h + push cs + pop ds + rep movsb + pop es ds + mov es:[002Ch],dx + ret +@@err: mov ax,2000h + jmp report_error + + +;============================================================================= +open_exec: + push ds es + mov ax,es:[002Ch] ; get environment selector + test ax,ax ; check if selector is NULL + jz @@err ; if yes, jump to error + lar cx,ax + jnz @@err + mov es,ax + xor ax,ax + xor di,di + mov cx,0FFFFh +@@1: repne scasb ; look for end of environment + scasb + jcxz @@err ; reached end of environment + jnz @@1 + inc di + inc di + push ds es + pop ds es + push di + mov si,di + mov di,offs start +@@2: lodsb + stosb + test al,al + jnz @@2 + pop di + movzx edx,di ; DS:EDX = pointer to exec name + mov ax,3DC0h ; open file + int 21h + pop es ds + mov _exec_handle,ax ; store file handle + mov ax,2001h + jc file_error ; if error, jump + ret +@@err: mov ax,2000h + jmp report_error + + + + +;============================================================================= +load_exec_header: + xor edx,edx ; DS:EDX = ptr + mov ecx,64 ; ECX = 64 bytes to load + mov _err_code,2002h ; "error in exec file" + call load_fs_block + cmp wptr fs:[0000h],'ZM' ; exec must be 'MZ' file type + jnz file_errorm + mov eax,fs:[003Ch] ; get start of 32-bit code + mov edx,fs:[0018h] ; get start of MZ reloc-table + mov _exec_start,eax + ret + + + + +;============================================================================= +open_extrn_exec: + push ds es + push ds es ; swap DS and ES + pop ds es + mov di,offs start ; copy application exec name + rep movsb + push es + pop ds + mov bptr [di],0 + mov edx,offs start + mov ax,3DC0h + int 21h + jc @@1 ; if error opening, try ".EXE" + pop es ds + mov _exec_handle,ax + ret + +@@1: mov bx,offs start +@@2: cmp bptr [bx],2Eh + stc + jz @@err + inc bx + cmp bx,di + jb @@2 + mov eax,4558452Eh + cmp eax,[di-4] + stc + jz @@err + mov eax,6578652Eh + cmp eax,[di-4] + stc + jz @@err + mov [di],eax + mov bptr [di+4],0 + mov ax,3DC0h + int 21h +@@err: pop es ds + mov _exec_handle,ax + mov ax,3001h + jc file_error + ret + + +;============================================================================= +load_extrn_exec_header: + xor edx,edx ; DS:EDX = ptr + mov ecx,64 ; ECX = 64 bytes to load + mov _err_code,3002h ; "error in app file" + call load_fs_block + call seek_from_start ; move to file start + + xor ebp,ebp + mov _exec_start,ebp ; default start of exec offset and + mov _app_off_datapages,ebp ; LE/LX data offset in file + cmp wptr fs:[0000h],'ZM' ; is exec 'MZ' file type + jnz search_for_le ; if not, search for known exec type + mov eax,fs:[0018h] ; MZ reloc-tab must be at offset 0040h + cmp ax,40h + jnz search_for_mz + mov eax,fs:[003Ch] ; if yes, get start of 32-bit code + test ax,ax ; check if it is bound + jz search_for_mz ; if not, search + mov _exec_start,eax + ret + + +search_for_mz: + xor esi,esi +@@0: movzx eax,wptr fs:[0004h] ; get pages in file + shl eax,9 ; *512 + movzx ebx,wptr fs:[0002h] ; get bytes on last page + add eax,ebx + mov bx,fs:[0000h] + cmp bx,'ZM' + jz @@1 + cmp bx,'WB' + jz @@2 + jmp @@3 +@@1: sub eax,0200h +@@2: mov esi,ebp + add ebp,eax + mov edx,ebp + call seek_from_start + mov ecx,64 + xor edx,edx + call load_fs_block + test eax,eax + jnz @@0 + mov ax,3003h + jmp file_error ; if zero, no app in file +@@3: mov bx,fs:[0000h] + cmp bx,'EL' + jz @@4 + cmp bx,'XL' + jz @@4 + cmp bx,'CL' + jz @@4 + cmp bx,'EP' + jz @@4 + mov edx,ebp + call seek_from_start + call search_for_le +@@4: cmp eax,esi + jz @@5 + mov edx,esi + add eax,10h + add edx,10h + and al,0F0h + and dl,0F0h + cmp eax,edx + jz @@5 + mov _exec_start,ebp + mov _app_off_datapages,esi +@@5: ret + +search_for_le: +@@1: mov edx,_lobufzero ; DS:EDX = current ptr + mov ecx,_lobufsize ; ECX = bytes to load + call load_gs_block + test ax,ax ; check if no bytes read + mov ax,3003h + jz file_error ; if true, no app in file + shr cx,1 +@@2: mov ax,gs:[edx+0] + mov bx,gs:[edx+2] + test bx,bx + jnz @@4 + cmp ax,'EL' ; 'LE' type + jz @@3 + cmp ax,'XL' ; 'LX' type + jz @@3 + cmp ax,'CL' ; 'LC' type + jz @@3 + cmp ax,'PE' ; 'PE' type + jz @@3 +@@4: add edx,2 + add ebp,2 ; increment pointer in file + loop @@2 + jmp @@1 +@@3: ret + + + + + +;============================================================================= +close_exec: + mov bx,cs:_exec_handle + mov ah,3Eh + int 21h + ret + + +;============================================================================= +seek_from_start: + push bx ecx edx eax + mov ecx,edx + shr ecx,16 + mov bx,cs:_exec_handle + mov ax,4200h + int 21h + pop eax edx ecx bx + jc file_errorm + ret + + +;============================================================================= +load_fs_block: + push bx ds fs + pop ds + jmp @load_block +load_gs_block: + push bx ds gs + pop ds +@load_block: + mov bx,cs:_exec_handle + mov ah,3Fh + int 21h + pop ds bx + jc file_errorm + ret + + +;============================================================================= +verbose_getmem: + pop bp + mov ax,0FF90h + int 21h + shr eax,10 + test eax,0FFFF0000h + mov dx,offs v_msg04 + jz @@1 + mov dx,offs v_msg05 + shr eax,10 +@@1: push dx + push ax + mov ah,48h + mov bx,-1 + int 21h + shr bx,6 + push bx + jmp bp + +verbose_showsys: + test _misc_byte2,00010000b + jz @@done + call verbose_getmem + movzx eax,_sys_type + lea eax,v_msg02[eax*4+eax] + push ax + movzx ax,_cpu_type + imul ax,100 + add ax,86 + push ax + mov dx,offs v_msg01 + call prints + add sp,10 +@@done: ret + +verbose_showloadhdr: + test _misc_byte2,00010000b + jz @@done + movzx eax,_app_type + lea eax,v_msg03[eax*2+eax] + push ax + push offs start + mov dx,offs v_msg10 + call prints + add sp,4 +@@done: ret + +verbose_showloadobj: + test _misc_byte2,00010000b + jz @@done + pushad + mov ax,dx + shr edx,16 + shl ebx,12 + push dx + push ax + push ebp + push ebx + push edi + push cx + mov dx,offs v_msg11 + call prints + add sp,18 + popad +@@done: ret + +verbose_showstartup: + test _misc_byte2,00010000b + jz @@done + push wptr _seg_env + push wptr es:[002Ch] + push wptr _sel_es + call verbose_getmem + mov eax,_app_eip + sub eax,_unreloc_eip + push eax + push wptr _app_eip_object + push offs excmsgB + push dptr _app_esp + push wptr _sel32_ss + push dptr _app_eip + push wptr _sel32_cs + mov dx,offs v_msg12 + call prints + add sp,32 +@@done: ret + + +win_focus_vm: ; Windows 9x - set focus on specified VM + test _misc_byte2,00000010b + jz @@done + xor bx,bx + mov ax,168Bh + int 2Fh +@@done: ret + + +PopState diff -uNr a/dos32a/src/dos32a/text/client/strings.asm b/dos32a/src/dos32a/text/client/strings.asm --- a/dos32a/src/dos32a/text/client/strings.asm false +++ b/dos32a/src/dos32a/text/client/strings.asm bd8829fe63241db333e5d3a39488ea8a7fa5f07c02e5e93372b034749f7ab05c5aee575fba19757fa645f78418216c7f763b084f3f6c360d6944b60ec300d126 @@ -0,0 +1,339 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +PushState + + +.8086 +;============================================================================= +; report_error: displays error code(AX) and error message +; report_errorm: retreives error code from memory +; +report_errorm: + mov ax,cs:_err_code +; +; note: this function may autimatically terminate the client +; +report_error: + push bx ds + cmp cs:_sel_ds,0 + jnz @@1 + mov ds,cs:_seg_ds + jmp @@2 +@@1: mov ds,cs:_sel_ds +@@2: xor bx,bx +@@3: cmp ah,g_errtab[bx] ; check Global error # + jz @@4 ; if found, jump + cmp bptr [bx],0FFh + jz @@done + add bx,4 + jmp @@3 + +@@4: cmp g_errtab[bx+1],1 ; check if warning + jnz @@5 ; if not, jump + test _misc_byte,00000001b ; check if report warnings on + jz @@done ; if not, done +@@5: push ax cx dx + push bx + mov bl,g_errtab[bx+1] + mov bh,0 + mov cx,bx + add bx,bx ; BX = error header # + mov dx,h_errtab[bx] ; DX = Header error string + pop bx + + push di si ; SI, DI = event. parameters + mov si,wptr g_errtab[bx+2] ; SI = Local error offset + mov bl,al + mov bh,0 + add bx,bx ; BX = Local error # + mov di,[bx+si] ; DX = Local error string + test di,di + jz @@6 + push ax + call prints + pop ax + mov dx,di + call prints + call printcr +@@6: pop si di + cmp cl,1 + jnz @@exit + pop dx cx ax +@@done: pop ds bx + ret + +@@exit: mov al,-1 + cmp _sel_cs,0 + jnz @@0 + jmp exit86 +@@0: jmp exit386 + + + + +.8086 +;============================================================================= +; display copyright message and version number +; +copyright: + test _misc_byte2,00001000b + jz @@done + mov ax,_version + mov bx,offs ver_msg + mov si,offs cpr_msg + push ax + mov al,ah + aam + add al,30h + mov [bx+0],al + pop ax + aam + add ax,3030h + mov [bx+2],ah + mov [bx+4],al + mov cx,offs cpr_end - offs cpr_msg +@@1: lodsb + push cx + xor bx,bx + mov ah,0Eh + int 10h + pop cx + loop @@1 +@@done: ret + + + +.8086 +;============================================================================= +; Console I/O Routines (a la printf...) +;============================================================================= +STRSIZE = 0100h + +@char db 0,0 +@crlf db cre + +;============================================================================= +; Print character in AL +; +printc: + push dx + mov @char,al + mov dx,offs @char + jmp @prnt + +;============================================================================= +; Print NewLine (CR,LF) +; +printcr: + push dx + mov dx,offs @crlf +@prnt: call prints + pop dx + ret + +;============================================================================= +; Print string +; DX = offset +; ... = arguments pushed on stack +; +prints: + push ax bx cx dx si di bp ds es + push ss + pop es + mov bp,sp + sub sp,STRSIZE + add bp,2*10 ; BP -> argument list + mov si,dx ; DS:SI -> string + mov di,sp ; ES:DI -> space for formatted string + push di +@@loop: lodsb + cmp al,'%' + jz @@args + cmp al,'$' + jnz @@next + mov al,'?' +@@next: stosb + test al,al + jnz @@loop + pop di + call writes + add sp,STRSIZE + pop es ds bp di si dx cx bx ax + ret +@@args: lodsb + cmp al,'%' + jz @@next + cmp al,'c' ; char + jz @@c + cmp al,'s' ; string + jz @@s + cmp al,'b' ; byte + jz @@b + cmp al,'w' ; word + jz @@w + cmp al,'l' ; long + jz @@l + cmp al,'d' ; decimal + jz @@d + jmp @@next ; unrecognized +@@c: mov al,[bp] + add bp,2 + jmp @@next +@@s: mov bx,[bp] + add bp,2 +@@s0: mov al,[bx] + inc bx + test al,al + jz @@loop + cmp al,'$' + jnz @@s1 + mov al,'?' +@@s1: stosb + jmp @@s0 +@@b: mov ah,[bp] + add bp,2 + mov cx,2 + call @@hex + jmp @@loop +@@w: mov ax,[bp] + add bp,2 + mov cx,4 + call @@hex + jmp @@loop +@@l: mov ax,[bp+2] + mov cx,4 + call @@hex + mov ax,[bp] + add bp,4 + mov cx,4 + call @@hex + jmp @@loop +@@d: mov ax,[bp] + add bp,2 + xor cx,cx + call @@dec + jmp @@loop +@@hex: rol ax,4 + mov bl,al + and bl,0Fh + add bl,30h + cmp bl,39h + jbe @@hex0 + add bl,07h +@@hex0: xchg ax,bx + stosb + xchg ax,bx + loop @@hex + ret +@@dec: mov bx,10000 + call @@dec0 + mov bx,1000 + call @@dec0 + mov bx,100 + call @@dec0 + mov bx,10 + call @@dec0 + jmp @@dec2 +@@dec0: xor dx,dx + div bx + test ax,ax + jz @@dec1 + inc cx +@@dec1: test cx,cx + jz @@dec3 +@@dec2: add al,30h + stosb +@@dec3: mov ax,dx + ret + +;============================================================================= +writes: xor al,al + mov dx,di + mov cx,-1 + repne scasb + dec di + push es + pop ds + mov ax,0924h + mov [di],al + cmp cs:_sel_cs,0 + jnz @@0 + int 21h + ret + +.386p +;----------------------------------------------------------------------------- +@@0: push ebp + sub esp,32h + mov ebp,esp + mov [ebp+1Ch],ax + mov [ebp+14h],dx + mov ax,cs:_seg_ss + mov [ebp+24h],ax + call int21h + add esp,32h + pop ebp + ret + + + + +.386p +;============================================================================= +file_error: + mov si,offs start + jmp report_error +file_errorm: + mov si,offs start + jmp report_errorm +dos_error: + mov si,ax + mov ax,8002h + jmp common_error +dpmi_error: + mov si,ax + mov ax,8003h +common_error: + cli + lss esp,fptr cs:_sel_esp + jmp report_error + + +PopState diff -uNr a/dos32a/src/dos32a/text/include.asm b/dos32a/src/dos32a/text/include.asm --- a/dos32a/src/dos32a/text/include.asm false +++ b/dos32a/src/dos32a/text/include.asm 5cd2dc61279847939808d44479cbec8974139d712642af7418805cf5c4e559a2f92da743a33e02f2324c1817dbbb1a140ee01aeb1ca926beed23ec1b57172317 @@ -0,0 +1,46 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +cr equ 0Dh, 0Ah +cre equ 0Dh, 0Ah ,0 +offs equ offset +bptr equ byte ptr +wptr equ word ptr +dptr equ dword ptr +fptr equ fword ptr diff -uNr a/dos32a/src/dos32a/text/kernel/detect.asm b/dos32a/src/dos32a/text/kernel/detect.asm --- a/dos32a/src/dos32a/text/kernel/detect.asm false +++ b/dos32a/src/dos32a/text/kernel/detect.asm 36e0e6789ede354c5b348b6336d89a0b543d5fbf60e689cad9e37851bf8598dae139dcc8bc08e59fd3ebfae9033d24698820c41046b2bc51cf9cf0f1dc6db380 @@ -0,0 +1,424 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; Get Protected Mode Info +;========================= +; In: Nothing +; Out: AX = return code: +; 0000h = DOS version below 4.00 +; 0001h = no 80386+ detected +; 0002h = system already in protected mode and no VCPI or DPMI found +; 0003h = DPMI - host is not 32bit +; 0004h = VCPI - incompatible PIC mappings +; CF = set on error, if no error: +; BX = number of paragraphs needed for protected mode data (may be 0) +; CL = processor type +; CH = protected mode type: +; 00h = raw +; 01h = XMS +; 02h = VCPI +; 03h = DPMI +; DX = size of removable Kernel body (in bytes) +; DI = base of removable Kernel body +;============================================================================= + Align 4 +@area1_db label byte +@area1_dw label word +@area1_dd label dword + +pm32_info: + cld + push ds es ; preserve registers + push cs cs ; DS = CS (_KERNEL) + pop ds es + + call cpu_detect ; get processor type + cmp al,3 ; check if processor is 80386+ + mov ax,1 ; error in case no 80386+ + jae @@0 + jmp @@fail + +@@0: call fpu_detect ; detect/initialize FPU + + mov ah,30h ; get DOS version + int 21h + cmp al,4 ; if DOS version is below 4.0 + mov ax,0 ; return with error code 0 + jb @@fail + + mov ax,4300h ; check for XMS + int 2Fh + cmp al,80h + jnz @@1 ; jump if XMS not found + + push es + mov ax,4310h + int 2Fh + mov xms_call[0],bx ; store XMS driver address + mov xms_call[2],es + mov ah,30h + int 21h ; HIMEM.SYS bug fix + mov ah,88h + xor bx,bx + call dptr xms_call ; get XMS v3 free mem in KB + test bl,bl ; if no XMS v3, use v2 + jz @@xms1 + mov ah,08h + call dptr xms_call ; get XMS v2 free mem in KB + movzx eax,ax +@@xms1: mov xms_data,eax + pop es + + pushf + pop ax ; AX = flags + and ah,0CFh ; reset IOPL to 0 + push ax ; (can only be done at CPL 0) + popf ; reload flags with new IOPL + pushf + pop ax ; AX = flags + test ah,30h ; is IOPL still 0? + jz @@4 ; if yes, omit VCPI/DPMI tests + +@@1: call @@detect_VCPI ; check for VCPI first + call @@detect_DPMI ; check for DPMI second + + smsw ax ; AX = machine status word + and al,1 ; is system in protected mode? + mov ax,2 ; error code in case in protected mode + jnz @@fail ; if in protected mode, fail + +@@4: cmp xms_data,0 ; check if XMS_mem is present + setnz ch ; if yes, pmode type is XMS + mov bx,80h ; BX = memory requirement (IDT) + +@@vcpi: movzx ax,pm32_rmstacks ; size of real mode stack area + imul ax,pm32_rmstacklen + add bx,ax + + movzx ax,pm32_pmstacks ; size of protected mode stack area + imul ax,pm32_pmstacklen + add bx,ax + + movzx ax,pm32_callbacks ; size of callbacks + imul ax,25 + add ax,0Fh + shr ax,4 + add bx,ax + + mov ax,pm32_selectors ; size of GDT + add ax,SYSSELECTORS+1 + shr ax,1 + add bx,ax + +@@done: xor ax,ax ; success code, also clear carry flag + mov cl,cputype + mov pmodetype,ch ; store pmode type + + mov dx,offs @kernel_end - offs @kernel_beg + mov di,offs @kernel_beg + +@@exit: pop es ds ; restore other registers + retf ; return + +@@fail: stc ; carry set, failed + jmp @@exit + + + + +;============================================================================= +@@detect_DPMI: ; detect a DPMI host + pop bp + + mov ax,1687h ; check for DPMI + int 2Fh + test ax,ax ; DPMI present? + jnz @@d0 ; if no, exit routine + + mov ax,1 ; error code in case no processor 386+ + cmp cl,3 ; is processor 386+? (redundant) + jb @@fail ; if no, fail + + mov al,3 ; error code in case DPMI not 32bit + test bl,1 ; is DPMI 32bit? + jz @@fail ; if no, fail + + mov wptr dpmiepmode[0],di ; store DPMI initial mode switch addx + mov wptr dpmiepmode[2],es + mov bx,si ; BX = number of paragraphs needed + mov ch,3 ; pmode type is 3 (DPMI) + jmp @@done ; go to done ok +@@d0: jmp bp ; return to calling routine + + +;============================================================================= +@@detect_VCPI: ; detect a VCPI server + pop bp + + xor ax,ax ; get INT 67h vector + mov es,ax + mov ax,es:[67h*4] + or ax,es:[67h*4+2] ; is vector NULL + jz @@d0 ; if yes, no VCPI + + mov ax,0DE00h ; call VCPI installation check + int 67h + test ah,ah ; AH returned as 0? + jnz @@d0 ; if no, no VCPI + + mov ax,0DE0Ah ; get PIC mappings + int 67h + mov picmaster,bl + mov picslave,cl + mov ax,0004h ; error code 4 in case of exit + cmp bl,cl ; BL=CL, only one PIC available + je @@fail + cmp bl,30h ; PICs mapped on system vectors? + je @@fail + cmp cl,30h + je @@fail + cmp cl,08h ; slave PIC shouldn't be mapped onto INT 08h + je @@fail + test bl,bl ; should not be mapped on INT 00h + je @@fail + test cl,cl + je @@fail + + mov edx,xms_data ; EDX=get free XMS memory + mov ecx,edx ; ECX=free XMS memory in KB + jecxz @@v1 ; skip if none + + test pm32_mode,00001000b ; check if VCPI+XMS alloc scheme + jz @@vA ; if not, jump (save some DOS memory) + call xms_allocmem ; alloc XMS memory in EDX + mov di,dx ; DI=handle + dec ax ; if AX=0001, no error occured + jz @@v1 +@@vA: xor ecx,ecx ; if error, XMS memory in ECX = 0 + +@@v1: mov ax,0DE03h + int 67h ; EDX=free VCPI pages + + push es ecx edx di + test pm32_mode,00000100b ; check if VCPI smart pagetable alloc + jz @@v1a ; no, use standard detection + + mov ah,48h ; allocate 4K block of memory + mov bx,0100h ; for VCPI pagetable + int 21h + jc @@v1a ; INT 21h failed, use standard alloc + + mov es,ax ; ES=returned segment + xor di,di ; DI=zero pointer + sub sp,8*3 ; DS:SI=pointer to structure + mov si,sp + push ds + push ss + pop ds + mov ax,0DE01h ; get PM interface + int 67h + pop ds + add sp,8*3 ; discard structure on stack + mov ah,49h ; discard pagetable and free DOS mem + int 21h + mov eax,1000h ; pagetable limit 4K + sub ax,di ; minus used part + shr ax,2 ; convert to 4K pages + jmp @@v1b + +@@v1a: xor eax,eax +@@v1b: pop di edx ecx es + + mov esi,ecx ; ECX=XMS free mem,EDX=VCPI free pages + shr esi,2 ; ESI=XMS_freemem/4 (to match 4Kpages) + lea esi,[edx+esi+3FFh] ; ESI=XMS_4Kmem+VCPI_4Kpages+4M_align + sub esi,eax ; minus free 0th pagetable space + jnc @@v1c ; just in case... + adc esi,eax +@@v1c: shr esi,10 ; ESI=ESI/1024 + jecxz @@v2 + + mov dx,di + mov ah,0Ah ; free what was allocated + call dptr xms_call +@@v2: movzx ax,pm32_maxpages + cmp ax,si + jbe @@v3 + mov ax,si + +@@v3: test ax,ax ; if no pages, check for DOS/32A + jnz @@v5 + pushad + mov bp,sp + mov ax,0FF88h ; check if running under DOS/32A + int 21h + cmp eax,'ID32' ; if present, use the already alloc'ed pagetables + jnz @@v4 + mov [bp+1Ch],si ; store pagetables in AX +@@v4: popad + +@@v5: cmp al,64 ; limit the number of pagetables to + jbe @@v6 ; maximum 64, = 256MB + mov al,64 +@@v6: mov pagetables,al ; BX = VCPI page tables needed + add al,pm32_maxfpages ; + physical memory mappable pages + shl ax,8 ; 100h paragraphs per page table + add ax,100h+100h+0FFh+7+80h ; +page_dir+0th_page+align_buf+TSS+IDT + mov bx,ax + mov ch,2 ; pmode type is 2 (VCPI) + jmp @@vcpi ; go to figure other memory needed +@@v0: jmp bp ; return to calling routine + + + + + +;============================================================================= +cpu_detect: ; detect: 286, 386, 486, 586 etc + cli + mov cl,2 ; CL: cputype=2 (80286) + pushf + pop ax + or ax,0F000h + push ax + popf + pushf + pop ax + and ax,0F000h + jne @@1 + jmp @@x1 +@@1: inc cl ; CPU = 80386 + pushfd + pop eax + mov edx,eax + xor eax,00040000h + push eax + popfd + pushfd + pop eax + xor eax,edx + jne @@2 + jmp @@x1 +@@2: inc cl ; CPU = 80486 + push edx + popfd + pushfd + pushfd + pop eax + mov edx,eax + xor eax,00200000h + push eax + popfd + pushfd + pop eax + xor eax,edx + jne @@3 + jmp @@x2 +@@3: xor eax,eax + db 0Fh, 0A2h ; CPUID + mov cpuidlvl,eax ; set CPUID level + mov eax,1 + db 0Fh, 0A2h ; CPUID + and ah,0Fh + mov cl,ah +@@x2: popfd + xor eax,eax + xor edx,edx +@@x1: mov al,cl + mov cputype,al ; store processor type + sti + ret + +fpu_detect: ; detect 8087, 287, 387, 487 etc + push large 0 + mov bp,sp + fninit + fnstcw wptr [bp+2] + mov ax,wptr [bp+2] + cmp ah,03h + jnz @@done ; done: no FPU present + mov wptr [bp],1 + and wptr [bp+2],0FF7Fh + wait + fldcw wptr [bp+2] + fdisi + fstcw wptr [bp+2] + wait + test wptr [bp+2],0080h + jnz @@done ; done: 8087 is present + mov wptr [bp],2 + fninit + wait + fld1 + wait + fldz + wait + fdivp st(1),st + wait + fld st(0) + wait + fchs + wait + fcompp + wait + fnstsw ax + wait + fnclex + wait + sahf + jz @@done ; done: 80287 is present + mov wptr [bp],3 + mov al,cputype + cmp al,4 + jb @@done ; done: 80387 is present + mov bptr [bp],al ; done: 80487+ (build-in) +@@done: pop eax + and eax,7 + jz @@exit + mov cx,8 +@@loop: fldz ; set ST(0) to ST(7) to +ZERO + loop @@loop + finit ; reinitialize FPU +@@exit: mov fputype,al + ret + + Align 4 +@area1_end label byte + diff -uNr a/dos32a/src/dos32a/text/kernel/exit.asm b/dos32a/src/dos32a/text/kernel/exit.asm --- a/dos32a/src/dos32a/text/kernel/exit.asm false +++ b/dos32a/src/dos32a/text/kernel/exit.asm 17d172764e9b940676e174ec57a1e9f06646e5fd581215eb887be9332be29b62ea93255c0fcd9f99b21860708a63ab130c17c9d95d1c98efcc85ee107dbe282f @@ -0,0 +1,173 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; Exit Protected Mode +;============================================================================= + +int21h_pm: + cmp ah,4Ch ; watch for INT 21h AH=4Ch + jne @@done + + cli + cld + push ax ; save error code in AL + + mov ds,cs:seldata + mov es,selzero + + mov eax,oldcr0 ; restore CR0 + mov cr0,eax + + mov eax,oldint1Bh ; restore critical INTs + mov es:[4*1Bh],eax + mov eax,oldint1Ch + mov es:[4*1Ch],eax + mov eax,oldint21h + mov es:[4*21h],eax + mov eax,oldint23h + mov es:[4*23h],eax + mov eax,oldint24h + mov es:[4*24h],eax + mov eax,oldint2Fh + mov es:[4*2Fh],eax + + call mem_dealloc ; dealloc memory for current process + movzx bx,pmodetype ; appropriate exit routine + add bx,bx + call @@exit[bx] ; call cleanup routine on exit + + pop ax ; restore AX +@@done: jmp int_matrix+4*21h ; go to INT 21h redirection + +@@exit dw r_exit + dw x_exit + dw v_exit + dw d_exit + + +; deallocate memory for this process (eg all blocks matching id32_process_id) +;============================================================================= +mem_dealloc: + cmp id32_process_id,0 ; no need in freeing memory when + jz @@done ; only one process is running + + mov esi,mem_ptr + mov eax,mem_free + or eax,esi ; check if memory was allocated + jz @@done ; if not, we are done + +@@1: mov eax,es:[esi+04h] + mov edx,es:[esi+08h] + btr eax,31 + cmp edx,dptr id32_process_id ; block allocated from this process + jnz @@2 ; if not, jump + mov es:[esi+04h],eax ; otherwise set this block as free +@@2: lea esi,[esi+eax+10h] ; get ptr to next memory block + cmp esi,mem_top ; check if at top of memory + jb @@1 ; if not, loop + push ds es + pop ds + call int31_linkfreeblocks + pop ds +@@done: ret + + +; RAW exit prologue +;============================================================================= +r_exit: mov eax,oldint15h ; put back old INT 15h handler + mov es:[4*15h],eax + ret + +; XMS exit prologue +;============================================================================= +x_exit: call xms_dealloc + mov ah,A20_state ; reset A20 gate to initial state + and ah,1 + xor ah,1 ; calculate appropriate function num + add ah,3 + jmp xms_call_pm + +; VCPI exit prologue +;============================================================================= +v_exit: mov cx,vcpi_allocmem ; check if memory was allocated + mov esi,pagetablefree + jcxz xms_dealloc ; if no VCPI memory was allocated, try XMS + +@@0: mov edx,es:[esi] + add esi,4 + and dx,0F000h + mov ax,0DE05h + call fptr vcpi_calleip + loop @@0 + + mov eax,vcpi_cr3 ; reload CR3 to flush page cache + mov cr3,eax + +;----------------------------------------------------------------------------- +xms_dealloc: ; XMS deallocate memory + mov dx,xms_handle ; check if memory was allocated + test dx,dx + jz d_exit ; if not, done + +@@0: mov ah,0Dh ; unlock XMS memory + call xms_call_pm + mov ah,0Ah ; free XMS memory +xms_call_pm: + push ss + pop es + sub esp,32h + mov edi,esp + xor ecx,ecx + mov [esp+14h],dx ; DX + mov [esp+1Ch],ax ; AX + mov eax,dptr xms_call ; real mode CS:IP + mov [esp+20h],cx ; clear flags + mov [esp+2Eh],ecx ; clear SS:SP + mov [esp+2Ah],eax ; put in structure + xor bx,bx + mov ax,0301h + int 31h + add esp,32h + +; DPMI exit prologue (actually there is no such thing) +;============================================================================= +d_exit: ret + + diff -uNr a/dos32a/src/dos32a/text/kernel/init.asm b/dos32a/src/dos32a/text/kernel/init.asm --- a/dos32a/src/dos32a/text/kernel/init.asm false +++ b/dos32a/src/dos32a/text/kernel/init.asm f1e2a860c622bee6310eb184f72e802a660975dd37269a71387e7e06a43b71bd8d8b9e501873eacb1701b155e8955bd9d18ef46f5751e120e283ebbccd9567ba @@ -0,0 +1,1072 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; Initialize Protected Mode +;=========================== +; In: BX = client version +; DX = offset of Client's Safe Exit Routine (used by exception handler) +; ES = real mode segment for protected mode data (ignored if not needed) +; +; Out: AX = return code: +; 0005h = DPMI - could not enter 32bit protected mode +; 0006h = DPMI - could not allocate needed selectors +; 0007h = could not enable A20 gate +; BX = kernel code selector +; ECX = amount of allocated memory (in bytes) +; EDX = pointer to allocated memory (from 0) +; SI = current process ID (when spawned) +; DI = version of the previously installed DOS/32A (0 if none) +; CF = set on error, if no error: +; ESP = high word clear +; CS = 16bit selector for real mode CS with limit of 64k +; SS = selector for real mode SS with limit of 64k +; DS = selector for real mode DS with limit of 64k +; ES = selector for PSP with limit of 100h +; FS = 0 (NULL selector) +; GS = 0 (NULL selector) +;============================================================================= + +pm32_init: + cld + pushad + push ds + push cs ; DS = _KERNEL + pop ds + + xor eax,eax + mov kernel_code,cs + mov client_version,bx + mov client_call[0],dx + mov ax,cs ; set base addx of _KERNEL + shl eax,4 + mov codebase,eax + add vcpi_gdtaddx,eax ; adjust addresses for VCPI structure + add vcpi_idtaddx,eax + add vcpistrucaddx,eax + btr pm32_maxextmem,31 ; limit extended memory to 2GB + + push es ; clear @area1 memory block + push cs + pop es + mov di,offs @area1_db + mov cx,(offs @area1_end - offs @area1_db) /2 + xor ax,ax + rep stosw + pop es + + mov bp,sp + mov [bp+02h],ax ; set DI to 0 (prev D32A version) + mov ax,0FF88h ; detect if DOS/32A is present + int 21h + cmp eax,'ID32' ; check if we were spawned + jnz @@1 ; if not, jump + + mov [bp+02h],bx ; set DI to prev. version of D32A + cmp bx,client_version ; check versions + jnz @@1 ; if not equal, jump + mov id32_mem_free,ecx + mov id32_mem_ptr,edx + mov id32_mem_vcpi,edi + shr esi,16 ; get previous process id + inc si ; increment (make it this process id) + mov id32_process_id,si ; store the new, current process id + mov pm32_maxextmem,0 ; use already allocated memory + +@@1: movzx bx,pmodetype ; jump to appropriate init code + add bx,bx + jmp @@init[bx] + +@@init dw r_init + dw x_init + dw v_init + dw d_init + + +;============================================================================= +dvxr_init: ; DPMI/VCPI/XMS/raw common init tail + xor ax,ax ; allocate selector for return code + mov cx,1 + int 31h + jnc @@0 +@@err: mov ax,4CFFh ; could not allocate selector + int 21h ; terminate immediately + +@@0: mov bp,sp + mov bx,ax ; new code descriptor for return + mov ax,0007h ; set base address of calling segment + mov dx,[bp+36] + mov cx,dx + shl dx,4 + shr cx,12 + int 31h + jc @@err + + inc ax ; set selector limit to 64k + xor cx,cx + mov dx,0FFFFh + int 31h + jc @@err + + inc ax ; set selector type and access rights + mov dx,cs ; get DPL from current CPL, and access + lar cx,dx ; rights and type from current CS + shr cx,8 ; type is already 16bit code segment + int 31h + jc @@err + + mov [bp+36],bx ; store selector in return address + + cmp cs:pmodetype,3 ; if DPMI, no need in client_call + jz @@1 ; DPMI will handle all the exceptions + push ds ; store client's code selector + mov ds,cs:seldata + mov client_call[2],bx + pop ds + +@@1: xor bx,bx ; init successful, carry clear + +;----------------------------------------------------------------------------- +init_done: ; return with return code + mov [bp+1Eh],bx ; set AX=return code + jc @@1 + mov eax,cs:mem_free + mov edx,cs:mem_ptr + mov [bp+1Ah],eax ; set ECX=amount of allocated memory + mov [bp+16h],edx ; set EDX=pointer to allocated memory + or eax,edx ; if allocated some memory, exit + jnz @@1 + call init_done_id32 +@@1: pop ds + popad + mov bx,cs ; return BX=kernel code selector + mov si,cs:id32_process_id ; return SI=current process ID + cld + retf + +init_done_id32: + cmp cs:pmodetype,3 ; if under DPMI, exit + jz @@done + mov ds,cs:seldata + cmp id32_process_id,0 ; if this is the first process (mom) + jz @@done ; then we're done + + mov eax,id32_mem_free + mov edx,id32_mem_ptr + mov [bp+1Ah],eax ; set ECX=amount of allocated memory + mov [bp+16h],edx ; set EDX=pointer to allocated memory + mov mem_free,eax + mov mem_ptr,edx + lea ecx,[eax+10h] ; size of memory + 16 bytes + lea eax,[ecx+edx] ; top of memory + mov mem_top,eax + + mov al,pmodetype ; now check if running under VCPI + cmp al,0 + jz @@done + cmp al,1 + jz @@done + push es + mov esi,id32_mem_vcpi ; import pagetables from prev process + mov edi,pagetablefree + mov es,selzero + mov ds,selzero + shr ecx,12 + rep movs dptr es:[edi],[esi] + pop es +@@done: ret + + + + + +;============================================================================= +;****** NOTE: DPMI host will provide all INT 31h functions and +; will be responsible for any memory allocation. + +d_init: pop ds ; get original caller DS from stack + mov ax,1 ; enter DPMI protected mode + call cs:dpmiepmode + push ds ; put DS back onto stack + jnc dvxr_init ; error? if not, go on with init + mov bx,6 ; error entering protected mode, set + cmp ax,8011h ; error code and abort + stc + jz init_done + dec bx ; error code 5, not 6 + jmp init_done + + + + + + Align 16 +@kernel_beg label byte ;** Begin of kernel code +@callback_data label byte ;** CALLBACK DATA Structure + +;============================================================================= +v_init: xor eax,eax + mov ax,es ; align data area on page boundary + add ax,00FFh + xor al,al + mov es,ax + mov dx,ax ; set base and top of page table area + + shl eax,4 + add eax,1000h ; skip Page Directory + mov pagetablebase,eax ; 0th PageTable linear address + add eax,1000h ; skip 0th PageTable + movzx ecx,pagetables + shl ecx,12 + add eax,ecx + mov pagetabletop,eax ; Nth PageTable linear adress + mov phystablebase,eax ; set base and top of physical pages + movzx ecx,pm32_maxfpages + shl ecx,12 + add eax,ecx + mov phystabletop,eax + + xor di,di + xor eax,eax ; clear PageDir and 0th PageTable + mov cx,0800h + rep stos dptr es:[di] + + mov gs,dx ; GS = segment of Page Directory + mov ax,dx + add ax,0100h + mov es,ax ; ES = segment of 0th Page Table + mov fs,ax ; FS = segment of 0th Page Table + + sub sp,8*3 ;***NOTE: stack will be restored later + mov si,sp ; DS:SI = ptr to VCPI structure + xor di,di ; ES:DI = ptr to imported 0th PageTab + push ds + push ss + pop ds + mov ax,0DE01h ; get VCPI protected mode interface + int 67h + pop ds + + push di ;** store DI = ptr to free entry + mov vcpi_calleip,ebx ; store protected mode VCPI call EIP +@@1: and bptr es:[di+1],0F1h ; clear bits 9-11 in imported PageTab + sub di,4 + jnc @@1 + + mov cx,dx ; get physical address of PageDir + shr cx,8 + mov ax,0DE06h + int 67h + and dx,0F000h + mov vcpi_cr3,edx ; set VCPI CR3 register +; +; Map VCPI 0th PageTable into our PageDir +; + mov cx,es ; CX = 0th PageTable addr + shr cx,8 ; convert to PageTable number + mov ax,0DE06h ; VCPI get pagetable Physical Addr + int 67h + and dh,0F0h + mov dl,07h + mov gs:[0000h],edx ; store address in PageDir +; +; Map the rest of our custom PageTables into our PageDir +; + mov ax,es ; advance to the 1st PageTable + add ax,0100h + mov es,ax + + mov si,ax ; SI = segment of 1st PageTable + mov al,pagetables ; AL = PageTables to alloc + mov ebx,1 ; EBX = index ptr into PageDir + call vcpi_setup_pagetables ; initialize VCPI PageDir and PageTabs +; +; Map PageTables for phys. mapping into PageDir +; + mov ax,gs ; advance PageDir to 8000_0000h addr + add ax,80h + mov gs,ax + + mov al,pm32_maxfpages ; phystables to allocate + xor ebx,ebx ; EBX = index ptr into PageDir + call vcpi_setup_pagetables ; initialize VCPI PageDir and PageTabs + pop di ;** restore DI = ptr to free entry + + xor eax,eax + test pm32_mode,00000100b ; if smart pagetables is off + jnz @@2 ; then align pagetablefree to + mov di,1000h ; first allocated free pagetable +@@2: mov ax,di ; set base of usable page table area + add eax,pagetablebase + mov pagetablefree,eax + + push si es + call vcpi_alloc_ems ; allocate VCPI memory + pop es si + + push si ; SI = segment of TSS (for later use) + xor di,di ; clear TSS with all 0, not really + mov cx,34h ; needed, but just to be safe + xor ax,ax + rep stos word ptr es:[di] + mov eax,vcpi_cr3 ; set CR3 in TSS + mov es:[1Ch],eax + mov dword ptr es:[64h],680000h ; set offset of I/O permission bitmap and clear T bit + add si,7 ; increment next data area ptr + mov es,si + mov rmtopmswrout,offs v_rmtopmsw ; set VCPI mode switch addresses + mov pmtormswrout,offs v_pmtormsw + jmp vxr_init ; go to VCPI/XMS/raw continue init + + +vcpi_setup_pagetables: + push bp + movzx bp,al ; BP = PageTables to alloc + test bp,bp + jz @@done +@@1: mov cx,si ; CX = PageTable segment + shr cx,8 ; convert to PageTable number + mov ax,0DE06h ; VCPI get PageTable Physical Addr + int 67h + and dh,0F0h + mov dl,07h + mov gs:[ebx*4],edx ; store address in PageDir + add si,0100h ; increment pagetable segment (4K) + mov es,si + xor di,di ; clear PageTable + xor eax,eax + mov cx,0400h + rep stos dptr es:[di] + inc bx ; increment index in PageDir + dec bp ; decrement PageTable counter + jnz @@1 ; if no, loop +@@done: pop bp + ret + +vcpi_alloc_ems: + push fs + pop es ; ES:DI ptr to free entry in 0th page + movzx eax,pagetables ; calculate free linear space + shl eax,22 ; convert PageTables to bytes (*4M) + mov ecx,1000h + sub cx,di ; ECX = unused space in 0th PageTable + and cl,0FCh + shl ecx,10 ; convert 4K pages to bytes + add eax,ecx ; EAX = available linear space (bytes) + mov ecx,pm32_maxextmem ; ECX = memory to allocate (bytes) + cmp ecx,eax ; choose smallest value + jbe @@0 + mov ecx,eax +@@0: xor ebx,ebx ; EBX = counter of allocated pages + jecxz @@done ; if no memory to be allocated, done + +@@1: cmp di,1000h ; if NOT overflowing page (DX>4096) + jb @@2 ; then jump + mov ax,es ; else adjust ES:DI pointer to next PG + add ax,0100h + mov es,ax + xor di,di + +@@2: mov ax,0DE04h ; allocate 4K VCPI page + int 67h + test ah,ah ; check if error + jnz @@3 ; if yes, then we are done + and dh,0F0h ; clear avail bits + mov dl,07h ; set page as user/writeable/present + mov es:[di],edx ; store page addr in PageTable + add di,4 ; increment ptr into PageTable + inc bx ; increment allocated page counter + sub ecx,4096 + ja @@1 ; loop until no more pages to allocate + +@@3: mov vcpi_allocmem,bx ; store alloc pages for deallocation + cmp ecx,4096 ; is there memory left to allocate + jb @@4 ; no, then done + test pm32_mode,00001000b ; check if VCPI+XMS allocation scheme + jz @@4 ; enabled, if not jump + call vcpi_alloc_xms ; try XMS memory allocation + +@@4: shl ebx,12 ; convert allocated pages to bytes + jz @@done ; allocated any memory? if no, jump + mov mem_free,ebx ; store amount of allocated memory + mov eax,pagetablefree ; figure out address of memory + sub eax,pagetablebase + shl eax,10 + mov mem_ptr,eax +@@done: ret + +vcpi_alloc_xms: + push ebx ; save EBX counter + shr ecx,10 ; convert bytes to KB + and cl,0FCh ; mask ECX to match 4KB pages + +@@1: mov edx,ecx + jecxz @@done ; if EDX=0, no mem to be allocated + call xms_allocmem ; XMS allocate extended memory + dec ax + jz @@2 ; if got memory, jump + sub ecx,4 ; try less memory, subtract 4K page + jnc @@1 ; loop til there is no memory to alloc + jmp @@done ; no memory allocated, done + +@@2: mov xms_handle,dx ; store handle + mov ah,0Ch ; XMS lock extended memory + call dptr xms_call + dec ax + jz @@3 ; if locked memory, jump + xor dx,dx + xchg dx,xms_handle ; reset xms_handle: no mem allocated + mov ah,0Ah ; free allocated XMS memory + call dptr xms_call + jmp @@done + +@@3: shl edx,16 ; convert DX:BX to EDX pointer + mov dx,bx + shr ecx,2 ; ECX=memory allocated in 4K blocks + movzx eax,cx + pop ebx + add ebx,eax ; adjust allocated page number + push ebx + +@@4: cmp di,1000h ; if NOT overflowing page (DX>4096) + jb @@5 ; then jump + mov ax,es ; else adjust ES:DI pointer to next PG + add ax,0100h + mov es,ax + xor di,di + +@@5: and dh,0F0h ; clear avail bits + mov dl,07h ; set page as user/writeable/present + mov es:[di],edx ; set linear memory addr + add di,4 ; increment pointer + add edx,4096 ; increment address + loop @@4 + +@@done: pop ebx ; restore EBX counter + ret + + + + + +;============================================================================= +x_init: mov ah,07h ; query A20 + call dptr xms_call + mov A20_state,al + mov ah,03h ; global enable A20 + call dptr xms_call + mov bx,0007h ; error code 0007h in case of error + dec ax ; error enabling A20? + stc + jnz init_done ; if yes, exit with error 0007h + + mov eax,xms_data ; get KB of free XMS memory + mov edx,pm32_maxextmem ; get requested amount of memory + shr edx,10 ; convert to KB + cmp edx,eax + jbe @@1 + mov edx,eax + +@@1: mov esi,edx + test edx,edx ; check if no extended memory is to + jz @@done ; be allocated, if so, then jump + + call xms_allocmem ; allocate EDX KB memory + dec ax + jnz @@done ; no memory has been allocated + mov xms_handle,dx ; store handle + + mov ah,0Ch ; lock extended memory + call dptr xms_call + dec ax + jz @@2 ; if no error, jump + xor dx,dx + xchg dx,xms_handle ; reset handle: no mem allocated + mov ah,0Ah ; free allocated extended memory + call dptr xms_call + jmp @@done + +@@2: mov wptr mem_ptr[0],bx ; store linear pointer to memory + mov wptr mem_ptr[2],dx + shl esi,10 ; convert to bytes + mov dptr mem_free,esi ; store amount of memory allocated +@@done: jmp xr_init ; go to XMS/raw continue init + + + + + +;============================================================================= +r_init: call enable_A20 ; enable A20 + mov bx,0007h ; error code 0007h + jc init_done ; exit if error enabling A20 + + push es + + push ss + pop es + xor eax,eax + mov ebx,eax + mov ecx,eax + mov edi,eax + + sub sp,32 + mov di,sp + +@@0: mov cl,20 + mov eax,0000E820h ; try INT 15h, AX=0E820h allocation scheme + mov edx,534D4150h ; "SMAP" + int 15h + jc @@noE820 ; cover all the possible + jcxz @@noE820 ; exit paths + cmp eax,534D4150h ; "SMAP" + jnz @@noE820 + + xor eax,eax + cmp eax,es:[di+04h] ; hiword: base address (must be 0) + jnz @@0 + cmp eax,es:[di+0Ch] ; hiword: length in bytes (must be 0) + jnz @@0 + inc ax + cmp eax,es:[di+10h] ; type: memory, available to OS (must be 1) + jnz @@0 + + mov edx,es:[di+00h] ; loword: base address + cmp edx,00100000h + jnz @@0 + mov eax,es:[di+08h] ; loword: length in bytes + add edx,eax + + add sp,32 + pop es + jmp @@temper + +@@noE820: + add sp,32 + pop es + + xor bx,bx + xor cx,cx + xor dx,dx + mov ax,0E801h ; try INT 15h, AX=0E801h allocation scheme + stc + int 15h + jc @@noE801 + + mov di,cx ; test if configured memory is > 0 + or di,dx + jz @@useE801 ; if not, use extended memory (AX,BX) + + mov ax,cx ; use configured memory (CX,DX) + mov bx,dx + +@@useE801: + mov di,ax ; test if extended memory is > 0 + or di,bx + jz @@noE801 ; if not, skip E801 + + movzx eax,ax ; EBX holds extended/configured memory above 16M in 64K blocks + movzx ebx,bx ; EAX holds extended/configured memory in range 1..16M in 1K blocks + shl ebx,6 + add eax,ebx ; compute total memory as 1K blocks + jmp @@calcmem + +@@noE801: + xor eax,eax ; try INT 15h, AX=88h allocation scheme + mov ah,88h ; how much extended memory free + int 15h + test ax,ax ; if none, done with raw init + jz xr_init + +@@calcmem: + shl eax,10 ; EAX = size of memory (bytes) + lea edx,[eax+100000h] ; EDX = base of memory + +@@temper: + cmp eax,pm32_maxextmem ; check how much memory to alloc + jbe @@1 ; pick lowest value + mov eax,pm32_maxextmem + +@@1: add eax, 000003FFh ; align memory to KB + and eax,0FFFFFC00h + sub edx,eax + mov mem_ptr,edx ; store extended memory base + mov mem_free,eax ; store size of extended memory + shr eax,10 ; convert to KB + test eax,0ffff0000h + jz @@2 + or ax,0ffffh +@@2: mov mem_used,ax ; set used memory + +xr_init: ; XMS/raw common init tail + mov wptr picslave,0870h + mov rmtopmswrout,offs xr_rmtopmsw ; set XMS/raw mode switch addresses + mov pmtormswrout,offs xr_pmtormsw + + + + +;============================================================================= +vxr_init: ; VCPI/XMS/raw common init tail + call install_ints ; install interrupts and except handl. + + xor eax,eax + mov ax,es + mov idtseg,ax ; set IDT segment base address + mov ebx,eax + shl ebx,4 + mov idtbase,ebx ; set IDT linear base address + + add ax,80h ; size of IDT + mov rmstackbase,ax + + movzx bx,pm32_rmstacks ; set top and base of real mode stack + mov cx,pm32_rmstacklen + mov rmstacklen,cx + imul bx,cx ; area for interrupt redirection + add ax,bx + mov rmstacktop,ax + mov rmstacktop2,ax + + shl eax,4 + mov pmstackbase,eax ; set next data area to end of RM stk + + movzx ebx,pm32_pmstacks ; set protected mode stack area top + movzx ecx,pm32_pmstacklen ; for callbacks + shl ecx,4 + mov pmstacklen,ecx ; protected mode stack size in bytes + imul ebx,ecx + add eax,ebx + mov pmstacktop,eax ; protected mode stack area top + mov pmstacktop2,eax + + mov callbackbase,eax ; top of stacks is base of callbacks + shr eax,4 ; BX = seg of callback area + mov callbackseg,ax + mov es,ax ; ES = seg of callback area + + call allocate_callbacks ; allocate callbacks + + xor eax,eax + mov ax,es ; set GDT base address + mov gdtseg,ax ; store segment of GDT + shl eax,4 + mov gdtbase,eax + movzx ecx,pm32_selectors ; set GDT limit + lea ecx,[8*ecx+8*SYSSELECTORS-1] + mov gdtlimit,cx + xor di,di ; clear GDT with all 0 + inc cx + shr cx,1 + xor eax,eax + rep stos wptr es:[di] + + cmp pmodetype,2 ; if under VCPI, do VCPI GDT set up + jne @@f0 + pop ax ; restore TSS seg from stack + shl eax,4 ; set up TSS selector in GDT + mov es:[SELVCPITSS+2],eax + mov bptr es:[SELVCPITSS],67h ; limit + mov bptr es:[SELVCPITSS+5],89h ; access rights + add eax,64h-4*9 ; unused part of TSS is also + mov vcpiswitchstack,eax ; temporary switch stack + mov di,SELVCPICODE ; copy 3 VCPI descriptors from stack + mov si,sp ; to GDT + mov cl,4*3 + rep movs wptr es:[di],ss:[si] + add sp,8*3 ;***NOTE: (VCPI) adjust stack + +@@f0: mov ax,0FFFFh + mov wptr es:[SELZERO],ax ; set SELZERO limit + mov wptr es:[SELCALLBACK],ax ; set callback DS limit + mov ax,0DF92h + mov wptr es:[SELZERO+5],ax ; set SELZERO rights + mov wptr es:[SELCALLBACK+5],ax ; set callback DS rights + + mov ax,cs ; AX = base + mov bx,SELCODE ; BX = index to SELCODE descriptor + mov cx,0FFFFh ; CX = limit (64k) + mov dx,109Ah ; DX = access rights + call vxr_initsetdsc + mov bx,SELDATA ; BX = index to SELDATA descriptor + mov dx,1092h ; DX = access rights + call vxr_initsetdsc + mov ax,0040h + mov bx,SELBIOSDATA + call vxr_initsetdsc + + mov bx,8*SYSSELECTORS ; BX = base of free descriptors + push bx ; store selector + mov ax,ss ; set caller SS descriptor + mov dx,5092h + call vxr_initsetdsc + mov ax,[bp] ; set caller DS descriptor + mov [bp],bx ; put DS selector on stack for exit + call vxr_initsetdsc + + push bx ; get PSP segment + mov ah,51h + int 21h + mov si,bx ; SI = PSP segment + pop bx + + push ds + mov ds,si ; set caller environment descriptor + mov ax,ds:[002Ch] + test ax,ax ; is environment seg 0? + jz @@f1 ; if yes, dont convert to descriptor + mov ds:[002Ch],bx ; store selector value in PSP + call vxr_initsetdsc + mov ax,si ; set caller PSP descriptor +@@f1: mov cx,0FFh ; limit is 100h bytes + call vxr_initsetdsc + pop ds + + sub bx,8 + mov cx,bx ; CX = ES descriptor, PSP + pop dx ; DX = SS descriptor, from stack + mov ax,SELZERO ; AX = DS descriptor, SELZERO + movzx ebx,sp ; EBX = SP, current SP - same stack + mov si,SELCODE ; target CS is SELCODE, same segment + mov edi,offs @@swpm ; target EIP + jmp rmtopmswrout ; jump to mode switch routine +; +; now we are in protected mode +; +@@swpm: cli + mov edi,cs:codebase ; EDI = offset of _KERNEL from 0 + + mov eax,cs:vcpi_cr3 ; EAX = CR3 + mov cr3,eax ; reload CR3 register to flush TLB + + mov eax,cr0 + mov oldcr0[edi],eax ; preserve original CR0 + + xor eax,eax + mov cr2,eax ; reset CR2 page fault addr register + + cmp eax,cs:cpuidlvl ; check CPUID level + jz @@0 ; if not available, jump + mov al,1 + db 0Fh, 0A2h ; CPUID + test edx,01000000h ; test if FXSAVE/FXRSTOR available (FXSR bit) + jz @@0 ; if not, jump + mov eax,cr4 ; load CR4 into EAX + or ax,0200h ; set OSFXFR bit + mov cr4,eax ; reload CR4 (note: OSXMMEXCPT is left unchanged) + mov eax,cr0 ; load CR0 in EAX + and al,0F9h ; clear EM & MP bits + mov cr0,eax ; reload CR0 + +@@0: clts + + mov eax,ds:[4*15h] ; preserve INT 15h + mov oldint15h[edi],eax + mov eax,ds:[4*1Bh] ; preserve INT 1Bh - (CTRL-Break) + mov oldint1Bh[edi],eax + mov eax,ds:[4*1Ch] ; preserve INT 1Ch - (timer ticks) + mov oldint1Ch[edi],eax + mov eax,ds:[4*21h] ; preserve INT 21h - (DOS API) + mov oldint21h[edi],eax + mov eax,ds:[4*23h] ; preserve INT 23h - (DOS CTRL-C) + mov oldint23h[edi],eax + mov eax,ds:[4*24h] ; preserve INT 24h - (DOS Critical handler) + mov oldint24h[edi],eax + mov eax,ds:[4*2Fh] ; preserve INT 2Fh - (Multiplex) + mov oldint2Fh[edi],eax + + mov ax,cs:kernel_code ; install real mode INT 21h handler + shl eax,16 + mov ax,offs int21h_rm + mov ds:[4*21h],eax + + cmp cs:pmodetype,0 ; is system raw? + jnz @@1 ; if not, we are done + cmp cs:id32_process_id,0 ; is this the only instance? + jnz @@1 ; if not, we are done + + mov ax,offs int15h_rm + mov ds:[4*15h],eax ; install real mode INT 15h handler + +@@1: push ds es edi + push cs + pop ds ; DS = code base (executable) + mov es,seldata ; ES = code base (writeable) + mov ax,0303h + mov esi,offs int1Bh ;** NOTE: EDI points to init_code + mov edi,offs @callback_data+00h ;** EDI = callback data structure + int 31h ;** which will be used only once + push cx dx ;** at startup. + mov si,offs int1Ch + mov di,offs @callback_data+32h + int 31h + push cx dx + mov si,offs int23h + mov di,offs @callback_data+64h + int 31h + push cx dx + mov si,offs int24h + mov di,offs @callback_data+96h + int 31h + push cx dx + mov ds,seldata ; DS = data selector + pop newint24h ; set allocated callbacks + pop newint23h + pop newint1Ch + pop newint1Bh + pop edi es ds + + xor eax,eax + mov ebx,cs:mem_ptr ; EBX = base of extended memory + mov ecx,cs:mem_free ; ECX = size of extended memory + mov edx,ebx ; align ptr to memory on para boundary + add ebx,0Fh + and bl,0F0h + mov esi,ebx + sub esi,edx ; get the difference + add esi,10h ; plus 16 bytes for 1st block header + sub ecx,esi ; reduce size of free memory + ja @@2 ; if no error, jump + mov mem_ptr[edi],eax ; not enough memory even for one + mov mem_free[edi],eax ; memory block header, done now + jmp @@done + +@@2: mov eax,12345678h ; header id + mov [ebx+00h],eax ; set header id + mov [ebx+0Ch],eax ; set header id + movzx eax,id32_process_id ; load current process id + mov [ebx+08h],eax ; set current process id + mov [ebx+04h],ecx ; set first block unused/currentsize + lea edx,[ebx+ecx+10h] ; get pointer to next block (mem_top) + mov mem_top[edi],edx ; set top of memory + mov mem_ptr[edi],ebx ; set base of memory + mov mem_free[edi],ecx ; set size of memory + +@@done: sti + jmp dvxr_init ; go to DPMI/VCPI/XMS/raw init tail + + + + + + + +;============================================================================= +; Initialize interrupt tables +; +; The setup is performed once at startup. The goal is to reduce +; run-time complexity of the interrupt handling code by collecting +; as much info as possible about system config and doing init here. +; +install_ints: + xor di,di ; set up IDT + xor ecx,ecx + mov dx,wptr picslave +; +; initialize IDT, point all INTs into int_matrix call table +; +@@1: lea eax,[ecx*4 + SELCODE*10000h + offs int_matrix] + stos dptr es:[di] + mov eax,8E00h ; interrupt gate type (IF=0) + mov bl,cl ; isolate high 5 bits of int num + and bl,0F8h + test cl,0F0h ; one of the low 16 interrupts? + jz @@2 ; if yes, store as interrupt gate + cmp bl,dl ; one of the high IRQs? + je @@2 ; if yes, store as interrupt gate + cmp bl,dh ; one of the low IRQs? + je @@2 ; if yes, store as interrupt gate + mov ax,8F00h ; set to trap gate type (IF=unchanged) +@@2: stos dptr es:[di] + inc cl ; increment interrupt number + jnz @@1 ; loop if more interrupts to go +; +; initialize IDT, redirect INT 21h and INT 31h +; + mov wptr es:[8*21h],offs int21h_pm ; protected mode INT 21h + mov wptr es:[8*31h],offs int31h_pm ; protected mode INT 31h + + push ds es + push ds + pop es ; ES = DS +; +; initialize real-mode IRQ table, copy vectors from real-mode Interrupt table +; + xor ax,ax + mov ds,ax + mov di,offs irqtab_rm + movzx si,dh + shl si,2 + mov cx,8 + rep movs dptr es:[di],ds:[si] + movzx si,dl + shl si,2 + mov cl,8 + rep movs dptr es:[di],ds:[si] +; +; initialize protected-mode Exception table, point exctab_pm entries into exc_matrix call table +; + mov cl,16 + mov di,offs exctab_pm + mov ax,offs exc_matrix +@@3: stos wptr es:[di] + mov wptr es:[di+2],SELCODE + add di,6 + add ax,4 + loop @@3 + + pop es ds +; +; install INTs 00..0Eh (exceptions), +; modify call targets in int_matrix call table such that they point to irq_fail +; + mov ax,offs irq_fail ; offset of fail routine + sub ax,offs int_matrix+4 ; calculate offset displacement + mov di,offs int_matrix+2 ; DI = pointer into CALL matrix + mov cl,15 +@@l1: mov ds:[di],ax ; modify CALL address + sub ax,4 ; PUSH + CALL = 4 bytes + add di,4 + loop @@l1 +; +; install IRQs 0..15 (PIC dependent), +; modify call targets in int_matrix call table such that they point to either irq_normal or irq_tester +; + movzx dx,picmaster ; install IRQ 0-7 (INT 08-0Fh) + call setup_irqs + movzx dx,picslave ; install IRQ 8-15 (INT 70-77h) + call setup_irqs +; +; install INT 2 (special setup to handle co-proc) +; modify call target of INT 02h in int_matrix call table such that it points to int_main +; +; mov ax,(offs int_main) - (offs int_matrix+4) - 02h*4 +; mov wptr int_matrix[02h*4+2],ax ; install INT 02h (NMI) + +; +; install IRQ 7 (special setup to handle supurious signals) +; modify call target of INT 0Fh in int_matrix call table such that it points to irq_normal +; + cmp picmaster,10h ; setup IRQ 7, damn it! + jae @@done + mov ax,(offs irq_normal) - (offs int_matrix+4) - 0Fh*4 + mov wptr int_matrix[0Fh*4+2],ax ; install INT 0Fh (IRQ 7) + +@@done: ret + + +;----------------------------------------------------------------------------- +setup_irqs: + cmp dl,0Fh + mov ax,offs irq_tester ; if DX is in range INT 00..0Fh + jbe @@0 ; install as IRQ check handler + mov ax,offs irq_normal ; else no IRQ check is needed +@@0: shl dx,2 + sub ax,offs int_matrix+4 + sub ax,dx + mov di,offs int_matrix+2 + add di,dx + mov cl,8 ; 8 IRQs to go +@@loop: mov ds:[di],ax + sub ax,4 ; PUSH + CALL is 4 bytes + add di,4 ; next entry in int_matrix call table + loop @@loop + ret + + +;----------------------------------------------------------------------------- +allocate_callbacks: + movzx cx,pm32_callbacks ; CL = number of callbacks + jcxz @@done ; if no, done with this part + xor di,di ; location within callback seg + mov ax,6866h + mov dx,kernel_code + + push ds + push es + pop ds +@@1: mov wptr ds:[di],6066h ; PUSHAD instruction + mov bptr ds:[di+2],ah ; PUSH WORD instruction + mov wptr ds:[di+3],0 ; immediate 0 used as free flag + mov wptr ds:[di+5],ax ; PUSH DWORD instruction + mov bptr ds:[di+11],0B9h ; MOV CX,? instruction + mov wptr ds:[di+14],ax ; PUSH DWORD instruction + mov bptr ds:[di+20],0EAh ; JMP FAR PTR ?:? intruction + mov wptr ds:[di+21],offs callback + mov wptr ds:[di+23],dx + add di,25 ; increment ptr to callback + loop @@1 ; if more callbacks to do, loop + pop ds + + add di,0Fh ; align next data area on paragraph + shr di,4 + mov ax,es + add ax,di + mov es,ax ; set ES to base of next data area +@@done: ret + + +;----------------------------------------------------------------------------- +vxr_initsetdsc: ; set descriptor for VCPI/XMS/raw init + push ax + movzx eax,ax ; EAX = base of segment + shl eax,4 + mov wptr es:[bx],cx ; limit = CX + mov dptr es:[bx+2],eax ; base address = EAX + mov wptr es:[bx+5],dx ; access rights = DX + add bx,8 ; increment descriptor index + pop ax + ret + + +;----------------------------------------------------------------------------- +xms_allocmem: + push edi + mov edi,edx + mov ah,89h + call dptr xms_call + cmp ax,0001h + jz @@ok + mov dx,di + mov ah,09h + call dptr xms_call +@@ok: pop edi + ret + + diff -uNr a/dos32a/src/dos32a/text/kernel/int31h.asm b/dos32a/src/dos32a/text/kernel/int31h.asm --- a/dos32a/src/dos32a/text/kernel/int31h.asm false +++ b/dos32a/src/dos32a/text/kernel/int31h.asm d52f90a508196384327f644b88c734078e61942dd930c95f1f8934b1eb2f8102d826725a5838274568920e21f7ff5d90f87c5927a7a61baa305546e43b01b05f @@ -0,0 +1,1923 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; INT 31h INTERFACE +;============================================================================= + + evendata +;============================================================================= +int31h_tab label word + dw 0300h ; simulate real mode int + dw int31h_0300 + dw 0301h ; call rm proc RETF + dw int31h_0301 + dw 0302h ; call rm proc IRET + dw int31h_0302 +;--------------------------------------------------------------------- + dw 0000h ; allocate descriptor + dw int31h_0000 + dw 0001h ; free descriptor + dw int31h_0001 + dw 0002h ; map seg to sel + dw int31h_0002 + dw 0003h ; get sel increment value + dw int31h_0003 + dw 0006h ; get sel base addr + dw int31h_0006 + dw 0007h ; set sel base addr + dw int31h_0007 + dw 0008h ; set sel limit + dw int31h_0008 + dw 0009h ; set sel access rights + dw int31h_0009 + dw 000Ah ; create alias sel + dw int31h_000A + dw 000Bh ; get descriptor + dw int31h_000B + dw 000Ch ; set descriptor + dw int31h_000C + dw 000Eh ; get multi descriptors + dw int31h_000E + dw 000Fh ; set multi descriptors + dw int31h_000F +;--------------------------------------------------------------------- + dw 0100h ; alloc DOS memory + dw int31h_0100 + dw 0101h ; free DOS memory + dw int31h_0101 + dw 0102h ; resize DOS memory + dw int31h_0102 +;--------------------------------------------------------------------- + dw 0200h ; get real mode int + dw int31h_0200 + dw 0201h ; set real mode int + dw int31h_0201 + dw 0202h ; get pm exception vector + dw int31h_0202 + dw 0203h ; set pm exception vector + dw int31h_0203 + dw 0204h ; get pm int + dw int31h_0204 + dw 0205h ; set pm int + dw int31h_0205 +;--------------------------------------------------------------------- + dw 0303h ; alloc callback + dw int31h_0303 + dw 0304h ; free callback + dw int31h_0304 + dw 0305h ; get state save/restore addr + dw int31h_0305 + dw 0306h ; get raw mode switch addr + dw int31h_0306 +;--------------------------------------------------------------------- + dw 0400h ; get DPMI version + dw int31h_0400 +;--------------------------------------------------------------------- + dw 0500h ; get free mem info + dw int31h_0500 + dw 0501h ; alloc mem + dw int31h_0501 + dw 0502h ; free mem + dw int31h_0502 + dw 0503h ; resize mem + dw int31h_0503 + dw 050Ah ; get linear mem block and size + dw int31h_050A +;--------------------------------------------------------------------- + dw 0600h ; lock linear region *VM* + dw int31h_0600 + dw 0601h ; unlock linear region *VM* + dw int31h_0601 + dw 0602h ; Mark Real Mode Region as Pageable *VM* + dw int31h_0602 + dw 0603h ; Relock Real Mode Region *VM* + dw int31h_0603 + dw 0604h ; get page size *VM* + dw int31h_0604 +;--------------------------------------------------------------------- + dw 0702h ; mark page *VM* + dw int31h_0702 + dw 0703h ; discard page *VM* + dw int31h_0703 +;--------------------------------------------------------------------- + dw 0800h ; physical mem mapping *VM* + dw int31h_0800 + dw 0801h ; free mapped mem *VM* + dw int31h_0801 +;--------------------------------------------------------------------- + dw 0900h ; get/disable VIS + dw int31h_0900 + dw 0901h ; get/enable VIS + dw int31h_0901 + dw 0902h ; get VIS + dw int31h_0902 +;--------------------------------------------------------------------- + dw 0A00h ; vendor specific + dw int31h_0A00 +;--------------------------------------------------------------------- +; dw 0B00h ; Set Debug Watchpoint +; dw int31h_0B00 +; dw 0B01h ; Clear Debug Watchpoint +; dw int31h_0B01 +; dw 0B02h ; Get State of Debug Watchpoint +; dw int31h_0B02 +; dw 0B03h ; Reset Debug Watchpoint +; dw int31h_0B03 +;--------------------------------------------------------------------- + dw 0E00h ; get FPU status + dw int31h_0E00 + dw 0E01h ; set FPU emulation + dw int31h_0E01 +;--------------------------------------------------------------------- + dw 0EEFFh ; PMODE/W compatible call + dw int31h_EEFF +;--------------------------------------------------------------------- +int31h_end label word + + + + +;============================================================================= +int31h_pm: + cli + cld + push ds es fs gs ; push registers on stack + pushad + + push bx + mov ds,cs:seldata ; DS -> KERNEL + + cmp ax,int31h_cache[0] ; check if function # is in cache + mov bx,int31h_cache[2] ; retrieve cached target addr + je @@2 ; if cached, jump + + xor bx,bx ; do a linear search +@@0: cmp ax,int31h_tab[bx] ; found function # ? + je @@1 ; if yes, jump + + add bx,4 ; advance to next entry + cmp bx,(offs int31h_end - offs int31h_tab) ; end of table? + jb @@0 ; loop until end of table + + pop bx ; no function found + jmp int31fail8001 ; exit with error 8001h + +@@1: mov bx,int31h_tab[bx+2] ; get address of the appropriate handler + mov int31h_cache[0],ax ; store function # in cache + mov int31h_cache[2],bx ; store function addr in cache + +@@2: mov ds,selzero ; DS -> 0 (beginning of memory) + xchg bx,[esp] ; store target addr & restore BX + ret + + +;----------------------------------------------------------------------------- +int31fail8001: ; INT 31h return fail with error 8001h + mov al,01h + jmp int31failx +int31fail8010: ; INT 31h return fail with error 8010h + mov al,10h + jmp int31failx +int31fail8011: ; INT 31h return fail with error 8011h + mov al,11h + jmp int31failx +int31fail8012: ; INT 31h return fail with error 8012h + mov al,12h + jmp int31failx +int31fail8013: ; INT 31h return fail with error 8013h + mov al,13h + jmp int31failx +int31fail8015: ; INT 31h return fail with error 8015h + mov al,15h + jmp int31failx +int31fail8016: ; INT 31h return fail with error 8016h + mov al,16h + jmp int31failx +int31fail8021: ; INT 31h return fail with error 8021h + mov al,21h + jmp int31failx +int31fail8022: ; INT 31h return fail with error 8022h + mov al,22h + jmp int31failx +int31fail8023: ; INT 31h return fail with error 8023h + mov al,23h + jmp int31failx +int31fail8024: ; INT 31h return fail with error 8024h + mov al,24h + jmp int31failx +int31fail8025: ; INT 31h return fail with error 8025h + mov al,25h + +int31failx: + mov ah,80h + mov [esp+28],ax ; set AX on stack to 8010h for POPAD + jmp int31fail + + + +;----------------------------------------------------------------------------- +int31failbx: ; INT 31h return fail with BX,AX + mov wptr [esp+16],bx ; put BX onto stack for POPAD + jmp int31failax +int31failcx: ; INT 31h return fail with CX,AX + mov wptr [esp+24],cx ; put CX onto stack for POPAD +int31failax: ; INT 31h return fail with AX + mov wptr [esp+28],ax ; put AX onto stack for POPAD + + +;----------------------------------------------------------------------------- +int31fail: ; INT 31h return fail, pop all regs + popad + pop gs fs es ds +int31failnopop: ; INT 31h return fail with carry set + or bptr [esp+8],01h ; set carry in EFLAGS on stack + iretd + + +;----------------------------------------------------------------------------- +int31okedx: ; INT 31h return ok with EDX,CX,AX + mov [esp+20],edx ; put EDX onto stack for POPAD + jmp int31okcx +int31okdx: ; INT 31h return ok with DX,CX,AX + mov [esp+20],dx ; put DX onto stack for POPAD + jmp int31okcx +int31oksinoax: ; INT 31h return ok SI,DI,BX,CX + mov ax,[esp+28] ; get old value of AX for restore +int31oksi: ; INT 31h return ok SI,DI,BX,CX,AX + mov [esp+4],si ; put SI onto stack for POPAD + mov [esp+0],di ; put DI onto stack for POPAD +int31okbx: + mov [esp+16],bx ; put BX onto stack for POPAD +int31okcx: ; INT 31h return ok with CX,AX + mov [esp+24],cx ; put CX onto stack for POPAD +int31okax: ; INT 31h return ok with AX + mov [esp+28],ax ; put AX onto stack for POPAD + + +;----------------------------------------------------------------------------- +int31ok: ; INT 31h return ok, pop all regs + popad + pop gs fs es ds +int31oknopop: ; INT 31h return ok with carry clear + and bptr [esp+8],0FEh ; clear carry in EFLAGS on stack + iretd + + + + + +;============================================================================= +; Helper functions +;============================================================================= + +;----------------------------------------------------------------------------- +int31testsel: ; test for valid selector BX + pop bp ; pop return address + cmp bx,cs:gdtlimit ; selector BX out of range? + ja int31fail8022 ; if yes, fail with error 8022h + mov edi,cs:gdtbase ; get base of GDT + and ebx,0FFF8h ; mask offset table index and RPL + test bptr ds:[edi+ebx+6],10h ; is descriptor used? + jz int31fail8022 ; if descriptor not used, fail 8022h + jmp bp ; return ok + +;----------------------------------------------------------------------------- +int31testaccess: ; test access bits in CX + pop bp ; pop return address + test ch,20h ; test MUST BE 0 bit in CH + jnz int31fail8021 ; if not 0, error 8021h + test cl,90h ; test present and MUST BE 1 bits + jz int31fail8021 ; if both 0, error 8021h + jpo int31fail8021 ; if unequal, error 8021h + test cl,60h ; test DPL + jnz int31fail8021 ; if not 0, error 8021h + test cl,8 ; if code, more tests needed + jz @@0 ; if data, skip code tests + test cl,2 ; readable? + jz int31fail8021 + test cl,4 ; non-conform? + jnz int31fail8021 +@@0: jmp bp ; return ok + +;----------------------------------------------------------------------------- +int31testint: + movzx ebx,bl ; EBX = interrupt number + mov al,bl + mov ah,bl + and ax,0F807h + movzx esi,al + cmp ah,picmaster ; if 1st PIC, offset = buffer + 0 + jz @@done + add si,8 + cmp ah,picslave ; if 2nd PIC, offset = buffer + 8 + jz @@done + or si,-1 +@@done: ret ; return: ZF = 0 if BL is IRQ, otherwise ZF = 1 + + + + + +;============================================================================= +; DESCRIPTOR FUNCTIONS +;============================================================================= + +;============================================================================= +; Allocate Descriptors +; +int31h_0000: + test cx,cx ; if CX = 0, error 8021h + jz int31fail8021 + + mov edx,cs:gdtbase ; get base of GDT + movzx eax,cs:gdtlimit ; EAX = last selector index + and al,0F8h + + mov bx,cx ; BX = number of selectors to find +@@l0: test bptr [edx+eax+6],10h ; is descriptor used? + jnz @@f0 + dec bx ; found free descriptor, dec counter + jnz @@f1 ; continue if need to find more + + mov ebx,eax ; found all descriptors requested +@@l1: mov dptr [edx+ebx],0 ; set entire new descriptor + mov dptr [edx+ebx+4],109200h + add bx,8 ; increment selector index + loop @@l1 ; dec counter of descriptors to mark + jmp int31okax ; return ok, with AX + +@@f0: mov bx,cx ; reset number of selectors to find +@@f1: sub ax,8 ; dec current selector counter + cmp ax,8*SYSSELECTORS ; more descriptors to go? + jae @@l0 ; if yes, loop + jmp int31fail8011 ; did not find descriptors + + +;============================================================================= +; Free Descriptor +; +int31h_0001: + mov ax,cs + cmp ax,bx + jz int31fail8022 ; cannot free CS selector + mov ax,ss + cmp ax,bx + jz int31fail8022 ; cannot free SS selector + call int31testsel ; test for valid selector BX + xor eax,eax + mov [edi+ebx+0],eax ; mark descriptor as free + mov [edi+ebx+4],eax + + mov cx,4 ; zero any segregs loaded with BX + lea ebp,[esp+32] ; EBP -> selectors on stack +@@l0: cmp wptr [ebp],bx ; selector = BX? + jne @@f0 ; if no, continue loop + + mov [ebp],ax ; zero selector on stack + +@@f0: add ebp,2 ; increment selector ptr + loop @@l0 ; loop + jmp int31ok ; return ok + + +;============================================================================= +; Map Real-Mode Segment to Descriptor +; +int31h_0002: + mov ds,cs:seldata + + mov cx,16 ; max 16 selectors + mov si,offs segmentbases ; check, if segment already mapped +@@0: mov ax,[si+0] ; is selector zero (free entry) + test ax,ax + jz @@1 ; if yes, loop + cmp bx,[si+2] ; compare segment values + jz int31okax ; if already mapped, done +@@1: add si,4 + loop @@0 + + mov cl,16 + mov si,offs segmentbases ; search for a free entry +@@2: cmp wptr [si],0 ; this field free? + jz @@3 ; if yes, use it + add si,4 + loop @@2 + jmp int31fail8010 ; no entry free + +@@3: mov [si+2],bx ; store segment + movzx edi,bx ; convert to linear address + shl edi,4 + mov cl,1 + xor ax,ax + int 31h ; allocate selector + jc int31failax + mov [si+0],ax ; store selector + + mov bx,ax + xor cx,cx + mov dx,-1 + mov ax,8 + int 31h ; set descriptor limit 64k + + mov dx,di + shr edi,16 + mov cx,di + mov ax,7 + int 31h ; set descriptor base + + mov cx,0092h + mov ax,9 + int 31h ; set access rights + + mov ax,bx ; return selector + jmp int31okax + + +;============================================================================= +; Get Selector Increment Value +; +int31h_0003: + mov ax,8 ; selector increment value is 8 + jmp int31okax ; return ok, with AX + + +;============================================================================= +; Get Segment Base Address +; +int31h_0006: + call int31testsel ; test for valid selector BX + + mov dx,wptr ds:[edi+ebx+2] ; low word of 32bit linear address + mov cl,bptr ds:[edi+ebx+4] ; high word of 32bit linear address + mov ch,bptr ds:[edi+ebx+7] + jmp int31okdx ; return ok, with DX, CX, AX + + +;============================================================================= +; Set Segment Base Address +; +int31h_0007: + call int31testsel ; test for valid selector BX + + mov wptr ds:[edi+ebx+2],dx ; low word of 32bit linear address + mov bptr ds:[edi+ebx+4],cl ; high word of 32bit linear address + mov bptr ds:[edi+ebx+7],ch + jmp int31ok ; return ok + + +;============================================================================= +; Set Segment Limit +; +int31h_0008: + call int31testsel ; test for valid selector BX + cmp cx,0Fh ; is limit greater than 1M? + jbe @@1 ; if not, jump + + or dx,0FFFh ; auto-adjust limit + shrd dx,cx,12 ; DX = low 16 bits of page limit + shr cx,12 ; CL = high 4 bits of page limit + or cl,80h ; set granularity bit in CL + +@@1: mov wptr ds:[edi+ebx],dx ; put low word of limit + and bptr ds:[edi+ebx+6],50h ; mask off G and high nibble of limit + or bptr ds:[edi+ebx+6],cl ; put high nibble of limit + jmp int31ok ; return ok + + +;============================================================================= +; Set Descriptor Access Rights +; +int31h_0009: + call int31testsel ; test for valid selector BX + call int31testaccess ; test access bits in CX + + or ch, 10h ; set AVL bit, descriptor used + and ch,0D0h ; mask off low nibble of CH + and bptr ds:[edi+ebx+6],0Fh ; mask off high nibble access rights + or bptr ds:[edi+ebx+6],ch ; or in high access rights byte + mov bptr ds:[edi+ebx+5],cl ; put low access rights byte + jmp int31ok ; return ok + + +;============================================================================= +; Create Alias Descriptor +; +int31h_000A: + call int31testsel ; test for valid selector BX + + xor ax,ax ; allocate descriptor + mov cx,1 + int 31h + jc int31fail8011 ; if failed, descriptor unavailable + + push ax ; preserve allocated selector + push ds ; copy descriptor and set type data + pop es + movzx edi,ax ; EDI = target selector + mov esi,cs:gdtbase ; ESI -> GDT + add edi,esi ; adjust to target descriptor in GDT + add esi,ebx ; adjust to source descriptor in GDT + + movs dptr es:[edi],ds:[esi] ; copy descriptor + lods dptr ds:[esi] + mov ah,92h ; set descriptor type - R/W up data + stos dptr es:[edi] + pop ax ; restore allocated selector + jmp int31okax ; return ok, with AX + + +;============================================================================= +; Get Descriptor +; +int31h_000B: + call int31testsel ; test for valid selector BX + lea esi,[edi+ebx] ; ESI -> descriptor in GDT + mov edi,[esp] ; get EDI buffer ptr from stack + movs dptr es:[edi],ds:[esi] ; copy descriptor + movs dptr es:[edi],ds:[esi] + jmp int31ok ; return ok + + +;============================================================================= +; Set Descriptor +; +int31h_000C: + call int31testsel ; test for valid selector BX + mov esi,[esp] ; ESI = EDI buffer ptr from stack + mov cx,es:[esi+5] ; get access rights from descriptor + call int31testaccess ; test access bits in CX + + push ds es ; swap DS and ES, target and source + pop ds es + + add edi,ebx ; adjust EDI to descriptor in GDT + movs dptr es:[edi],ds:[esi] ; copy descriptor + lods dptr ds:[esi] + or al,10h ; set descriptor AVL bit + stos wptr es:[edi] + jmp int31ok ; return ok + + +;============================================================================= +; Get Multiple Descriptors +; +int31h_000E: + mov ax,000Bh ; function 000Bh, get descriptor + jmp int31h_000EF ; go to common function + + +;============================================================================= +; Set Multiple Descriptors +; +int31h_000F: + mov ax,000Ch ; function 000Ch, set descriptor + +int31h_000EF: ; common to functions 000Eh and 000Fh + test cx,cx ; if CX = 0, return ok immediately + jz int31ok + + mov dx,cx ; DX = number of descriptors + xor cx,cx ; CX = successful counter +@@l0: mov bx,es:[edi] ; BX = selector to get + add edi,2 + int 31h ; get/set descriptor + jc int31failcx ; if error, fail with AX and CX + + add edi,8 ; increment descriptor ptr + inc cx ; increment successful copy counter + dec dx ; decrement loop counter + jnz @@l0 ; if more descriptors to go, loop + jmp int31ok ; return ok + + + + + + +;============================================================================= +; DOS MEMORY FUNCTIONS +;============================================================================= + +;============================================================================= +; Allocate DOS Memory Block +; +int31h_0100: + mov ah,48h ; DOS alloc memory function + call int31010x_f2 ; allocate memory + jc int31failbx ; if fail, exit with AX=err, BX=maxmem + + mov dx,ax ; DX=segment of DOS memory block + xor ax,ax ; allocate descriptor + mov cx,1 + int 31h + jnc @@1 + mov ah,49h ; if error allocating descriptor + call int31010x_f2 ; free what was allocated + jmp int31fail8011 ; and exit with error 8011h + +@@1: mov [esp+14h],ax ; set selector in DX + mov [esp+1Ch],dx ; set base address in AX + mov bx,ax + mov cx,dx + shl dx,4 + shr cx,12 + mov ax,0007h ; set selector base + int 31h + + mov cx,0092h ; set access rights + mov al,09h + int 31h + jmp int31010x ; set selector size + + +;============================================================================= +; Free DOS Memory Block +; +int31h_0101: + mov ah,49h + mov si,dx ; preserve DX = selector + call int31010x_f1 + jc int31failax + mov bx,si ; restore selector in BX + jmp int31h_0001 + + +;============================================================================= +; Resize DOS Memory Block +; +int31h_0102: + mov ah,4Ah + mov si,dx ; preserve DX = selector + call int31010x_f1 + jc int31failbx + mov bx,si ; restore selector in BX + +int31010x: + movzx edx,wptr [esp+10h] ; get original size + shl edx,4 ; convert para to bytes + dec edx ; limit=size-1 + shld ecx,edx,16 + mov ax,0008h ; set limit + int 31h + jmp int31ok + + +;----------------------------------------------------------------------------- +int31010x_f1: + pop bp + push ax bx + mov bx,dx ; BX = selector + mov ax,0006h ; get base + int 31h + pop bx ax + jc int31failax + shrd dx,cx,4 ; adjust CX:DX to segment value + push bp + +int31010x_f2: + xor cx,cx + push cx ; set real mode SS:SP + push cx + sub esp,10 + push dx ; set real mode ES + push cx ; set real mode flags + pushad ; set real mode registers + push ss + pop es + mov edi,esp + mov bl,21h + mov ax,0300h + int 31h + mov bx,[esp+10h] ; get BX from structure + mov ax,[esp+1Ch] ; get AX from structure + lea esp,[esp+32h] + pop bp + jc int31failax ; if error, fail + bt wptr [esp-14h],0 + jmp bp + + + + + + +;============================================================================= +; INTERRUPT FUNCTIONS +;============================================================================= + +;============================================================================= +; Get Real Mode Interrupt Vector +; +int31h_0200: + movzx ebx,bl ; EBX = BL (interrupt number) + mov dx,[ebx*4+0] ; load real mode vector offset + mov cx,[ebx*4+2] ; load real mode vector segment + jmp int31okdx ; return ok, with AX, CX, DX + + +;============================================================================= +; Set Real Mode Interrupt Vector +; +int31h_0201: + mov ebp,dr7 + xor eax,eax ; temporarily disable null-ptr protection + mov dr7,eax + + movzx ebx,bl ; EBX = BL (interrupt number) + mov [ebx*4+0],dx ; set real mode vector offset + mov [ebx*4+2],cx ; set real mode vector segment + + mov dr7,ebp + jmp int31ok ; return ok + + +;============================================================================= +; Get Processor Exception Handler Vector +; +int31h_0202: + mov ds,cs:seldata + cmp bl,20h ; must be in range 00..1Fh + jae int31fail8021 ; invalid value + + xor cx,cx + xor edx,edx + cmp bl,10h ; if not in range 00..0Fh + jae @@done ; return 0:0 + + movzx ebx,bl + mov cx,wptr exctab_pm[ebx*8+4] ; get user-defined exception handler CS + mov edx,dptr exctab_pm[ebx*8+0] ; get user-defined exception handler EIP + +@@done: mov ax,[esp+28] + jmp int31okedx ; return ok, with AX, CX, EDX + + +;============================================================================= +; Set Processor Exception Handler Vector +; +int31h_0203: + xchg bx,cx ; swap INT number with INT selector + call int31testsel ; test for valid selector BX + xchg bx,cx + + mov ds,cs:seldata + cmp bl,20h ; must be in range 00..1Fh + jae int31fail8021 ; invalid value + + cmp bl,10h ; if not in range 00..0Fh + jae @@done ; then done + + movzx ebx,bl + mov wptr exctab_pm[ebx*8+4],cx ; set user-defined exception handler CS + mov dptr exctab_pm[ebx*8+0],edx ; set user-defined exception handler EIP + +@@done: jmp int31ok ; return ok + + +;============================================================================= +; Get Protected Mode Interrupt Vector +; +int31h_0204: + mov ds,cs:seldata + call int31testint ; check if one of IRQs + jz @@1 ; if yes, read from buffer + +@@0: shl ebx,3 ; adjust for location in IDT + add ebx,idtbase ; add base of IDT + mov ds,selzero + mov edx,dptr [ebx+4] ; get high word of offset + mov dx,wptr [ebx+0] ; get low word of offset + mov cx,wptr [ebx+2] ; get selector + jmp @@done + +@@1: bt irqset_pm,si ; check if IRQ is installed + jnc @@2 ; if not, return built-in handler + test bl,0F0h ; check if IRQ is above INT 0Fh + jnz @@0 ; if yes, don't buffer: read from IDT + + mov cx,wptr irqtab_pm[esi*8+4] ; get user-defined IRQ handler CS + mov edx,dptr irqtab_pm[esi*8+0] ; get user-defined IRQ handler EIP + jmp @@done + +@@2: mov cx,SELCODE ; load built-in IRQ handler CS + lea edx,std_matrix[esi*4] ; load built-in IRQ handler EIP + +@@done: mov ax,[esp+28] + jmp int31okedx ; return ok, with AX, CX, EDX + + +;============================================================================= +; Set Protected Mode Interrupt Vector +; +int31h_0205: + xchg bx,cx ; swap int number with int selector + call int31testsel ; test for valid selector BX + xchg bx,cx + + mov ds,cs:seldata + mov es,selzero + movzx ecx,cx ; ECX = CX (selector) + + call int31testint ; check if one of IRQs + jz @@1 ; if yes, install in buffer + cmp bl,1Bh ; process special interrupts + jz @@1Bh + cmp bl,1Ch + jz @@1Ch + cmp bl,23h + jz @@23h + cmp bl,24h + jz @@24h + +@@0: shl ebx,3 ; adjust for location in IDT + add ebx,idtbase ; add base of IDT + mov wptr es:[ebx+0],dx ; set low word of offset + shr edx,16 + mov wptr es:[ebx+6],dx ; set high word of offset + mov wptr es:[ebx+2],cx ; set selector + jmp @@done + +@@1: cmp cx,SELCODE ; check if restoring IRQ + jnz @@2 ; if not, jump + + btr irqset_rm,si ; reset IRQ installed bit (RM) + btr irqset_pm,si ; reset IRQ installed bit (PM) + mov eax,irqtab_rm[esi*4] ; restore real mode interrupt + mov es:[ebx*4],eax + cmp bl,10h ; check if INT vector is above INT 0Fh + jae @@0 ; if yes, install into IDT + + jmp @@done + +@@2: bts irqset_rm,si ; set IRQ installed bit (RM) + bts irqset_pm,si ; set IRQ installed bit (PM) + mov eax,es:[ebx*4] ; get CS:IP of real mode INT vector + mov irqtab_rm[esi*4],eax ; save CS:IP of real mode INT vector + lea eax,back_matrix[esi*4] ; get address of real mode IRQ callback + mov wptr es:[ebx*4+0],ax ; set real mode IRQ callback IP + mov wptr es:[ebx*4+2],_KERNEL ; set real mode IRQ callback CS + cmp bl,10h ; check if INT vector is above INT 0Fh + jae @@0 ; if yes, install into IDT + + mov wptr irqtab_pm[esi*8+4],cx ; install CS into IRQ buffer + mov dptr irqtab_pm[esi*8+0],edx ; install EIP into IRQ buffer + +@@done: jmp int31ok ; return ok + +@@1Bh: cmp cx,SELCODE ; install real mode INT 1Bh callback + mov eax,newint1Bh + jnz @@1Bh0 + mov eax,oldint1Bh +@@1Bh0: mov es:[4*1Bh],eax + jmp @@0 + +@@1Ch: cmp cx,SELCODE ; install real mode INT 1Ch callback + mov eax,newint1Ch + jnz @@1Ch0 + mov eax,oldint1Ch +@@1Ch0: mov es:[4*1Ch],eax + jmp @@0 + +@@23h: cmp cx,SELCODE ; install real mode INT 23h callback + mov eax,newint23h + jnz @@23h0 + mov eax,oldint23h +@@23h0: mov es:[4*23h],eax + jmp @@0 + +@@24h: cmp cx,SELCODE ; install real mode INT 24h callback + mov eax,newint24h + jnz @@24h0 + mov eax,oldint24h +@@24h0: mov es:[4*24h],eax + jmp @@0 + + +;============================================================================= +; Get and Disable Virtual Interrupt State +; +int31h_0900: + add esp,26h ; adjust stack + pop ds ; restore DS + btr wptr [esp+8],9 ; test and clear IF bit in EFLAGS + setc al ; set AL = carry (IF flag from EFLAGS) + jmp int31oknopop ; return ok, dont pop registers + + +;============================================================================= +; Get and Enable Virtual Interrupt State +; +int31h_0901: + add esp,26h ; adjust stack + pop ds ; restore DS + bts wptr [esp+8],9 ; test and set IF bit in EFLAGS + setc al ; set AL = carry (IF flag from EFLAGS) + jmp int31oknopop ; return ok, dont pop registers + + +;============================================================================= +; Get Virtual Interrupt State +; +int31h_0902: + add esp,26h ; adjust stack + pop ds ; restore DS + bt wptr [esp+8],9 ; just test IF bit in EFLAGS + setc al ; set AL = carry (IF flag from EFLAGS) + jmp int31oknopop ; return ok, dont pop registers + + + + + + +;============================================================================= +; REAL/PROTECTED MODE TRANSLATION FUNCTIONS +;============================================================================= + +;============================================================================= +; Call Real Mode Procedure with Far Return Frame +; Call Real Mode Procedure with Interrupt Return Frame +; +int31h_0301: +int31h_0302: + mov ebp,dptr es:[edi+2Ah] ; get target CS:IP from structure + jmp int3103 ; go to common code + + +;============================================================================= +; Simulate Real Mode Interrupt +; +int31h_0300: + movzx ebx,bl ; get real mode INT CS:IP + mov ebp,dptr ds:[ebx*4] ; read from real mode interrupt table + +int3103: ; common to 0300h, 0301h, and 0302h + mov gs,cs:seldata + movzx ebx,wptr es:[edi+2Eh] ; EBX = SP from register structure + movzx edx,wptr es:[edi+30h] ; EDX = SS from register structure + mov ax,bx ; check if caller provided stack + or ax,dx + jnz @@f3 ; if yes, go on to setup stack + + mov dx,cs:rmstacktop ; DX = SS for real mode redirection + mov bx,cs:rmstacklen ; get size of real mode stack + sub dx,bx ; adjust DX to next stack location + cmp dx,cs:rmstackbase ; exceeded real mode stack space? + jb int31fail8012 ; if yes, error 8012h + mov gs:rmstacktop,dx ; update ptr for possible reenterancy + shl bx,4 ; adjust BX from paragraphs to bytes + +@@f3: lea edi,[edx*4] ; EDI -> top of real mode stack + lea edi,[edi*4+ebx] + + mov ax,ss + xchg ax,gs:rmstackss ; preserve and set new top of stack + push ax ; parms for possible reenterancy + lea eax,[esp-4] + xchg eax,gs:rmstackesp + push eax + + movzx ecx,cx + mov ax,cx ; EAX = length of stack parms + add ax,ax ; convert words to bytes + sub bx,2Eh ; adjust real mode SP for needed vars + sub bx,ax ; adjust real mode SP for stack parms + + push ds es ; swap DS and ES + pop ds es + + std ; string copy backwards + sub edi,2 ; copy stack parms from protected mode + lea esi,[ecx*2+esp+38h] ; stack to real mode stack + rep movs wptr es:[edi],ss:[esi] + + mov esi,[esp+06h] ; ESI = offset of structure from stack + mov ax,ds:[esi+20h] ; AX = FLAGS from register structure + cmp bptr [esp+22h],1 ; check AL on stack for function code + jz @@f4 ; if function 0301h, go on + and ah,0FCh ; 0300h or 0302h, clear IF and TF flag + stos wptr es:[edi] ; put flags on real mode stack + sub bx,2 + +@@f4: cld ; string copy forward + lea edi,[edx*4] ; EDI -> bottom of stack + lea edi,[edi*4+ebx] + mov cl,8 ; copy general regs to real mode stack + rep movs dptr es:[edi],ds:[esi] + add esi,6 ; copy FS and GS to real mode stack + movs dptr es:[edi],ds:[esi] + + mov wptr es:[edi+8],_KERNEL ; return address from call + mov wptr es:[edi+6],offs @@f1 + mov wptr es:[edi+4],ax ; store FLAGS for real mode IRET maybe + mov dptr es:[edi],ebp ; put call address to real mode stack + mov ax,[esi-6] ; real mode DS from register structure + mov cx,[esi-8] ; real mode ES from register structure + mov si,_KERNEL ; real mode target CS:IP + mov di,offs @@f0 + db 66h ; JMP DWORD PTR, as in 32bit offset, + jmp wptr cs:pmtormswrout ; not seg:16bit offset + +@@f0: popad ; load regs with call values + pop fs gs + iret ; go to call address + +@@f1: push gs fs ds es ; store registers on stack + pushf ; store flags on stack + cli + pushad + + xor eax,eax + mov ax,ss ; EAX = linear ptr to SS + xor ebp,ebp + shl eax,4 + mov bp,sp ; EBP = SP + add ebp,eax ; EBP -> stored regs on stack + + mov dx,cs:rmstackss ; get protected mode SS:ESP from stack + mov ebx,cs:rmstackesp + mov ax,SELZERO ; DS selector value for protected mode + mov cx,SELDATA ; ES selector value for protected mode + mov si,SELCODE ; target CS:EIP in protected mode + mov edi,offs @@f2 + jmp cs:rmtopmswrout ; go back to protected mode + +@@f2: push es + pop gs + pop es:rmstackesp + pop es:rmstackss + mov esi,ebp ; copy return regs from real mode + mov edi,[esp] ; get structure offset from stack + mov es,[esp+24h] + mov ecx,15h ; stack to register structure + cld + rep movs wptr es:[edi],ds:[esi] + + cmp dptr es:[edi+4],0 ; stack provided by caller? + jne int31ok ; if yes, done now + mov ax,cs:rmstacklen ; restore top of real mode stack + add gs:rmstacktop,ax + jmp int31ok ; return ok + + +;============================================================================= +; Allocate Real Mode Callback Address +; +int31h_0303: + mov bl,cs:pm32_callbacks ; CL = total number of callbacks + test bl,bl ; are there any? + jz int31fail8015 ; if no, error 8015h + + mov edx,cs:callbackbase ; EDX -> base of callbacks + mov ecx,edx ; for later use + +@@l0: cmp wptr [edx+3],0 ; is this callback free? + jz @@f0 ; if yes, allocate + add edx,25 ; increment ptr to callback + dec bl ; decrement loop counter + jnz @@l0 ; if more callbacks to check, loop + jmp int31fail8015 ; no free callback, error 8015h + +@@f0: mov bx,[esp+38] ; BX = caller DS from stack + mov [edx+3],bx ; store callback parms in callback + mov [edx+7],esi + mov [edx+12],es + mov [edx+16],edi + sub edx,ecx ; DX = offset of callback + shr ecx,4 ; CX = segment of callback + jmp int31okdx ; return ok, with DX, CX, AX + + +;============================================================================= +; Free Real Mode Callback Address +; +int31h_0304: + cmp cx,cs:callbackseg ; valid callback segment? + jne int31fail8024 ; if no, error 8024h + + movzx ebx,dx ; EBX = offset of callback + xor ax,ax ; check if valid offset + xchg dx,ax + mov cx,25 + div cx + test dx,dx ; is there a remainder + jnz int31fail8024 ; if yes, not valid, error 8024h + test ah,ah ; callback index too big? + jnz int31fail8024 ; if yes, not valid, error 8024h + cmp al,cs:pm32_callbacks ; callback index out of range? + jae int31fail8024 ; if yes, not valid, error 8024h + + add ebx,cs:callbackbase ; EBX -> callback + mov wptr [ebx+3],0 ; set callback as free + jmp int31ok ; return ok + + +;============================================================================= +; Get State Save/Restore Addresses +; +int31h_0305: ; get state save/restore addresses + add esp,26h ; adjust stack + pop ds ; restore DS + xor ax,ax ; size needed is none + mov bx,cs:kernel_code ; real mode seg of same RETF + mov cx,offs vxr_saverestorerm ; same offset of 16bit RETF + mov si,cs ; selector of routine is this one + mov edi,offs vxr_saverestorepm ; offset of simple 32bit RETF + jmp int31oknopop ; return ok, dont pop registers + + +;============================================================================= +; Get Raw CPU Mode Switch Addresses +; +int31h_0306: ; get raw mode switch addresses + add esp,26h ; adjust stack + pop ds ; restore DS + mov si,cs ; selector of pmtorm rout is this one + mov edi,cs:pmtormswrout ; offset in this seg of rout + mov bx,cs:kernel_code ; real mode seg of rmtopm rout + mov cx,cs:rmtopmswrout ; offset of rout in real mode + jmp int31oknopop ; return ok, dont pop registers + + + + + + +;============================================================================= +; MISC FUNCTIONS +;============================================================================= + +;============================================================================= +; Get DPMI Version +; +int31h_0400: + add esp,26h ; adjust stack + pop ds ; restore DS + mov ax,005Ah ; return version 0.9 + mov bx,0003h ; capabilities + cmp cs:pmodetype,2 + jnz @@1 + mov bl,1 +@@1: mov cl,cs:cputype ; processor type + mov dx,wptr cs:picslave ; master and slave PIC values + jmp int31oknopop ; return ok, don't pop registers + + +;============================================================================= +; Get Vendor-Specific API Entry Point +; +int31h_0A00: + add esp,26h ; adjust stack + pop ds ; restore DS + + push es edi ecx esi ; save regs that will be modified + push cs ; ES = CS + pop es + + mov ecx,15 ; search for vendor1 string + mov edi,offs @@str1 + push esi + repe cmps bptr ds:[esi],es:[edi] + pop esi + mov edi,offs @@ent1 ; ES:EDI = sel:offset of entry SUNSYS + jz @@0 ; if found, jump + test cs:pm32_mode,10000000b ; check if to ignore DOS/4G extensions + jnz @@err ; if not, we are done + mov cl,16 ; search for vendor2 string + mov edi,offs @@str2 + repe cmps bptr ds:[esi],es:[edi] + jnz @@err ; if not found, done + mov edi,offs @@ent2 ; ES:EDI = sel:offset of entry DOS/4G + pop esi ecx + add esp,6 + jmp int31oknopop + +@@0: add esp,14 + xor eax,eax ; clear high words + mov ebx,eax + mov ecx,eax + mov edx,eax + mov ax,cs:client_version ; AX = DOS Extender Version Number + mov bl,cs:pm32_mode ; BL = kernel configuration + mov bh,cs:pmodetype ; BH = system software type + mov cl,cs:cputype ; CL = processor type + mov ch,cs:fputype ; CH = FPU type + mov dx,wptr cs:picslave ; DX = PIC values (unremapped) + jmp int31oknopop + +@@err: pop esi ecx edi es ; if none of the strings were idetified + mov ax,8001h ; return with AX=8001h + jmp int31failnopop + +@@str1 db 'SUNSYS DOS/32A',0 ; vendor1 API ID-string (DOS/32A) +@@str2 db 'RATIONAL DOS/4G',0 ; vendor2 API ID-string (DOS/4G) + +@@ent2: mov ax,8500h ; vendor2 API entry point (DOS/4G) + jmp dptr cs:client_call + +@@ent1: test al,al ; vendor1 API entry point (DOS/32A) + jz API_func00 + cmp al,01h + jz API_func01 + cmp al,02h + jz API_func02 + cmp al,03h + jz API_func03 + cmp al,04h + jz API_func04 + cmp al,05h + jz API_func05 + cmp al,06h + jz API_func06 + cmp al,07h + jz API_func07 + cmp al,08h + jz API_func08 + cmp al,09h + jz API_func09 + stc + db 66h + retf + +;--------------------------------------------------------------------- +API_func00: ; API function 00h: get access to IDT & GDT + mov bx,SELZERO + movzx ecx,cs:gdtlimit ; ECX = GDT limit + movzx edx,cs:idtlimit ; EDX = IDT limit + mov esi,cs:gdtbase ; BX:ESI = pointer to GDT + mov edi,cs:idtbase ; BX:EDI = pointer to IDT + jmp API_funcok + +;--------------------------------------------------------------------- +API_func01: ; API function 01h: get access to PageTables + mov bx,SELZERO + movzx ecx,cs:pagetables ; ECX = number of allocated pagetables + movzx edx,cs:pm32_maxfpages ; EDX = number of allocated phystables + mov esi,cs:pagetablebase ; BX:ESI = pointer to 0th pagetable + mov edi,cs:phystablebase ; BX:EDI = pointer to phystable + inc cx + jmp API_funcok + +;--------------------------------------------------------------------- +API_func02: ; API function 02: get access to INT tables + mov bx,SELDATA + mov esi,offs irqset_rm ; BX:ESI = pointer to INT switches + mov edi,offs irqtab_rm ; BX:EDI = pointer to INT tables + jmp API_funcok + +;--------------------------------------------------------------------- +API_func03: ; API function 03: get access to EXT memory + mov bx,SELZERO + mov ecx,cs:mem_free ; ECX = size of allocated memory + mov edx,cs:mem_ptr ; EDX = pointer to allocated memory + mov esi,cs:mem_top ; ESI = top of allocated memory + jmp API_funcok + +;--------------------------------------------------------------------- +API_func04: ; API function 04: get access to rm-stacks + mov bx,SELZERO + movzx ecx,cs:rmstacklen ; ECX = size of one stack + movzx edx,cs:rmstacktop ; EDX = pointer to top of stack + movzx esi,cs:rmstackbase ; ESI = base of stack area + movzx edi,cs:rmstacktop2 ; EDI = default top of stack + jmp API_funcok + +;--------------------------------------------------------------------- +API_func05: ; API function 05: get access to pm-stacks + mov bx,SELZERO + mov ecx,cs:pmstacklen ; ECX = size of one stack + mov edx,cs:pmstacktop ; EDX = pointer to top of stack + mov esi,cs:pmstackbase ; ESI = base of stack area + mov edi,cs:pmstacktop2 ; EDI = default top of stack + jmp API_funcok + +;--------------------------------------------------------------------- +API_func06: ; API function 06: get kernel selectors + mov bx,SELCODE ; BX = Kernel code selector + mov cx,SELDATA ; CX = Kernel data selector + mov dx,SELZERO ; DX = Kernel zero selector + movzx esi,wptr cs:kernel_code ; ESI = Kernel code segment + mov di,wptr cs:client_call[2] ; DI = Client code selector + jmp API_funcok + +;--------------------------------------------------------------------- +API_func07: ; API function 07: get critical handler entry + mov cx,cs:client_call[2] ; CX = default 16bit selector + mov dx,cs:client_call[0] ; DX = default 16bit offset + jmp API_funcok + +;--------------------------------------------------------------------- +API_func08: ; API function 08: set critical handler entry + push ds + mov ds,cs:seldata + mov client_call[2],cx ; CX = custom 16bit selector + mov client_call[0],dx ; DX = custom 16bit offset + pop ds + jmp API_funcok + +;--------------------------------------------------------------------- +API_func09: ; API function 09: get access to p. counters + mov cx,SELDATA ; CX = Kernel data selector + mov edx,offs _pc_base ; EDX = base of performance counters + +;--------------------------------------------------------------------- +API_funcok: + clc + db 66h + retf + + + + + + +;============================================================================= +; MEMORY FUNCTIONS +;============================================================================= + +;============================================================================= +; Get Free Memory Information +; +int31h_0500: + or eax,-1 + mov ecx,0Ch + push edi + rep stos dptr es:[edi] + pop edi + mov eax,cs:mem_ptr + or eax,cs:mem_free + jz @@1 + call int31_checkblocks + call int31_getfreemem + +@@1: mov ebx,eax + mov edx,eax ; EDX = largest free block + mov eax,cs:mem_free + shr eax,12 ; EAX = total memory pages + shr ebx,12 ; EBX = free pages left + shr ecx,12 ; ECX = total allocated memory + push es + pop ds + mov [edi+00h],edx ; 00h - largest free block + mov [edi+04h],ebx ; 04h - max unlocked pages + mov [edi+08h],ebx ; 08h - max locked pages + mov [edi+0Ch],eax ; 0Ch - total linear space + mov [edi+10h],ebx ; 10h - + mov [edi+14h],ecx ; 14h - + mov [edi+18h],eax ; 18h - total pages + mov [edi+1Ch],ecx ; 1Ch - total free mem in pages + jmp int31ok + + +;============================================================================= +; Allocate Memory Block +; +int31h_0501: + call int31_checkifmemavail + call int31_testbxcxtoebx ; convert BX:CX to EBX + call int31_checkblocks + mov esi,cs:mem_ptr ; get pointer to memory +@@1: mov eax,[esi+04h] ; get block size + btr eax,31 ; check if memory block is used + jc @@2 ; if yes, jump + cmp eax,ebx ; check if block is large enough + jae int31_allocblock ; if yes, allocate block +@@2: lea esi,[esi+eax+10h] ; load address of next memory block + cmp esi,cs:mem_top ; check if at top of memory + jb @@1 ; if not, loop + jmp int31fail8013 ; fail: not enough memory + + +;============================================================================= +; Free Memory Block +; +int31h_0502: + shl esi,16 ; convert SI:DI to ESI + mov si,di + call int31_checkifmemavail + call int31_checkblocks + call int31_checkhandle + btr dptr [esi+04h],31 ; set block as free + call int31_linkfreeblocks + jmp int31ok + + +;============================================================================= +; Resize Memory Block +; +int31h_0503: + shl esi,16 ; convert SI:DI to ESI + mov si,di + call int31_checkifmemavail + call int31_testbxcxtoebx ; convert BX:CX to EBX + call int31_checkblocks + call int31_checkhandle + + mov eax,[esi+04h] ; get size of this block + btr eax,31 ; check if block is used + jnc int31fail8023 ; if block is free, fail + cmp eax,ebx ; check if enough memory + jae int31_allocblock ; if yes, reallocate block + mov [esi+04h],eax ; set this block as free + lea edi,[esi+eax+10h] ; get address of next block + cmp edi,cs:mem_top ; check if at top of memory + jae @@0 + mov edx,[edi+04h] ; get size of next block + btr edx,31 ; check if block next to us is free + jc @@0 ; if not, jump + lea edx,[eax+edx+10h] ; calculate total size (this+hdr+next) + cmp edx,ebx ; check if enough + jb @@0 ; if not, jump + mov eax,edx ; set this size = (this + next) + mov [esi+04h],eax ; link this and next blocks + jmp int31_allocblock ; and go to the allocation routine + +@@0: mov edi,cs:mem_ptr ; get pointer to memory +@@1: mov edx,[edi+04h] ; get block size + btr edx,31 ; check if memory block is used + jc @@2 ; if yes, jump + cmp edx,ebx ; check if block is large enough + jae @@3 ; if yes, allocate block +@@2: lea edi,[edi+edx+10h] ; load address of next memory block + cmp edi,cs:mem_top ; check if at top of memory + jb @@1 ; if not, loop + bts eax,31 ; set this block as used + mov [esi+04h],eax ; restore state of this block + jmp int31fail8013 ; fail: not enough memory + +@@3: push esi edi + mov ecx,eax + shr ecx,2 + add esi,10h + add edi,10h + rep movs dptr es:[edi],ds:[esi] + mov cl,al + and cl,3 + rep movs bptr es:[edi],ds:[esi] + pop edi esi + call int31_linkfreeblocks + mov esi,edi + mov eax,edx + jmp int31_allocblock ; and go to the allocation routine + + +;============================================================================= +; Get Memory Block Size and Base +; +int31h_050A: + shl esi,16 ; convert SI:DI to ESI + mov si,di + call int31_checkifmemavail + call int31_checkblocks + call int31_checkhandle + mov ebx,[esi+04h] ; check if block is used + btr ebx,31 + jnc int31fail8023 + add esi,10h + xchg ebx,esi + mov cx,bx + shr ebx,16 + mov di,si + shr esi,16 + jmp int31oksinoax + + + +;----------------------------------------------------------------------------- +int31_checkifmemavail: ; check if memory had been allocated + pop bp + push eax + mov eax,cs:mem_ptr + or eax,cs:mem_free + pop eax + jz int31fail8013 + jmp bp + +;----------------------------------------------------------------------------- +int31_checkblocks: ; check if memory had been overwritten + push eax esi + mov esi,cs:mem_ptr +@@1: test si,000Fh ; blocks must be para aligned + jnz @@err + mov eax,12345678h ; header id + cmp eax,[esi+00h] ; if no header_id at block start + jnz @@err ; then signal error + cmp eax,[esi+0Ch] ; if no header_id at block end + jnz @@err ; then signal error + mov eax,[esi+04h] ; get block size + btr eax,31 ; reset the used flag + lea esi,[esi+eax+10h] ; load address of next memory block + cmp esi,cs:mem_ptr + jb @@err + cmp esi,cs:mem_top ; check if at top of memory + ja @@err + jb @@1 ; if not, loop + pop esi eax +@@done: ret + +@@err: mov ds,cs:seldata + xor eax,eax + mov mem_ptr,eax ; set to zero to prevent looping error + mov mem_free,eax ; when exiting + mov ax,8400h + jmp dptr client_call + +;----------------------------------------------------------------------------- +int31_checkhandle: + pop bp ; check for valid handle in ESI + cmp esi,cs:mem_ptr + jb @@1 + cmp esi,cs:mem_top + ja @@1 + mov eax,12345678h + cmp eax,[esi+00h] + jnz @@1 + cmp eax,[esi+0Ch] + jnz @@1 + jmp bp +@@1: jmp int31fail8023 ; fail: invalid handle + +;----------------------------------------------------------------------------- +int31_testbxcxtoebx: ; convert BX:CX to EBX + pop bp + shl ebx,16 + mov bx,cx + test ebx,ebx + jz int31fail8021 ; BX:CX cannot be zero + add ebx,0Fh ; align EBX on para boundary + and bl,0F0h + bt ebx,31 + jc int31fail8021 ; cannot allocate that much memory + jmp bp + +;----------------------------------------------------------------------------- +int31_getfreemem: + xor eax,eax ; reset free memory size + xor ecx,ecx + mov esi,cs:mem_ptr ; get pointer to memory +@@1: mov edx,[esi+04h] ; get block size + btr edx,31 ; check if memory block is used + jc @@2 ; if yes, jump + add ecx,edx + cmp eax,edx ; pick largest value + ja @@2 + mov eax,edx +@@2: lea esi,[esi+edx+10h] ; load addres of next memory block + cmp esi,cs:mem_top ; check if at top of memory + jb @@1 ; if not, loop + ret + +;----------------------------------------------------------------------------- +int31_allocblock: + mov ecx,12345678h + movzx edx,cs:id32_process_id + sub eax,ebx ; nextsize=actualsize-allocsize + sub eax,10h ; is nextsize<16 (header size) + jb @@1 ; if yes, do not create next block + lea edi,[esi+ebx+10h] ; EDI = ptr to next block + mov [edi+00h],ecx ; header ID1 + mov [edi+04h],eax ; set next block as free/size + mov [edi+08h],edx ; process_ID + mov [edi+0Ch],ecx ; header ID2 + +@@1: bts ebx,31 ; set this block as used + mov [esi+00h],ecx ; header ID1 + mov [esi+04h],ebx ; store this block size in header + mov [esi+08h],edx ; process_ID + mov [esi+0Ch],ecx ; header ID2 + call int31_linkfreeblocks + + lea ebx,[esi+10h] ; EBX = ptr to memory block (-header) + mov cx,bx + shr ebx,16 + mov di,si + shr esi,16 + jmp int31oksinoax + +;----------------------------------------------------------------------------- +int31_linkfreeblocks: + pushad + mov edi,cs:mem_ptr ; EDI = ptr to 1st block handle + mov ebp,cs:mem_top + + mov eax,[edi+04h] ; get 1st block size + btr eax,31 + lea esi,[edi+eax+10h] ; ESI = ptr to 2nd block handle + cmp esi,ebp ; check if at top of memory + jae @@done ; if yes, done + mov esi,edi ; ESI=EDI = ptr to 1st block + +@@1: mov eax,[esi+04h] ; get block size + btr eax,31 ; check if block is used + jc @@4 ; if yes, jump + + xor ebx,ebx ; reset amount of free block memory + xor ecx,ecx ; reset number of free blocks in raw + mov edi,esi ; remember addr of first free block + jmp @@3 + +@@2: add ecx,10h ; increment number of free blocks + mov eax,[esi+04h] ; get block size + btr eax,31 ; check if block is free + lea ebx,[eax+ebx] ; amount of free memory encountered + jnc @@3 ; if yes, jump + sub ebx,eax + sub ecx,10h + add ebx,ecx + add [edi+04h],ebx + jmp @@4 + +@@3: lea esi,[esi+eax+10h] ; calculate address of next block + cmp esi,ebp ; check if at top of memory + jb @@2 ; if not, loop + add ebx,ecx + add [edi+04h],ebx + jmp @@done + +@@4: lea esi,[esi+eax+10h] ; calculate address of next block + cmp esi,ebp ; check if at top of memory + jb @@1 ; if not, loop + +@@done: popad + ret + + + + + + +;============================================================================= +; VIRTUAL MEMORY FUNCTIONS (not supported) +;============================================================================= + +;============================================================================= +; Lock Linear Region +; Unlock Linear Region +; Mark Real Mode Region as Pageable +; Relock Real Mode Region +; Mark Page as Demand Paging Candidate +; Discard Page Contents +; +int31h_0600: +int31h_0601: +int31h_0602: +int31h_0603: +int31h_0702: +int31h_0703: + jmp int31ok + + +;============================================================================= +; Get Page Size +; +int31h_0604: + xor bx,bx + mov cx,1000h + jmp int31okbx + + + + + +;============================================================================= +; PHYSICAL MEMORY MAPPING FUNCTIONS +;============================================================================= + +;============================================================================= +; Physical Address Mapping +; +int31h_0800: + shl ebx,16 ; convert BX:CX to EBX + shl esi,16 ; convert SI:DI to ESI + mov bx,cx + mov si,di + cmp ebx,100000h ; check if mapping under 1MB limit + jb int31fail8021 ; if yes, error + test esi,esi ; check if size is zero + jz int31fail8021 ; if yes, error + cmp cs:pmodetype,2 ; check if system is VCPI + jz @@vcpi ; if yes, do VCPI memory mapping + jmp int31ok ; if under raw/XMS, do nothing + +@@vcpi: cmp cs:pm32_maxfpages,0 ; check if any linear memory avail. + jz int31fail8012 ; if not, signal error 8012h + + push ds + pop es + mov edi,cs:phystablebase ; get base of pagetables +@@0: mov eax,ebx ; EAX = physical address + lea ecx,[esi+0FFFh] ; ECX = size of memory to map + and ax,0F000h + shr ecx,12 + mov edx,edi +@@1: cmp edi,cs:phystabletop ; are there any pages mapped left + jae @@3 ; no, go on with mapping + + mov ebp,[edi] + and bp,0F000h + cmp eax,ebp ; check if page already mapped + jz @@2 ; if yes, go to check next page + add edi,4 ; increment pointer into pagetables + jmp @@0 ; loop + +@@2: add edi,4 ; increment pointer into pagetables + add eax,4096 + dec ecx ; decrement amount of pages checked + jnz @@1 ; if there are more left, loop + mov eax,ebx + and ax,0F000h + sub ebx,eax + jmp @@done ; region already mapped, we are done + +@@3: mov edi,cs:phystablebase ; get base of pagetables + mov ecx,cs:phystabletop ; get number of available pagetables + sub ecx,edi + shr ecx,2 ; convert to 4KB pages + mov eax,ebx + and ax,0F000h + lea ebp,[ebx+esi+0FFFh] ; EBP = number of required 4KB pages + sub ebp,eax + shr ebp,12 + +@@4: test ecx,ecx ; check if no linear space left + jz int31fail8021 ; if yes, error + xor eax,eax + repne scas dptr es:[edi] ; scan for first free page + lea edx,[edi-4] ; EDX = first free page address + repe scas dptr es:[edi] ; scan for amount of free pages + mov eax,edi + sub eax,edx + shr eax,2 ; EAX = free pages available + cmp eax,ebp ; check if enough free pages + jb @@4 ; no, must loop + + mov eax,ebx ; EAX = physical address + and ax,0F000h + sub ebx,eax + mov edi,edx ; EDI = address of first free page + mov ecx,ebp + mov al,07h ; set page as user/writeable/present + cmp cs:cputype,3 ; check if CPU is 486+ + jbe @@loop ; if not, jump + mov al,1Fh ; set PCD and PWT bits (no page cache) + +@@loop: stos dptr es:[edi] ; map one 4KB page + add eax,4096 ; go for next page + loop @@loop ; loop until no pages left + or bptr [edx+1],2 ; mark start of mapped block + or bptr [edi-3],4 ; mark end of mapped block + +@@done: sub edx,cs:phystablebase + shl edx,10 + add edx,ebx + + mov [esp+18h],dx + shr edx,16 + or dx,8000h + mov [esp+10h],dx + + mov eax,cs:vcpi_cr3 + mov cr3,eax + xor eax,eax + mov cr2,eax + jmp int31ok + + +;============================================================================= +; Free Physical Address Mapping +; +int31h_0801: + cmp cs:pmodetype,2 + jz @@vcpi + jmp int31ok ; if under raw/XMS, do nothing + +@@vcpi: cmp cs:pm32_maxfpages,0 ; check if any linear memory avail. + jz int31fail8012 ; if not, signal error 8012h + + and bx,7FFFh + shl ebx,16 + mov bx,cx + shr ebx,10 + and bl,0FCh + + add ebx,cs:phystablebase + cmp ebx,cs:phystablebase ; check if addr is in range + jb int31fail8025 + cmp ebx,cs:phystabletop + jae int31fail8025 + test bptr [ebx+1],2 + jz int31fail8025 + +@@loop: xor eax,eax ; clear page table entries + xchg eax,[ebx] + add ebx,04h + test ah,04h + jz @@loop + +@@1: mov eax,cs:vcpi_cr3 + mov cr3,eax + xor eax,eax + mov cr2,eax + jmp int31ok + + + + + + +;============================================================================= +; FPU RELATED FUNCTIONS +;============================================================================= + +;============================================================================= +; Get Coprocessor Status +; +int31h_0E00: + movzx ax,cs:fputype ; get FPU type + shl ax,4 ; put FPU type in bits 4..7 + + smsw dx ; get MSW in DX + and dl,06h ; mask MP & EM bits + shr dl,1 ; map MP & EM bits to MPv & EMv bits + or al,dl ; put MPv & EMv bits into AL + shl dl,2 ; map MP & EM bits to MPr & EMr bits + or al,dl ; put MPr & EMr bits into AL + + jmp int31okax + + +;============================================================================= +; Set Coprocessor Emulation +; +int31h_0E01: + mov ds,cs:seldata + and bl,00000011b ; mask MPv & EMv bits + shl bl,1 ; map MPv & EMv bits to MP & EM bits + + smsw ax ; get MSW in AX + or al,bl ; set MP & EM bits + lmsw ax ; reload MSW + + jmp int31ok + + + + + + +;============================================================================= +; NON-STANDARD FUNCTIONS +;============================================================================= + +;============================================================================= +; PMODE/W id function +; +int31h_EEFF: + add esp,26h ; adjust stack + pop ds ; restore DS + push cs + pop es ; ES = CS + mov eax,'D32A' ; load id-string + mov ebx,offs $+2 ; ES:EBX points to itself ('\0' within opcode) + mov ch,cs:pmodetype + mov cl,cs:cputype + mov dx,cs:client_version + jmp int31oknopop + diff -uNr a/dos32a/src/dos32a/text/kernel/intr.asm b/dos32a/src/dos32a/text/kernel/intr.asm --- a/dos32a/src/dos32a/text/kernel/intr.asm false +++ b/dos32a/src/dos32a/text/kernel/intr.asm bab1bb5a6d9129aae18a2c2b6091d3cd25d3441a42437476f424062021d17ca473f9369452d2695def5d54d3e97f4e1fa28848f7f109ed939d3c3ec5f0898f40 @@ -0,0 +1,676 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +; interrupt tables +;============================================================================= + Align 16 +int_matrix: ; INT redirectors + rept 256 ; 256 INTs + push ax + call near ptr int_main + endm +;============================================================================= +std_matrix: ; Standard IRQ redirectors + rept 16 ; 16 IRQs + push ax + call near ptr irq_standard + endm +;============================================================================= +back_matrix: ; Real mode IRQ callbacks + rept 16 ; 16 IRQs + push ax + call near ptr irq_callback + endm +;============================================================================= +exc_matrix: ; Exceptions + rept 16 ; 16 EXCs + push ax + call near ptr exc_handler + endm + + + + + +;============================================================================= +; Out of Real-Mode virtual stack space handler: handles virtual stack +; overflows which may occur during a switch from PM to RM. +; +critical_error_rm: + cli + mov ds,cs:seldata ; DS points to kernel + mov es,selzero ; ES points to zero + + mov eax,oldint1Ch ; restore INT 1Ch + mov es:[4*1Ch],eax + + mov ax,rmstacktop2 ; restore RM virtual stack + mov rmstacktop,ax ; to a safe value + + mov ax,8200h ; AX = kernel error code + jmp dptr client_call ; enter client's run-time error handler + +;============================================================================= +; Out of Protected-Mode virtual stack space handler: handles virtual stack +; overflows which may occur during a switch from RM to PM. +; +critical_error_pm: + cli + xor ax,ax + mov ds,cs:kernel_code ; DS points to kernel + mov es,ax ; ES points to zero + + mov eax,oldint1Ch ; restore INT 1Ch + mov es:[4*1Ch],eax + + mov eax,pmstacktop2 ; restore PM virtual stack + mov pmstacktop,eax ; to a safe value + + mov ebx,eax ; EBX = ESP for protected mode + mov ax,SELDATA ; DS selector for protected mode + mov cx,ax + mov dx,SELZERO ; SS selector = zero selector + mov si,SELCODE ; target protected mode CS:EIP + mov edi,offs @@0 + jmp rmtopmswrout ; switch to protected mode + +@@0: mov ax,8300h ; AX = kernel error code + jmp dptr client_call ; enter client's run-time error handler + + + + + +;============================================================================= +; INT Redirector +; +; Default interrupt handler: reflects interrupts issued in protected mode +; (and for which no user-defined handler is installed) to real-mode. +; +int_main: + cli ; disable interrupts + + pop ax ; get caller address in AX + sub ax,offs int_matrix+1 ; calculate INT number + shr ax,2 ; now AX = INT ##h + + pushad + push ds es fs gs + mov ds,cs:seldata + + inc _pc_intpmtorm ; increment INT PM->RM counter + mov @@N,al ; modify code with interrupt number + + mov dx,rmstacktop ; DX = SS for real mode redirection + mov bx,rmstacklen ; get size of real mode stack + movzx esi,dx ; EBP -> top of real mode stack + sub dx,bx ; adjust DX to next stack location + shl esi,4 + cmp dx,rmstackbase ; exceeded real mode stack space? + jb critical_error_rm ; if yes, critical error + mov rmstacktop,dx ; update ptr for possible reenterancy + shl bx,4 ; set real mode SP to top of stack + + mov es,selzero ; copy registers from protected mode + mov ds,selzero ; DS -> 0 (beginning of memory) + lea edi,[esi-26h] + mov ecx,8 + mov [esi-2],ss ; store SS:ESP on real mode stack + mov [esi-6],esp + lea esi,[esp+8] + cld + rep movs dptr es:[edi],ss:[esi] + mov ax,[esp+28h] ; move AX to real mode stack frame + mov [edi-04h],ax + mov si,_KERNEL ; real mode target CS:IP + mov di,offs @@0 + sub bx,26h ; adjust real mode SP for stored vars + db 66h ; JMP DWORD PTR, as in 32bit offset, + jmp wptr cs:pmtormswrout ; not seg:16bit offset + +@@0: popad ; load regs with int call values + db 0CDh ; issue INT ##h in real-mode +@@N db 000h + + pushad ; store registers on stack + pushf ; store flags on stack + cli ; disable interrupts + xor eax,eax ; EAX = linear ptr to SS + mov ebp,eax + mov ax,ss + shl eax,4 + mov bp,sp ; EBP = SP + mov ebx,[bp+22h] ; get protected mode SS:ESP from stack + mov dx,[bp+26h] + add ebp,eax ; EBP -> stored regs on stack + mov ax,SELZERO ; DS selector value for protected mode + mov cx,SELDATA ; ES selector value for protected mode + mov si,SELCODE ; target CS:EIP in protected mode + mov edi,offs @@1 + jmp cs:rmtopmswrout ; go back to protected mode + +@@1: inc es:_pc_intrmtopm ; increment INT RM->PM counter + + mov ax,es:rmstacklen ; restore top of real mode stack + add es:rmstacktop,ax + + mov ax,ds:[ebp] ; move return FLAGS from real mode + and ax,08D5h ; stack to protected mode stack + mov dx,[esp+32h] + and dx,not 08D5h + or ax,dx + mov [esp+32h],ax + mov eax,ebp + mov edi,[eax+2] ; restore return registers from real + mov esi,[eax+6] ; mode stack + mov ebp,[eax+10] + mov ebx,[eax+18] + mov edx,[eax+22] + mov ecx,[eax+26] + mov eax,[eax+30] + + pop gs fs es ds ; restore segment regs + add esp,22h ; skip old registers + iretd ;**no pop AX + + + + + +;============================================================================= +; irq_tester is called only for interrupts INT 08..0Fh, only when +; master PIC is mapped onto those INTs +; +irq_tester: ; redirection for IRQs mapped on INT 08..0Fh + mov al,0Bh ; query master interrupt controller + out 20h,al + in al,20h + test al,al + jz irq_fail ; if no pending IRQ, jump + + mov ax,[esp] ; get caller address from stack + sub ax,offs int_matrix+1 ; calculate INT number + shr ax,2 ; AX = INT number + mov [esp],ax ; save INT number + + and al,07h ; AX = IRQ number + bt cs:irqset_pm,ax ; check if user handler is installed + pop ax ; restore INT number + jnc irq_down ; if not, proceed + + and al,07h ; AX = IRQ number + shl ax,3 + xchg ax,bx + sub esp,6 ; alloc 6 bytes on stack + mov [esp+4],ax ; put BX on stack + mov ax,wptr cs:irqtab_pm[bx+0] ; get target offset loword(EIP) + mov [esp+0],ax + mov ax,wptr cs:irqtab_pm[bx+2] ; get target offset hiword(EIP) + mov [esp+2],ax + mov bx,wptr cs:irqtab_pm[bx+4] ; get target selector CS + xchg bx,[esp+4] ; put CS and restore BX + mov ax,[esp+6] ; restore AX + db 66h ; do 32bit far ret to the + retf ; appropriate interrupt handler + + +;============================================================================= +; irq_normal is called for IRQs that do not need to be tested against +; CPU exceptions +; +irq_normal: ; Standard IRQ handler that will send + pop ax ; all the IRQs that have not been + sub ax,offs int_matrix+1 ; hooked in protected mode to real + shr ax,2 ; mode + +;----------------------------------------------------------------------------- +; reflects an IRQ to the real-mode handler +; +irq_down: + pushad + push ds es fs gs + mov ds,cs:seldata + + inc _pc_irqpmtorm ; increment IRQ PM->RM counter + + movzx eax,al ; EAX = interrupt number + + mov dx,rmstacktop ; DX = SS for real mode redirection + mov bx,rmstacklen ; get size of real mode stack + movzx esi,dx ; ESI -> top of real mode stack + sub dx,bx ; adjust DX to next stack location + shl esi,4 + cmp dx,rmstackbase ; exceeded real mode stack space? + jb critical_error_rm ; if yes, critical error + mov rmstacktop,dx ; update ptr for possible reenterancy + shl bx,4 ; set real mode SP to top of stack + + mov ds,selzero ; DS -> 0 (beginning of memory) + mov edi,[eax*4] ; get real mode interrupt CS:IP + mov [esi-2],ss ; store SS: on real mode stack + mov [esi-6],esp ; store ESP on real mode stack + mov dptr [esi-10],_KERNEL ; set target FLAGS and CS on RM stack + mov wptr [esi-12],offs @irq ; set target IP on RM stack + shld esi,edi,16 + sub bx,12 ; adjust real mode SP for stored vars + db 66h ; JMP DWORD PTR, as in 32bit offset, + jmp wptr cs:pmtormswrout ; not seg:16bit offset + + + + + +;============================================================================= +; Exception Handler +; +; We get here when: +; + an interrupt in range INT 00..0Fh occurs +; + irq_tester function determines that there is no pending IRQ +; in the interrupt controller +; +irq_fail: + pop ax ; get call address + sub ax,offs int_matrix+1 ; calculate INT ## + shr ax,2 +; +; invoke a user-defined exception handler +; + cmp al,08h ; exceptions 08h, 0A..0Eh push error codes + jb @@2 + cmp al,09h + je @@2 + cmp al,0Eh + ja @@2 +; +; rearrange stack frame: have exception code +; +@@1: sub esp,16h + mov [esp+08h],eax ; save hiword(EAX) + + movzx eax,ax + mov eax,cs:exctab_pm[eax*8+0] + mov [esp+00h],eax ; target EIP + + movzx eax,wptr [esp+08h] + mov eax,cs:exctab_pm[eax*8+4] + mov [esp+04h],eax ; target CS + + mov ax,[esp+16h] ; restore AX + mov [esp+08h],ax ; save loword(EAX) + + mov ax,cs + mov [esp+0Ch],eax ; ret CS + + mov eax,[esp+18h] + mov [esp+10h],eax ; EC + mov eax,[esp+1Ch] + mov [esp+14h],eax ; EIP + mov eax,[esp+20h] + mov [esp+18h],eax ; CS + mov eax,[esp+24h] + mov [esp+1Ch],eax ; EFL + + jmp @@run +; +; rearrange stack frame: no exception code +; +@@2: sub esp,1Ah + mov [esp+08h],eax ; save hiword(EAX) + + movzx eax,ax + mov eax,cs:exctab_pm[eax*8+0] + mov [esp+00h],eax ; target EIP + + movzx eax,wptr [esp+08h] + mov eax,cs:exctab_pm[eax*8+4] + mov [esp+04h],eax ; target CS + + mov ax,[esp+1Ah] ; restore AX + mov [esp+08h],ax ; save loword(EAX) + + mov ax,cs + mov [esp+0Ch],eax ; ret CS + + xor eax,eax + mov [esp+10h],eax ; EC + mov eax,[esp+1Ch] + mov [esp+14h],eax ; EIP + mov eax,[esp+20h] + mov [esp+18h],eax ; CS + mov eax,[esp+24h] + mov [esp+1Ch],eax ; EFL + +@@run: lea eax,[esp+28h] + mov [esp+20h],eax ; ESP + + mov ax,ss + movzx eax,ax + mov [esp+24h],eax ; SS + + mov ax,offs @@ret ; ret EIP + xchg eax,[esp+08h] ; restore EAX + + db 66h ; do 32bit far ret to the + retf ; appropriate exception handler + + +; exception handler epilogue +; note: we don't reload the stack but simply ignore SS:ESP values on eh's stack frame +@@ret: mov [esp],eax + mov eax,[esp+0Ch] + mov [esp+14h],eax + mov eax,[esp+08h] + mov [esp+10h],eax + mov eax,[esp+04h] + mov [esp+0Ch],eax + mov eax,[esp] + add esp,0Ch + iretd + + +;============================================================================= +; Invoke built-in exception handler +; +exc_handler: + pop ax + sub ax,offs exc_matrix+1 + shr ax,2 + + mov ah,81h ; kernel run-time error 81h + jmp dptr cs:client_call ; jump to built-in exception handler + + + + + + +;============================================================================= +; Standard IRQ Handler +; +; This is a built-in IRQ handler. It is returned by INT 31h, AX=0204h +; for BL values identifying IRQs for which no user-defined handler had been +; installed. When a user-defined IRQ handler chains, the call goes here. +; +irq_standard: ; Standard IRQ handler that will send + cli + pop ax ; by default all the IRQs from + sub ax,offs std_matrix+1 ; protected mode to real mode + shr ax,2 + + pushad + push ds es fs gs + mov ds,cs:seldata + + inc _pc_irqpmtorm ; increment IRQ PM->RM counter + + movzx eax,al ; EAX = IRQ number + + mov dx,rmstacktop ; DX = SS for real mode redirection + mov bx,rmstacklen ; get size of real mode stack + movzx esi,dx ; ESI -> top of real mode stack + sub dx,bx ; adjust DX to next stack location + shl esi,4 + cmp dx,rmstackbase ; exceeded real mode stack space? + jb critical_error_rm ; if yes, critical error + mov rmstacktop,dx ; update ptr for possible reenterancy + shl bx,4 ; set real mode SP to top of stack + + mov edi,irqtab_rm[eax*4] ; get real mode interrupt CS:IP + mov ds,selzero ; DS -> 0 (beginning of memory) + mov [esi-2],ss ; store SS: on real mode stack + mov [esi-6],esp ; store ESP on real mode stack + mov dptr [esi-10],_KERNEL ; set target FLAGS and CS on RM stack + mov wptr [esi-12],offs @irq ; set target IP on RM stack + shld esi,edi,16 + sub bx,12 ; adjust real mode SP for stored vars + db 66h ; JMP DWORD PTR, as in 32bit offset, + jmp wptr cs:pmtormswrout ; not seg:16bit offset + +@irq: cli + mov ax,SELDATA ; DS selector value for protected mode + mov cx,ax ; ES selector value for protected mode + pop ebx ; get protected mode SS:ESP from stack + pop dx + mov si,SELCODE ; target CS:EIP in protected mode + mov edi,offs @@2 + jmp cs:rmtopmswrout ; go back to protected mode + +@@2: inc _pc_irqrmtopm ; increment IRQ RM->PM counter + + mov ax,rmstacklen ; restore top of real mode stack + add rmstacktop,ax + + pop gs fs es ds ; restore all registers + popad + pop ax ; restore original AX + iretd + + + + + + + + +; IRQ Callback +; +; Used by IRQs in real mode to process protected mode IRQ handlers. +; +;============================================================================= +irq_callback: + cli + pop ax + sub ax,offs back_matrix+1 + shr ax,2 ; AX = IRQ number + + pushad + push ds es fs gs + mov ds,cs:kernel_code + + inc _pc_irqcbrmtopm ; increment IRQCallback RM->PM counter + mov temp_int,al + + mov edx,pmstacktop ; EDX = ESP for protected mode + mov ebx,edx + sub edx,pmstacklen + cmp edx,pmstackbase ; exceeded protected mode stack space? + jb critical_error_pm ; if yes, critical error + mov pmstacktop,edx ; update ptr for possible reenterancy + + mov bp,ss ; save real mode SS:SP in EBP + shl ebp,16 + mov bp,sp + mov si,irqcallbackptr ; save ESP across mode switches + mov dptr @callback_data[si+100h],esp + add irqcallbackptr,4 + + mov ax,SELCODE ; prot. mode DS + mov cx,SELZERO ; prot. mode ES + mov dx,cx ; prot. mode SS + mov si,ax ; prot. mode CS + mov edi,offs @@0 ; prot. mode EIP + jmp rmtopmswrout ; switch to protected mode + +@@0: movzx bx,temp_int + shl bx,3 ; BX = pointer to interrupt ##h + pushfd ; set return eflags + push large SELCODE ; set return CS on PM stack + push large offs @@1 ; set return EIP on PM stack + db 66h + jmp dptr irqtab_pm[bx] ; go to prot. mode interrupt handler + +@@1: mov ax,_KERNEL ; AX = real mode DS + mov si,ax ; SI = real mode CS + mov di,offs @@2 ; DI = real mode IP + mov bx,bp ; BX = real mode SP + shr ebp,16 + mov dx,bp ; DX = real mode SS + db 66h + jmp wptr cs:pmtormswrout ; switch to real mode + +@@2: inc _pc_irqcbpmtorm ; increment IRQCallback PM->RM counter + + mov eax,pmstacklen + add pmstacktop,eax + + sub irqcallbackptr,4 ; restore original ESP + mov si,irqcallbackptr + mov esp,dptr @callback_data[si+100h] + + pop gs fs es ds + popad + pop ax + iret ; return from IRQ callback + + + + + + + + +;============================================================================= +; Real mode callback actual code: +; +;## pushad +;## push 0 ; if 0, callback is free +;## push large 0 +;## mov cx,0 ; load CX with callers ES +;## push large +;## jmp far ptr ?:? +; +callback: ; real mode callback handler + mov ax,sp ; preserve SS:SP for callback + push ss + push ax + push gs fs ds es ; preserve real mode regs for callback + pushf ; preserve FLAGS for callback + cli + push cs + pop ds + + inc _pc_cbrmtopm ; increment Callback RM->PM counter + + mov ebp,pmstacktop ; EBP = ESP for protected mode + mov ebx,ebp ; set EBX to next stack location + sub ebx,pmstacklen + mov pmstacktop,ebx ; update ptr for possible reenterancy + cmp ebx,pmstackbase ; exceeded protected mode stack space? + jb critical_error_pm ; if yes, critical error + + xor eax,eax ; EAX = base address of SS + mov ebx,eax + mov ax,ss + shl eax,4 + mov bx,sp ; EBX = current linear SS:SP + add ebx,eax + + mov es,ds:gdtseg ; set for protected mode callback DS + or eax,92000000h ; base address in GDT + mov es:[SELCALLBACK+2],eax + mov ax,SELZERO ; DS selector for protected mode + mov dx,ax ; SS selector = DS selector + mov si,SELCODE ; target protected mode CS:EIP + mov edi,offs @@0 + jmp rmtopmswrout ; go to protected mode + +@@0: mov edi,[esp+14] ; EDI -> register structure from stack + lea esi,[esp+24] ; copy general registers from stack + mov ecx,8 ; to register structure + cld + rep movs dptr es:[edi],ds:[esi] + + mov esi,esp ; copy FLAGS, ES, DS, FG, and GS + movs wptr es:[edi],ds:[esi] + movs dptr es:[edi],ds:[esi] + movs dptr es:[edi],ds:[esi] + lods dptr ds:[esi] ; EAX = real mode SS:SP from stack + add ax,42 ; adjust SP for stuff on stack + mov es:[edi+4],eax ; put in register structure + mov ds,cs:selcallback ; DS = callback DS selector + sub edi,42 ; EDI -> register structure + movzx esi,ax ; ESI = old real mode SP + xchg esp,ebp ; ESP = protected mode stack + pushfd ; push flags for IRETD from callback + push large cs ; push 32bit CS for IRETD + push large offs @@1 ; push 32bit EIP for IRETD + movzx eax,wptr [ebp+22] ; EAX = target CS of callback + push eax ; push 32bit CS for RETF to callback + push dptr [ebp+18] ; push 32bit EIP for retf + db 66h ; 32bit RETF to callback + retf + +@@1: cli + push es ; DS:ESI = register structure + pop ds + mov esi,edi + mov es,cs:selzero ; ES -> 0 (beginning of memory) + movzx ebx,wptr [esi+2Eh] ; EBX = real mode SP from structure + movzx edx,wptr [esi+30h] ; EDX = real mode SS from structure + sub bx,42 ; subtract size of vars to be put + mov ebp,[esi+0Ch] ; EBP = pushed ESP from real mode + mov bp,bx ; EBP = old high & new low word of ESP + lea edi,[edx*4] ; EDI -> real mode base of stack + lea edi,[edi*4+ebx] ; of vars to be stored + mov ecx,8 ; copy general registers to stack + cld + rep movs dptr es:[edi],ds:[esi] + mov eax,[esi+6] ; EAX = return FS and GS for real mode + mov es:[edi],eax ; store on real mode stack for return + mov eax,[esi+10] ; EAX = return CS:IP for real mode + mov es:[edi+4],eax ; store on real mode stack for return + mov ax,[esi] ; AX = return FLAGS for real mode + mov es:[edi+8],ax ; store on real mode stack for return + mov ax,[esi+4] ; AX = return DS for real mode + mov cx,[esi+2] ; CX = return ES for real mode + mov si,_KERNEL ; real mode target CS:IP + mov di,offs @@2 + db 66h ; JMP DWORD PTR, as in 32bit offset, + jmp wptr cs:pmtormswrout ; not seg:16bit offset + +@@2: inc cs:_pc_cbpmtorm ; increment Callback PM->RM counter + + mov esp,ebp ; restore total ESP, old high word + mov eax,cs:pmstacklen ; restore top of protected mode stack + add cs:pmstacktop,eax + + popad ; get callback return general regs + pop fs gs ; get callback return FS and GS values + iret ; go to callback return CS:IP + diff -uNr a/dos32a/src/dos32a/text/kernel/misc.asm b/dos32a/src/dos32a/text/kernel/misc.asm --- a/dos32a/src/dos32a/text/kernel/misc.asm false +++ b/dos32a/src/dos32a/text/kernel/misc.asm 78db6faa3e49482cb71408bd5ecfcb1edd8f545e7c001583d085a9030605c72c7c07fa9741f71df400a68ce75aaf89fc23420c73ffee3074424e9942ad3bd70f @@ -0,0 +1,295 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +; Real mode INT 15h +;============================================================================= +int15h_rm: + cmp ah,88h ; if function 88h, need to process + jz @@1 + cmp ax,0E801h ; if function 0E801h, not supported + jz @@err + cmp ax,0E820h ; if function 0E820h, not supported + jz @@err + jmp cs:oldint15h ; chain to the old INT 15h handler + +@@1: pushf ; call old INT 15h handler + call cs:oldint15h + sub ax,cs:mem_used ; adjust AX by extended memory used + jnc @@ok + xor ax,ax ; reset on overflow + +@@ok: push bp + mov bp,sp + and bptr [bp+6],0FEh ; clear carry flag on stack for IRET + pop bp + iret + +@@err: push bp + mov bp,sp + or bptr [bp+6],01h ; set carry flag on stack for IRET + pop bp + iret + + + +; Real mode INT 21h +;============================================================================= +int21h_rm: + cmp cs:id32_tsrmode_id,0 ; if we are TSR, ignore 0FF88h calls + jnz @@1 + + cmp ax,0FF88h ; DOS/32A id call + jz int21h_call + + cmp cs:id32_spawned_id,0 ; check if we're in spawn mode + jnz @@1 ; if yes, chain to the previous handler + + cmp ah,4Ch ; Real mode INT 21h + jz int21h_exit + cmp ah,4Bh + jz int21h_spawn + cmp ah,31h + jz int21h_tsr +@@1: jmp cs:oldint21h ; go to original real mode INT 21h + + +;----------------------------------------------------------------------------- +int21h_exit: + cli + mov bp,ax ; preserve AX=exit code + mov ax,SELDATA ; DS selector for protected mode + mov cx,ax + mov dx,SELZERO ; SS selector = zero selector + mov ebx,cs:pmstacktop ; EBX = ESP for protected mode + mov si,SELCODE ; target protected mode CS:EIP + mov edi,offs @@1 + jmp cs:rmtopmswrout ; switch to protected mode +@@1: mov ax,bp ; restore AX=exit code + jmp int21h_pm + +;----------------------------------------------------------------------------- +int21h_spawn: + mov cs:id32_spawned_id,1 ; disable memory deallocation + pushf + call cs:oldint21h + mov cs:id32_spawned_id,0 + pop bx cx dx ; pop IP, CS, FLG + push cx bx ; push CS, IP + retf + +;----------------------------------------------------------------------------- +int21h_call: ; DOS/32A functional call (real mode) + mov eax,'ID32' ; EAX = "ID32" + movzx ebx,cs:client_version ; EBX = client version + mov ecx,cs:mem_free ; ECX = size of free memory + mov edx,cs:mem_ptr ; EDX = base of free memory + mov si,cs:id32_process_id ; SI(hi) = previous process id + shl esi,16 + movzx si,cs:pagetables ; SI(lo) = pagetables allocated + mov edi,cs:pagetablefree ; EDI = base of free pagetable space + iret + +;----------------------------------------------------------------------------- +int21h_tsr: + mov cs:id32_tsrmode_id,1 ; indicate that we are going TSR + jmp cs:oldint21h + + + +; Protected mode INT 1Bh callback handler +;============================================================================= +int1Bh: call intold_save + int 1Bh ; call protected mode INT 1Bh + mov ax,6 + jmp intold_restore + + +; Protected mode INT 1Ch callback handler +;============================================================================= +int1Ch: call intold_save + push ds + mov ds,cs:selzero ; restore default INT 1Ch + mov eax,cs:oldint1Ch + mov ds:[4*1Ch],eax + pop ds + int 1Ch ; call protected mode INT 1Ch + push ds + mov ds,cs:selzero ; restore callback INT 1Ch + mov eax,cs:newint1Ch + mov ds:[4*1Ch],eax + pop ds + mov ax,6 + jmp intold_restore + + +; Protected mode INT 23h callback handler +;============================================================================= +int23h: call intold_save + clc + mov ebp,esp + int 23h ; call protected mode INT 23h + mov esp,ebp + setc ah + mov al,es:[edi+20h] + and al,0FEh + add al,ah + mov es:[edi+20h],al + mov ax,4 + jmp intold_restore + + +; Protected mode INT 24h callback handler +;============================================================================= +int24h: call intold_save + push edi + push dptr ds:[esi+1Ah] ; CS, FLG + push dptr ds:[esi+16h] ; ES, IP + push dptr ds:[esi+12h] ; BP, DS + push dptr ds:[esi+0Eh] ; SI, DI + push dptr ds:[esi+0Ah] ; CX, DX + push dptr ds:[esi+06h] ; AX, BX + mov ax,wptr es:[edi+1Ch] ; get register AX + mov bp,wptr es:[edi+08h] ; get register BP + mov si,wptr es:[edi+04h] ; get register SI + mov di,wptr es:[edi+00h] ; get register DI + int 24h ; call protected mode INT 24h + add esp,18h + pop edi + mov es:[edi+1Ch],al + mov ax,6 + jmp intold_restore + + +;----------------------------------------------------------------------------- +intold_save: + pop bp + mov ax,ds:[esi+04h] ; update FLAGS in structure + mov es:[edi+20h],ax + mov eax,ds:[esi+00h] ; update CS:IP in structure + mov es:[edi+2Ah],eax + push es edi + jmp bp + +;----------------------------------------------------------------------------- +intold_restore: + pop edi es + add es:[edi+2Eh],ax + iretd + + + + +;============================================================================= +; Enable/Disable A20 Line +;============================================================================= +enable_A20: ; hardware enable gate A20 + pushf + cli + call enablea20test ; is A20 already enabled? + setz al ; AL = 00h (OFF), AL = 01h (ON) + mov A20_state,al + jz @@done ; if yes, done + in al,92h ; PS/2 A20 enable + or al,02h + jmp short $+2 + jmp short $+2 + jmp short $+2 + out 92h,al + call enablea20test + jz @@done + call enablea20kbwait ; AT A20 enable + jnz @@f0 + mov al,0D1h + out 64h,al + call enablea20kbwait + jnz @@f0 + mov al,0DFh + out 60h,al + call enablea20kbwait +@@f0: mov cx,0800h ; wait for A20 to enable do 800h tries +@@l0: call enablea20test ; is A20 enabled? + jz @@done ; if yes, done + in al,40h ; get current tick counter + jmp short $+2 + jmp short $+2 + jmp short $+2 + in al,40h + mov ah,al +@@l1: in al,40h ; wait a single tick + jmp short $+2 + jmp short $+2 + jmp short $+2 + in al,40h + cmp al,ah + je @@l1 + loop @@l0 ; loop for another try + popf + stc ; error: set carry flag + ret +@@done: popf + clc ; success: clear carry + ret + +;----------------------------------------------------------------------------- +enablea20kbwait: ; wait for safe to write to 8042 + xor cx,cx +@@0: jmp short $+2 + jmp short $+2 + jmp short $+2 + in al,64h ; read 8042 status + test al,2 ; buffer full? + loopnz @@0 ; if yes, loop + ret + +;----------------------------------------------------------------------------- +enablea20test: ; test for enabled A20 + push fs gs + xor ax,ax ; set A20 test segments 0 and 0ffffh + mov fs,ax + dec ax + mov gs,ax + mov al,fs:[0000h] ; get byte from 0:0 + mov ah,al ; preserve old byte + not al ; modify byte + xchg al,gs:[0010h] ; put modified byte to 0ffffh:10h + cmp ah,fs:[0000h] ; set zero if byte at 0:0 not modified + mov gs:[0010h],al ; put back old byte at 0ffffh:10h + pop gs fs + ret ; return, zero if A20 enabled + diff -uNr a/dos32a/src/dos32a/text/kernel/mode.asm b/dos32a/src/dos32a/text/kernel/mode.asm --- a/dos32a/src/dos32a/text/kernel/mode.asm false +++ b/dos32a/src/dos32a/text/kernel/mode.asm e9591a4ffd6987f8195684ec71f0ffeb3d4d7313cbd3a4aaebd33a918de186baf6fbbc9ebd062753cf29db992a4b9c9ce3a7384a45d09f9a464ff61ffeda4f8a @@ -0,0 +1,207 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; Mode Switching Routines +;============================================================================= + +;============================================================================= +; VCPI real mode to protected mode switch +; +; AX = protected mode DS +; CX = protected mode ES +; DX = protected mode SS +; EBX = protected mode stack pointer +; ESI = protected mode target CS +; EDI = protected mode target IP +; + Align 4 +v_rmtopmsw: + pushf ; store FLAGS + cli + mov ds,cs:kernel_code ; DS = _KERNEL + pop tempw0 ; move FLAGS from stack to temp + mov tempw1,ax ; store AX (protected mode DS) + mov tempw2,si ; store SI (protected mode CS) + mov esi,vcpistrucaddx ; ESI = linear addx of VCPI structure + mov ax,0DE0Ch ; VCPI switch to protected mode + int 67h +v_rmtopmswpm: + mov ss,dx ; load protected mode SS:ESP + mov esp,ebx + mov ds,cs:tempw1 ; load protected mode DS + mov es,cx ; load protected mode ES + xor ax,ax + mov fs,ax ; load protected mode FS with NULL + mov gs,ax ; load protected mode GS with NULL + pushfd ; store EFLAGS + mov ax,cs:tempw0 ; move bits 0-11 of old FLAGS onto + and ah,0Fh ; stack for IRETD + mov [esp],ax + push cs:tempd1 ; store protected mode target CS + push edi ; store protected mode target EIP + iretd ; go to targed addx in protected mode + +;============================================================================= +; VCPI protected mode to real mode switch +; +; AX = real mode DS +; CX = real mode ES +; DX = real mode SS +; BX = real mode stack pointer +; SI = real mode target CS +; DI = real mode target IP +; + Align 4 +v_pmtormsw: + pushf ; store FLAGS + cli + push ax ; store AX (real mode DS) + mov ds,cs:selzero ; DS -> 0 (beginning of memory) + movzx ebx,bx ; clear high word of EBX, real mode SP + mov eax,cs:vcpiswitchstack ; EAX -> top of temporary switch stack + movzx edx,dx ; clear high word of EDX, real mode SS + mov dptr ds:[eax+32],0 ; store real mode GS + movzx ecx,cx ; clear high word of ECX, real mode ES + mov dptr ds:[eax+28],0 ; store real mode FS + mov ds:[eax+20],ecx ; store real mode ES + pop cx ; move real mode DS from protected + mov ds:[eax+24],ecx ; mode stack to VCPI call stack + mov ds:[eax+16],edx ; store real mode SS + mov ds:[eax+12],ebx ; store real mode SP + mov dptr ds:[eax+4],_KERNEL ; store real mode CS + mov dptr ds:[eax],offs @@0 ; store real mode IP + pop bx ; restore FLAGS from stack + mov ss,cs:selzero ; SS -> 0 (beginning of memory) + mov esp,eax ; ESP = stack ptr for VCPI call + mov ax,0DE0Ch ; VCPI switch to real mode (V86) + call fptr cs:vcpi_calleip +@@0: push bx ; store old FLAGS + push si ; store target CS in real mode + push di ; store target IP in real mode + iret ; go to target addx in real mode + + +;============================================================================= +; XMS/RAW real mode to protected mode switch +; +; AX = protected mode DS +; CX = protected mode ES +; DX = protected mode SS +; EBX = protected mode stack pointer +; ESI = protected mode target CS +; EDI = protected mode target IP +; + Align 4 +xr_rmtopmsw: + pushfd ; store EFLAGS + cli + push ax ; store AX (protected mode DS) + lidt fptr cs:idtlimit ; load protected mode IDT + lgdt fptr cs:gdtlimit ; load protected mode GDT + mov eax,cr0 ; switch to protected mode + or al,01h + mov cr0,eax + db 0EAh ; JMP FAR PTR SELCODE:$+4 + dw $+4,SELCODE ; (clear prefetch que) + pop ds ; load protected mode DS + mov es,cx ; load protected mode ES + xor ax,ax + mov fs,ax ; load protected mode FS with NULL + mov gs,ax ; load protected mode GS with NULL + pop eax + mov ss,dx ; load protected mode SS:ESP + mov esp,ebx + and ah,0BFh ; set NT=0 in old EFLAGS + push ax ; set current FLAGS + popf + push eax ; store old EFLAGS + push esi ; store protected mode target CS + push edi ; store protected mode target EIP + iretd ; go to target addx in protected mode + +;============================================================================= +; XMS/RAW protected mode to real mode switch +; +; AX = real mode DS +; CX = real mode ES +; DX = real mode SS +; BX = real mode stack pointer +; SI = real mode target CS +; DI = real mode target IP +; + Align 4 +xr_pmtormsw: + pushf ; store FLAGS + cli + push ax ; store AX (real mode DS) + mov ds,cs:seldata ; DS -> 0 (beginning of memory) + pop tempw0 ; move real mode DS from stack to temp + pop tempw1 ; move FLAGS from stack to temp + mov ax,SELDATA ; load descriptors with real mode seg + mov ds,ax ; attributes + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax ; load descriptor with real mode attr + movzx esp,bx ; load real mode SP, high word 0 + lidt fptr rmidtlimit ; load real mode IDT + mov eax,cr0 ; switch to real mode + and al,0FEh ; turn off protected mode + mov cr0,eax + db 0EAh ; JMP FAR PTR _KERNEL:$+4 + dw $+4,_KERNEL ; (clear prefetch que) + mov ss,dx ; load real mode SS + mov ds,cs:tempw0 ; load real mode DS + mov es,cx ; load real mode ES + xor ax,ax + mov fs,ax ; load real mode FS with NULL + mov gs,ax ; load real mode GS with NULL + push cs:tempw1 ; store old FLAGS + push si ; store real mode target CS + push di ; store real mode target IP + iret ; go to target addx in real mode + + +;============================================================================= +vxr_saverestorepm: ; VCPI/XMS/RAW save/restore status + db 66h ; no save/restore needed, 32bit RETF +vxr_saverestorerm: ; VCPI/XMS/RAW save/restore status + retf ; no save/restore needed, 16bit RETF + diff -uNr a/dos32a/src/dos32a/text/oemtitle.asm b/dos32a/src/dos32a/text/oemtitle.asm --- a/dos32a/src/dos32a/text/oemtitle.asm false +++ b/dos32a/src/dos32a/text/oemtitle.asm e478320339d8dfd14b68cb0fb7cf300aeb3cc96784a90a195dd06505f42d82a42ef46b46d87ed0a64af9cbd8ab543b0ad5d692dc003266243b207b825a6a1d45 @@ -0,0 +1,47 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + +;============================================================================= +; OEM info +; +db 'DOS/32A' ,0 +db 'Copyright (C) 1996-2006 by Narech K.' ,0 +db ??date ,0 +db ??time ,0 diff -uNr a/dos32a/src/dos32a/text/testbeta.asm b/dos32a/src/dos32a/text/testbeta.asm --- a/dos32a/src/dos32a/text/testbeta.asm false +++ b/dos32a/src/dos32a/text/testbeta.asm fe662b35dee08d6866d8f292b38888b7451d4d337fd1b47d056a487021e47eb5adcb64c3ec1350d67075a7cc15ab64f70b0d3755dc624cff7a9454cfe2d61369 @@ -0,0 +1,195 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + +;============================================================================= +; Low-level debugging support for beta releases +; +; Note: this code is shared between CLIENT & KERNEL; whenever there is a need +; to differentiate between the two (seg/sel regs and such), use the +; BUILDING_KERNEL and BUILDING_CLIENT macro symbols +; +;============================================================================= + + +;============================================================================= +; write the contents of AL (8-bit) register to STDOUT +; +dbg_hexal: + push dx + mov dx,offs hexbuf+6 + jmp mkhex + +;============================================================================= +; write the contents of AX (16-bit) register to STDOUT +; +dbg_hexax: + push dx + mov dx,offs hexbuf+4 + jmp mkhex + +;============================================================================= +; write the contents of EAX (32-bit) register to STDOUT +; +; works from real & protected modes, should be fairly transparent to the app +; +dbg_hexeax: + push dx + mov dx,offs hexbuf +mkhex: push eax cx si di ds dx + smsw si + test si,1 + jz @@0 +; +; TODO: rewrite this shit pronto! (in particular avoid memory r/w access a la CLIENT/strings.asm) +; + +If BUILDING_KERNEL eq 0 + mov ds,cs:_sel_ds + jmp @@1 +@@0: mov ds,cs:_seg_ds +Else + mov ds,cs:seldata + jmp @@1 +@@0: mov ds,cs:kernel_code +Endif + +@@1: mov di,7 + +@@cvt: mov si,ax + and si,000Fh + mov cl,cs:hextab[si] + mov ds:hexbuf[di],cl + shr eax,4 + dec di + jns @@cvt + pop si + + mov cx,offs hexbuf+10 + sub cx,si +@@loop: lodsb + mov dl,al + mov ah,2 + int 21h + loop @@loop + pop ds di si cx eax dx + ret +hextab db '0123456789ABCDEF' +hexbuf db ' ',13,10 + + +;============================================================================= +; pause until a key is pressed +; +; note: this switches CPU to real mode (BIOS Fn Int16h/AX=0) +; +dbg_kbhit: + push ax + xor ax,ax + int 16h + pop ax + ret + +;============================================================================= +; beep a sound from the PC speaker +; AX = frequency +; CX = time +; +dbg_beep: +@@0: push cx dx ax ; AX=frequency, CX=time + mov al,0B6h ; set frequency + out 43h,al + pop ax + out 42h,al ; fLow + mov al,ah + out 42h,al ; fHigh + in al,61h ; beep on + or al,03h + out 61h,al +@@loop: in al,40h + in al,40h + mov ah,al +@@1: in al,40h + in al,40h + cmp ah,al + je @@1 + loop @@loop + in al,61h ; beep off + and al,not 03h + out 61h,al + pop dx cx + ret + +;============================================================================= +; halt execution forever +; +; this blocks app execution in an endless loop, with predicate AX being tested +; for being zero; the state of AX is then expected to be changed by an external +; debugger (i.e. from an emulator) so that debugging can proceed from that point +; +dbg_halt: + pushf + cli + push ax + xor ax,ax +@@loop: test ax,ax + jz @@loop + pop ax + sti + popf + ret + +;============================================================================= +; convinience fn: peep a beep, then die a little in hope of a better future +; +; real men don't use no hardware debuggers! +; +dbg_break: + pushf + push ax cx + mov cx,0200h + mov ax,0500h + call dbg_beep + mov ax,0100h + call dbg_beep + mov ax,0500h + call dbg_beep + pop cx ax + popf + jmp dbg_halt + diff -uNr a/dos32a/src/sb/main.c b/dos32a/src/sb/main.c --- a/dos32a/src/sb/main.c false +++ b/dos32a/src/sb/main.c 2a93fe78aab27f99d2c936b99b69a8d91d96b4262c255567ed72a644b3acf49b62b307bcfa67fc15a51f66fa5972266113a9a3212f9c4fdd82da7ea4b41cd037 @@ -0,0 +1,688 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "main.h" + + char* version = "9.1.2"; + char newname[80]; + char newname2[80]; + char filename[80]; + char name_bn[80]; + char name_un[80]; + char* bufptr; + char* bufptr2; + char* fileptr; + + char* stubname; + char* stubname1 = "DOS32A.EXE"; + char* stubname2 = "STUB32A.EXE"; + char* stubname3 = "STUB32C.EXE"; + char* errstr = "SB/32A fatal:"; + char* tempname = "$$SB32$$.TMP"; + + int execargn = 1; + int filesize = 0; + int oldfilesize = 0; + int newfilesize = 0; + + int Main_Type = -1; + int Exec_Type = -1; + int Extender_Type = -1; + + int bind = FALSE; + int unbind = FALSE; + int overwrite = FALSE; + int quiet = FALSE; + int silent = TRUE; + int bind_name = FALSE; + int unbind_name = FALSE; + + + + +/****************************************************************************/ +void err_open(char *str) { + printf("%s cannot open file \"%s\"\n",errstr,str); + exit(1); +} +void err_rdonly(char *str) { + printf("%s cannot open Read-Only file \"%s\"\n",errstr,str); + exit(1); +} +void err_seek(char *str) { + printf("%s error seeking in file \"%s\"\n",errstr,str); + exit(1); +} +void err_read(char *str) { + printf("%s error reading from file \"%s\"\n",errstr,str); + exit(1); +} +void err_support(char *str) { + printf("%s unsupported exec format in file \"%s\"\n",errstr,str); + exit(1); +} +void err_dest(char *str) { + printf("%s destination file \"%s\" already exists\n",errstr,str); + exit(1); +} +void err_mem(char *str) { + printf("%s not enough memory to load file \"%s\"\n",errstr,str); + exit(1); +} +void err_crtmp(void) { + printf("%s error creating temp file\n",errstr); + exit(1); +} +void err_wrtmp(void) { + printf("%s error writing to temp file\n",errstr); + exit(1); +} +void err_rdstub(void) { + printf("%s error reading from stub file\n",errstr); + exit(1); +} +void err_invstub(void) { + printf("%s invalid stub file format\n",errstr); + exit(1); +} +void err_nod32a(void) { + printf("%s cannot find file \"DOS32A.EXE\"\n",errstr); + exit(1); +} +void err_nostub(char *str) { + printf("%s cannot find file \"%s\"\n",errstr,str); + exit(1); +} +void err_arg(char *str) { + printf("%s invalid or misplaced command or option \"%s\"\n",errstr,str); + exit(1); +} +void err_sameact(void) { + printf("%s cannot Bind and Unbind at the same time\n",errstr); + exit(1); +} +void err_nullname(void) { + printf("%s you must specify a file name with /BN or /UN options\n",errstr); + exit(1); +} +void err_environment(void) { + printf("%s DOS/32A environment variable is not set up properly\n",errstr); + printf("You need to reinstall DOS/32 Advanced DOS Extender on this computer\n"); + exit(1); +} + + + +/****************************************************************************/ +void ShowCopyright() +{ + Print("SB/32A -- Bind Utility version %s\n",version); + Print("Copyright (C) 1996-2006 by Narech K.\n"); +} + + + +void ArgInit(int argc, char *argv[]) +{ + int n,m; + int argn=14; + char *args[] = { "bs", "bc", "bn", "rs", "rc", "un", "b", "r", "u", "o", "q", "s", "h", "?" }; + + execargn=1; + + if(argc>=2) + { + for(n=1; n=argc) + { +l1: Print("SB/32A fatal: syntax is SB [commands] [options] \n\n"); + Print("Commands:\n"); + Print("---------\n"); + Print("/B Bind DOS/32A to Linear Executable\n"); + Print("/BS Bind STUB/32A to Linear Executable\n"); + Print("/BC Bind STUB/32C to Linear Executable\n"); + Print("/R Replace existing Stub/Extender with DOS/32A\n"); + Print("/RS Replace existing Stub/Extender with STUB/32A\n"); + Print("/RC Replace existing Stub/Extender with STUB/32C\n"); + Print("/U Unbind Linear Executable from the existing Stub\n\n"); + Print("Options:\n"); + Print("--------\n"); + Print("/BNfilename.xxx Specify destination file name when Binding\n"); + Print("/UNfilename.xxx Specify destination file name when Unbinding\n"); + Print("/O Unconditionally Overwrite existing files\n"); + Print("/Q Quiet mode (partially disables console output)\n"); + Print("/S Silent mode (totally disables console output)\n"); + Print("/H or /? This help\n"); + exit(1); + } +} + + +void OpenExec(char *argv[]) +{ + int n,m; + + strcpy(filename,argv[execargn]); + n=open_exec(filename); + + if(n==-2) + err_rdonly(argv[execargn]); + if(n!=0) + { + strcpy(filename,argv[execargn]); + strcat(filename,".exe"); + n=open_exec(filename); + if(n==-2) + err_rdonly(argv[execargn]); + if(n!=0) + { + strcpy(filename,argv[execargn]); + strcat(filename,".le"); + n=open_exec(filename); + if(n==-2) + err_rdonly(argv[execargn]); + if(n!=0) + { + strcpy(filename,argv[execargn]); + strcat(filename,".lx"); + n=open_exec(filename); + if(n==-2) + err_rdonly(argv[execargn]); + if(n!=0) + { + strcpy(filename,argv[execargn]); + strcat(filename,".lc"); + n=open_exec(filename); + if(n==-2) + err_rdonly(argv[execargn]); + } + } + } + } + if(n==-1) + err_open(argv[execargn]); +} + + + + +/****************************************************************************/ +int GetExecType(char *argv[]) +{ + int n; + + n=check_if_unbound_exec(); + + if(n==-1) + err_seek(argv[execargn]); + else if(n==-2) + err_read(argv[execargn]); + else if(n==-3) + err_support(argv[execargn]); + + return(n); +} + +int FindExecType(char *argv[]) +{ + int n; + + n=get_exec_start(); + if(n==-1) + err_read(argv[execargn]); + else if(n==-2) + return(-1); + + n=get_exec_type(); + if(n==-1) + err_read(argv[execargn]); + else if(n==-2) + return(-1); + + return(n); +} + +int GetExtenderType(char *argv[]) +{ + int n; + + n=get_extender_type(); + if(n==-1) + err_read(argv[execargn]); + + return(n); +} + + + + + + + + + + +/****************************************************************************/ +void main(int argc, char *argv[]) +{ + int n=-1; + int m=-1; + int l=-1; + int e=-1; + int x,y; + char buf[80]; + + ArgInit(argc, argv); + OpenExec(argv); + filesize=filelength(exec_handle); + n=GetExecType(argv); + + if(n==0) + { + m=FindExecType(argv); + l=GetExtenderType(argv); + } + + Main_Type=n; /* file format: LE, LX, LC, PE */ + Exec_Type=m; /* same as "n" when bound */ + Extender_Type=l; /* Stub/Extender type */ + + Print("\n"); + Print("Application Name: \"%s\"\n",argv[execargn]); + Print("Application Size: %d bytes\n",filesize); + Print("Application Type: "); + if(n!=0) + { + if(n==1) Print(" Unbound LE-style file format Linear Executable"); + if(n==2) Print(" Unbound LX-style file format Linear Executable"); + if(n==3) Print(" Unbound LC-style file format Linear Executable"); + if(n==4) Print(" Unbound PE-style file format Linear Executable"); + if(n==5) Print(" Unbound PMW1-style file format Linear Executable"); + } + else + { + if(m==-1) + { + Print(" Standard DOS Executable\n"); + close_exec(); + exit(127); /* signal error to SC compressor */ + } + if(l==0) Print(" Unknown Stub File bound to\n"); + if(l==1) Print(" DOS/32 Advanced DOS Extender bound to\n"); + if(l==2) Print(" STUB/32C Configurable Stub File bound to\n"); + if(l==3) Print(" STUB/32A Standard Stub File bound to\n"); + if(l==4) Print(" DOS/4G DOS Extender bound to\n"); + if(l==5) Print(" PMODE/W DOS Extender bound to\n"); + + if(m==1) Print(" LE-style file format Linear Executable"); + if(m==2) Print(" LX-style file format Linear Executable"); + if(m==3) Print(" LC-style file format Linear Executable"); + if(m==4) Print(" PE-style file format Portable Executable"); + if(m==5) Print(" PMW1-style file format Linear Executable"); + } + Print("\n"); + + if(n==3 || m==3) + DisplayOEMInfo(); + + unlink(tempname); + + if(unbind_name==FALSE) + { + strcpy(newname,filename); + bufptr=(char *)strchr(newname,'.'); + if(bufptr!=NULL) strset(bufptr,0); + if(Main_Type==1 || Exec_Type==1) strcat(newname,".le"); + if(Main_Type==2 || Exec_Type==2) strcat(newname,".lx"); + if(Main_Type==3 || Exec_Type==3) strcat(newname,".lc"); + if(Main_Type==4 || Exec_Type==4) strcat(newname,".pe"); + if(Main_Type==5 || Exec_Type==5) strcat(newname,".pmw"); + } + else + strcpy(newname,name_un); + + if(bind_name==FALSE) + { + strcpy(newname2,filename); + bufptr2=(char *)strchr(newname2,'.'); + if(bufptr2!=NULL) + strset(bufptr2,0); + strcat(newname2,".exe"); + } + else + strcpy(newname2,name_bn); + + + if(bind==TRUE && unbind==TRUE) + err_sameact(); + if(bind) + { + BindExec(argv); + if(!silent) printf("SB/32A: File \"%s\" has been successfully bound\n", filename); + } + else if(n==0) if(unbind) + { + UnbindExec(argv); + if(!silent) printf("SB/32A: File \"%s\" has been successfully unbound\n", filename); + } + + close_exec(); + exit(0); +} + + + + + + + + + + +void UnbindExec(char *argv[]) +{ + int n,m; + + Print("\n"); + Print(" Unbinding file: \"%s\"\n",filename); + Print("Destination file: \"%s\"\n",newname); + CheckIfExists(newname); + + n=unbind_exec(); + if(n==-1) err_mem(filename); + if(n==-2) err_read(filename); + if(n==-3) err_crtmp(); + if(n==-4) err_wrtmp(); + + unlink(newname); + copy_file(tempname,newname); + unlink(tempname); + + oldfilesize=GetFileSize(newname); + if(quiet!=TRUE) + printf("Destination size: %d bytes (%1.1f%%)\n", oldfilesize, (float)(oldfilesize+0.01)/(float)(filesize+0.01) *100); +} + + +void BindExec(char *argv[]) +{ + int n,m; + int stubsize; + int execsize; + int stubhandle; + int exechandle; + char *ptr; + char *envname; + char envbuf[256]; + + CheckIfExists(newname2); + if(Main_Type==0) + UnbindExec(argv); + + Print("\n"); + Print(" Binding file: \"%s\"\n",newname); + Print("Destination file: \"%s\"\n",newname2); + + stubhandle=open(stubname,O_RDWR | O_BINARY); + if(stubhandle==-1) + { + envname=getenv("DOS32A"); + if(envname==0) + err_nod32a(); + ptr=strchr(envname,' '); + if(ptr==NULL) + ptr=strchr(envname,0); + memset(envbuf,0,256); + strncpy(envbuf,envname,(dword)ptr-(dword)envname); + strcat(envbuf,"\\BINW\\"); strcat(envbuf,stubname); + stubhandle=open(envbuf,O_RDWR | O_BINARY); + + if(stubhandle==-1) + err_nostub(envbuf); + } + stubsize=filelength(stubhandle); + + exechandle=open(newname,O_RDWR | O_BINARY); + if(exechandle==-1) + err_open(newname); + + execsize=filelength(exechandle); + + n=bind_exec(stubhandle, exechandle, stubsize, execsize); + close(exechandle); + close(stubhandle); + unlink(newname); + close_exec(); + switch(n) + { + case -1: err_mem(newname); + case -2: err_rdstub(); + case -3: err_read(newname); + case -4: err_crtmp(); + case -5: err_wrtmp(); + case -6: err_invstub(); + } + + unlink(newname2); + copy_file(tempname,newname2); + unlink(tempname); + + newfilesize=GetFileSize(newname2); + if(quiet!=TRUE) + printf("Destination size: %d bytes (%1.1f%%)\n", newfilesize, (float)(newfilesize+0.01)/(float)(filesize+0.01) *100); + if(quiet!=TRUE) + printf(" Stub file used: \"%s\"\n",stubname); +} + + + +/****************************************************************************/ +void Print(char *format, ...) +{ + va_list arglist; + char buffer[1024]; + if(quiet==FALSE) + { + va_start(arglist,format); + vsprintf(buffer,format,arglist); + printf(buffer); + va_end(arglist); + } +} +void CheckIfExists(char *name) +{ + int n; + n=open(name,O_RDWR | O_BINARY); + if(n!=-1) + { + close(n); + if(!overwrite) + err_dest(name); + } +} +int GetFileSize(char *name) +{ + int n; + int m=0; + n=open(name,O_RDWR | O_BINARY); + if(n!=-1) + { + m=filelength(n); + close(n); + } + return(m); +} +void CheckEnvironment() +{ + if(getenv("DOS32A")==NULL) + err_environment(); +} +void copy_file(char *f1, char *f2) +{ + int c; + FILE *src; + FILE *dest; + + if( (f1[1] != ':') && (f2[1] != ':') ) + { + rename(f1,f2); + return; + } + + if((src=fopen(f1,"rb"))!=NULL) + { + if((dest=fopen(f2,"wb"))!=NULL) + { + while((c=fgetc(src))!=EOF) fputc(c,dest); + fclose(dest); + } + fclose(src); + } +} + +void DisplayOEMInfo() +{ + + char *ptr; + + if((ptr=find_oem_info()) == NULL) + return; + + Print("\n"); + Print("Application OEM Information:\n"); + + Print("-------------------------------------------------------------------------------\n"); + Print("%s\n",ptr); + Print("-------------------------------------------------------------------------------\n"); +} + diff -uNr a/dos32a/src/sb/main.h b/dos32a/src/sb/main.h --- a/dos32a/src/sb/main.h false +++ b/dos32a/src/sb/main.h 5b19d7975c131e7063ea1b05c3791f5d29c155e71a7cbb2de7af3bf325b090e2167f5f6cfd14fe4bf758ba186204f8340fdb2208b1cfa81ec0e0d4f6be6dc9c2 @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +extern int open_exec(char *); +extern void close_exec(void); + +extern int check_if_unbound_exec(void); +extern int get_exec_start(void); +extern int get_exec_type(void); +extern int get_extender_type(void); +extern int unbind_exec(void); +extern int bind_exec(int, int, int, int); +extern char *find_oem_info(void); + +extern short exec_handle; diff -uNr a/dos32a/src/sb/sbind.asm b/dos32a/src/sb/sbind.asm --- a/dos32a/src/sb/sbind.asm false +++ b/dos32a/src/sb/sbind.asm c2f600f3be23ac47109c0ec399b6b1dade0c992d545bd5c60fc26d80314e3314358af929286454d59c0716f25f473588453a706cf10a740b0e0662bf036e25ef @@ -0,0 +1,819 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .486p + .MODEL flat + LOCALS + NOJUMPS + +include stddef.inc + +EXTRN _filesize :dword +EXTRN _Main_Type :dword +EXTRN _Exec_Type :dword +EXTRN _tempname :dword + +PUBLIC open_exec_, close_exec_ +PUBLIC check_if_unbound_exec_ +PUBLIC get_exec_start_ +PUBLIC get_exec_type_ +PUBLIC get_extender_type_ +PUBLIC _exec_handle +PUBLIC unbind_exec_ +PUBLIC bind_exec_ +PUBLIC find_oem_info_ + +.CODE +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + + + + +bind_exec_: + pushad + mov _tmp_handle1,eax + mov _tmp_handle2,edx + mov _tmp_size1,ebx + mov _tmp_size2,ecx + + lea eax,[ebx+ecx+0FFFh] + call allocate_memory + jc @@err1 + + mov ebx,_tmp_handle1 ; load stub + mov ecx,_tmp_size1 + mov edx,dword ptr _mem_ptr + mov ah,3Fh + int 21h + jc @@err2 + + movzx eax,word ptr [edx+0018h] ; get reloc tab offset + mov esi,dword ptr _mem_ptr + add esi,eax + add esi,_tmp_size1 + mov ebx,0040h + mov edi,dword ptr _mem_ptr + add edi,ebx + add edi,_tmp_size1 + mov ecx,_tmp_size1 + inc ecx + std + rep movsb + cld + + mov edi,dword ptr _mem_ptr + add edi,eax + sub ebx,eax + jc @@err6 ; invalid stub format + mov ecx,ebx + xor eax,eax + rep stosb + mov eax,_tmp_size1 + add eax,ebx + mov _tmp_size1,eax + + mov esi,dword ptr _mem_ptr + mov edx,eax + and eax,1FFh + mov [esi+02h],ax + + mov eax,edx + shr eax,9 + inc eax + mov [esi+04h],ax + + movzx eax,word ptr [esi+06] + lea eax,[eax*4] + add eax,004Fh + shr eax,4 + mov [esi+08h],ax + + mov ax,0040h + mov [esi+18h],ax + + mov eax,_tmp_size1 + mov [esi+3Ch],eax + + mov ebx,_tmp_handle2 ; load exec + mov ecx,_tmp_size2 + mov edx,dword ptr _mem_ptr + add edx,_tmp_size1 + mov ah,3Fh + int 21h + jc @@err3 + + pushad + mov eax,_exec_start + mov ecx,eax + mov edx,eax + shr ecx,16 + mov ebx,_tmp_handle2 + mov ax,4200h + int 21h ; move to next exec in file + popad + jc @@err3 + + mov eax,_tmp_size1 ; update Data Pages Offset + mov ebp,[edx+80h] + add eax,ebp + + cmp _Main_Type,0 + jz @@0 + + cmp _Main_Type,1 + jz @@1 + cmp _Main_Type,2 + jz @@1 + jmp @@2 + +@@0: + cmp _Exec_Type,1 + jz @@1 + cmp _Exec_Type,2 + jz @@1 + jmp @@2 + +@@1: mov [edx+80h],eax + +@@2: mov edx,_tempname ; create temp file + mov ecx,00h + mov ah,3Ch + int 21h + mov _temp_handle,ax + jc @@err4 + + mov edx,dword ptr _mem_ptr + mov ecx,_tmp_size1 + add ecx,_tmp_size2 + mov bx,_temp_handle ; write to temp file + mov ah,40h + int 21h + jc @@err5 + + mov bx,_temp_handle ; close temp file + mov ah,3Eh + int 21h + call free_memory + popad + xor eax,eax + ret + +@@err1: call free_memory + popad + mov eax,-1 + ret +@@err2: call free_memory + popad + mov eax,-2 + ret +@@err3: call free_memory + popad + mov eax,-3 + ret +@@err4: call free_memory + popad + mov eax,-4 + ret +@@err5: call free_memory + popad + mov eax,-5 + ret +@@err6: call free_memory + popad + mov eax,-6 + ret + + +unbind_exec_: + pushad + call seek_to_start + mov eax,_filesize ; allocate memory + add eax,0FFFh + call allocate_memory + jc @@err1 + + mov bx,_exec_handle ; load exec + mov ecx,_filesize + mov edx,dword ptr _mem_ptr + mov ah,3Fh + int 21h + jc @@err2 + + mov edx,_tempname ; create temp file + mov ecx,00h + mov ah,3Ch + int 21h + mov _temp_handle,ax + jc @@err3 + + mov edx,dword ptr _mem_ptr + mov ecx,_filesize + add edx,_exec_start + sub ecx,_exec_start + mov eax,[edx+80h] ; update Data Pages Offset + mov ebp,_exec_start + sub ebp,_app_off_datapages + sub eax,ebp + cmp _Exec_Type,1 + jz @@1 + cmp _Exec_Type,2 + jz @@1 + jmp @@2 +@@1: mov [edx+80h],eax + +@@2: mov bx,_temp_handle ; write to temp file + mov ah,40h + int 21h + jc @@err4 + + mov bx,_temp_handle ; close temp file + mov ah,3Eh + int 21h + call free_memory + popad + xor eax,eax + ret + +@@err1: call free_memory + popad + mov eax,-1 + ret +@@err2: call free_memory + popad + mov eax,-2 + ret +@@err3: call free_memory + popad + mov eax,-3 + ret +@@err4: call free_memory + popad + mov eax,-4 + ret + + + + +;----------------------------------------------------------------------------- +allocate_memory: + pushad + mov ebx,eax + mov ax,0FF91h + int 21h + mov _mem_ptr,ebx + mov _mem_handle,esi + popad + ret + +free_memory: + pushad + mov esi,_mem_handle + mov ax,0FF92h + int 21h + popad + ret + + + + + + + +open_exec_: + pushad + xor ecx,ecx + mov edx,eax + mov ax,4300h + int 21h + test ecx,01h + jnz @@err2 + mov ax,3D02h + int 21h + jc @@err1 + mov _exec_handle,ax + popad + xor eax,eax + ret +@@err1: popad + mov eax,-1 + ret +@@err2: popad + mov eax,-2 + ret + +close_exec_: + pushad + mov bx,_exec_handle + mov ah,3Eh + int 21h + popad + ret + + +check_if_unbound_exec_: + pushad + call seek_to_start + jc @@err1 + mov ax,3F00h + mov bx,_exec_handle + mov ecx,64 ; ECX = 64 bytes to load + mov edx,_buffer ; DS:EDX = ptr + int 21h + jc @@err2 + call seek_to_start + jc @@err1 + cmp word ptr [edx],'ZM' ; is exec 'MZ' file type + jz @@0 + cmp word ptr [edx],'EL' ; is exec 'LE' file type + jz @@1 + cmp word ptr [edx],'XL' ; is exec 'LX' file type + jz @@2 + cmp word ptr [edx],'CL' ; is exec 'LC' file type + jz @@3 + cmp word ptr [edx],'EP' ; is exec 'PE' file type + jz @@4 + cmp dword ptr [edx],'1WMP' ; is exec 'PMW1' file type + jz @@5 + popad + mov eax,-3 + ret +@@err1: popad + mov eax,-1 + ret +@@err2: popad + mov eax,-2 + ret + +@@0: popad + mov eax,0 + ret +@@1: popad + mov eax,1 + ret +@@2: popad + mov eax,2 + ret +@@3: popad + mov eax,3 + ret +@@4: popad + mov eax,4 + ret +@@5: popad + mov eax,5 + ret + + + + +get_exec_start_: + pushad + mov _saved_stack,esp + call load_exec_header + popad + xor eax,eax + ret + +@err1: mov esp,_saved_stack + popad + mov eax,-1 + ret +@err2: mov esp,_saved_stack + popad + mov eax,-2 + ret + + +load_exec_header: + call seek_to_start + jc @err1 + + mov ax,3F00h + mov bx,_exec_handle + mov ecx,64 ; ECX = 64 bytes to load + mov edx,_buffer ; DS:EDX = ptr + int 21h + jc @err1 + + call seek_to_start + jc @err1 + + xor ebp,ebp ; reset ptr in app + cmp word ptr [edx],'ZM' ; is exec 'MZ' file type + jnz search_for_le ; if not, search for known exec type + + mov eax,[edx+18h] ; MZ reloc-tab must be at offset 0040h + cmp ax,40h + jnz search_for_mz + + mov eax,[edx+3Ch] ; get start of 32-bit code + test ax,ax ; check if exec is bound + jz search_for_mz ; if not, search + mov _exec_start,eax + mov _app_off_datapages,0 + ret + + +search_for_mz: + xor esi,esi + +@@0: movzx eax,wptr [edx+04h] ; get pages in file + shl eax,9 ; *512 + movzx ebx,wptr [edx+02h] ; get bytes on last page + add eax,ebx + cmp wptr [edx],'ZM' + jz @@1 + cmp wptr [edx],'WB' + jz @@2 + jmp @@3 +@@1: sub eax,0200h +@@2: mov esi,ebp + add ebp,eax + + mov ecx,ebp + mov edx,ebp + shr ecx,16 + mov bx,_exec_handle + mov ax,4200h + int 21h ; move to next exec in file + jc @err1 + mov ax,3F00h + mov bx,_exec_handle + mov ecx,64 + mov edx,_buffer + int 21h + jc @err1 + test eax,eax + jz @err2 ; unknown exec format + jmp @@0 + +@@3: cmp wptr [edx],'EL' + jz @@4 + cmp wptr [edx],'XL' + jz @@4 + cmp wptr [edx],'CL' + jz @@4 + mov ecx,ebp + mov edx,ebp + shr ecx,16 + mov bx,_exec_handle + mov ax,4200h + int 21h ; move to next exec in file + jc @err1 + call search_for_le +@@4: mov _exec_start,ebp + mov _app_off_datapages,esi + ret + + +search_for_le: +@@1: mov edx,_buffer ; DS:EDX = current ptr + mov ecx,1000h ; ECX = bytes to load + mov ax,3F00h + mov bx,_exec_handle + int 21h + jc @err1 + test eax,eax ; check if no bytes read + jz @err2 ; if true, no app in file + shr ecx,1 +@@2: mov ax,[edx+0] + mov bx,[edx+2] + test bx,bx + jnz @@4 + cmp ax,'EL' ; 'LE' type + jz @@3 + cmp ax,'XL' ; 'LX' type + jz @@3 +@@4: cmp ax,'CL' ; 'LC' type (Linear Compressed) + jz @@3 + add edx,2 + add ebp,2 ; increment pointer in file + loop @@2 + jmp @@1 +@@3: mov _app_off_datapages,0 + ret + + +get_exec_type_: + pushad + mov edx,_exec_start + mov ecx,edx + shr ecx,16 + mov bx,_exec_handle + mov ax,4200h + int 21h + jc @@err1 + + mov ax,3F00h + mov bx,_exec_handle + mov ecx,64 + mov edx,_buffer + int 21h + jc @@err1 + test eax,eax + jz @@err2 ; unknown exec format + + cmp wptr [edx],'EL' + jz @@1 + cmp wptr [edx],'XL' + jz @@2 + cmp wptr [edx],'CL' + jz @@3 + cmp wptr [edx],'EP' + jz @@4 + cmp dptr [edx],'1WMP' + jz @@5 + +@@err2: popad + mov eax,-2 + ret +@@err1: popad + mov eax,-1 + ret + +@@0: popad + xor eax,eax + ret +@@1: popad + mov eax,1 + ret +@@2: popad + mov eax,2 + ret +@@3: popad + mov eax,3 + ret +@@4: popad + mov eax,4 + ret +@@5: popad + mov eax,5 + ret + + + +get_extender_type_: + pushad + call seek_to_start + jc @@err1 + + mov ax,3F00h + mov bx,_exec_handle + mov ecx,0400h ; ECX = 64 bytes to load + mov edx,_buffer ; DS:EDX = ptr + int 21h + jc @@err1 + + mov ebx,_buffer + mov esi,offs _str_dos32a + lea edi,[ebx+009Ah] + call check_string + jnc @@1 + mov ebx,_buffer + mov esi,offs _str_stb32a + lea edi,[ebx+006Ah] + call check_string + jnc @@2 + mov ebx,_buffer + mov esi,offs _str_stub32a + lea edi,[ebx+0040h] + call check_string + jnc @@3 + + mov ebx,_buffer + mov esi,offs _str_dos32a_new + lea edi,[ebx+009Ch] + call check_string + jnc @@1 + mov ebx,_buffer + mov esi,offs _str_stub32c_new + lea edi,[ebx+006Ch] + call check_string + jnc @@2 + mov ebx,_buffer + mov esi,offs _str_stub32a_new + lea edi,[ebx+0040h] + call check_string + jnc @@3 + + mov esi,offs _str_dos4g + lea edi,[ebx+025Ah] + call check_string + jnc @@4 + mov esi,offs _str_dos4g + lea edi,[ebx+025Ch] + call check_string + jnc @@4 + + mov esi,offs _str_pmodew + lea edi,[ebx+0055h] + call check_string + jnc @@5 + + popad + xor eax,eax + ret +@@err1: popad + mov eax,-1 + ret + +@@1: popad + mov eax,1 ; DOS/32A + ret +@@2: popad + mov eax,2 ; STUB/32A Configurable + ret +@@3: popad + mov eax,3 ; STUB/32A Standard + ret +@@4: popad + mov eax,4 ; DOS/4G + ret +@@5: popad + mov eax,5 ; PMODE/W + ret + + +check_string: + pushad +@@0: mov al,[esi] + test al,al + jz @@ok + cmp al,[edi] + jnz @@err + inc esi + inc edi + jmp @@0 +@@ok: popad + clc + ret +@@err: popad + stc + ret + + +seek_to_start: + pushad + xor ecx,ecx + xor edx,edx + jmp common_seek +seek_from_start: + pushad + mov ecx,edx + shr ecx,16 +common_seek: + mov bx,_exec_handle + mov ax,4200h + int 21h + popad + ret +seek_from_current: + pushad + mov ecx,edx + shr ecx,16 + mov bx,_exec_handle + mov ax,4201h + int 21h + popad + ret +read_from_exec: + pushad + mov ah,3Fh + mov bx,_exec_handle + int 21h + mov [esp+1Ch],eax + popad + ret + + +find_oem_info_: + pushad + mov edx,_exec_start + call seek_from_start + jc @@err + + mov ecx,10h ; read LC header + mov edx,_buffer + call read_from_exec + jc @@err + + mov al,[edx+05h] ; get LC flags + test al,80h ; check if OEM is appended + jz @@err + + xor esi,esi ; current Object # + movzx ebp,byte ptr [edx+04h] ; get # of Objects + +@@1: mov ecx,10h ; read Object header + mov edx,_buffer + call read_from_exec + jc @@err + mov edx,[edx+04h] ; get Object compressed size + call seek_from_current + jc @@err + inc esi + cmp esi,ebp + jnz @@1 + + mov ecx,0Ch ; read Fixups header + mov edx,_buffer + call read_from_exec + jc @@err + mov edx,[edx+04h] ; get Fixups compressed size + call seek_from_current + jc @@err + + xor eax,eax + mov ecx,128 + mov edi,_buffer + rep stosd + + mov ecx,512 + mov edx,_buffer + call read_from_exec + jc @@err + test eax,eax ; if read nothing, no OEM info + jz @@err + + popad + mov eax,_buffer + ret + +@@err: popad + xor eax,eax + ret + + + +.DATA +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +_buffer dd offset @buffer + +_str_dos32a_new db 'DOS/32A',0 +_str_stub32a_new db 'STUB/32A',0 +_str_stub32c_new db 'STUB/32C',0 + +_str_dos32a db 'DOS/32 Advanced.',0 +_str_stb32a db 'DOS/32 Advanced!',0 +_str_stub32a db 'DOS/32 Advanced stub file.',0 +_str_dos4g db 'DOS/4G',0 +_str_pmodew db 'PMODE/W',0 + +_exec_start dd 0 +_app_off_datapages dd 0 + + + +.DATA? +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +@buffer db 10000h dup(?) +_tmp_handle1 dd ? +_tmp_handle2 dd ? +_tmp_size1 dd ? +_tmp_size2 dd ? + +_mem_ptr dd ? +_mem_handle dd ? + +_exec_handle dw ? +_saved_stack dd ? +_temp_handle dw ? + +end diff -uNr a/dos32a/src/sc/encode.c b/dos32a/src/sc/encode.c --- a/dos32a/src/sc/encode.c false +++ b/dos32a/src/sc/encode.c 9ad61fb3cacf038c459d4ab9107d0c3ad7520830c77750a7bb03b6c820f5a132893dd600879c479f68afcfc2fa79c6c4783592ad5d8642e032f2601c214f6d49 @@ -0,0 +1,289 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +//#include + +#define N 4*1024 // size of the buffer +#define F 18 +#define THRESHOLD 2 +#define NIL N + + + uchar text_buf[N+F-1]; + + int match_position; + int match_length; + int node[N+1]; + int lnode[N+1]; + int rnode[N+257]; + + int bytecount = 0; + int printcount = 0; + ulong textsize = 0; + ulong codesize = 0; + + char cc = 0; + char xc = 0; + char *srcaddr = NULL; + char *destaddr = NULL; + + +int getbyte() +{ + if(bytecount-- > 0) + return(*srcaddr++); + else + return(EOF); +} + +void putbyte(char c) +{ + *destaddr++=(c^xc); + xc=c; +} + +void InitTree(void) +{ + int i; + + for(i=N+1; i<=N+256; i++) + rnode[i]=NIL; + for(i=0; i=0) + { + if(rnode[p]!=NIL) + p=rnode[p]; + else + { + rnode[p]=r; + node[r]=p; + return; + } + } + else + { + if(lnode[p]!=NIL) + p=lnode[p]; + else + { + lnode[p]=r; + node[r]=p; + return; + } + } + for(i=1; imatch_length) + { + match_position=p; + if((match_length=i)>=F) + break; + } + } + node[r]=node[p]; + lnode[r]=lnode[p]; + rnode[r]=rnode[p]; + node[lnode[p]]=r; + node[rnode[p]]=r; + if(rnode[node[p]]==p) + rnode[node[p]]=r; + else + lnode[node[p]]=r; + node[p]=NIL; +} + +void DeleteNode(int p) +{ + int q; + + if(node[p]==NIL) + return; + if(rnode[p]==NIL) + q=lnode[p]; + else if(lnode[p]==NIL) + q=rnode[p]; + else + { + q=lnode[p]; + if(rnode[q]!=NIL) + { + do + { + q=rnode[q]; + } + while(rnode[q]!=NIL); + + rnode[node[q]]=lnode[q]; + node[lnode[q]]=node[q]; + lnode[q]=lnode[p]; + node[lnode[p]]=q; + } + rnode[q]=rnode[p]; + node[rnode[p]]=q; + } + node[q]=node[p]; + if(rnode[node[p]]==p) + rnode[node[p]]=q; + else + lnode[node[p]]=q; + node[p]=NIL; +} + +void Encode(void) +{ + int i, c, len, r, s, last_match_length, code_buf_ptr; + char code_buf[17], mask; + + bytecount=textsize; + InitTree(); + code_buf[0]=0; + + code_buf_ptr=mask=1; + s=0; + r=N-F; + + for(i=s; ilen) + match_length=len; + if(match_length<=THRESHOLD) + { + match_length=1; + code_buf[0]|=mask; + code_buf[code_buf_ptr++]=text_buf[r]; + } + else + { + code_buf[code_buf_ptr++]=(uchar)match_position; + code_buf[code_buf_ptr++]=(uchar)(((match_position>>4)&0xf0)|(match_length-(THRESHOLD+1))); + } + if((mask<<=1)==0) + { + for(i=0; i=printcount) + { + printcount+=256; + if(bytecount<=0) + ShowCount(99); + else + ShowCount((int)(((float)(textsize-bytecount)/(float)textsize)*100)); + } + while(i++0); + + if(code_buf_ptr>1) + { + for(i=0; i=2) + { + for(n=1; n=argc) + { +l1: Print("SC/32A fatal: syntax is SC [commands] [options] \n\n"); + Print("Commands:\n"); + Print("---------\n"); + Print("/B Bind DOS/32A to produced LC Executable\n"); + Print("/BS Bind STUB/32A to produced LC Executable\n"); + Print("/BC Bind STUB/32C to produced LC Executable\n"); + Print("/U Produce Unbound Linear Compressed Executable\n\n"); + Print("Options:\n"); + Print("--------\n"); + Print("/D Turn off all optimization features\n"); + Print("/DA Disable Advanced preprocessing of Executable\n"); + Print("/DE Disable Encoding of LC Executable (no compression)\n"); + Print("/DR Disable Removing of post-zero areas from Executable\n"); + Print("/DS Disable Smart Encoding when compressing Executable\n"); + Print("/V[0|1|2] Verbose mode (displays additional information)\n"); + Print("/Q Quiet mode (partially disables console output)\n"); + Print("/S Silent mode (totally disables console output)\n"); + Print("/H or /? This help\n"); + exit(0); + + } +} + + + +/****************************************************************************/ +void OpenExec() +{ + if(open_exec(tempname1)==-1) + { + CopyFile(oldfilename,tempname1); + if(open_exec(tempname1)==-1) + err_open(tempname1); + } +} +void CloseExec() +{ + close_exec(); +} +void CreateTemp() +{ + if(create_temp()==-1) err_temp(tempname2); +} +int FindExecType() +{ + int n; + + n=get_exec_type(); + if(n==-1) + err_read(tempname1); + if(n==-2) + err_support(oldfilename); + if(n==3) + err_formlc(oldfilename); + if(n==4) + err_formpe(oldfilename); + if(n==5) + err_formpmw1(oldfilename); + return(n); +} + + + + + + + + + +/****************************************************************************/ +void main(int argc, char *argv[]) +{ + int n; + +// Debug_Init(); + + setbuf(stdout,NULL); +// CheckEnvironment(); + ArgInit(argc, argv); + DeleteTempFiles(); + CreateD32AEnvVar(); + CheckExec(argv); + oldfilesize=GetFileSize(oldfilename); + UnbindExec(); + + OpenExec(); + Exec_Type=FindExecType(); + Print("\n"); + if(!verbose) Print("+ Unbinding Exec : Ok.\n"); + else Print("+ Unbinding Exec : Ok. (%s-style)\n",execstyle[Exec_Type-1]); + CloseExec(); + + if(advanced) + { + if(!quiet) printf("+ Preprocessing Exec : "); + n=relocate_exec(tempname1); + if(n!=0) + { + Print("Error! \n"); + err_relocator(n); + } + if(!verbose) Print("Ok.\n"); + else Print("Ok. (%d fixups)\n",relocated_fixups); + } + + OpenExec(); + CompressExec(); + CloseExec(); + + if(bind) + { + BindExec(); + if(!verbose) Print("+ Binding Exec : Ok.\n"); + else Print("+ Binding Exec : Ok. (Stub file used: \"%s\")\n",stubnames[bindtype]); + } + else + { + unlink(newfilename); + copy_file(tempname2,newfilename); + unlink(tempname2); + + } + newfilesize=GetFileSize(newfilename); + DeleteTempFiles(); + + if(!quiet) + { + printf("\n Original Exec Stats: \"%s\", %s-style, %d bytes\n", oldfilename, execstyle[Exec_Type-1], oldfilesize); + printf("Compressed Exec Stats: \"%s\", %s-style, %d bytes (%1.1f%%)\n", newfilename, execstyle[2], newfilesize, (float)(newfilesize+0.01)/(float)(oldfilesize+0.01) *100); + } + else + { + if(!silent) printf("SC/32A: File \"%s\" has been successfully compressed\n", oldfilename); + } + exit(0); +} + + + + +/****************************************************************************/ +void CompressExec() +{ + int n; + + CreateTemp(); + CreateLCHeader(); + CreateLCObjects(); + CreateLCFixups(); + AppendTitleFile(); + close_temp(); + unlink(tempname1); +} + + +/****************************************************************************/ +void CreateLCHeader() +{ + int n; + + Print("+ Creating LC Header : "); + n=create_lc_header(); + if(n!=0) + { + Print("Error! \n"); + if(n==-1) + err_seek(tempname1); + if(n==-2) + err_read(tempname1); + if(n==-3) + err_write(tempname2); + if(n==-4) + err_linker(tempname1); + if(n==-5) + err_objects(tempname1); + } + else + { + if(!verbose) + Print("Ok.\n"); + else + Print("Ok. (%d Objects)\n",app_num_objects); + } +} + + +void CreateLCObjects() +{ + int n; + int obj; + char c; + + for(obj=1; obj<=app_num_objects; obj++) + { + Print("+ Encoding Object #%-2d: ",obj); + + n=create_lc_object(obj); + if(n!=0) + { + Print("Error! \n"); + if(n==-1) err_seek(tempname1); + if(n==-2) err_read(tempname1); + if(n==-3) err_mem(); + if(n==-4) err_write(tempname2); + if(n==-5) err_lcobjhdr(tempname1); + } + + c = app_obj_seekattr[obj] ? '*':' '; + + if(!quiet) + { + printf("[û] "); + if(!verbose) printf("(%1.1f%%)\n", ((float)(obj_new_size+0.01)/(float)(obj_old_size+0.01))*100); + else + { printf("Old=%7d, New=%7d, (%1.1f%%) (%s)%c\n", obj_old_size,obj_new_size, ((float)(obj_new_size+0.01)/(float)(obj_old_size+0.01))*100, encodetype[app_enc_status], c); + if(verbxtra) printf(" ** %s **, ** %s **, %7d - fixups\n", app_obj_iscode ? "CODE":"DATA", app_obj_is32bit ? "32bit":"16bit", app_obj_seekattr[obj]); + } + } + } +} + + +void CreateLCFixups() +{ + int n; + + Print("+ Encoding LC Fixups : "); + n=create_lc_fixups(); + if(n!=0) + { + Print("Error!\n"); + if(n==-1) err_seek(tempname1); + if(n==-2) err_read(tempname1); + if(n==-3) err_mem(); + if(n==-4) err_write(tempname2); + } + + if(quiet!=TRUE) + { + printf("[û] "); + if(!verbose) printf("(%1.1f%%)\n", ((float)(obj_new_size+0.01)/(float)(obj_old_size+0.01))*100); + else printf("Old=%7d, New=%7d, (%1.1f%%) (%s)\n", obj_old_size,obj_new_size, ((float)(obj_new_size+0.01)/(float)(obj_old_size+0.01))*100, encodetype[app_enc_status]); + } +} + + + + + + + + + + +/****************************************************************************/ +void UnbindExec() +{ + int n; + + char temppath[128]; // passed as *path argument + char tempname[128]; // passed as *argv[0] + char tempparm[128]; // name of file to be processed + + const char *path=temppath; + const char *arg0=bindname; + const char *arg1="/U"; + const char *arg2="/O"; + const char *arg3="/S"; + const char *arg4=tempparm; + const char *arg5=oldfilename; + + + strcpy(temppath,bindname); + strcpy(tempname,bindname); + strcpy(tempparm,"/UN"); + strcat(tempparm,tempname1); + n=spawnle(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + + if(n==-1) + { + GetDOS32APath(); + strcpy(temppath,dos32apath); + strcat(temppath,bindname); + strcpy(tempname,dos32apath); + strcat(tempname,bindname); + n=spawnle(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + if(n==-1) + { + strcpy(temppath,bindname); + strcpy(tempname,bindname); + n=spawnlpe(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + if(n==-1) + err_nosb(); + } + } + if(n!=0) + { + if(n==127) + err_support(oldfilename); + else + { + DeleteTempFiles(); + exit(1); + } + } +} + +/****************************************************************************/ +void BindExec() +{ + int n; + + char temppath[128]; // passed as *path argument + char tempname[128]; // passed as *argv[0] + char tempparm[128]; // -UN name of file + char tempparm2[128]; // -BN name of file + char temptype[8]; // action type, either "-R" or "-RS" + + const char *path=temppath; + const char *arg0=bindname; + const char *arg1=temptype; + const char *arg2="/S"; + const char *arg3=tempparm; + const char *arg4=tempparm2; + const char *arg5=tempname2; + + + if(bindtype==0) + strcpy(temptype,"/R"); + else if(bindtype==1) + strcpy(temptype,"/RS"); + else if(bindtype==2) + strcpy(temptype,"/RC"); + + strcpy(temppath,bindname); + strcpy(tempname,bindname); + + strcpy(tempparm,"/UN"); + strcat(tempparm,tempname2); + strcpy(tempparm2,"/BN"); + strcat(tempparm2,newfilename); + n=spawnle(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + + if(n==-1) + { + GetDOS32APath(); + strcpy(temppath,dos32apath); + strcat(temppath,bindname); + strcpy(tempname,dos32apath); + strcat(tempname,bindname); + n=spawnle(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + if(n==-1) + { + strcpy(temppath,bindname); + strcpy(tempname,bindname); + n=spawnlpe(P_WAIT, path, arg0,arg1,arg2,arg3,arg4,arg5, NULL, NULL); + if(n==-1) + err_nosb(); + } + } + if(n!=0) + { + if(n==127) + err_support(tempname2); + else + { + DeleteTempFiles(); + exit(1); + } + } +} + + +/****************************************************************************/ +void Print(char *format, ...) +{ + va_list arglist; + char buffer[1024]; + if(quiet==FALSE) + { + va_start(arglist,format); + vsprintf(buffer,format,arglist); + printf(buffer); + va_end(arglist); + } +} +int GetFileSize(char *name) +{ + int n,m; + if( (n=open(name,O_RDONLY | O_BINARY)) == -1) return(0); + m=filelength(n); + close(n); + return(m); +} +void GetDOS32APath() +{ + char *ptr; + char *envname; + char envbuf[512]; + + dos32apath[0]=NULL; + envname=getenv("DOS32A"); + if(envname!=0) + { + ptr=strchr(envname,' '); + if(ptr==NULL) + ptr=strchr(envname,0); + memset(envbuf,0,256); + strncpy(envbuf,envname,(dword)ptr-(dword)envname); + strcat(envbuf,"\\BINW\\"); + strcpy(dos32apath,envbuf); + } + else + strcat(dos32apath, ".\\"); +} +void CreateD32AEnvVar() +{ + int n; + char *envname; + + envname=getenv("DOS32A"); + if(envname!=0) + { + strcpy(dos32aenv,envname); + strcat(dos32aenv," /NOC"); + } + else + strcpy(dos32aenv," /NOC"); + n=setenv("DOS32A",dos32aenv,1); +// if(n!=0) +// Print("WARNING: could not adjust DOS32A environment variable\n"); +} +void DeleteTempFiles() +{ + close_temp(); + close_exec(); + unlink(tempname1); + unlink(tempname2); +} +void ShowCount(int count) +{ + if(quiet!=TRUE) + if(nocount!=TRUE) + printf("%02d%%\b\b\b",count); +} +void CopyFile(char *f1, char *f2) { + int c; + FILE *src; + FILE *dest; + unlink(f2); + if((src=fopen(f1,"rb"))!=NULL) + { + if((dest=fopen(f2,"wb"))!=NULL) + { + while((c=fgetc(src))!=EOF) + fputc(c,dest); + fclose(dest); + } + fclose(src); + } +} +void CheckExec(char *argv[]) +{ + char *bufptr; + + strcpy(oldfilename,argv[execargn]); + strcpy(newfilename,argv[execargn]); + bufptr=(char *)strchr(newfilename,'.'); + if(bufptr!=NULL) + strset(bufptr,0); + if(bind==TRUE) + strcat(newfilename,".exe"); + else + strcat(newfilename,".lc"); + + if(CheckIfExists(oldfilename)==TRUE) + return; + bufptr=(char *)strchr(oldfilename,'.'); + if(bufptr!=NULL) + return; + strcat(oldfilename,".exe"); + + if(CheckIfExists(oldfilename)==TRUE) + return; + bufptr=(char *)strchr(oldfilename,'.'); + if(bufptr!=NULL) + strset(bufptr,0); + strcat(oldfilename,".le"); + + if(CheckIfExists(oldfilename)==TRUE) + return; + bufptr=(char *)strchr(oldfilename,'.'); + if(bufptr!=NULL) + strset(bufptr,0); + strcat(oldfilename,".lx"); + + if(CheckIfExists(oldfilename)==TRUE) + return; + strcpy(oldfilename,argv[execargn]); +} +int CheckIfExists(char *name) +{ + int n; + n=open(name,O_RDWR | O_BINARY); + if(n!=-1) + { + close(n); + return(TRUE); + } + return(FALSE); +} +void CheckEnvironment() +{ + if(getenv("DOS32A")==NULL) + err_environment(); +} + +void copy_file(char *f1, char *f2) +{ + int c; + FILE *src; + FILE *dest; + + if( (f1[1] != ':') && (f2[1] != ':') ) + { + rename(f1,f2); + return; + } + if((src=fopen(f1,"rb"))!=NULL) + { + if((dest=fopen(f2,"wb"))!=NULL) + { + while((c=fgetc(src))!=EOF) + fputc(c,dest); + fclose(dest); + } + fclose(src); + } +} + +void AppendTitleFile() +{ + int n,m,k; + char *ptr; + char *dirptr; + char tempbuf[512]; + + dirptr=inffilename-1; + strcpy(inffilename,oldfilename); + for(ptr=inffilename; *ptr!=0; ptr++) if(*ptr=='\\') dirptr=ptr; + + *(dirptr+1)=0; + strcat(inffilename,titlename); + + m=GetFileSize(inffilename); + if(m==0 || m>512) return; + + if( (n=open(inffilename,O_RDONLY | O_BINARY)) != -1) + { + k=0; + Print("+ Appending OEM Info : "); + memset(tempbuf,0,512); + if(read(n,&tempbuf,m) == -1) k++; + if(write_oem_to_temp(temp_handle,&tempbuf,m+1) == -1) k++; + if(k==0) + { + Print("Ok."); + if(verbose) Print(" (%d bytes)",m); + Print("\n"); + } + else + Print("Error!\n"); + close(n); + } +} diff -uNr a/dos32a/src/sc/main.h b/dos32a/src/sc/main.h --- a/dos32a/src/sc/main.h false +++ b/dos32a/src/sc/main.h e5664bdd7ef6611ce8cea95bc6b28adb8ff9c374d35dd80072377927808ea072380f11c357bb46ebbcc2f68735190896ef85eb51372ffbaed47a3727c63df238 @@ -0,0 +1,80 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +extern int app_num_objects; + +extern int get_exec_type(void); + +extern int create_temp(void); +extern int close_temp(void); + +extern int create_lc_header(void); +extern int create_lc_object(long); +extern int create_lc_fixups(void); + +extern int relocate_exec(char *); +extern int write_oem_to_temp(int, char *, int); + +extern unsigned short exec_handle; +extern unsigned short temp_handle; + +extern int obj_old_size; +extern int obj_new_size; +extern int relocated_fixups; + +extern byte app_enc_status; +extern byte app_obj_iscode; +extern byte app_obj_is32bit; +extern long app_obj_seekattr[]; + + diff -uNr a/dos32a/src/sc/scomp.asm b/dos32a/src/sc/scomp.asm --- a/dos32a/src/sc/scomp.asm false +++ b/dos32a/src/sc/scomp.asm 7407f0f5dbf89fa2208bb0081acd65212aa69f8416e094abe601866bdae12bf6a87054dafbcea4884905f4e423bc48b41b02f9dbaaff5f5a43cfbdaea3da9b7c @@ -0,0 +1,879 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .486p + .MODEL flat + LOCALS + NOJUMPS + +include stddef.inc + +APP_MAXOBJECTS = 64 +LC_SPECVER = 04h + +EXTRN _tempname2 :dword +EXTRN _Exec_Type :dword +EXTRN _quiet :dword +EXTRN _smart :dword +EXTRN _strip :dword +EXTRN _encode :dword +EXTRN _nocount :dword +EXTRN CompressData_ :near + +PUBLIC _exec_handle +PUBLIC _temp_handle +PUBLIC _app_num_objects +PUBLIC _app_enc_status +PUBLIC _app_obj_iscode +PUBLIC _app_obj_is32bit + +PUBLIC open_exec_, close_exec_ +PUBLIC create_temp_, close_temp_ +PUBLIC write_oem_to_temp_ +PUBLIC get_exec_type_ + +PUBLIC _obj_old_size, _obj_new_size + +PUBLIC create_lc_header_ +PUBLIC create_lc_object_ +PUBLIC create_lc_fixups_ + + +.CODE +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + +;----------------------------------------------------------------------------- +; LC Header Format +; +; 0000 DD "LC" \0\0 +; 0004 DB # of Objects +; 0005 DB reserved, 0 +; 0006 DB EIP Object # +; 0007 DB ESP Object # +; 0008 DD EIP Offset +; 000C DD ESP Offset +; + +create_lc_header_: + pushad + call seek_to_start ; move to exec start + jc @@err1 + mov ecx,0A8h + mov edx,_buffer + call read_from_exec ; load LE/LX header + jc @@err2 + + mov esi,_buffer ; source LE/LX header + lea edi,[esi+0100h] ; destination LC header + + mov eax,'CL' + mov [edi+0000h],eax ; LC signature + mov eax,[esi+0044h] + mov [edi+0004h],al ; # of Objects + mov al,LC_SPECVER + mov [edi+0005h],al ; LC implement. + mov eax,[esi+0018h] + mov [edi+0006h],al ; EIP Object # + mov eax,[esi+0020h] + mov [edi+0007h],al ; ESP Object # + mov eax,[esi+001Ch] + mov [edi+0008h],eax ; EIP Offset + mov eax,[esi+0024h] + mov [edi+000Ch],eax ; ESP Offset + + mov eax,[esi+0010h] ; check Module Flags + and eax,2000h + jnz @@err4 + mov eax,[esi+0044h] ; check # of Objects + cmp eax,APP_MAXOBJECTS + ja @@err5 + mov _app_num_objects,eax + mov eax,[esi+0040h] + mov _app_off_objects,eax + mov eax,[esi+0048h] + mov _app_off_objpagetab,eax + mov eax,[esi+0068h] + mov _app_off_fixpagetab,eax + mov eax,[esi+006Ch] + mov _app_off_fixrectab,eax + mov eax,[esi+0080h] + mov _app_off_datapages,eax + mov eax,[esi+0030h] + mov _app_siz_fixrectab,eax + mov eax,[esi+002Ch] + mov _app_siz_lastpage,eax + + mov eax,0FFFh + cmp _Exec_Type,1 + jz @@1 + mov eax,1 + mov ecx,[esi+002Ch] ; get Page Offset Shift for LX-type + shl eax,cl ; max shift is 15 (8000h-1) + dec eax +@@1: mov _app_off_pageshift,eax + + mov ecx,16 + mov edx,edi + call write_to_temp ; write LC header to temp file + jc @@err3 + popad + xor eax,eax + ret + +@@err1: popad ; error seeking in exec + mov eax,-1 + ret +@@err2: popad ; error loading from exec + mov eax,-2 + ret +@@err3: popad ; error writing to temp + mov eax,-3 + ret +@@err4: popad ; error in application exec + mov eax,-4 + ret +@@err5: popad ; too many objects in exec + mov eax,-5 + ret + + + + +;----------------------------------------------------------------------------- +; Object Header Format +; +; 0000 DD Virtual Size (Uncompressed Size) +; bit 31: 0=encoded, 1=not encoded +; 0004 DD Compressed Size +; 0008 DW Object Flags +; 000A DW Extended Object Flags +; 000C DW Page Table Index +; 000E DW # of Page Table Entries +; 0010 ... ...Object Data... +; + +create_lc_object_: + pushad + mov _tmp_cur_object,eax + mov _app_enc_status,1 + mov _app_obj_iscode,0 + mov _app_obj_is32bit,0 + + call print_reading + + mov edx,_app_off_objects ; move to current Object head + call seek_to_edx + jc @@err1 + + mov ecx,18h ; load Object header + mov edx,_buffer + call read_from_exec + jc @@err2 + add _app_off_objects,ecx + + mov edx,_app_off_datapages + call seek_to_edx + jc @@err1 + + mov esi,_buffer + mov eax,[esi+0000h] ; Virtual Size + mov ebx,[esi+0010h] ; # of Page Table Entries + mov _app_obj_virtsize,eax + + call alloc_exec_buffer + jc @@err3 + call clear_exec_buffer + + mov ecx,eax + mov eax,ebx + xor ebp,ebp + test eax,eax ; check if # Page Table Entries = 0 + jz @@5 ; if yes, skip loading + shl eax,12 ; convert # Page Table Entries to bytes + cmp eax,ecx ; check if # bytes >= bytes to load + jae @@1 ; if yes, jump + mov ecx,eax ; else adjust number of bytes to read + +@@1: mov eax,_tmp_cur_object ; get Object # + cmp eax,_app_num_objects + jnz @@3 + cmp _Exec_Type,1 + jnz @@2 + lea ecx,[ebx-1] ; load LE-style Last Object (BSS) + shl ecx,12 + add ecx,_app_siz_lastpage + jmp @@3 +@@2: mov ecx,ebx ; load LX-style Last Object (BSS) + shl ecx,12 + cmp ecx,_app_obj_virtsize + jb @@3 + mov ecx,_app_obj_virtsize +@@3: mov ebp,ecx ; EBP = bytes to load (phys. size) + mov edx,_exec_buffer + call read_from_exec ; load object data + jc @@err2 + + mov eax,ecx + mov edx,_app_off_pageshift + test eax,edx + jz @@4 + mov ecx,edx + not edx + and eax,edx + lea eax,[eax+ecx+1] +@@4: add _app_off_datapages,eax + +@@5: mov eax,ebp ; EAX = size + mov _obj_old_size,eax + shl eax,1 ; double that + add eax,10h ; + Object header size + call alloc_temp_buffer + jc @@err3 + call clear_temp_buffer + + mov eax,ebp + test eax,eax ; if null-size Object + jz @@6 ; then skip compressing it + call find_last_byte + mov ebp,eax + + call print_nothing + + mov eax,_exec_buffer ; EAX = source + mov edx,_temp_buffer ; EDX = destination + add edx,10h ; skip header size + mov ebx,ebp ; EBX = size + call compress_data ; returns: EAX = new size + +@@6: call print_writing + + mov ebp,eax ; EBP = compressed size + mov _obj_new_size,eax + mov esi,_buffer + mov edi,_temp_buffer + + mov eax,[esi+0000h] ; Virtual Size + cmp _app_enc_status,0 + jz @@l1 + or eax,80000000h +@@l1: mov [edi+0000h],eax + mov eax,ebp ; Compressed Size + mov [edi+0004h],eax + mov eax,[esi+0008h] ; Object Flags + mov [edi+0008h],ax + mov eax,0 ; Extended Flags + mov [edi+000Ah],ax + mov eax,[esi+000Ch] ; Page Table Index + test eax,0FFFF0000h + jnz @@err5 + mov [edi+000Ch],ax + mov eax,[esi+0010h] ; # of Page Table Entries + test eax,0FFFF0000h + jnz @@err5 + mov [edi+000Eh],ax + + lea ecx,[ebp+10h] + mov edx,_temp_buffer + call write_to_temp + jc @@err4 + + mov eax,[esi+0008h] ; Object Flags + test eax,0004h + setnz _app_obj_iscode ; 1=code, 0=data + test eax,2000h + setnz _app_obj_is32bit ; 1=32bit, 0=16bit + + call free_temp_buffer + call free_exec_buffer + + call print_nothing + + popad + xor eax,eax + ret +@@err1: popad ; error seeking in exec + mov eax,-1 + ret +@@err2: popad ; error reading from exec + mov eax,-2 + ret +@@err3: popad ; error allocating memory + mov eax,-3 + ret +@@err4: popad ; error writing to temp + mov eax,-4 + ret +@@err5: popad ; object header overflow + mov eax,-5 + ret + + + + + + +;----------------------------------------------------------------------------- +; +; Fixups Header Format +; +; 0000 DD Uncompresed Size +; bit 31: 0=encoded, 1=not encoded +; 0004 DD Compressed Size +; 0008 DD Fixup Record Table Offset +; 000C ... ...Fixup Page Table Data ... +; 000C+[0008] ...Fixup Record Table Data ... + +create_lc_fixups_: + pushad + mov _app_enc_status,1 + + call print_reading + + mov eax,_app_siz_fixrectab + call alloc_exec_buffer + jc @@err3 + call clear_exec_buffer + + mov edx,_app_off_fixpagetab + call seek_to_edx + jc @@err1 + mov ecx,_app_siz_fixrectab + mov edx,_exec_buffer + call read_from_exec + jc @@err2 + + mov eax,_app_siz_fixrectab + mov _obj_old_size,eax + shl eax,1 + add eax,0Ch + call alloc_temp_buffer + jc @@err3 + call clear_temp_buffer + + mov eax,_app_siz_fixrectab + call find_last_byte + mov ebp,eax + + call print_nothing + + mov eax,_exec_buffer ; EAX = source + mov edx,_temp_buffer ; EDX = destination + add edx,0Ch ; skip header size + mov ebx,ebp ; EBX = size + call compress_data + mov ebp,eax + mov _obj_new_size,eax + + call print_writing + + mov edi,_temp_buffer + + mov eax,_app_siz_fixrectab + cmp _app_enc_status,0 + jz @@l1 + or eax,80000000h +@@l1: mov [edi+0000h],eax + mov [edi+0004h],ebp + mov eax,_app_off_fixrectab + mov ebx,_app_off_fixpagetab + sub eax,ebx + mov [edi+0008h],eax + + lea ecx,[ebp+0Ch] + mov edx,_temp_buffer + call write_to_temp + jc @@err4 + + call free_temp_buffer + call free_exec_buffer + + call print_nothing + + popad + xor eax,eax + ret + +@@err1: popad ; error seeking in exec + mov eax,-1 + ret +@@err2: popad ; error reading from exec + mov eax,-2 + ret +@@err3: popad ; error allocating memory + mov eax,-3 + ret +@@err4: popad ; error writing to temp + mov eax,-4 + ret + + + + +;----------------------------------------------------------------------------- +compress_data: + mov _app_enc_status,0 + cmp _encode,TRUE ; if NOT encode, copy data + jnz @@2 + cmp _smart,TRUE ; if NOT smart, compress data + jnz CompressData_ + test ebx,ebx + jnz @@0 + xor eax,eax + mov _app_enc_status,1 + ret + +@@0: push eax edx ebx + call CompressData_ + pop ebx edx + cmp eax,ebx + ja @@1 + add esp,4 + ret + +@@1: pop eax +@@2: pushad + mov esi,eax + mov edi,edx + mov ecx,ebx + shr ecx,2 + rep movsd + mov ecx,ebx + and ecx,03h + rep movsb + popad + mov eax,ebx + mov _app_enc_status,1 + ret + + +comment ~ +;----------------------------------------------------------------------------- +; Find the most common byte in the _exec_buffer (very slow) +; In: EAX = size of buffer +; Out: EAX = byte +; +find_common_byte: + pushad + mov ebp,eax + sub esp,0100h*4 + xor eax,eax + mov edi,esp + mov ecx,0100h + rep stosd + xor eax,eax + mov ebx,0100h + Align 4 +@@1: mov ecx,ebp + mov edi,_exec_buffer + Align 4 +@@2: scasb + jnz @@3 + inc dword ptr [esp+eax*4] + Align 4 +@@3: dec ecx + jnz @@2 + inc eax + dec ebx + jnz @@1 + xor eax,eax + xor ebx,ebx + xor edx,edx +@@4: cmp eax,[esp+ebx*4] + jae @@5 + mov eax,[esp+ebx*4] + mov edx,ebx +@@5: inc ebx + cmp ebx,0100h + jb @@4 + add esp,0100h*4 + mov [esp+1Ch],edx + popad + ret +~ + + +;----------------------------------------------------------------------------- +; Find the last *non-zero* byte in the _exec_buffer +; In: EAX = real size of the buffer +; Out: EAX = virtual size of the buffer +; +find_last_byte: + pushad + cmp _strip,TRUE + jnz @@done + + mov ecx,eax + jecxz @@done + xor eax,eax + mov edi,_exec_buffer + lea edi,[edi+ecx-1] + std + repe scasb + cld + cmp al,[edi+1] + jz @@1 + inc ecx +@@1: mov [esp+1Ch],ecx +@@done: popad + ret + + + +;----------------------------------------------------------------------------- +open_exec_: + pushad + mov edx,eax + mov ax,3D02h + int 21h + jc @@0 + mov _exec_handle,ax +@@0: popad + mov eax,0 + sbb eax,eax + ret + +close_exec_: + pushad + mov bx,_exec_handle + cmp bx,-1 + jz @@0 + mov ah,3Eh + int 21h + mov _exec_handle,-1 +@@0: popad + ret + +create_temp_: + pushad + mov edx,_tempname2 ; create temp2 file + mov ecx,00h + mov ah,3Ch + int 21h + jc @@0 + mov _temp_handle,ax +@@0: popad + mov eax,0 + sbb eax,eax + ret + +close_temp_: + pushad + mov bx,_temp_handle + cmp bx,-1 + jz @@0 + mov ah,3Eh + int 21h + mov _temp_handle,-1 +@@0: popad + ret + + +;----------------------------------------------------------------------------- +get_exec_type_: + pushad + call seek_to_start + mov ax,3F00h + mov bx,_exec_handle + mov ecx,4 + mov edx,_buffer + int 21h + jc @@err1 + test eax,eax + jz @@err2 ; unknown exec format + cmp wptr [edx],'EL' + jz @@1 + cmp wptr [edx],'XL' + jz @@2 + cmp wptr [edx],'CL' + jz @@3 + cmp wptr [edx],'EP' + jz @@4 + cmp dptr [edx],'1WMP' + jz @@5 +@@err2: popad + mov eax,-2 + ret +@@err1: popad + mov eax,-1 + ret +@@1: popad + mov eax,1 + ret +@@2: popad + mov eax,2 + ret +@@3: popad + mov eax,3 + ret +@@4: popad + mov eax,4 + ret +@@5: popad + mov eax,5 + ret + + +;----------------------------------------------------------------------------- +write_oem_to_temp_: + pushad + mov ecx,ebx + mov ebx,eax + mov ah,40h + mov bx,_temp_handle + int 21h + jc @@err + + xor ecx,ecx + xor edx,edx + mov ax,4200h + mov bx,_temp_handle + int 21h + jc @@err + + mov ah,3Fh + mov bx,_temp_handle + mov ecx,10h + mov edx,_buffer + int 21h + jc @@err + + xor ecx,ecx + xor edx,edx + mov ax,4200h + mov bx,_temp_handle + int 21h + jc @@err + + mov edx,_buffer + mov al,[edx+05h] + or al,80h + mov [edx+05h],al + + mov ah,40h + mov bx,_temp_handle + mov ecx,10h + mov edx,_buffer + int 21h + jc @@err + + popad + xor eax,eax + ret + +@@err: popad + mov eax,-1 + ret + +;----------------------------------------------------------------------------- +seek_to_start: + pushad + xor ecx,ecx + xor edx,edx + mov bx,_exec_handle + mov ax,4200h + int 21h + popad + ret +seek_to_edx: + pushad + mov ecx,edx + shr ecx,16 + mov bx,_exec_handle + mov ax,4200h + int 21h + popad + ret +read_from_exec: + pushad + mov ah,3Fh + mov bx,_exec_handle + int 21h + popad + ret +write_to_temp: + pushad + mov ah,40h + mov bx,_temp_handle + int 21h + popad + ret +alloc_exec_buffer: + pushad + lea ebx,[eax+10h] + mov ax,0FF91h + int 21h + mov _exec_buffer,ebx + mov _exec_bufhand,esi + popad + ret +free_exec_buffer: + pushad + mov esi,_exec_bufhand + mov ax,0FF92h + int 21h + popad + ret +alloc_temp_buffer: + pushad + lea ebx,[eax+10h] + mov ax,0FF91h + int 21h + mov _temp_buffer,ebx + mov _temp_bufhand,esi + popad + ret +free_temp_buffer: + pushad + mov esi,_temp_bufhand + mov ax,0FF92h + int 21h + popad + ret +clear_exec_buffer: + pushad + mov ecx,eax + mov edx,eax + shr ecx,2 + and edx,3 + xor eax,eax + mov edi,_exec_buffer + rep stosd + mov ecx,edx + rep stosb + popad + ret +clear_temp_buffer: + pushad + mov ecx,eax + mov edx,eax + shr ecx,2 + and edx,3 + xor eax,eax + mov edi,_temp_buffer + rep stosd + mov ecx,edx + rep stosb + popad + ret + + +print_reading: + pushad + cmp _quiet,0 + jnz @@0 + cmp _nocount,TRUE + jz @@0 + mov ax,0FF80h + mov edx,offset _str_reading + int 21h +@@0: popad + ret +print_writing: + pushad + cmp _quiet,0 + jnz @@0 + cmp _nocount,TRUE + jz @@0 + mov ax,0FF80h + mov edx,offset _str_writing + int 21h +@@0: popad + ret +print_nothing: + pushad + cmp _quiet,0 + jnz @@0 + cmp _nocount,TRUE + jz @@0 + mov ax,0FF80h + mov edx,offset _str_nothing + int 21h +@@0: popad + ret + + + +.DATA +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +_buffer dd offset @buffer +_exec_handle dw -1 +_temp_handle dw -1 + +_str_reading db 'Reading...',8,8,8,8,8,8,8,8,8,8,0 +_str_writing db 'Writing...',8,8,8,8,8,8,8,8,8,8,0 +_str_nothing db ' ',8,8,8,8,8,8,8,8,8,8,0 + + + +.DATA? +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +@buffer db 1000h dup(?) + +_exec_type dd ? +_exec_name dd ? + +_exec_buffer dd ? +_exec_bufhand dd ? +_temp_buffer dd ? +_temp_bufhand dd ? + +__saved_esp dd ? +_tmp_cur_object dd ? +_tmp_cnt_bytes dd ? +_obj_old_size dd ? +_obj_new_size dd ? + +;----------------------------------------------------------------------------- +_app_num_objects dd ? +_app_off_objects dd ? +_app_off_objpagetab dd ? +_app_off_fixpagetab dd ? +_app_off_fixrectab dd ? +_app_off_datapages dd ? +_app_siz_fixrectab dd ? +_app_siz_lastpage dd ? +_app_off_pageshift dd ? +_app_obj_virtsize dd ? + +_app_enc_status db ? ; 0=encoded, 1=not encoded +_app_obj_iscode db ? +_app_obj_is32bit db ? + +end diff -uNr a/dos32a/src/sc/sload.asm b/dos32a/src/sc/sload.asm --- a/dos32a/src/sc/sload.asm false +++ b/dos32a/src/sc/sload.asm f659b2e628b30b8fc9c60de5749927d9cd6e8c08a805cd23ca2f038e3be77dc952beda8a7b4967dadd7c8bcfb2bf8c831d8f130d274414acaef2109d68df4288 @@ -0,0 +1,857 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .386p + .MODEL flat + LOCALS + NOJUMPS + +APP_MAXOBJECTS = 64 + +EXTRN _quiet :dword +EXTRN _nocount :dword + +PUBLIC relocate_exec_ +PUBLIC _relocated_fixups +PUBLIC _app_obj_seekattr + +include stddef.inc + +.CODE +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + +relocate_exec_: + pushad + mov __saved_esp,esp + mov __filename_ptr,eax + mov _relocated_fixups,0 + call clear_struct + call open_exec + call load_application +; call relocate_application + call free_resources + call close_exec + xor eax,eax + jmp common_exit + + + + +;============================================================================= +load_application: + mov __loader_esp,esp + call load_header ; load 'LE'/'LX' exec header + mov ecx,1 ; start with Object #1 +@@1: call show_progress + mov _app_cur_object,ecx + call load_object ; load object + call create_selector ; allocate selector for loaded object + push edx ; save Object Selector/Object Flags + push edi ; save Address of loaded Object + push esi ; save Page Table Index + push ebx ; save # Page Table Entries + inc ecx ; increment Current_Object# + cmp ecx,_app_num_objects + jbe @@1 ; loop until all objects are loaded + call preload_fixups ; preload fixup tables and records + mov ebp,esp ; base pointer to last loaded Object + mov ebx,_app_num_objects ; number of Objects + dec ebx + shl ebx,4 + mov _app_tmp_addr1,ebx + mov __current_object,0 +@@4: inc __current_object + call relocate_object + sub ebx,10h + jnc @@4 + call unload_fixups ; free allocated memory for fixups + mov esp,__loader_esp + ret + + +;relocate_application: +; mov ebp,1 +; xor eax,eax +; xor ebx,ebx +; mov _err_code,3002h +;@@1: cmp _app_obj_seekattr[ebp*4],0 +; jz @@2 +; mov edx,_app_obj_seekptr[ebp*4] +; call seek_from_start +; mov ah,40h +; mov bx,__exec_handle +; mov ecx,_app_obj_seeksize[ebp*4] +; jecxz @@2 +; mov edx,_app_buf_allocbase[ebp*4] +; int 21h +; jc file_errorm +;@@2: inc ebp ; increment Current_Object# +; cmp ebp,_app_num_objects +; jbe @@1 ; loop until all objects are loaded +; ret + + + + +;----------------------------------------------------------------------------- +load_header: + sub esp,0ACh + mov ecx,0A8h ; load 'LE' header + mov ebp,esp + lea edx,[esp+4] + mov _err_code,3002h ; "error in app file" + + call load_fs_block + mov edx,__exec_start + + mov ax,[ebp+0010h] ; get Module Flags + and ax,2000h ; check if not-loadable;/no-fixups + mov ax,3005h + jnz file_error + mov eax,[ebp+0044h] ; get # Objects + mov ecx,eax + cmp eax,APP_MAXOBJECTS + mov ax,4001h ; "too many objects" + ja file_error + mov _app_num_objects,ecx + + mov eax,[ebp+0040h] ; get Object Table Offset + add eax,edx + mov _app_off_objects,eax + mov eax,[ebp+0048h] ; get Object PageTable Offset + add eax,edx + mov _app_off_objpagetab,eax + mov eax,[ebp+0068h] ; get Fixup PageTable Offset + add eax,edx + mov _app_off_fixpagetab,eax + mov eax,[ebp+006Ch] ; get Fixup Record Table Offset + add eax,edx + mov _app_off_fixrectab,eax + mov eax,[ebp+0080h] ; get Data Pages Offset + add _app_off_datapages,eax + + mov eax,[ebp+0030h] ; get Fixup Records Size + mov _app_siz_fixrecstab,eax + mov eax,[ebp+002Ch] ; get Bytes on Last Page (LE-only) + mov _app_siz_lastpage,eax + + mov eax,0FFFh + cmp _app_type,0 + jz @@done + mov eax,1 + mov ecx,[ebp+002Ch] ; get Page Offset Shift for LX-type + shl eax,cl ; max shift is 15 (8000h-1) + dec eax + +@@done: mov _app_off_pageshift,eax + add esp,0ACh + ret + + + +;----------------------------------------------------------------------------- +load_object: + push ecx + + mov _err_code,3002h ; "error in app file" + mov edx,_app_off_objects + call seek_from_start ; move to object header + + sub esp,18h + mov ecx,18h + mov edx,esp + mov ebp,esp + call load_fs_block ; load object header + add _app_off_objects,eax + + mov edx,_app_off_datapages ; get Data_Pages_Offset + mov eax,_app_cur_object + mov _app_obj_seekptr[eax*4],edx + call seek_from_start ; move to object data + mov eax,[ebp+0000h] ; get Virtual_Size[Object] + mov ebx,[ebp+0010h] ; get # Page Table Entries + mov ecx,[ebp+0008h] ; get Flags[Object] + mov esi,[ebp+000Ch] ; get Page Table Index + add esp,18h + + push ecx ; save Object Flags + call alloc_block ; allocate EAX memory block to EDI + mov ecx,eax ; ECX = bytes to read + mov ebp,eax ; EBP = preserve Virtual Size + mov edx,edi ; EDX = addres to read to + call fill_zero_pages ; fill allocated memory with zeroes + + mov eax,ebx + test eax,eax ; check if # Page Table Entries = 0 + jz @@5 ; if yes, skip loading + shl eax,12 ; convert # Page Table Entries to bytes + cmp eax,ecx ; check if # bytes >= bytes to load + jae @@1 ; if yes, jump + mov ecx,eax ; else adjust number of bytes to read + +@@1: mov eax,[esp+4] ; get Object # + cmp eax,_app_num_objects + jnz @@3 + cmp _app_type,0 + jnz @@2 + lea ecx,[ebx-1] ; load LE-style Last Object (BSS) + shl ecx,12 + add ecx,_app_siz_lastpage + jmp @@3 +@@2: mov ecx,ebx ; load LX-style Last Object (BSS) + shl ecx,12 + +@@3: mov _err_code,3002h ; "error in app file" + mov eax,_app_cur_object + push eax + call load_gs_block ; load object data + pop edx + mov _app_obj_seeksize[edx*4],eax + mov eax,ecx + mov edx,_app_off_pageshift + test eax,edx + jz @@4 + mov ecx,edx + not edx + and eax,edx + lea eax,[eax+ecx+1] +@@4: add _app_off_datapages,eax + +@@5: pop edx ; restore Object Flags +@@done: pop ecx + ret + + + + +;============================================================================= +relocate_object: + xor eax,eax + cmp eax,[ebp+ebx+0] ; get # Page Table Entries[Object] + jnz @@0 ; if zero, done + ret +@@0: cmp _app_type,0 + jnz relocate_lx_object + +relocate_le_object: + mov ecx,[ebp+ebx+4] ; get Page Table Index + mov edx,_app_off_objpagetab ; get Object Page Table Offset in exec + lea edx,[ecx*4+edx-4] + mov _err_code,3002h ; "error in app file" + call seek_from_start ; *1) move file ptr +@@1: push eax ; EAX = counter + mov ecx,4 + sub esp,4 + mov edx,esp + mov _err_code,3002h ; "error in app file" + call load_fs_block ; load block + xor ecx,ecx ; get index into FixupPageTab + mov ch,[esp+0001h] + mov cl,[esp+0002h] + add esp,4 + jecxz @@2 + mov eax,_app_off_fixpagetab ; get Fixup Page Table Offset + lea eax,[ecx*4+eax-4] + mov esi,[eax+00h] ; get offset of 1st fixup table + mov ecx,[eax+04h] ; get offset of 2nd fixup table + sub ecx,esi ; calculate size of 1st tab + jz @@2 ; if 1st == 2nd, no fixups + add esi,_app_off_fixrectab ; get Fixup Record Table Offset + mov edi,[esp] ; get current page number + shl edi,12 + add edi,[ebp+ebx+8] ; address of page target to fix in mem + add ecx,esi + call apply_fixups ; patch target with fixup data +@@2: pop eax + inc eax + cmp eax,[ebp+ebx+0] + jb @@1 + ret + +relocate_lx_object: + mov ecx,[ebp+ebx+4] ; get Page Table Index + mov edx,_app_off_fixpagetab ; get Fixup Page Table Offset + lea edx,[ecx*4+edx-4] +@@1: push eax edx ; EAX = counter + mov esi,[edx+00h] ; get offset of 1st fixup table + mov ecx,[edx+04h] ; get offset of 2nd fixup table + sub ecx,esi ; calculate size of 1st tab + jz @@2 ; if 1st == 2nd, no fixups + add esi,_app_off_fixrectab ; get Fixup Record Table Offset + mov edi,[esp+4] ; get current page number + shl edi,12 + add edi,[ebp+ebx+8] ; address of page target to fix in mem + add ecx,esi + call apply_fixups ; patch target with fixup data +@@2: pop edx eax + add edx,4 + inc eax + cmp eax,[ebp+ebx+0] + jb @@1 + ret + + + +;============================================================================= + Align 4 +apply_fixups: +@@0: call show_progress + inc _relocated_fixups + push ecx edi + mov _err_code,4005h ; "unrecognized fixup data" + mov cx,[esi+0] ; get SRC/FLAGS + movsx edx,word ptr [esi+2] ; get SRCOFF + movzx eax,word ptr [esi+4] ; get OBJNUM + add edi,edx ; calculate dest addr to be fixed + test cx,0F20h ; SrcLists/Imports not supported + jnz file_errorm ; jump if one of these + test cx,4000h ; test if 16bit object number + jnz @@1 ; if yes, jump + mov ah,0 + dec esi +@@1: add esi,6 + dec eax ; Object Number - 1 + shl eax,4 + mov edx,_app_tmp_addr1 + sub edx,eax + jc file_errorm + mov _app_tmp_addr2,edx + mov edx,[ebp+edx+8] ; EDX = Destination Object Address + mov al,cl + and al,0Fh + cmp al,02h ; check if 16bit Selector + jz @@3 ; if yes, jump + cmp al,08h + ja file_errorm + mov eax,[esi] + test cx,1000h ; check for Alias flag + jnz @@2 ; if not, jump + movzx eax,ax + sub esi,2 +@@2: add esi,4 +@@3: push esi + mov esi,ecx + and esi,0Fh + lea esi,[esi*4] + mov _err_code,4006h ; "16bit fixup overflow" + call fix_tab[esi] + pop esi +@@5: pop edi ecx + cmp esi,ecx + jb @@0 + ret + + +; +; EAX = Data +; EDX = Address of Object +; EDI = Address to Fixup +; EBP:EBX = Ptr to Current Object Table +;----------------------------------------------------------------------------- +fix_byte: + call mark_object + mov eax,_dummy_fill ;** dummy fill + mov [edi+0],al + call patch_it8 + ret +fix_16off: + call mark_object + mov eax,_dummy_fill ;** dummy fill + mov [edi+0],ax + call patch_it16 + ret +fix_32off: + call mark_object + add eax,edx + mov eax,_dummy_fill ;** dummy fill + mov [edi+0],eax + call patch_it32 + ret +fix_32selfrel: + call mark_object + add eax,edx + lea ecx,[edi+4] + sub eax,ecx + test word ptr [ebp+ebx+12],2000h + jnz @@1 + lea ecx,[eax+8002h] + shr ecx,16 + jnz file_errorm + mov eax,_dummy_fill ;** dummy fill + mov [edi+0],ax + call patch_it16 + ret +@@1: mov eax,_dummy_fill ;** dummy fill + mov [edi+0],eax + call patch_it32 + ret +fix_16sel: + call mark_object + call check_range + mov edx,_dummy_fill ;** dummy fill + mov [edi+0],dx + call patch_it16 + ret +fix_1616ptr: + call mark_object + call check_range + mov eax,_dummy_fill ;** dummy fill + mov edx,_dummy_fill ;** dummy fill + mov [edi+0],ax + mov [edi+2],dx + call patch_it32 + ret +fix_1632ptr: + call mark_object + add eax,edx + mov eax,_dummy_fill ;** dummy fill + mov [edi+0],eax + call patch_it32 + call check_range + mov edx,_dummy_fill ;** dummy fill + mov [edi+4],dx + add edi,4 + call patch_it16 + ret +fix_invalid: + mov ax,4005h ; "unrecognized fixup data" + jmp file_error + +check_range: + test word ptr [ebp+ebx+12],1000h ; check if 16:16 alias requird + jnz @@1 ; if yes, jump + test cl,10h + jnz @@1 +@@0: mov ecx,_app_tmp_addr2 + mov dx,[ebp+ecx+14] ; get selector + ret +@@1: test cl,10h + jz @@0 + mov ecx,_app_tmp_addr2 + mov dx,[ebp+ecx+14] ; get selector + test eax,0FFFF0000h ; check 64K range + jnz file_errorm + ret + + + Align 4 +fix_tab label dword + dd fix_byte ; 00h + dd fix_invalid ; 01h + dd fix_16sel ; 02h + dd fix_1616ptr ; 03h + dd fix_invalid ; 04h + dd fix_16off ; 05h + dd fix_1632ptr ; 06h + dd fix_32off ; 07h + dd fix_32selfrel ; 08h + + + + + + + + +;----------------------------------------------------------------------------- +; In: ECX = size +; Out: EDI = address +; +fill_zero_pages: + pushad + mov dl,cl + shr ecx,2 + xor eax,eax + rep stosd + mov cl,dl + and cl,3 + rep stosb + popad + ret + + +;----------------------------------------------------------------------------- +; In: EAX = size +; Out: EDI = address +; +alloc_block: + xor edi,edi + test eax,eax ; if size of Object is zero + jz @@null ; then report warning 9005 + push eax ebx esi + mov _err_code,4003h ; "not enough DPMI mem" + mov ebx,eax + mov ax,0FF91h ; allocate DPMI memory + int 21h + mov _app_tmp_addr1,esi + mov edi,ebx + pop esi ebx eax + jc file_errorm ; if failed, error +@@null: ret + + + + + + + + +;----------------------------------------------------------------------------- +create_selector: + push ebx edx + xor eax,eax + mov [esp+2],ax ; store selector in high word of EDX + pop edx + mov _app_buf_allocbase[ecx*4],edi + mov ebx,_app_tmp_addr1 + mov _app_buf_allochandle[ecx*4],ebx + pop ebx + ret + + +preload_fixups: + mov ebx,_app_siz_fixrecstab ; allocate memory for fixups + mov ax,0FF91h + int 21h + mov ax,4004h + jc file_error ; if not enough memory, error + mov _app_buf_fixrecstab,esi + mov _err_code,3002h ; "error in app file" + mov edx,_app_off_fixpagetab ; move file ptr to fixups + call seek_from_start + mov edx,ebx + mov ecx,_app_siz_fixrecstab + call load_gs_block + mov eax,_app_off_fixrectab + mov ebx,_app_off_fixpagetab + sub eax,ebx + add eax,edx + mov _app_off_fixpagetab,edx + mov _app_off_fixrectab,eax + ret + + +unload_fixups: + mov esi,_app_buf_fixrecstab + mov ax,0FF92h + int 21h + ret + + + +;============================================================================= +open_exec: + sub esp,40h + mov __exec_handle,-1 + mov _err_code,3001h ; "could not open app exec" + mov ax,3D02h + mov edx,__filename_ptr + int 21h + jc file_errorm + mov __exec_handle,ax + mov ecx,40h + mov edx,esp + mov _err_code,3002h ; "error in app exec" + call load_fs_block + xor eax,eax + mov _err_code,3004h ; "exec format not supported" + cmp word ptr [edx],'EL' + jz @@1 + cmp word ptr [edx],'XL' + jnz file_errorm +@@1: mov __exec_start,eax + mov _app_off_datapages,0 + mov edx,eax + mov _err_code,3002h ; "error in app exec" + call seek_from_start + mov ecx,04h + mov edx,esp + call load_fs_block + mov _err_code,3004h ; "exec format not supported" + cmp word ptr [edx],'EL' + mov _app_type,0 + jz @@2 + cmp word ptr [edx],'XL' + mov _app_type,1 + jnz file_errorm +@@2: add esp,40h + ret + +close_exec: + mov bx,__exec_handle + cmp bx,-1 + jz @@1 + mov ah,3Eh + int 21h + mov __exec_handle,-1 +@@1: ret + + +free_resources: + mov ecx,_app_num_objects + jecxz @@2 +@@1: mov ax,0FF92h + mov esi,_app_buf_allochandle[ecx*4] + int 21h + loop @@1 +@@2: ret + + + +;============================================================================= +clear_struct: + mov ecx,offset @app_struct_end + mov edi,offset @app_struct_begin + sub ecx,edi + xor eax,eax + rep stosb + ret + + + + +;============================================================================= +;dpmi_error: +; movzx eax,ax +; bts eax,31 +; jmp common_exit +file_errorm: + mov ax,_err_code +file_error: + movzx eax,ax +common_exit: + mov esp,__saved_esp + mov [esp+1Ch],eax + call close_exec + popad + ret + + +;============================================================================= +seek_to_start: + pushad + xor ecx,ecx + xor edx,edx + jmp common_seek +seek_from_start: + pushad + mov ecx,edx + shr ecx,16 +common_seek: + mov bx,__exec_handle + mov ax,4200h + int 21h + jc file_errorm + popad + ret +seek_from_start@pos: + pushad + xor ecx,ecx + xor edx,edx + mov bx,__exec_handle + mov ax,4201h + int 21h + jc file_errorm + mov wptr __oldfilepos[0],ax + mov wptr __oldfilepos[2],dx + popad + jmp seek_from_start +load_fs_block: +load_gs_block: + push ebx + mov bx,__exec_handle + mov ah,3Fh + int 21h + pop ebx + jc file_errorm + ret + +mark_object: + push eax + mov eax,__current_object + inc _app_obj_seekattr[eax*4] + pop eax + ret + +patch_it32: + pushad + mov edx,edi + mov eax,__current_object + sub edx,_app_buf_allocbase[eax*4] + add edx,_app_obj_seekptr[eax*4] + call seek_from_start@pos + mov ah,40h + mov bx,__exec_handle + mov ecx,4 + mov edx,offset _dummy_fill + int 21h + jc file_errorm + mov edx,__oldfilepos + call seek_from_start + popad + ret + +patch_it16: + pushad + mov edx,edi + mov eax,__current_object + sub edx,_app_buf_allocbase[eax*4] + add edx,_app_obj_seekptr[eax*4] + call seek_from_start@pos + mov ah,40h + mov bx,__exec_handle + mov ecx,2 + mov edx,offset _dummy_fill + int 21h + jc file_errorm + mov edx,__oldfilepos + call seek_from_start + popad + ret + +patch_it8: + pushad + mov edx,edi + mov eax,__current_object + sub edx,_app_buf_allocbase[eax*4] + add edx,_app_obj_seekptr[eax*4] + call seek_from_start@pos + mov ah,40h + mov bx,__exec_handle + mov ecx,1 + mov edx,offset _dummy_fill + int 21h + jc file_errorm + mov edx,__oldfilepos + call seek_from_start + popad + ret + + +show_progress: + pushad + cmp _quiet,TRUE + jz @@done + cmp _nocount,TRUE + jz @@done + mov al,_str0 + inc al + and al,03h + mov _str0,al + jnz @@done + + mov ah,09h ; else show string1 + mov edx,offset _str1 + int 21h ; Note: nested calls (RM->PM->RM) + + mov al,_str1+1 ; ajust string + mov ah,"\" + cmp al,"-" + jz @@1 + mov ah,"|" + cmp al,"\" + jz @@1 + mov ah,"/" + cmp al,"|" + jz @@1 + mov ah,"-" + cmp al,"/" + jz @@1 + +@@1: mov _str1+1,ah +@@done: popad + ret + +.DATA +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + +_err_code dw 0 +_dummy_fill dd 0 +_relocated_fixups dd 0 + +_str0 db 0 +_str1 db '[-]',08h,08h,08h,'$' + + +.DATA? +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +@app_struct_begin label byte +_app_type db ? +_app_load db ? +_app_tmp_addr1 dd ? +_app_tmp_addr2 dd ? +_app_num_objects dd ? +_app_off_objects dd ? + +_app_off_objpagetab dd ? +_app_off_fixpagetab dd ? +_app_off_fixrectab dd ? +_app_off_datapages dd ? +_app_off_pageshift dd ? +_app_siz_fixrecstab dd ? +_app_siz_lastpage dd ? +_app_buf_fixrecstab dd ? + +_app_cur_object dd ? + +_app_buf_allocbase dd APP_MAXOBJECTS dup(?) +_app_buf_allochandle dd APP_MAXOBJECTS dup(?) + +_app_obj_seekptr dd APP_MAXOBJECTS dup(?) +_app_obj_seeksize dd APP_MAXOBJECTS dup(?) +_app_obj_seekattr dd APP_MAXOBJECTS dup(?) +@app_struct_end label byte + +;----------------------------------------------------------------------------- +__filename_ptr dd ? +__structure_ptr dd ? + +__current_object dd ? + +__oldfilepos dd ? +__exec_handle dw ? +__exec_start dd ? +__saved_esp dd ? +__saved_ss dw ? +__loader_esp dd ? + + + +end + diff -uNr a/dos32a/src/ss/iface.c b/dos32a/src/ss/iface.c --- a/dos32a/src/ss/iface.c false +++ b/dos32a/src/ss/iface.c 4ee9764af5a0e2db23da67677a71a952212adb6b948f2e624da9a12e218240aea855fedeeff3c2215e20c9215b0ea98ff469462cf87dfae131d0382aacfd00fa @@ -0,0 +1,179 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +void CloseAllWindows() +{ + int n; + for(n=0; n<16; n++) CloseWindow(); +} + +void Print_At(int y, int x, char *format, ...) +{ + va_list arglist; + char buffer[256]; + SetPos(y,x); + va_start(arglist,format); + vsprintf(buffer,format,arglist); + Prints(buffer); + va_end(arglist); +} + +void Print(char *format, ...) +{ + va_list arglist; + char buffer[256]; + va_start(arglist,format); + vsprintf(buffer,format,arglist); + Prints(buffer); + va_end(arglist); +} + + +unsigned long Input(int y, int x, int l, unsigned long old) +{ + int n; + char c; + char buf[80]; + + Print_At(y,x-1,"<"); + Print_At(y,x+l,">"); + for(n=0; n0) + { + Print_At(y,x+n,"."); + n--; + goto l0; + } else goto l0; + } + buf[n]=c; + Print_At(y,x+n,"%c",c); + } + +l1: buf[n]=0; + + Print_At(y,x-1," "); + Print_At(y,x+l," "); + for(n=0; n"); + for(n=0; n8) m=0; x=xx; strcpy(buf,defbuf[m]); goto l8; } + if(keycode==DOWN) { m--; if(m<0) m=8; x=xx; strcpy(buf,defbuf[m]); goto l8; } + } while(c<0x20); + + if(c==0x08) + { + if(n>0) + { + Print_At(y,x+n,"."); + n--; + goto l0; + } else goto l0; + } + buf[n]=c; + Print_At(y,x+n,"%c",c); + } + +l1: buf[n]=0; + + Print_At(y,x-1," "); + Print_At(y,x+l," "); + for(n=0; n [config.d32 | command] [option]\n\n", errstr); + printf("Commands:\n"); + printf("---------\n"); + printf("/I or /INFO Write DOS/32A Configuration to console\n"); + printf("/L or /LOCK Lock Configuration in file\n"); + printf("/U or /UNLOCK Unlock Configuration in file\n\n"); + printf("Options:\n"); + printf("--------\n"); + printf("/Q or /QUIET Quiet mode (partially disables console output)\n"); + printf("/S or /SILENT Silent mode (totally disables console output)\n"); + printf("/H or /? This help\n"); + exit(1); + } + if( stricmp(argv[1],"/h")==0 || + stricmp(argv[1],"-h")==0 || + stricmp(argv[1],"-?")==0) goto l2; + + strcpy(buf,argv[1]); + n=ReadHeader(buf,&id32); + if(n==1) + { + strcat(buf,".exe"); + n=ReadHeader(buf, &id32); + } + if(n==1) { printf("%s cannot open file \"%s\"\n", errstr, argv[1]); exit(1); } + if(n==2) { printf("%s cannot read from file \"%s\"\n", errstr, argv[1]); exit(1); } + if(n==3) { printf("%s unsupported executable format in file \"%s\"\n", errstr, argv[1]); exit(1); } + if(id32.id!='23DI') { printf("%s \"%s\" is not a DOS/32A executable\n", errstr, argv[1]); exit(1); } + id32_old=id32; + + if(argc>2) + { + if( stricmp(argv[2],"-lock")==0 || + stricmp(argv[2],"/lock")==0 || + stricmp(argv[2],"-l")==0 || + stricmp(argv[2],"/l")==0) + { + id32.dos32a_misc2=((id32.dos32a_misc2&0x3F)|0x40); + if(WriteHeader(&id32)==0) if(!silent) printf("SS/32A: Configuration has been successfully locked!\n"); + else printf("SS/32A: Could not lock configuration!\n"); + CloseFile(); + exit(0); + } + else + if( stricmp(argv[2],"-unlock")==0 || + stricmp(argv[2],"/unlock")==0 || + stricmp(argv[2],"-u")==0 || + stricmp(argv[2],"/u")==0) + { + id32.dos32a_misc2=((id32.dos32a_misc2&0x3F)&0xBF); + if(WriteHeader(&id32)==0) if(!silent) printf("SS/32A: Configuration has been successfully unlocked!\n"); + else printf("SS/32A: Could not unlock configuration!\n"); + CloseFile(); + exit(0); + } + else + if( stricmp(argv[2],"-info")==0 || + stricmp(argv[2],"/info")==0 || + stricmp(argv[2],"-i")==0 || + stricmp(argv[2],"/i")==0) + { + ShowHeaderInfo(); + CloseFile(); + exit(0); + } + if((id32.dos32a_misc2&0x40)==0x40) + { + printf("SS/32A: Configuration in file \"%s\" is locked!\n",buf); + exit(0); + } + + + n=open(argv[2],O_RDONLY | O_BINARY); + if(n==-1) + { + strcpy(buf2,argv[2]); + strcat(buf2,".d32"); + n=open(buf2,O_RDONLY | O_BINARY); + if(n==-1) + { + envname=getenv("DOS32A"); + if(envname!=NULL) + { + ptr=strchr(envname,' '); + if(ptr==NULL) ptr=strchr(envname,0); + memset(envbuf,0,256); + strncpy(envbuf,envname,(dword)ptr-(dword)envname); + strcat(envbuf,"\\D32\\"); strcat(envbuf,buf2); + n=open(envbuf,O_RDWR | O_BINARY); + } + } + } + if(n!=-1) + { + read(n,&id32,24); + close(n); + if(id32.id!='23DI') { printf("%s \"%s\" is not a DOS/32A configuration file\n", errstr, argv[2]); exit(1); } + id32.dos32a_misc2=((id32.dos32a_misc2&0x3F) | (id32_old.dos32a_misc2&0xC0)); + if(WriteHeader(&id32)!=0) { printf("%s could not configure file \"%s\"\n", errstr, buf); exit(1); } + CloseFile(); + if(!silent) printf("SS/32A: File \"%s\" has been successfully configured\n",buf); + exit(0); + } + else + { + printf("%s cannot open configuration file \"%s\"\n", errstr, argv[2]); + exit(1); + } + } + file_type=GetFileType(); + extn_type=GetExtenderType(); +} + + + + +/****************************************************************************/ +void ShowCopyright(int argc, char *argv[]) +{ + char buf[80]; + DrawBackground(); + SetColor(YELLOW); + SetBackColor(BLUE); + Print_At(0,25,"þþþ Configuration Utility þþþ"); + SetColor(LIGHTBLUE); + Print_At(0,1,"DOS/32A Extender"); + Print_At(0,66,"Version %s",version); + Print_At(24,21,"Copyright (C) 1996-2006 by Narech K."); + + strcpy(buf,argv[1]); + strupr(buf); + Print_At(24,14,"³"); + Print_At(24,64,"³"); + SetColor(LIGHTWHITE); + Print_At(24,1,"%.13s",buf); + +} + +void ShowHeaderInfo() +{ + printf("DOS/32A Header Info\n"); + printf("----------------------------\n"); + printf("Header signature: %.4s\n",&id32.id); + printf("Kernel misc. byte: 0x%02X\n",id32.kernel_misc); + printf("Kernel PageTables #: 0x%02X\n",id32.kernel_pagetables); + printf("Kernel PhysTables #: 0x%02X\n",id32.kernel_phystables); + printf("Kernel Callbacks #: 0x%02X\n",id32.kernel_callbacks); + printf("Kernel Selectors #: 0x%04X\n",id32.kernel_selectors); + printf("Kernel RM stacks #: 0x%02X\n",id32.kernel_rmstacks); + printf("Kernel PM stacks #: 0x%02X\n",id32.kernel_pmstacks); + printf("Kernel RM stack size: 0x%04X\n",id32.kernel_rmstacklen); + printf("Kernel PM stack size: 0x%04X\n",id32.kernel_pmstacklen); + printf("Kernel max. ext. mem: 0x%08X\n",id32.kernel_maxextmem); + printf("DOS/32A misc. byte: 0x%02X\n",id32.dos32a_misc); + printf("DOS/32A 2nd misc. byte: 0x%02X\n",id32.dos32a_misc2); + printf("DOS/32A low buf. size: 0x%04X\n",id32.dos32a_lowbufsize); + printf("DOS/32A version #: 0x%04X\n",id32.dos32a_version); +/* + if(id32.dos32a_version>=0x0700) + { + printf("DOS/32A build name: %s\n",id32.dos32a_buildname); + printf("DOS/32A build version: %s\n",id32.dos32a_buildvers); + printf("DOS/32A copyright note: %s\n",id32.dos32a_copyright1); + printf(" %s\n",id32.dos32a_copyright2); + printf("DOS/32A build date: %s\n",id32.dos32a_builddate); + printf("DOS/32A build time: %s\n",id32.dos32a_buildtime); + } +*/ +} + +void CheckIfLocked() +{ + if((id32.dos32a_misc2&0x40)==0x40) + { + SetColor(LIGHTWHITE); + SetBackColor(RED); + OpenWindow(10,24,5,32); + SetColor(YELLOW); + Print_At(11,28,"Configuration is Locked!"); + SetColor(BLUE); + SetBackColor(WHITE); + SetBlink(ON); + Print_At(13,27," Press any key to exit... "); + SetBlink(OFF); + GetKey(); + CloseAllWindows(); + VideoReset(); + exit(0); + } +} + +void CheckVersion() +{ + if(id32.dos32a_version==0) + return; + if(id32.dos32a_version!=version2) + { + SetColor(LIGHTWHITE); + SetBackColor(RED); + OpenWindow(10,18,8,44); + SetColor(LIGHTWHITE); + Print_At(11,20,"WARNING:"); + SetColor(YELLOW); + Print_At(11,29,"DOS Extender's version does not"); + Print_At(12,20,"match the version of the Setup Program!!"); + SetColor(BLUE); + SetBackColor(WHITE); + SetBlink(ON); + Print_At(15,27," Press any key to exit... "); + SetBlink(OFF); + GetKey(); + CloseWindow(); + DiscardExit(); + } +} + +int CheckIfModified() +{ + if( id32.id!=id32_old.id || + id32.kernel_misc!=id32_old.kernel_misc || + id32.kernel_pagetables!=id32_old.kernel_pagetables || + id32.kernel_phystables!=id32_old.kernel_phystables || + id32.kernel_callbacks!=id32_old.kernel_callbacks || + id32.kernel_selectors!=id32_old.kernel_selectors || + id32.kernel_rmstacks!=id32_old.kernel_rmstacks || + id32.kernel_pmstacks!=id32_old.kernel_pmstacks || + id32.kernel_rmstacklen!=id32_old.kernel_rmstacklen || + id32.kernel_pmstacklen!=id32_old.kernel_pmstacklen || + id32.kernel_maxextmem!=id32_old.kernel_maxextmem || + id32.dos32a_misc!=id32_old.dos32a_misc || + (id32.dos32a_misc2&0x3F)!=(id32_old.dos32a_misc2&0x3F) || + id32.dos32a_lowbufsize!=id32_old.dos32a_lowbufsize || + id32.dos32a_version!=id32_old.dos32a_version + ) modified_flag=TRUE; + else modified_flag=FALSE; + return(modified_flag); +} + +void ShowModified() +{ + SetColor(LIGHTBLUE); + SetBackColor(BLUE); + if(CheckIfModified()==TRUE) Print_At(24,0,"*"); + else Print_At(24,0," "); +} + + +/****************************************************************************/ +void AskExit() +{ + if(CheckIfModified()==TRUE) + { + SetColor(LIGHTWHITE); + SetBackColor(RED); + OpenWindow(10,24,5,32); + SetColor(YELLOW); + Print_At(11,29,"Apply Changes on Exit?"); + SetColor(BLUE); + SetBackColor(WHITE); + SetBlink(ON); + Print_At(13,32," "); + Print_At(13,42," "); + SetBlink(OFF); + GetKey(); + } + CloseAllWindows(); + VideoReset(); + if(keycode!=ESC && keychar!='n' && keychar!='N') + if(WriteHeader(&id32)!=0) + { + printf("%s could not write to file\n" ,errstr); + exit(1); + } + CloseFile(); + exit(0); +} + +void ApplyExit() +{ + CloseAllWindows(); + VideoReset(); + if(WriteHeader(&id32)!=0) + { + printf("%s could not write to file\n", errstr); + exit(1); + } + CloseFile(); + exit(0); +} + +void DiscardExit() +{ + CloseAllWindows(); + VideoReset(); + CloseFile(); + exit(0); +} + +void RestoreDefaults() +{ + id32.kernel_misc= 0x3F; + id32.kernel_pagetables= 64; + id32.kernel_phystables= 2; + id32.kernel_callbacks= 16; + id32.kernel_selectors= 256; + id32.kernel_rmstacks= 8; + id32.kernel_pmstacks= 8; + id32.kernel_rmstacklen= 0x20; + id32.kernel_pmstacklen= 0x20; + id32.kernel_maxextmem= 0xFFFFFFFF; + id32.dos32a_misc= 0x3F; + id32.dos32a_misc2= (id32.dos32a_misc2 & 0xC0) | 0x09; + id32.dos32a_lowbufsize= 0x0200; +} + + +void ValidateConfig() +{ + id32.kernel_misc = (id32.kernel_misc & 0xBF); + if(id32.kernel_maxextmem>=0x7FFFFFFF) id32.kernel_maxextmem=0xFFFFFFFF; + id32.dos32a_lowbufsize = (id32.dos32a_lowbufsize & 0x0FFF); + ShowModified(); +} + + +void ShowMemory() +{ + memtotal=( + (mem_dos32a)+ + (0x0400)+ // RM INT table + (0x0800)+ // PM INT table + (id32.dos32a_lowbufsize*16)+ // DOS buffer + (id32.kernel_selectors*8)+ // Selectors + (id32.kernel_callbacks*25)+ // Callbacks + (id32.kernel_rmstacks*id32.kernel_rmstacklen*16)+ + (id32.kernel_pmstacks*id32.kernel_pmstacklen*16) + )/1024; + + SetColor(LIGHTWHITE); + SetBackColor(CYAN); + Print_At(10,24," "); + if(memtotal<1024) + Print_At(10,24,"%3dKB",memtotal); + else + { + SetColor(RED); + Print_At(10,24," >1MB"); + SetColor(LIGHTWHITE); + } + + if(id32.dos32a_version==0) + Print_At(9,26,"N/A"); + else + { + Print_At(9,25,"%d.%02d",(id32.dos32a_version&0xFF00)>>8,id32.dos32a_version&0x00FF); + if((id32.dos32a_misc2&0x80)!=0x80) + /* Professional */ + //Print_At(9,21,"Pro"); + ; + else + /* Beta */ + Print_At(9,20,"Beta"); + } +} + +void CreateConfig() +{ + int n; + char *name; + char *ptr; + char buf[80]; + + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(10,10,3,60); + SetColor(YELLOW); + Print_At(10,13," Create Predefined Configuration "); + SetColor(LIGHTWHITE); + Print_At(11,12,"Enter file name:"); + name=InputString(11,30,37,cfgfilename); + if(name!=NULL && name[0]!=0) + { + strcpy(buf,name); + ptr=(char *)strchr(buf,'.'); + if(ptr!=NULL) strset(ptr,0); + strcpy(cfgfilename,buf); + strcat(buf,".D32"); + n=open(buf,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU); + if(n!=-1) + { + write(n,&id32,24); + close(n); + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + strupr(buf); + for(n=0; n<13; n++) + { + SetPos(24,66+n); + PrintC(' '); + } + Print_At(24,66,"%.13s",buf); + } + else DiskError(); + } + CloseWindow(); +} + +void RestoreConfig() +{ + int n; + char *envname; + char envbuf[256]; + char *name; + char *ptr; + char buf[80]; + + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(10,10,3,60); + SetColor(YELLOW); + Print_At(10,13," Restore Predefined Configuration "); + SetColor(LIGHTWHITE); + Print_At(11,12,"Enter file name:"); + + name=InputString(11,30,37,cfgfilename); + if(name!=NULL && name[0]!=0) + { + strcpy(buf,name); + ptr=(char *)strchr(buf,'.'); + if(ptr!=NULL) strset(ptr,0); + strcpy(cfgfilename,buf); + strcat(buf,".d32"); + n=open(buf,O_RDONLY | O_BINARY); + if(n==-1) + { + envname=getenv("DOS32A"); + if(envname!=NULL) + { + ptr=strchr(envname,' '); + if(ptr==NULL) ptr=strchr(envname,0); + memset(envbuf,0,256); + strncpy(envbuf,envname,(dword)ptr-(dword)envname); + strcat(envbuf,"\\D32\\"); strcat(envbuf,buf); + n=open(envbuf,O_RDWR | O_BINARY); + } + } + if(n!=-1) + { + read(n,&id32,24); + close(n); + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + strupr(buf); + for(n=0; n<13; n++) + { + SetPos(24,66+n); + PrintC(' '); + } + Print_At(24,66,"%.13s",buf); + } + else DiskError(); + } + ValidateConfig(); + CloseWindow(); + if(mainmenu_sel==1) ShowBannerStatus(); + +} + +void ClearConfigName() +{ + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + Print_At(24,66," "); +} + + +void ShowBannerStatus() +{ + if((id32.dos32a_misc2&0x80)==0) + { + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + Print_At(12,10,"10) Show Copyright Banner at Startup .................."); + } + else + { + SetColor(WHITE); + SetBackColor(BLUE); + Print_At(12,10,"10) Show Copyright Banner at Startup .................."); + SetColor(LIGHTWHITE); + } +} + +void DiskError() +{ + SetColor(LIGHTWHITE); + SetBackColor(RED); + OpenWindow(10,24,5,32); + SetColor(YELLOW); + Print_At(11,28,"Error Reading/Writing!"); + SetColor(BLUE); + SetBackColor(WHITE); + SetBlink(ON); + Print_At(13,26," Press a key to continue... "); + SetBlink(OFF); + GetKey(); + CloseWindow(); + keychar=keycode=0; +} + + + + + + +/****************************************************************************/ +void ShowSysInfo() +{ + unsigned long n; + char *systab[6]={" Clean"," XMS"," VCPI"," DPMI","WinDPMI","Unknown" }; + char *cputab[6]={ "80386","80486","80586","80686","80786","80886" }; + char *filetab[5]={ " N/A", "\"LE\"", "\"LX\"", "\"LC\"", "\"PE\"" }; + + SetColor(LIGHTWHITE); + SetBackColor(CYAN); + OpenWindow(2,1,10,30); + SetColor(LIGHTGREEN); + Print_At(2,4," General Information "); + + SetColor(LIGHTBLUE); + Print_At( 3,3,"CPU Type:"); + Print_At( 4,3,"System Type:"); + Print_At( 5,3,"Free DOS Memory:"); + Print_At( 6,3,"Free High Memory:"); + Print_At( 8,3,"Bound File Type:"); + if(extn_type==2) Print_At( 9,3,"STUB/32C Version:"); + else Print_At( 9,3,"DOS/32A Version:"); + Print_At(10,3,"DOS Memory Required:"); + SetColor(LIGHTWHITE); + + n=get_cpu_type(); + if(n-3 > 5) + Print_At(3,24,"?????"); + else + Print_At(3,24,cputab[n-3]); + + systype=n=get_sys_type(); + Print_At(4,22,systab[n]); + + n=get_lomem_size()+get_dosmem_used(mem_dos32a); + Print_At(5,21,"%6dKB",(n/1024)+1); + + n=get_himem_size(); + Print_At(6,21,"%6dKB",n/1024); + + Print_At(8,25,filetab[file_type]); + +} + +void ShowEnvInfo() +{ + char *str; + SetColor(LIGHTWHITE); + SetBackColor(WHITE); + OpenWindow(14,1,3,76); + SetColor(LIGHTGREEN); + Print_At(14,4," DOS/32A Environment String "); + SetColor(LIGHTWHITE); + str=getenv("DOS32A"); + if(str==NULL) Print_At(15,3,"(Not Defined)"); + else Print_At(15,3,"DOS32A=%.74s",str); +} + +void ShowHelp(int menu, int header) +{ + char c; + SetColor(LIGHTWHITE); + SetBackColor(GREEN); + DrawWindow(18,1,5,76); + SetColor(LIGHTGREEN); + Print_At(18,4," Quick Help "); + SetColor(LIGHTWHITE); + + SetPos(19,3); + if(menu==0) PrintHelp(mainhlp[header]); + if(menu==1) PrintHelp(kernelhlp[header]); + if(menu==2) PrintHelp(extenderhlp[header]); +} + + + +void ShowMemReq() +{ + int n,m; + + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(6,14,8,52); + SetColor(YELLOW); + Print_At(6,17," DOS/32A Memory Requirements "); + SetColor(LIGHTWHITE); + + + Print_At( 8,16,"Clean System:"); + Print_At( 9,16,"XMS System: "); + Print_At(10,16,"VCPI System: "); + Print_At(11,16,"DPMI System: "); + +/*** Clean ***/ +/*** XMS ***/ + n= ( + (mem_dos32a)+ + (0x0400)+ // RM INT table + (0x0800)+ // PM INT table + (id32.dos32a_lowbufsize*16)+ // DOS buffer + (id32.kernel_selectors*8)+ // Selectors + (id32.kernel_callbacks*25)+ // Callbacks + (id32.kernel_rmstacks*id32.kernel_rmstacklen*16)+ + (id32.kernel_pmstacks*id32.kernel_pmstacklen*16) + )/1024; + Print_At( 8,30,"%3dKB",n); + Print_At( 9,30,"%3dKB",n); + +/*** VCPI ***/ + m= get_total_mem()/1024; + if(id32.kernel_pagetables=3) Print_At(11,40,"(approximately)"); + else Print_At(11,40,"(advisory info only)"); + + + GetKey(); + CloseWindow(); + keychar=keycode=0; + +} + +#include "menus.c" +#include "iface.c" + diff -uNr a/dos32a/src/ss/main.h b/dos32a/src/ss/main.h --- a/dos32a/src/ss/main.h false +++ b/dos32a/src/ss/main.h ef349ba2195e0c9f6432c9f6bd1098e21e21af6d391dc7c33466a2dd8a5fb10cd200ca37f60933fa8ef4c6e20a6639fcd9d97852d81ce1548f87553467b18175 @@ -0,0 +1,401 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define WHITE 7 +#define LIGHTGREEN 10 +#define LIGHTBLUE 11 +#define LIGHTRED 12 +#define YELLOW 14 +#define LIGHTWHITE 15 + +#define ESC 0x01 +#define ALT_X 0x2D +#define TAB 0x0F +#define ENTER 0x1C +#define HOME 0x47 +#define END 0x4F +#define PAGEUP 0x49 +#define PAGEDOWN 0x51 +#define SPACE 0x39 +#define UP 0x48 +#define DOWN 0x50 +#define LEFT 0x4B +#define RIGHT 0x4D +#define F1 0x3B +#define F2 0x3C +#define F3 0x3D +#define F4 0x3E +#define F5 0x3F +#define F6 0x40 +#define F7 0x41 +#define F8 0x42 +#define F9 0x43 +#define F10 0x44 + +void Print(char *, ...); +void Print_At(int, int, char *, ...); +void CloseAllWindows(void); +void ShowSysInfo(void); +void ShowEnvInfo(void); +void ShowHelp(int, int); +void ShowCopyright(int, char *[]); +void AskExit(void); +void ApplyExit(void); +void DiscardExit(void); +char *InputString(int, int, int, char *); + +void ShowKernelMenu(void); +void ShowKernelConfig(void); +void SelectKernelMenu(void); + +void ShowExtenderMemu(void); +void ShowExtenderConfig(void); +void SelectExtenderMenu(void); + +void ShowMainMenu(void); +void SelectMainMenu(void); +unsigned long Input(int, int, int, unsigned long); +void ShowMemory(void); + + +extern void VideoInit(void); +extern void VideoReset(void); +extern void DrawBackground(void); +extern void SetPos(char, char); +extern void SetColor(char); +extern void SetBackColor(char); +extern void SetBlink(char); +extern void Prints(char *); +extern void PrintHelp(char *); +extern short int GetKey(void); +extern void OpenWindow(char, char, char, char); +extern void DrawWindow(char, char, char, char); +extern void CloseWindow(void); +extern void ShowCursor(char, char, char); +extern dword get_cpu_type(void); +extern dword get_fpu_type(void); +extern dword get_sys_type(void); +extern dword get_himem_size(void); +extern dword get_lomem_size(void); +extern dword test_cpu(void); +extern dword get_dosmem_used(int); +extern dword get_total_mem(void); +extern dword get_dpmi_bufsize(void); +extern int ReadHeader(char *, void *); +extern int WriteHeader(void *); +extern void CloseFile(void); +extern int GetFileType(void); +extern int GetExtenderType(void); + +extern char keychar; +extern char keycode; + + +/************** Variables ***************************************************/ + + struct header { + dword id; + byte kernel_misc; + byte kernel_pagetables; + byte kernel_phystables; + byte kernel_callbacks; + word kernel_selectors; + byte kernel_rmstacks; + byte kernel_pmstacks; + word kernel_rmstacklen; + word kernel_pmstacklen; + dword kernel_maxextmem; + byte dos32a_misc; + byte dos32a_misc2; + word dos32a_lowbufsize; + word dos32a_version; + word dos32a_reserved; + + char dos32a_buildname[0x09]; + char dos32a_buildvers[0x10]; + char dos32a_copyright1[0x24]; + char dos32a_copyright2[0x15]; + char dos32a_builddate[0x09]; + char dos32a_buildtime[0x09]; + }; + + char* version = "9.1.2"; + int version2 = 0x090C; + int changed = 0; + int hexmode = 0; + + char startdir[80]; + + char cfgfilename[80]; + + int systype = 0; + int memtotal = 0; + int mem_dos32a = 0x75D0; + int mem_kernel = 0x27A0; + int file_type = 0; + int extn_type = 0; + + int silent = FALSE; + int modified_flag = FALSE; + + struct header id32; + struct header id32_old; + + int mainmenu_sel=0; + int mainmenu_xpos[7] = { 36,36,36,36, 36,36,36 }; + int mainmenu_ypos[7] = { 3, 4, 5, 6, 8, 9, 10 }; + int mainmenu_xlen[7] = { 40,40,40,40, 40,40,40 }; + + int kernelmenu_sel=0; + int kernelmenu_xpos[16] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 39,39,39,39, 19 }; + int kernelmenu_ypos[16] = { 3, 4, 5, 6, 7, 8, 9, 11,12,13,14, 11,12,13,14, 15 }; + int kernelmenu_xlen[16] = { 62,62,62,62,62,62,62,28,28,28,28, 32,32,32,32, 30 }; + + int extendermenu_sel=0; + int extendermenu_xpos[13] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18 }; + int extendermenu_ypos[13] = { 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14, 15 }; + int extendermenu_xlen[13] = { 62,62,62,62,62,62,62,62,62,62,62,62, 35 }; + + char* errstr="SS/32A fatal:"; + + + char* mainhlp[]={ + +"Configure DOS/32 Advanced built-in DPMI Server.", + + +"Configure DOS/32 Advanced DOS Extender.", + + +"Create that can be used for quick configuration\n\ +of your DOS/32 Advanced programs from the command line.", + + +"Restore previously created .", + + +"Discard the changes and restore old configuration.", + + +"Discard the changes you've made and Exit.", + + +"Apply the changes you've made and Exit." + +}; + + + char* kernelhlp[]={ +/* +"Controls the order of . When set to VCPI/DPMI, the\n\ +DOS Extender will try to detect, and if succeeded initialize a VCPI\n\ +server even though a DPMI host may be present in the system.", + +"Controls the order of . When set to XMS/VCPI, the\n\ +DOS Extender will whenever possible favour Clean and XMS systems before\n\ +the slower VCPI/DPMI ones.", +*/ +".", +".", + +/* +"Controls whether DOS/32 Advanced DPMI will internally handle and report\n\ +all the exceptions occured during program execution, or the program will\n\ +handle exceptions itself (no INT/EXC buffering and IRQ callbacking).", +*/ + +"When turned on, DOS/32 Advanced will use <0th PageTable> which maps first\n\ +4MB (including DOS' 640K), to map the extended memory it allocated. This\n\ +will often reduce the amount of used DOS memory by 4KB (one pagetable).", + + +"When turned on, DOS/32 Advanced will try to allocate extended memory\n\ +from both VCPI and XMS servers, making it possible to have an access to\n\ +all the memory available even when EMM386 with \"RAM nnn\" is installed.", + +/* +"Interrupts in range INT 08-0Fh can be , or .\n\ +DOS/32 Advanced is capable of trapping software INTs, issued to emulate\n\ +IRQs 0-7 (unremapped), and will do so when this option is turned on.", + + +"When turned on, DOS/32 Advanced will check, that extended memory blocks\n\ +allocated with ADPMI are not overwritten or corrupted. An error will be\n\ +reported when a program tries to write to memory it hadn't allocated.", +*/ +".", +".", + +/* +"DPMI function 0008h - requires limits greater than 1MB\n\ +to have low 12 bits set. DOS/32 Advanced allows users to manually choose\n\ +whether this check is to be done. Turn it off for DOS/4GW compatibility.", +*/ + +"When this option is turned on, DOS/32 Advanced DPMI will ignore calls to\n\ +function 0A00h with pointer in DS:ESI, thus forcing\n\ +programs to not to use DOS/4G API extensions.", + + +"The number of DOS/32 Advanced will allocate and make available\n\ +for program's use. It is not recommended to set this value below 16.", + + +"The number of DOS/32 Advanced will allocate and make available\n\ +for program's use. Note that at least 8 callbacks should be allocated to\n\ +ensure that DOS/32 Advanced itself will operate properly.", + + +"The number of that will be allocated by the DOS\n\ +Extender. Each time the protected mode program needs to call real mode\n\ +INT- or IRQ-handler, a Virtual stack will be used.", + + +"The number of that will be allocated by\n\ +DOS/32 Advanced. Whenever a real mode INT- or IRQ-handler needs to get\n\ +an access to the protected mode code, a Virtual stack will be used.", + + +"Maximum number of that will be allocated (in DOS memory)\n\ +under VCPI. Each PageTable will map 4MB of memory. Note that this is a\n\ +limit, not the actual number of pagetables that will be allocated.", + + +"Maximum number of for physical memory mapping under VCPI.\n\ +If you are sure that an application does not use physical memory mapping\n\ +feature, reset this value to zero.", + + +"The size of one in paragraphs.", + + +"The size of one in paragraphs.", + + +"Amount of that will be allocated and made available for\n\ +program's use. Values greater than 2GB will cause the DOS Extender to\n\ +allocate all the extended memory available in the machine." + +}; + + + char* extenderhlp[]={ + +"When turned off, no warnings will be displayed on the screen. Only fatal\n\ +and run-time errors will be reported to the user.", + + +"When turned on, run-time errors trapped by the DOS Extender will be\n\ +accompanied by a tone from the PC speaker. Note that no sound will be\n\ +generated on warnings and fatal errors.", + + +"When turned on, DOS/32 Advanced will save the whole (all 256 interrupt vectors) on startup and restore it on exit.", + + +"When turned on, the DOS Extender will on exit check and report all the\n\ + which had been modified (and not restored)\n\ +by a protected mode program.", + + +"Controls how application's are loaded into memory:\n\ +<#1> 16bit/32bit -> Low, High; <#2> 16bit -> Low, High 32bit -> High only\n\ +<#3> 16bit/32bit -> Low only; <#4> 16bit/32bit -> High only (as DOS/4GW)", + + +"Defines that are loaded high (into extended\n\ +memory). Can be either graph (16 bytes), or (4096 bytes). Note\n\ +that Objects loaded low (into DOS memory) are always PARAgraph aligned.", + + +"When turned on, DOS/32 Advanced will set VideoMode 03h (VideoBIOS Text\n\ +Mode) when it encounters a run-time error before writing a report on the\n\ +screen.", + + +"When this option is turned on and running under Windows (v3 and 4+), the\n\ +DOS Extender will switch the DOS Box of the Virtual Machine in which it\n\ +is currently running to .", + + +"When turned on, DOS/32 Advanced will write-protect the first 16 bytes of\n\ +memory starting at absolute address 0:0. Note that 386 debug registers\n\ +DR0-DR3 will be used to trap down writes to the memory at run-time.", + + +"This option controls whether the is to be displayed on\n\ +DOS Extender's startup.", + + +"When turned on, DOS/32 Advanced will search for \"\" string in the\n\ +environment, and if it is defined, configure itself according to it.", + + +"When this option is turned on, the DOS Extender will start in , monitoring its actions as it loads a protected mode application\n\ +and showing additional information in exception listing on exceptions.", + + +"Specifies the size of the (located in conventional\n\ +memory) which will be used by the DOS Extender when transferring data\n\ +from DOS to extended memory and back." + + +}; diff -uNr a/dos32a/src/ss/menus.c b/dos32a/src/ss/menus.c --- a/dos32a/src/ss/menus.c false +++ b/dos32a/src/ss/menus.c 18461b05c0b6a850e67b0c94ba7c63cfe386d1d27fb4ab5e042d0a7781dfb7e20e1a3970f77caa5a48c5316cba70ba1511a4d6f8f878b394d370e9cdf16f202a @@ -0,0 +1,502 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +void ShowMainMenu() +{ + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(2,35,10,42); + SetColor(YELLOW); + Print_At(2,38," Main Menu "); + SetColor(LIGHTWHITE); + + Print_At( 3,37,"F1 - Configure DOS/32A DPMI Kernel"); + Print_At( 4,37,"F2 - Configure DOS/32A DOS Extender"); + Print_At( 5,37,"F3 - Create Predefined Configuration"); + Print_At( 6,37,"F4 - Restore Predefined Configuration"); + Print_At( 8,37,"F5 - Restore Old Values"); + Print_At( 9,37,"F9 - Discard Changes and Exit"); + Print_At(10,37,"F10 - Apply Changes and Exit"); +} + + +/*--------------------------------------------------------------------------*/ +void SelectMainMenu() +{ + do { + ShowModified(); + ShowHelp(0,mainmenu_sel); + ShowCursor( mainmenu_ypos[mainmenu_sel], + mainmenu_xpos[mainmenu_sel], + mainmenu_xlen[mainmenu_sel]); + GetKey(); + ShowCursor( mainmenu_ypos[mainmenu_sel], + mainmenu_xpos[mainmenu_sel], + mainmenu_xlen[mainmenu_sel]); + + if(keycode==UP) mainmenu_sel--; + if(keycode==DOWN) mainmenu_sel++; + if(keycode==HOME) mainmenu_sel=0; + if(keycode==END) mainmenu_sel=6; + if(keycode==PAGEUP) mainmenu_sel=0; + if(keycode==PAGEDOWN) mainmenu_sel=6; + + if(keycode==F1) { mainmenu_sel=0; break; } + if(keycode==F2) { mainmenu_sel=1; break; } + if(keycode==F3) { mainmenu_sel=2; break; } + if(keycode==F4) { mainmenu_sel=3; break; } + if(keycode==F5) { mainmenu_sel=4; break; } + if(keycode==F6) { RestoreDefaults(); ClearConfigName(); ShowMemory(); } + if(keycode==F7) { ValidateConfig(); ShowMemory(); } + if(keycode==F8) { ShowMemReq(); ShowMemory(); } + if(keycode==F9) { mainmenu_sel=5; break; } + if(keycode==F10) { mainmenu_sel=6; break; } + + if(mainmenu_sel<0) mainmenu_sel=0; + if(mainmenu_sel>6) mainmenu_sel=6; + } while(keycode!=ESC && keycode!=ALT_X && keycode!=ENTER); + if(keycode==ESC || keycode==ALT_X) AskExit(); +} + + + + + +/****************************************************************************/ +void ShowKernelMenu() +{ + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(2,8,15,64); + SetColor(YELLOW); + Print_At(2,11," DPMI Kernel Configuration "); + SetColor(LIGHTWHITE); + + SetColor(WHITE); + Print_At( 3,10,"1) VCPI/DPMI Detection Order ...................."); + Print_At( 4,10,"2) XMS/VCPI Detection Order ....................."); + SetColor(LIGHTWHITE); + Print_At( 5,10,"3) VCPI SmartPage Allocation Mode ....................."); + Print_At( 6,10,"4) VCPI+XMS Allocation Scheme ........................."); + SetColor(WHITE); + Print_At( 7,10,"5) Trap and Report Emulated IRQs ......................"); + Print_At( 8,10,"6) Extended Memory Blocks Checking ...................."); + SetColor(LIGHTWHITE); + Print_At( 9,10,"7) Ignore DOS/4G API Extension Calls .................."); + Print_At(11,10,"Selectors:"); + Print_At(12,10,"Callbacks:"); + Print_At(13,10,"RMode Stacks:"); + Print_At(14,10,"PMode Stacks:"); + Print_At(11,40,"VCPI PageTables:"); + Print_At(12,40,"VCPI PhysTables:"); + Print_At(13,40,"RMode Stack Length:"); + Print_At(14,40,"PMode Stack Length:"); + Print_At(15,20,"Extended Memory: (Bytes)"); + + do + { + SelectKernelMenu(); + if(keycode!=ESC && keycode!=F1 && keycode!=F2) + switch(kernelmenu_sel) + { + case 0: id32.kernel_misc^=0x01; break; + case 1: id32.kernel_misc^=0x02; break; + case 2: id32.kernel_misc^=0x04; break; + case 3: id32.kernel_misc^=0x08; break; + case 4: id32.kernel_misc^=0x10; break; + case 5: id32.kernel_misc^=0x20; break; + case 6: id32.kernel_misc^=0x80; break; + case 7: id32.kernel_selectors=Input(11,29,6,id32.kernel_selectors); break; + case 8: id32.kernel_callbacks=Input(12,29,6,id32.kernel_callbacks); break; + case 9: id32.kernel_rmstacks=Input(13,29,6,id32.kernel_rmstacks); break; + case 10: id32.kernel_pmstacks=Input(14,29,6,id32.kernel_pmstacks); break; + case 11: id32.kernel_pagetables=Input(11,63,6,id32.kernel_pagetables); break; + case 12: id32.kernel_phystables=Input(12,63,6,id32.kernel_phystables); break; + case 13: id32.kernel_rmstacklen=Input(13,63,6,id32.kernel_rmstacklen); break; + case 14: id32.kernel_pmstacklen=Input(14,63,6,id32.kernel_pmstacklen); break; + case 15: + if(hexmode==0) id32.kernel_maxextmem=Input(15,38,10,id32.kernel_maxextmem); + else id32.kernel_maxextmem=Input(15,40,8,id32.kernel_maxextmem); + break; + } + } + while(keycode!=ESC && keycode!=F1 && keycode!=F2); + CloseWindow(); +} + + +/*--------------------------------------------------------------------------*/ +void ShowKernelConfig() +{ + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + +// if(id32.kernel_misc&0x01) Print_At(3,59," VCPI/DPMI");else Print_At(3,59," DPMI/VCPI"); + +// if(id32.kernel_misc&0x02) Print_At(4,60," XMS/VCPI");else Print_At(4,60," VCPI/XMS"); + + SetColor(WHITE); + Print_At(3,60," reserved"); + Print_At(4,60," reserved"); + SetColor(LIGHTWHITE); + + + if(id32.kernel_pagetables==0 && !(id32.kernel_misc&0x04)) { SetColor(LIGHTRED); SetBlink(1); } + if(id32.kernel_misc&0x04) Print_At(5,65,". ON");else Print_At(5,65," OFF"); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_misc&0x08) Print_At(6,65,". ON");else Print_At(6,65," OFF"); + + SetColor(WHITE); + Print_At(7,60," reserved"); + Print_At(8,60," reserved"); + SetColor(LIGHTWHITE); + + if(id32.kernel_misc&0x80) Print_At(9,65,". ON");else Print_At(9,65," OFF"); + + if(hexmode==0) + { + if(id32.kernel_selectors<16) SetColor(YELLOW); + if(id32.kernel_selectors==0) { SetColor(LIGHTRED); SetBlink(1); } + if(id32.kernel_selectors>8176) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(11,27,"%8d",id32.kernel_selectors); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_callbacks<8) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(12,27,"%8d",id32.kernel_callbacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_rmstacks<2) SetColor(YELLOW); + if(id32.kernel_rmstacks==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(13,27,"%8d",id32.kernel_rmstacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_pmstacks<2) SetColor(YELLOW); + if(id32.kernel_pmstacks==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(14,27,"%8d",id32.kernel_pmstacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_maxextmem>0x7FFFFFFF) Print_At(15,40," All"); + else if(id32.kernel_maxextmem==0) Print_At(15,40," None"); + else Print_At(15,38,"%10d",id32.kernel_maxextmem); + + if(id32.kernel_pagetables>64) SetColor(YELLOW); + if(id32.kernel_pagetables==0 && !(id32.kernel_misc&0x04)) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(11,61,"%8d",id32.kernel_pagetables); + SetColor(LIGHTWHITE); SetBlink(0); + + Print_At(12,61,"%8d",id32.kernel_phystables); + + if(id32.kernel_rmstacklen<0x10) SetColor(YELLOW); + if(id32.kernel_rmstacklen==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(13,61,"%8d",id32.kernel_rmstacklen); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_pmstacklen<0x10) SetColor(YELLOW); + if(id32.kernel_pmstacklen==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(14,61,"%8d",id32.kernel_pmstacklen); + SetColor(LIGHTWHITE); SetBlink(0); + + } + else + { + + if(id32.kernel_selectors<16) SetColor(YELLOW); + if(id32.kernel_selectors==0) { SetColor(LIGHTRED); SetBlink(1); } + if(id32.kernel_selectors>8176) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(11,27,"%7Xh",id32.kernel_selectors); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_callbacks<8) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(12,27,"%7Xh",id32.kernel_callbacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_rmstacks<2) SetColor(YELLOW); + if(id32.kernel_rmstacks==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(13,27,"%7Xh",id32.kernel_rmstacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_pmstacks<2) SetColor(YELLOW); + if(id32.kernel_pmstacks==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(14,27,"%7Xh",id32.kernel_pmstacks); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_maxextmem>0x7FFFFFFF) Print_At(15,40," All"); + else if(id32.kernel_maxextmem==0) Print_At(15,40," None"); + else Print_At(15,38," %8Xh",id32.kernel_maxextmem); + + if(id32.kernel_pagetables>64) SetColor(YELLOW); + if(id32.kernel_pagetables==0 && !(id32.kernel_misc&0x04)) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(11,61,"%7Xh",id32.kernel_pagetables); + SetColor(LIGHTWHITE); SetBlink(0); + + Print_At(12,61,"%7Xh",id32.kernel_phystables); + + if(id32.kernel_rmstacklen<0x10) SetColor(YELLOW); + if(id32.kernel_rmstacklen==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(13,61,"%7Xh",id32.kernel_rmstacklen); + SetColor(LIGHTWHITE); SetBlink(0); + + if(id32.kernel_pmstacklen<0x10) SetColor(YELLOW); + if(id32.kernel_pmstacklen==0) { SetColor(LIGHTRED); SetBlink(1); } + Print_At(14,61,"%7Xh",id32.kernel_pmstacklen); + SetColor(LIGHTWHITE); SetBlink(0); + } + SetColor(LIGHTBLUE); + if((id32.kernel_misc&0x01)!=(id32_old.kernel_misc&0x01)) Print_At(3,69,"*");else Print_At(3,69," "); + if((id32.kernel_misc&0x02)!=(id32_old.kernel_misc&0x02)) Print_At(4,69,"*");else Print_At(4,69," "); + if((id32.kernel_misc&0x04)!=(id32_old.kernel_misc&0x04)) Print_At(5,69,"*");else Print_At(5,69," "); + if((id32.kernel_misc&0x08)!=(id32_old.kernel_misc&0x08)) Print_At(6,69,"*");else Print_At(6,69," "); + if((id32.kernel_misc&0x10)!=(id32_old.kernel_misc&0x10)) Print_At(7,69,"*");else Print_At(7,69," "); + if((id32.kernel_misc&0x20)!=(id32_old.kernel_misc&0x20)) Print_At(8,69,"*");else Print_At(8,69," "); + if((id32.kernel_misc&0x80)!=(id32_old.kernel_misc&0x80)) Print_At(9,69,"*");else Print_At(9,69," "); + if((id32.kernel_selectors)!=(id32_old.kernel_selectors)) Print_At(11,35,"*");else Print_At(11,35," "); + if((id32.kernel_callbacks)!=(id32_old.kernel_callbacks)) Print_At(12,35,"*");else Print_At(12,35," "); + if((id32.kernel_rmstacks)!=(id32_old.kernel_rmstacks)) Print_At(13,35,"*");else Print_At(13,35," "); + if((id32.kernel_pmstacks)!=(id32_old.kernel_pmstacks)) Print_At(14,35,"*");else Print_At(14,35," "); + if((id32.kernel_pagetables)!=(id32_old.kernel_pagetables)) Print_At(11,69,"*");else Print_At(11,69," "); + if((id32.kernel_phystables)!=(id32_old.kernel_phystables)) Print_At(12,69,"*");else Print_At(12,69," "); + if((id32.kernel_rmstacklen)!=(id32_old.kernel_rmstacklen)) Print_At(13,69,"*");else Print_At(13,69," "); + if((id32.kernel_pmstacklen)!=(id32_old.kernel_pmstacklen)) Print_At(14,69,"*");else Print_At(14,69," "); + if((id32.kernel_maxextmem)!=(id32_old.kernel_maxextmem)) Print_At(15,48,"*");else Print_At(15,48," "); + SetColor(LIGHTWHITE); +} + + +/*--------------------------------------------------------------------------*/ +void SelectKernelMenu() +{ + do { + ShowModified(); + ShowHelp(1,kernelmenu_sel); + ShowKernelConfig(); + ShowCursor( kernelmenu_ypos[kernelmenu_sel], + kernelmenu_xpos[kernelmenu_sel], + kernelmenu_xlen[kernelmenu_sel]); + GetKey(); + ShowCursor( kernelmenu_ypos[kernelmenu_sel], + kernelmenu_xpos[kernelmenu_sel], + kernelmenu_xlen[kernelmenu_sel]); +// CloseWindow(); + + if(keychar>'0' && keychar<'8') kernelmenu_sel=keychar-'1'; + if(keycode==F3) CreateConfig(); + if(keycode==F4) RestoreConfig(); + if(keycode==F5) { id32=id32_old; ClearConfigName(); } + if(keycode==F6) { RestoreDefaults(); ClearConfigName(); } + if(keycode==F8) ShowMemReq(); + if(keycode==UP) kernelmenu_sel--; + if(keycode==DOWN) kernelmenu_sel++; + if(keycode==HOME) kernelmenu_sel=0; + if(keycode==END) kernelmenu_sel=16; + if(keycode==PAGEUP) + if(kernelmenu_sel>11) kernelmenu_sel=11; + else if(kernelmenu_sel>7) kernelmenu_sel=7; + else if(kernelmenu_sel>0) kernelmenu_sel=0; + if(keycode==PAGEDOWN) + if(kernelmenu_sel<7) kernelmenu_sel=7; + else if(kernelmenu_sel<11) kernelmenu_sel=11; + else if(kernelmenu_sel<15) kernelmenu_sel=15; + + if(keycode==LEFT) if(kernelmenu_sel>10 && kernelmenu_sel<15) kernelmenu_sel-=4; + if(keycode==RIGHT) if(kernelmenu_sel>6 && kernelmenu_sel<11) kernelmenu_sel+=4; + + if(keycode==TAB) hexmode^=1; + if(kernelmenu_sel<0) kernelmenu_sel=0; + if(kernelmenu_sel>15) kernelmenu_sel=15; + } while(keycode!=ESC && keycode!=F1 && keycode!=F2 && keycode!=ENTER && keycode!=SPACE); +} + + + + + +/****************************************************************************/ +void ShowExtenderMenu() +{ + int n; + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + OpenWindow(2,8,15,64); + SetColor(YELLOW); + Print_At(2,11," DOS Extender Configuration "); + SetColor(LIGHTWHITE); + + Print_At( 3,10," 1) Report Warnings ..................................."); + Print_At( 4,10," 2) Sound Alert on Run-Time Errors ...................."); + Print_At( 5,10," 3) Restore Real Mode INTs on Exit ...................."); + Print_At( 6,10," 4) Report Modified Real Mode INTs ...................."); + Print_At( 7,10," 5) Object Loading Scheme ............................."); + Print_At( 8,10," 6) Object Alignment when Loaded High ..............."); + Print_At( 9,10," 7) Clear Screen on Run-Time Errors ..................."); + Print_At(10,10," 8) Start Full-Screen under Windows ..................."); + Print_At(11,10," 9) Install Null-Pointer Protection ..................."); + + ShowBannerStatus(); + + Print_At(13,10,"11) Configure Using Environment ......................."); + Print_At(14,10,"12) Start Extender in Verbose Mode ...................."); + Print_At(15,19,"DOS Transfer Buffer Size: (Bytes)"); + + do { + SelectExtenderMenu(); + if(keycode!=ESC && keycode!=F1 && keycode!=F2) switch(extendermenu_sel) { + case 0: id32.dos32a_misc^=0x01; break; + case 1: id32.dos32a_misc^=0x02; break; + case 2: id32.dos32a_misc^=0x04; break; + case 3: id32.dos32a_misc^=0x08; break; + case 4: { n=(id32.dos32a_misc&0x30)>>4; n=(n+1)&0x03; + id32.dos32a_misc=((id32.dos32a_misc&0xCF)|(n<<4)); } break; + case 5: id32.dos32a_misc2^=0x04; break; + case 6: id32.dos32a_misc^=0x40; break; + case 7: id32.dos32a_misc2^=0x02; break; + case 8: id32.dos32a_misc^=0x80; break; + case 9: if((id32.dos32a_misc2&0x80)==0) id32.dos32a_misc2^=0x08; break; + case 10: id32.dos32a_misc2^=0x01; break; + case 11: id32.dos32a_misc2^=0x10; break; + case 12: id32.dos32a_lowbufsize= + Input(15,46,6,id32.dos32a_lowbufsize<<4)>>4; + if(id32.dos32a_lowbufsize>0x0FFF) id32.dos32a_lowbufsize=0x0FFF; + break; + } + } while(keycode!=ESC && keycode!=F1 && keycode!=F2); + CloseWindow(); +} + + + +/*--------------------------------------------------------------------------*/ +void ShowExtenderConfig() +{ + int n; + SetColor(LIGHTWHITE); + SetBackColor(BLUE); + if(id32.dos32a_misc&0x01) Print_At(3,65,". ON");else Print_At(3,65," OFF"); + if(id32.dos32a_misc&0x02) Print_At(4,65,". ON");else Print_At(4,65," OFF"); + if(id32.dos32a_misc&0x04) Print_At(5,65,". ON");else Print_At(5,65," OFF"); + if(id32.dos32a_misc&0x08) Print_At(6,65,". ON");else Print_At(6,65," OFF"); + Print_At(7,65,". #%d",((id32.dos32a_misc&0x30)>>4)+1); + if(id32.dos32a_misc2&0x04) Print_At(8,64," PAGE");else Print_At(8,64," PARA"); + if(id32.dos32a_misc&0x40) Print_At(9,65,". ON");else Print_At(9,65," OFF"); + if(id32.dos32a_misc2&0x02) Print_At(10,65,". ON");else Print_At(10,65," OFF"); + if(id32.dos32a_misc&0x80) Print_At(11,65,". ON");else Print_At(11,65," OFF"); + if((id32.dos32a_misc2&0x80)==0) + { + if(id32.dos32a_misc2&0x08) Print_At(12,65,". ON");else Print_At(12,65," OFF"); + } + else + { + SetColor(WHITE); + if(id32.dos32a_misc2&0x08) Print_At(12,65,". ON");else Print_At(12,65," OFF"); + SetColor(LIGHTWHITE); + } + if(id32.dos32a_misc2&0x01) Print_At(13,65,". ON");else Print_At(13,65," OFF"); + if(id32.dos32a_misc2&0x10) Print_At(14,65,". ON");else Print_At(14,65," OFF"); + + if(((id32.dos32a_lowbufsize<<4)&0xFFFF)<4096) SetColor(YELLOW); + if(((id32.dos32a_lowbufsize<<4)&0xFFFF)<1024) { SetColor(LIGHTRED); SetBlink(1); } + if(hexmode==0) Print_At(15,44,"%8d",(id32.dos32a_lowbufsize<<4)&0xFFFF); + else Print_At(15,44,"%7Xh",(id32.dos32a_lowbufsize<<4)&0xFFFF); + SetBlink(0); + + SetColor(LIGHTBLUE); + if((id32.dos32a_misc&0x01)!=(id32_old.dos32a_misc&0x01)) Print_At(3,69,"*");else Print_At(3,69," "); + if((id32.dos32a_misc&0x02)!=(id32_old.dos32a_misc&0x02)) Print_At(4,69,"*");else Print_At(4,69," "); + if((id32.dos32a_misc&0x04)!=(id32_old.dos32a_misc&0x04)) Print_At(5,69,"*");else Print_At(5,69," "); + if((id32.dos32a_misc&0x08)!=(id32_old.dos32a_misc&0x08)) Print_At(6,69,"*");else Print_At(6,69," "); + if((id32.dos32a_misc&0x30)!=(id32_old.dos32a_misc&0x30)) Print_At(7,69,"*");else Print_At(7,69," "); + if((id32.dos32a_misc2&0x04)!=(id32_old.dos32a_misc2&0x04)) Print_At(8,69,"*");else Print_At(8,69," "); + if((id32.dos32a_misc&0x40)!=(id32_old.dos32a_misc&0x40)) Print_At(9,69,"*");else Print_At(9,69," "); + if((id32.dos32a_misc2&0x02)!=(id32_old.dos32a_misc2&0x02)) Print_At(10,69,"*");else Print_At(10,69," "); + if((id32.dos32a_misc&0x80)!=(id32_old.dos32a_misc&0x80)) Print_At(11,69,"*");else Print_At(11,69," "); + if((id32.dos32a_misc2&0x08)!=(id32_old.dos32a_misc2&0x08)) Print_At(12,69,"*");else Print_At(12,69," "); + if((id32.dos32a_misc2&0x01)!=(id32_old.dos32a_misc2&0x01)) Print_At(13,69,"*");else Print_At(13,69," "); + if((id32.dos32a_misc2&0x10)!=(id32_old.dos32a_misc2&0x10)) Print_At(14,69,"*");else Print_At(14,69," "); + if((id32.dos32a_lowbufsize)!=(id32_old.dos32a_lowbufsize)) Print_At(15,52,"*");else Print_At(15,52," "); + SetColor(LIGHTWHITE); +} + + + +/*--------------------------------------------------------------------------*/ +void SelectExtenderMenu() +{ + int n; + + do { + ShowModified(); + ShowHelp(2,extendermenu_sel); + ShowExtenderConfig(); + ShowCursor( extendermenu_ypos[extendermenu_sel], + extendermenu_xpos[extendermenu_sel], + extendermenu_xlen[extendermenu_sel]); + GetKey(); + ShowCursor( extendermenu_ypos[extendermenu_sel], + extendermenu_xpos[extendermenu_sel], + extendermenu_xlen[extendermenu_sel]); +// CloseWindow(); + + if(keychar>'0' && keychar<='9') extendermenu_sel=keychar-'1'; + if(keychar=='0' || keychar=='a' || keychar=='A') extendermenu_sel=9; + if(keychar=='b' || keychar=='B') extendermenu_sel=10; + if(keychar=='c' || keychar=='C') extendermenu_sel=11; + if(keycode==F3) CreateConfig(); + if(keycode==F4) RestoreConfig(); + if(keycode==F5) { id32=id32_old; ClearConfigName(); ShowBannerStatus(); } + if(keycode==F6) { RestoreDefaults(); ClearConfigName(); } + if(keycode==F8) ShowMemReq(); + if(keycode==UP) extendermenu_sel--; + if(keycode==DOWN) extendermenu_sel++; + if(keycode==HOME) extendermenu_sel=0; + if(keycode==END) extendermenu_sel=12; + if(keycode==PAGEUP) + if(extendermenu_sel>11) extendermenu_sel=11; + else if(extendermenu_sel>6) extendermenu_sel=6; + else extendermenu_sel=0; + if(keycode==PAGEDOWN) + if(extendermenu_sel<6) extendermenu_sel=6; + else if(extendermenu_sel<11) extendermenu_sel=11; + else extendermenu_sel=12; + if(keycode==TAB) hexmode^=1; + if(extendermenu_sel<0) extendermenu_sel=0; + if(extendermenu_sel>12) extendermenu_sel=12; + } while(keycode!=ESC && keycode!=F1 && keycode!=F2 && keycode!=ENTER && keycode!=SPACE); +} + diff -uNr a/dos32a/src/ss/setup.asm b/dos32a/src/ss/setup.asm --- a/dos32a/src/ss/setup.asm false +++ b/dos32a/src/ss/setup.asm 435e4e724785e9c07ce7f45f78c638946cb524cdb209246ac5a21e6168e8d29d46110f4795bbf4d457b6f056b7c7a156d49c43c2e0b4be028516143725d6272a @@ -0,0 +1,1058 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .486p + .MODEL flat + LOCALS + NOJUMPS + + +PUBLIC VideoInit_, VideoReset_ +PUBLIC DrawBackground_ +PUBLIC GetKey_ +PUBLIC Printc_, Prints_, SetPos_, SetColor_, SetBackColor_, SetBlink_ +PUBLIC OpenWindow_, DrawWindow_, CloseWindow_, ShowCursor_, PrintHelp_ +PUBLIC get_himem_size_, get_lomem_size_, get_cpu_type_ +PUBLIC get_sys_type_, get_dosmem_used_, get_total_mem_, get_dpmi_bufsize_ +PUBLIC ReadHeader_, WriteHeader_, CloseFile_, GetFileType_, GetExtenderType_ + +PUBLIC _keychar, _keycode + +EXTRN _mem_dos32a : dword +EXTRN _mem_kernel : dword + +include stddef.inc + +.CODE + + +GetFileType_: + pushad + mov esi,offs @file_buffer + mov ax,4200h + mov bx,_file_handle + xor ecx,ecx + movzx edx,wptr [esi+3Ch] + int 21h + jc @@t_no + + mov ah,3Fh + mov bx,_file_handle + mov ecx,0004h + mov edx,offs @file_buffer+80h + int 21h + jc @@t_no + + cmp wptr [edx],'EL' + jz @@t_le + cmp wptr [edx],'XL' + jz @@t_lx + cmp wptr [edx],'CL' + jz @@t_lc + cmp wptr [edx],'EP' + jz @@t_pe + +@@t_no: popad ; not bound + xor eax,eax + ret +@@t_le: popad ; LE - style + mov eax,1 + ret +@@t_lx: popad ; LX - style + mov eax,2 + ret +@@t_lc: popad ; LC - style + mov eax,3 + ret +@@t_pe: popad ; PE - style + mov eax,4 + ret + + +;============================================================================= +GetExtenderType_: + pushad + mov esi,_buffer + mov ax,4200h + mov bx,_file_handle + xor ecx,ecx + xor edx,edx + int 21h + jc @@0 + + mov ax,3F00h + mov bx,_file_handle + mov ecx,0100h + mov edx,_buffer + int 21h + jc @@0 + + mov ebx,_buffer + mov esi,offs _str_dos32a + lea edi,[ebx+007Ch] + call check_string + jnc @@1 + mov ebx,_buffer + mov esi,offs _str_dos32a + lea edi,[ebx+009Ch] + call check_string + jnc @@1 + + mov ebx,_buffer + mov esi,offs _str_stub32c + lea edi,[ebx+004Ch] + call check_string + jnc @@2 + mov ebx,_buffer + mov esi,offs _str_stub32c + lea edi,[ebx+006Ch] + call check_string + jnc @@2 + + +@@0: popad + xor eax,eax ; N/A + ret +@@1: popad + mov eax,1 ; DOS/32A + ret +@@2: popad + mov eax,2 ; STUB/32C + ret + + +check_string: + pushad +@@0: mov al,[esi] + test al,al + jz @@ok + cmp al,[edi] + jnz @@err + inc esi + inc edi + jmp @@0 +@@ok: popad + clc + ret +@@err: popad + stc + ret + + +;============================================================================= +ReadHeader_: + pushad + + mov ebp,edx + mov edx,eax + mov ax,3D02h + int 21h + jc @@err1 + mov _file_handle,ax + + mov ah,3Fh + mov bx,_file_handle + mov ecx,0040h + mov edx,offs @file_buffer + int 21h + jc @@err2 + + mov esi,offs @file_buffer + cmp wptr [esi+00h],'ZM' + jnz @@err3 + mov ax,4200h + mov bx,_file_handle + xor ecx,ecx + movzx edx,wptr [esi+08h] + shl edx,4 + int 21h + jc @@err2 + + mov ah,3Fh + mov bx,_file_handle + mov ecx,0080h + mov edx,ebp + int 21h + jc @@err2 + + popad + xor eax,eax + ret +@@err1: popad + mov eax,1 ; error opening + ret +@@err2: popad + mov eax,2 ; error reading + ret +@@err3: popad + mov eax,3 ; invalid header type (not MZ exec) + ret + + + +;============================================================================= +WriteHeader_: + pushad + push eax + mov esi,offs @file_buffer + mov ax,4200h + mov bx,_file_handle + xor ecx,ecx + movzx edx,wptr [esi+08h] + shl edx,4 + int 21h + pop edx + jc @@err1 + mov ah,40h + mov bx,_file_handle + mov ecx,0080h + int 21h + jc @@err1 + popad + xor eax,eax + ret +@@err1: popad + mov eax,1 ; error writing + ret + +CloseFile_: + pushad + mov bx,_file_handle + mov ah,3Eh + int 21h + popad + ret + + + + + +;============================================================================= + Align 4 +get_dosmem_used_: + pushad + mov ebp,eax ; preserve EAX + mov ax,0FF89h + int 21h + cmp eax,'ID32' + jz @@l1 + popad + xor eax,eax + ret + +@@l1: pushad + mov ax,0FF8Ah + int 21h + cmp eax,'ID32' + jz @@l2 + popad + popad + xor eax,eax + ret + +@@l2: cmp ch,03h ; if SYS = DPMI + popad + jnz @@l3 + sub ebp,_mem_kernel ; kernel has been removed + +@@l3: mov eax,ebp ; DOS/32A exec size + add eax,0080h ; + DTA and Mouse_Buf + add eax,0400h ; + RM IDT + add eax,ecx ; + DOS Transfer Buffer + + mov ebp,eax ; D32A API get ptr to client + mov ax,0FF8Eh + int 21h + movzx eax,word ptr gs:[edi+08h] ; get size of DPMI required buffer + shl eax,4 + add eax,ebp + + test word ptr gs:[edi+06h],0001h ; check if STUB/32C is resident + jz @@done + add eax,2048 ; count in size of STUB/32C + +@@done: mov [esp+1Ch],eax + popad + ret + + + +;============================================================================= +get_himem_size_: + mov ax,0FF90h + int 21h + ret + + +;============================================================================= +get_lomem_size_: + mov ax,0FF94h + int 21h + ret + + +;============================================================================= +get_total_mem_: + pushad + xor eax,eax + mov al,30h + out 70h,al + in al,71h + mov ah,al + mov al,31h + out 70h,al + in al,71h + xchg al,ah + mov [esp+1Ch],eax + popad + ret + + +;============================================================================= +get_dpmi_bufsize_: + pushad + mov ax,0FF8Eh + int 21h + movzx eax,word ptr gs:[edi+08h] ; get size of DPMI required buffer + shl eax,4 + mov [esp+1Ch],eax + popad + ret + + + +;============================================================================= +; Get CPU type: 80386, 80486, PENTIUM, ... +; + Align 4 +get_cpu_type_: + pushad + mov ax,0400h ; DPMI get CPU + int 31h + movzx eax,cl + mov [esp+1Ch],eax + cmp cl,3 + ja @@1 + popad + ret + +@@1: pushfd + cli + pushfd + pop eax + mov edx,eax + xor eax,00200000h + push eax + popfd + pushfd + pop eax + xor eax,edx + jne @@l4 + jmp @@x +@@l4: xor eax,eax + db 0Fh, 0A2h + mov dword ptr [esp+1Ch+4],5 ; CPU is 586 + cmp eax,1 ; check CPUID level + jb @@x ; if level 1 not supported, exit + mov eax,1 + db 0Fh, 0A2h + mov al,ah + and eax,0Fh + mov [esp+1Ch+4],eax +@@x: sti + popfd + popad + ret + + +;============================================================================= +; Get SYSTEM type: raw, XMS, VCPI, DPMI +; + Align 4 +get_sys_type_: + pushad + mov ax,1600h + int 2Fh + test al,al + jz @@0 + cmp al,80h + jz @@0 + mov ch,4 + jmp @@1 + +@@0: mov ax,0FF8Ah + push fs + int 21h + pop fs + cmp eax,'ID32' + jz @@1 + mov ch,5 + +@@1: movzx eax,ch + mov [esp+1Ch],eax + popad + ret + + + + +;============================================================================= +VideoInit_: + pushad + mov esi,_screen_addr + mov edi,_buffer_addr + mov ecx,0800h + rep movsd + call sync_display + mov ax,0300h + xor ebx,ebx + int 10h ; get DOS cursor position + mov _old_video_pos,dx + mov ax,0200h + xor edx,edx + int 10h ; set cursor to 0,0 (hide under bkgnd) + call set_video_mode_init + mov _xpos,0 + mov _ypos,0 + mov _color,0Fh + popad + ret + +VideoReset_: + pushad + call sync_display + call set_video_mode_exit + mov ax,0200h + mov dx,_old_video_pos + xor ebx,ebx + int 10h + mov esi,_buffer_addr + mov edi,_screen_addr + mov ecx,0800h + rep movsd + popad + ret + +set_video_mode_init: + pushad + mov ah,0Fh + int 10h + cmp al,03h + jnz @@0 + cmp ah,80 + jnz @@0 + cmp bh,00h + jnz @@0 + jmp @@1 +@@0: mov ax,0003h + int 10h +@@1: mov ax,1003h ; toggle blink/background + mov bx,0001h + int 10h +; xor eax,eax +; mov edi,_screen_addr +; mov ecx,0800h +; rep stosd + popad + ret +set_video_mode_exit: + pushad + mov ah,0Fh + int 10h + cmp al,03h + jnz @@0 + cmp ah,80 + jnz @@0 + cmp bh,00h + jnz @@0 + jmp @@1 +@@0: mov ax,0003h + int 10h +@@1: mov ax,1003h ; toggle blink/background + mov bx,0000h + int 10h +; xor eax,eax +; mov edi,_screen_addr +; mov ecx,0800h +; rep stosd + popad + ret + +DrawBackground_: + pushad + call sync_display + mov edi,_screen_addr + mov ecx,80 + mov ax,1120h + rep stosw + mov ecx,80*23 + mov ax,1FB1h + rep stosw + mov ecx,80 + mov ax,1120h + rep stosw + popad + ret + + + +;----------------------------------------------------------------------------- +GetKey_: + pushad + xor eax,eax + int 16h + mov [esp+1Ch],eax + mov _keychar,al + mov _keycode,ah + popad + ret + + +Printc_: + pushad + cmp al,0Ah + jz @@1 + cmp al,0Dh + jz @@2 + mov edi,_screen_addr + movzx ebx,_ypos + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + movzx ebx,_xpos + lea ebx,[ebx*2] + add edi,ebx + mov [edi],al + inc edi + mov al,_color + mov [edi],al + popad + ret +@@1: mov _xpos,0 ; handle 0Ah + popad + ret +@@2: inc _ypos ; handle 0Dh + cmp _ypos,25 + jb @@3 + mov _ypos,0 +@@3: popad + ret + + + +Prints_: + pushad + mov esi,eax +@@loop: mov al,[esi] + inc esi + test al,al + jz @@done + call Printc_ + inc _xpos + cmp _xpos,80 + jae @@1 + jmp @@loop +@@1: mov _xpos,0 + inc _ypos + cmp _ypos,25 + jae @@2 + jmp @@loop +@@2: mov _ypos,0 + jmp @@loop +@@done: popad + ret + +SetPos_: + pushad + mov _xpos,dl + mov _ypos,al + popad + ret + +SetColor_: + pushad + and al,0Fh + mov ah,_color + and ah,0F0h + or al,ah + mov _color,al + popad + ret + +SetBackColor_: + pushad + and al,0Fh + mov ah,_color + and ah,0Fh + shl al,4 + or al,ah + mov _color,al + popad + ret + + +SetBlink_: + pushad + and al,01h + jnz @@1 + and _color,7Fh + jmp @@done +@@1: or _color,80h +@@done: popad + ret + +ShowCursor_: + pushad + movzx ebp,_xpos + push ebp + movzx ebp,_ypos + push ebp + mov _xpos,dl + mov _ypos,al + mov ecx,ebx + mov edi,_screen_addr + movzx ebx,_ypos + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + movzx ebx,_xpos + lea ebx,[ebx*2] + add edi,ebx + inc edi +@@1: mov al,[edi] + + mov ah,30h + cmp al,1Fh + jz @@2 + mov ah,1Fh + cmp al,30h + jz @@2 + + mov ah,37h + cmp al,17h + jz @@2 + mov ah,17h + cmp al,37h + jz @@2 + + mov ah,3Ch OR 80h + cmp al,1Ch OR 80h + jz @@2 + mov ah,1Ch OR 80h + cmp al,3Ch OR 80h + jz @@2 + + mov ah,3Eh + cmp al,1Eh + jz @@2 + mov ah,1Eh + cmp al,3Eh + jz @@2 + + mov ah,3Bh + cmp al,1Bh + jz @@2 + mov ah,1Bh + cmp al,3Bh + jz @@2 + +@@2: mov [edi],ah + add edi,2 + loop @@1 + pop eax + mov _ypos,al + pop eax + mov _xpos,al + popad + ret + + +PrintHelp_: + pushad + mov esi,eax + +@@0: lodsb + test al,al + jz @@done + cmp al,'[' + jz @@l1on + cmp al,']' + jz @@l1of + cmp al,'<' + jz @@l2on + cmp al,'>' + jz @@l2of + cmp al,0Dh + jz @@0 + cmp al,0Ah + jnz @@1 + inc _ypos + mov _xpos,3 + jmp @@0 +@@1: call Printc_ + inc _xpos + jmp @@0 + +@@done: popad + ret + +@@l1on: mov al,_color + mov _color2,al + and al,0F0h + or al,004h + mov _color,al + jmp @@0 +@@l1of: mov al,_color2 + mov _color,al + jmp @@0 +@@l2on: mov al,_color + mov _color3,al + and al,0F0h + or al,00Eh + mov _color,al + jmp @@0 +@@l2of: mov al,_color3 + mov _color,al + jmp @@0 + + +sync_display: + push eax edx + mov dx,03DAh +@@1: in al,dx + test al,08h + jnz @@1 +@@2: in al,dx + test al,08h + jz @@2 + pop edx eax + ret + + + +save_window: + pushad + mov esi,_screen_addr + mov ebx,_ywinpos + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add esi,edx + mov ebx,_xwinpos + lea ebx,[ebx*2] + add esi,ebx + mov edi,_window_addr + mov ecx,_xwinlen + mov edx,_ywinlen +@@1: push esi +@@2: mov ax,[esi] + mov [edi],ax + add esi,2 + add edi,2 + dec ecx + jnz @@2 + pop esi + add esi,80*2 + mov ecx,_xwinlen + dec edx + jnz @@1 + mov eax,_xwinpos + mov [edi+0*4],eax + mov eax,_ywinpos + mov [edi+1*4],eax + mov eax,_xwinlen + mov [edi+2*4],eax + mov eax,_ywinlen + mov [edi+3*4],eax + add edi,16 + mov _window_addr,edi + popad + ret + + +restore_window: + call sync_display + pushad + mov esi,_window_addr + sub esi,16 + mov eax,[esi+0*4] + mov _xwinpos,eax + mov ebx,[esi+1*4] + mov _ywinpos,ebx + mov ecx,[esi+2*4] + mov _xwinlen,ecx + mov edx,[esi+3*4] + mov _ywinlen,edx + imul ecx,edx + add ecx,ecx + sub esi,ecx + mov _window_addr,esi + mov edi,_screen_addr + mov ebx,_ywinpos + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + mov ebx,_xwinpos + lea ebx,[ebx*2] + add edi,ebx + mov ecx,_xwinlen + mov edx,_ywinlen +@@1: push edi +@@2: mov ax,[esi] + mov [edi],ax + add esi,2 + add edi,2 + dec ecx + jnz @@2 + pop edi + add edi,80*2 + mov ecx,_xwinlen + dec edx + jnz @@1 + popad + ret + + +draw_window: + pushad + mov edi,_screen_addr + mov ebx,_ywinpos + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + mov ebx,_xwinpos + lea ebx,[ebx*2] + add edi,ebx + mov ecx,_xwinlen + mov edx,_ywinlen +@@1: push edi +@@2: mov [edi],ax + add edi,2 + dec ecx + jnz @@2 + pop edi + add edi,80*2 + mov ecx,_xwinlen + dec edx + jnz @@1 + + mov eax,_xwinpos + mov edx,_ywinpos + mov _xpos,al + mov _ypos,dl + mov al, 'É' + call Printc_ + inc _xpos + mov ecx,_xwinlen + sub ecx,2 + mov al, 'Í' +@@3: call Printc_ + inc _xpos + loop @@3 + mov al, '»' + call Printc_ + + mov eax,_xwinpos + mov edx,_ywinpos + inc edx + mov _xpos,al + mov _ypos,dl + mov ecx,_ywinlen + sub ecx,2 + mov al, 'º' +@@4: call Printc_ + inc _ypos + loop @@4 + mov al, 'È' + call Printc_ + + mov eax,_xwinpos + mov edx,_ywinpos + inc edx + dec eax + add eax,_xwinlen + mov _xpos,al + mov _ypos,dl + mov ecx,_ywinlen + sub ecx,2 + mov al, 'º' +@@5: call Printc_ + inc _ypos + loop @@5 + mov al, '¼' + call Printc_ + + mov eax,_xwinpos + mov edx,_ywinpos + inc eax + dec edx + add edx,_ywinlen + mov _xpos,al + mov _ypos,dl + mov ecx,_xwinlen + sub ecx,2 + mov al, 'Í' +@@6: call Printc_ + inc _xpos + loop @@6 + + mov edi,_screen_addr + mov ebx,_ywinpos + inc ebx + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + mov ebx,_xwinpos + add ebx,_xwinlen + lea ebx,[ebx*2] + add edi,ebx + mov ecx,_ywinlen + inc edi + mov al,07h +@@7: mov [edi+0],al + mov [edi+2],al + add edi,80*2 + loop @@7 + + mov edi,_screen_addr + mov ebx,_ywinpos + add ebx,_ywinlen + lea edx,[ebx*4] + add edx,ebx + shl edx,5 + add edi,edx + mov ebx,_xwinpos + inc ebx + inc ebx + lea ebx,[ebx*2] + add edi,ebx + mov ecx,_xwinlen + inc edi + mov al,07h +@@8: mov [edi],al + add edi,2 + loop @@8 + + popad + ret + + +OpenWindow_: + pushad + inc ebx + inc ecx + inc ecx + mov _xwinpos,edx + mov _ywinpos,eax + mov _xwinlen,ecx + mov _ywinlen,ebx + call save_window + mov al,20h + mov ah,_color + dec _xwinlen + dec _xwinlen + dec _ywinlen + call draw_window + popad + ret + +DrawWindow_: + pushad + inc ebx + inc ecx + inc ecx + mov _xwinpos,edx + mov _ywinpos,eax + mov _xwinlen,ecx + mov _ywinlen,ebx + mov al,20h + mov ah,_color + dec _xwinlen + dec _xwinlen + dec _ywinlen + call draw_window + popad + ret + +CloseWindow_: + pushad + cmp _window_addr,offs @window_buffer + jbe @@done + call restore_window +@@done: popad + ret + + + + +.DATA +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +_str_dos32a db 'DOS/32A',0 +_str_stub32c db 'STUB/32C',0 + +_screen_addr dd 000B8000h +_buffer_addr dd offs @video_buffer +_window_addr dd offs @window_buffer +_buffer dd offs @file_buffer +_old_video_pos dw 0 +_xpos db 0 +_ypos db 0 +_color db 0 +_color2 db 0 +_color3 db 0 +_xwinpos dd 0 +_ywinpos dd 0 +_xwinlen dd 0 +_ywinlen dd 0 +_keychar db 0 +_keycode db 0 +_file_handle dw 0 + + +.DATA? +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +@video_buffer db 2000h dup(?) +@window_buffer db 10000h dup(?) +@file_buffer db 400h dup(?) +end diff -uNr a/dos32a/src/stub32a/stub32a.asm b/dos32a/src/stub32a/stub32a.asm --- a/dos32a/src/stub32a/stub32a.asm false +++ b/dos32a/src/stub32a/stub32a.asm 840002ba05b31bde2e2b7300af98b246beecdc4cdfd02a6b99799a5371d0d66ff14769344c5a654c62d6de7b9eae0d042a507e56bb80af1fe752fef121bb5ef5 @@ -0,0 +1,250 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .286 + .MODEL tiny + LOCALS + +.CODE +;============================================================================= +db 'STUB/32A' ,0 +db 'Copyright (C) 1996-2006 by Narech K.' ,0 +db ??date ,0 +db ??time ,0 + + +start: sti + push cs + pop ds + mov ax,es + mov bx,ss + mov _psp,ax + sub bx,ax + mov ax,sp + shr ax,4 + add bx,ax + inc bx + mov ah,4Ah + int 21h + jc err1 + +@@1: mov es,es:[002Ch] ; get environment + call make_cmd + mov bp,0090h + call exec + call find_path1 + call find_path2 + +err0: mov ah,09h + mov dx,offset str1 + mov byte ptr byte0,22h + int 21h +err1: mov ax,4CFFh + int 21h + + +;----------------------------------------------------------------------------- +make_cmd: + push ds es + push ss + pop ds + xor ax,ax + xor di,di + mov cx,7FFFh +@@1: repne scasb + scasb + jnz @@1 + inc di + inc di + mov si,di + repne scasb + sub di,si + mov cx,di + mov ax,di + mov di,0011h + push ss + push es + pop ds + pop es + rep movsb + mov byte ptr es:[di-1],20h + mov ds,cs:_psp + mov si,0081h + mov cl,[si-1] + add al,cl + inc cx + mov es:[0010h],al + rep movsb + pop es ds + ret + + +;----------------------------------------------------------------------------- +find_path1: + xor ax,ax + xor di,di +@@1: mov cx,0007h + mov si,offset path1 + rep cmpsb + jz @@2 + mov cl,0FFh + repne scasb + cmp al,es:[di] + jnz @@1 + ret +@@2: mov al,20h ; skip leading spaces + mov cl,0FFh + rep scasb + cmp word ptr es:[di],'\:' + jz @@3 + ret +@@3: dec di + mov bp,0090h +@@loop: mov al,es:[di] + test al,al + jz @@4 + inc di + cmp al,20h + jz @@4 + mov [bp],al + inc bp + jmp @@loop +@@4: mov byte ptr [bp],'\' + mov word ptr [bp+1],'IB' + mov word ptr [bp+3],'WN' + add bp,5 + jmp exec + + + + +;----------------------------------------------------------------------------- +find_path2: + xor ax,ax + xor di,di +@@1: mov cx,0005h + mov si,offset path2 + rep cmpsb + jz @@2 + mov cl,0FFh + repne scasb + cmp al,es:[di] + jnz @@1 + ret +@@2: mov bp,0090h +@@loop: mov al,es:[di] + test al,al + jz exec + inc di + cmp al,20h + jz @@loop + cmp al,';' + jz @@3 + mov [bp],al + inc bp + jmp @@loop +@@3: call exec + jmp @@2 + + +;----------------------------------------------------------------------------- +exec: push ds es di + xor si,si + cmp bp,0090h + jz @@0 + inc si + mov byte ptr [bp],'\' +@@0: lea di,[bp+si] + mov si,offset name1 + push ss + pop es + mov cx,11 + rep movsb + + push ss ss ss + pop ds es ax + xor bx,bx + mov word ptr ds:[0000h],bx + mov word ptr ds:[0002h],0010h + mov word ptr ds:[0004h],ax + mov word ptr ds:[0006h],005Ch + mov word ptr ds:[0008h],ax + mov word ptr ds:[000Ah],006Ch + mov word ptr ds:[000Ch],ax + + mov dx,0090h + mov ax,4B00h + int 21h + jc @@1 + + mov ah,4Dh + int 21h + mov ah,4Ch + int 21h + +@@1: pop di es ds + ret + + + + + + + +;============================================================================= +path1 db 'DOS32A=' +path2 db 'PATH=' +str1 db 'Cannot find file "' +name1 db 'DOS32A.EXE' +byte0 db 0,0Dh,0Ah,'$' + +$theend proc near + db 2 dup(0) +$theend endp + + +_psp dw ? + + + +.STACK +;============================================================================= + + +end start diff -uNr a/dos32a/src/stub32a/stub32c.asm b/dos32a/src/stub32a/stub32c.asm --- a/dos32a/src/stub32a/stub32c.asm false +++ b/dos32a/src/stub32a/stub32c.asm 1564a5d4b4385c7fc5fbd3309d09e16ef8d2e5e12d7d9133672edc828f3fb54120131bf7c03d95e8c1c0dd68eaf2954fb297ae32e5ee44d1cd0e400410e31f05 @@ -0,0 +1,357 @@ +; +; Copyright (C) 1996-2006 by Narech K. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. The end-user documentation included with the redistribution, if any, +; must include the following acknowledgment: +; +; "This product uses DOS/32 Advanced DOS Extender technology." +; +; Alternately, this acknowledgment may appear in the software itself, if +; and wherever such third-party acknowledgments normally appear. +; +; 4. Products derived from this software may not be called "DOS/32A" or +; "DOS/32 Advanced". +; +; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; + + .286 + .MODEL tiny + LOCALS + +;============================================================================= +_ID32 segment para public use16 'CODE0' +_ID32_SIZE=16 ; size excluding 'ID32' signature +;----------------------------------------------------------------------------- +db 'ID32' ; ID signature +db 00111111b ; KERNEL misc. bits: + ; bit 0: **deprecated** + ; bit 1: **deprecated** + ; bit 2: 0=VCPI smart page alloc off, 1=on /1=def + ; bit 3: 0=VCPI+XMS alloc scheme off, 1=on /1=def + ; bit 4: **deprecated** + ; bit 5: **deprecated** + ; bit 6: reserved /0=def + ; bit 7: 0=ignore 4G extensions off, 1=on /0=def +db 64 ; Max. number of page tables under VCPI /256MB +db 2 ; Max. number of page tables mem_mapping /4MB +db 16 ; Max. number of real mode callbacks /16 +dw 256 ; Max. number of Selectors under VCPI/XMS/raw /256 +db 8 ; Real mode Stack nesting +db 8 ; Protected mode Stack nesting +dw 20h ; Real mode Stack length, (in para) +dw 20h ; Protected mode Stack length, (in para) +dd 0FFFFFFFFh ; Max. extended memory to allocate in bytes +;----------------------------------------------------------------------------- +db 00111111b ; DOS/32A misc. bits: + ; bit 0: 0=console output off, 1=on /1=def + ; bit 1: 0=sound generation off, 1=on /1=def + ; bit 2: 0=restore INT table off, 1=on /1=def + ; bit 3: 0=report modified INTs off, 1=on /1=def + ; bit 4: 0=load 16 in lowmem off, 1=on /1=def + ; bit 5: 0=force load 16 low off, 1=on /1=def + ; bit 6: 0=cls on exception off, 1=on /0=def + ; bit 7: 0=null-ptr protect off, 1=on /0=def +if EXEC_TYPE eq 0 +db 00001001b ; DOS/32A Pro second misc. bits +else +db 10001001b ; DOS/32A Beta second misc. bits +endif + ; bit 0: 0=config by enironment off, 1=on /1=def + ; bit 1: 0=focus on this VM off, 1=on /0=def + ; bit 2: 0=align objects on PARA, 1=PAGE /0=def + ; bit 3: 0=show copyright off, 1=on /1=def + ; bit 4: 0=verbose mode off, 1=on /0=def + ; bit 5: reserved /0=def + ; bit 6: 0=lock configuration off, 1=on /* + ; bit 7: 0=Professional, 1=Beta /* +dw 0200h ; DOS INT 21h buffer in low memory (in para) /8 KB +dw 0000h ; Internal Version of DOS/32A (N/A for stub) +dw 0000h ; Reserved (v7.0+) +;----------------------------------------------------------------------------- +db 'STUB/32C' ,0 +db 'Copyright (C) 1996-2006 by Narech K.' ,0 +db ??date ,0 +db ??time ,0 + +_ID32 ends + + + + + +_TEXT16 segment dword public use16 'CODE1' +assume cs:_TEXT16, ds:_TEXT16 +;============================================================================= + +start: push cs + pop ds + mov ax,es + mov bx,ss + mov _psp,ax + sub bx,ax + mov ax,sp + shr ax,4 + add bx,ax + inc bx + mov ah,4Ah + int 21h + jc err1 + + push ax ds ; install INT 21h + xor ax,ax + mov ds,ax + cli + mov ax,ds:[21h*4+0] + mov cs:_ip21h,ax + mov ax,ds:[21h*4+2] + mov cs:_cs21h,ax + mov ax,offset int21h + mov ds:[21h*4+0],ax + mov ax,seg _TEXT16 + mov ds:[21h*4+2],ax + sti + pop ds ax + + +@@1: mov es,es:[002Ch] ; get environment + call make_cmd + mov bp,0090h + call exec + call find_path1 + call find_path2 + +err0: mov ah,09h + mov dx,offset str1 + mov byte ptr byte0,22h + int 21h +err1: mov ax,4CFFh + int 21h + + +;----------------------------------------------------------------------------- +make_cmd: + push ds es + push ss + pop ds + xor ax,ax + xor di,di + mov cx,7FFFh +@@1: repne scasb + scasb + jnz @@1 + inc di + inc di + mov si,di + repne scasb + sub di,si + mov cx,di + mov ax,di + mov di,0011h + push ss + push es + pop ds + pop es + rep movsb + mov byte ptr es:[di-1],20h + mov ds,cs:_psp + mov si,0081h + mov cl,[si-1] + add al,cl + inc cx + mov es:[0010h],al + rep movsb + pop es ds + ret + + +;----------------------------------------------------------------------------- +find_path1: + xor ax,ax + xor di,di +@@1: mov cx,0007h + mov si,offset path1 + rep cmpsb + jz @@2 + mov cl,0FFh + repne scasb + cmp al,es:[di] + jnz @@1 + ret +@@2: mov al,20h ; skip leading spaces + mov cl,0FFh + rep scasb + cmp word ptr es:[di],'\:' + jz @@3 + ret +@@3: dec di + mov bp,0090h +@@loop: mov al,es:[di] + test al,al + jz @@4 + inc di + cmp al,20h + jz @@4 + mov [bp],al + inc bp + jmp @@loop +@@4: mov byte ptr [bp],'\' + mov word ptr [bp+1],'IB' + mov word ptr [bp+3],'WN' + add bp,5 + jmp exec + + + + +;----------------------------------------------------------------------------- +find_path2: + xor ax,ax + xor di,di +@@1: mov cx,0005h + mov si,offset path2 + rep cmpsb + jz @@2 + mov cl,0FFh + repne scasb + cmp al,es:[di] + jnz @@1 + ret +@@2: mov bp,0090h +@@loop: mov al,es:[di] + test al,al + jz exec + inc di + cmp al,20h + jz @@loop + cmp al,';' + jz @@3 + mov [bp],al + inc bp + jmp @@loop +@@3: call exec + jmp @@2 + + +;----------------------------------------------------------------------------- +exec: push ds es di + xor si,si + cmp bp,0090h + jz @@0 + inc si + mov byte ptr [bp],'\' +@@0: lea di,[bp+si] + mov si,offset name1 + push ss + pop es + mov cx,11 + rep movsb + + push ss ss ss + pop ds es ax + xor bx,bx + mov word ptr ds:[0000h],bx + mov word ptr ds:[0002h],0010h + mov word ptr ds:[0004h],ax + mov word ptr ds:[0006h],005Ch + mov word ptr ds:[0008h],ax + mov word ptr ds:[000Ah],006Ch + mov word ptr ds:[000Ch],ax + + mov dx,0090h + mov ax,4B00h + int 21h + jc @@1 + + mov ah,4Dh + int 21h + mov ah,4Ch + int 21h + +@@1: pop di es ds + ret + + + +;----------------------------------------------------------------------------- + Align 4 +int21h: cmp ah,4Ch + jz @@1 + cmp ax,0FF87h + jz @@2 +@@0: jmp dword ptr cs:_ip21h + +@@1: push ax + call uninstall_int21h + pop ax + jmp @@0 + +@@2: call uninstall_int21h + mov ax,seg _ID32 + mov ds,ax ; DS:SI = pointer to configuration + xor si,si + mov dx,'ID' ; DX:AX = "ID32" ID-string + mov ax,'32' + iret + +;----------------------------------------------------------------------------- +uninstall_int21h: + cli + xor ax,ax + mov ds,ax + mov ax,cs:_ip21h + mov ds:[21h*4+0],ax + mov ax,cs:_cs21h + mov ds:[21h*4+2],ax + ret + + + +;============================================================================= +path1 db 'DOS32A=' +path2 db 'PATH=' +str1 db 'Cannot find file "' +name1 db 'DOS32A.EXE' +byte0 db 0,0Dh,0Ah,'$' + +$theend proc near + db 5 dup(0) +$theend endp + + + evendata +_ip21h dw ? +_cs21h dw ? +_psp dw ? + + +_TEXT16 ends + + +.STACK +;============================================================================= + + +end start diff -uNr a/dos32a/src/sver/main.c b/dos32a/src/sver/main.c --- a/dos32a/src/sver/main.c false +++ b/dos32a/src/sver/main.c 2403a2520f3db8267b901ec7a16c0a140798ee20394b54d1e5dff0201b99ca6c2fede20bfdc8f6ecdd402369f3c2bef70474dddd652edb7b8c5a157d1a6963a6 @@ -0,0 +1,415 @@ +/* + * Copyright (C) 1996-2006 by Narech K. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, + * must include the following acknowledgment: + * + * "This product uses DOS/32 Advanced DOS Extender technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. Products derived from this software may not be called "DOS/32A" or + * "DOS/32 Advanced". + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + + + char* version = "9.1.2"; + char* errstr = "SVER fatal:"; + + int fileisbound = TRUE; + int extendertype= 0; // 1=DOS/32A, 2=STUB/32A, 3=STUB32C + char* fileverptr = NULL; + + int extender_release; + int extender_revision; + int extender_major_version; + int extender_minor_version; + int extender_build_version; + + FILE* fp; + char buffer[512]; + char filename[256]; + char orgfilename[256]; + + +void err_usage() { + printf("%s syntax is SVER \n",errstr); + exit(1); +} +void err_open() { + printf("%s cannot open file \"%s\"\n",errstr,filename); + exit(1); +} +void err_read() { + printf("%s cannot read from file \"%s\"\n",errstr,filename); + exit(1); +} +void err_seek() { + printf("%s error seeking in file \"%s\"\n",errstr,filename); + exit(1); +} +void err_format() { + printf("%s unsupported exec format in file \"%s\"\n",errstr,filename); + exit(1); +} +void err_extender() { + printf("%s \"%s\" is not a DOS/32A executable\n",errstr,filename); + exit(1); +} + + +/****************************************************************************/ +void ShowCopyright() +{ + printf("SVER -- Version Reporting Utility version %s\n",version); + printf("Copyright (C) 1996-2006 by Narech K.\n"); +} + + +void ShowHelp() +{ + printf("\n"); + printf("The SVER Utility Program should be used to determine the version\n"); + printf("of DOS/32 Advanced DOS Extender, STUB/32A Standard Stub file and\n"); + printf("STUB/32C Configurable Stub file.\n"); + + printf("\n"); + printf("The SVER Utility Program can also be used to display any OEM\n"); + printf("(Original Equipment Manufacturer) Information possibly bound to\n"); + printf("the LC-style executables.\n"); + + printf("\n"); + printf("To display version and OEM information run the SVER Utility on a\n"); + printf("program you wish to inspect. Note that the SVER Utility supports\n"); + printf("DOS Extender version 7.0 or higher only.\n"); + + printf("\n"); + exit(0); +} + + +/****************************************************************************/ +void OpenFile() +{ + char buf[256]; + + strcpy(buf,filename); + if( (fp=fopen(buf,"rb")) == NULL) + { + strcpy(buf,filename); + strcat(buf,".exe"); + if( (fp=fopen(buf,"rb")) == NULL) + { + strcpy(buf,filename); + strcat(buf,".le"); + if( (fp=fopen(buf,"rb")) == NULL) + { + strcpy(buf,filename); + strcat(buf,".lx"); + if( (fp=fopen(buf,"rb")) == NULL) + { + strcpy(buf,filename); + strcat(buf,".lc"); + if( (fp=fopen(buf,"rb")) == NULL) + { + err_open(); + } + } + } + } + } + strcpy(orgfilename,buf); +} + +void ReadFileHeader() +{ + fread(&buffer,1,sizeof(buffer),fp); + if(ferror(fp)) + err_read(); +} + +void CheckFileFormat() +{ + if(strncmp(buffer,"MZ",2) == 0) + { + fileisbound=TRUE; + return; + } + if(strncmp(buffer,"LC",2) == 0) + { + fileisbound=FALSE; + return; + } + err_format(); +} + +void CheckStubExtender() +{ + if(fileisbound==FALSE) + return; + + if(strcmp(&buffer[0x7C],"DOS/32A") == 0) + { + fileverptr=(char *)(buffer+0x85); + extendertype=1; + return; + } + if(strcmp(&buffer[0x9C],"DOS/32A") == 0) + { + fileverptr=(char *)(buffer+0xA5); + extendertype=1; + return; + } + if(strcmp(&buffer[0x20],"STUB/32A") == 0) + { + fileverptr=(char *)(buffer+0x29); + extendertype=2; + return; + } + if(strcmp(&buffer[0x40],"STUB/32A") == 0) + { + fileverptr=(char *)(buffer+0x49); + extendertype=2; + return; + } + if(strcmp(&buffer[0x4C],"STUB/32C") == 0) + { + fileverptr=(char *)(buffer+0x55); + extendertype=3; + return; + } + if(strcmp(&buffer[0x6C],"STUB/32C") == 0) + { + fileverptr=(char *)(buffer+0x75); + extendertype=3; + return; + } + err_extender(); +} + + +void ShowApplicationName() +{ + + printf("\n"); + printf("Application name:\n"); + printf("-----------------\n"); + printf("\"%s\"\n", orgfilename); +} + + +void ShowExtenderVersion() +{ + char buf[8]; + + if(fileisbound==FALSE) + return; + + memset(buf,0,sizeof(buf)); + buf[0] = *(fileverptr+1); + extender_release=atoi(buf); + + memset(buf,0,sizeof(buf)); + buf[0] = *(fileverptr+6); + buf[1] = *(fileverptr+7); + extender_revision=atoi(buf); + + memset(buf,0,sizeof(buf)); + buf[0] = *(fileverptr+3); + buf[1] = *(fileverptr+4); + extender_major_version=atoi(buf); + + memset(buf,0,sizeof(buf)); + buf[0] = *(fileverptr+8); + buf[1] = *(fileverptr+9); + extender_minor_version=atoi(buf); + + memset(buf,0,sizeof(buf)); + buf[0] = *(fileverptr+11); + buf[1] = *(fileverptr+12); + buf[2] = *(fileverptr+13); + buf[3] = *(fileverptr+14); + extender_build_version=atoi(buf); + + + printf("\n"); + if(extendertype ==1 ) + { + printf("DOS/32 Advanced DOS Extender:\n"); + printf("-----------------------------\n"); + } + else if(extendertype == 2) + { + printf("STUB/32A Standard Stub File:\n"); + printf("----------------------------\n"); + } + else if(extendertype == 3) + { + printf("STUB/32C Configurable Stub File:\n"); + printf("--------------------------------\n"); + } + + // v9+ + if(extender_major_version == 0 && extender_minor_version == 0) + { + if(*(fileverptr-3-9) >= 9) + { + extender_minor_version = *(fileverptr-4-9); + extender_major_version = *(fileverptr-3-9); + } + else + { + if(extendertype == 2 || extendertype == 3) + printf("Version: N/A\n"); + else + printf("Version: Unknown\n"); + return; + } + } + + + if(extender_release != 0) + printf("Release: %d\n", extender_release); + + if(extender_major_version < 9) + printf("Version: %d.%d\n", extender_major_version, extender_minor_version); + else + printf("Version: %d.%d.%d\n", extender_major_version, extender_minor_version/10, extender_minor_version%10); + + if(extender_revision != 0) + printf("Revision: [%c]\n", extender_revision+'A'-1); + + if(extender_build_version != 0) + printf("Build: %04d\n", extender_build_version); +} + +void ShowOEMInfo() +{ + int n; + int objects; + unsigned long offs; + unsigned long size; + +// file type must be MZ or LC + if(strncmp(buffer,"MZ",2) != 0 && strncmp(buffer,"LC",2) != 0) return; + +// if MZ, move to Linear Exec start + if(strncmp(buffer,"MZ",2) == 0) + { + offs=0; + offs|=(unsigned long)buffer[0x3C]; + offs|=(unsigned long)buffer[0x3D]<<8; + offs|=(unsigned long)buffer[0x3E]<<16; + offs|=(unsigned long)buffer[0x3F]<<24; + if(offs == 0) return; + } + else offs=0; + + if(fseek(fp,offs,SEEK_SET) != 0) err_seek(); + fread(buffer,1,16,fp); + if(ferror(fp)) err_read(); + +// check if LC-style file format + if(strncmp(buffer,"LC",2) != 0) return; + +// check if OEM Info is appended + if( (buffer[5]&0x80) != 0x80) return; + + objects=buffer[4]; + +// scan through Objects + for(n=0; n