home *** CD-ROM | disk | FTP | other *** search
- DOS32 V1.2
- Copyright Adam Seychell Oct\1993
-
-
- A 386 32 bit dos extender for Assembly Programmers.
-
- Written By Adam Seychell. (5 / SEP / 1993)
-
- email s921880@minyos.xx.rmit.oz.au
-
-
-
- Copying.
-
- Feel free to copy and distribute this program.
- Use it in your programs any way you wish. I am
- distributing this to get people more familiar with
- protected mode programming.
- However if you use this software I require that you
- credit me for its use. Also if you write anything great
- I would appreciate if you could send me a copy of it.
- I have spent a lot of hours writting this DOS extender.
-
-
- ********* FEATURES **********
-
- * Supports DPMI ( windows and OS/2 compatibility !!! )
-
- * Supports XMS
-
- * Supports No memory mangers ( most powerful )
-
- * Data segment descriptors for
- 2. A Flat memory model.
- 3. Conventional memoryn block.
- 4. An allocated extended memory block
- ( size is defined by you).
-
- * All selector values are stored in the code segment.
-
- * Functions to set/get protected mode interrupt
- descriptor vectors.
-
- * Calling real mode interrupts is nearly as easy as
- calling in real mode itself. Switches to V86 mode when
- called.
-
- * Supports the SYSTEM BIOS COPY EXTENDED MEMORY BLOCK
- function INT 15h, AH = 87h for real mode. So a real
- mode TSR that calls this BIOS function (eg. HIMEM.SYS )
- will be emulated the dos extender. This allows TSRs like
- disk caches and ram drives to be running.
-
-
-
-
- Introduction.
-
- DOS32.ASM is a 386 protected mode initialise
- program. The purpose of it is to make protected mode
- programming very easy. When I was writing DOS32.ASM my aim was
- to use full 32bit power of the 386 while making it as easy as
- possible to program.
- The DOS32.ASM is meant to be assembled as an object
- file and then linked to you assembler program. You ASM file
- must follow the following rules. I tried to make this
- simple as possible.
-
-
- * The segment of your 32 bit program must be named CODE32
- * Pass V86 mode segment registers in the program segment.
- ( see below for details)
- * Must have a starting point called "START32:" in your
- program segment.
- * Requires you to load valid selectors in ES,GS,FS,SS,DS and
- set the stack pointer ( ESP ).
- * Must terminate the program with INT 21h, AH = 4Ch.
- * Requires a small include file to setup macros,
- structures ect.
-
-
- **** DETAILS ON WHAT DOS32 DOES. *****
-
- DOS32.ASM basicly contains code to set up segment descriptors
- in the LDT or GDT, enter/exit protected mode, allocated/free a
- extended memory block and call real mode interrupts. These
- parts of the DOS32.ASM will never have to be called directly
- form your program.
-
- Your programs code and data segment descriptors have the same
- base addresses. This base address in equal to the address of
- the CODE32 segment. It is easier to program with only a single
- code and data segment area. The stack can be anywhere you
- want it to be.
-
-
- DOS32 SERVICES
-
- Note. If operating under DPMI then all DPMI services will be
- available.
-
- When not operating under DPMI there are two services in the
- dos extender to set and get the protected mode interrupt
- vectors. These will work exactly the same as the real DPMI services.
-
- SET interrupt
- ax = 204h
- bl = interrupt number
- edx = offset
- cx = selector
- int 31h
- returns: carry set on error
-
- GET interrupt
- ax = 205h
- bl = interrupt number
- int 31h
- returns: edx = offset
- cx = selector
-
- Also the Programible Interrupt Controllers ( 8259) base vector
- values can be obtained from the DPMI Get Version function, int 31h
- ax = 400h. If not running under DPMI then only the PIC bases
- are returned.
- DH = master PIC ( pic 2 )
- DL = slave PIC ( pic 1 )
-
-
-
-
- AVAILABLE DESCRIPTORS .
- There are eight available descriptors for you program
- that DOS32.ASM initially sets up. The selector values for each
- descriptor is stored in the data segment under the labels:
-
-
- PSP_sel :Data descriptor for the Program Segment Prefix
- Base = the real mode PSP segment.
- Limit = 100h
-
- ENVIRONMENT_sel :Data descriptor for the Program Environment
- Base = 16 multiplied by the word at offset 2Ch of the PSP.
- Limit = 100h
-
- Data_sel :Data descriptor for your program segment "CODE32"
- Base = the real mode program segment.
- Limit = 1MB ( B=1 . i.e uses 32bit stack mode)
-
- Code32_sel :32 bit code descriptor for your program segment "CODE32"
- Base = the real mode program segment.
- Limit = 1MB
-
- XMS_sel :Data descriptor for the allocated extended memory block
- Base = the base address of the block
- Limit = Size of the allocated block ( see below)
-
- BASE_sel :Data descriptor for the free base memory
- Base = the unused base memory straight after
- MSDOS loads in you program. (see below)
- Limit = 1Mb
-
-
- VIDEO_sel :Data descriptor for the video area.
- Base = A0000h
- Limit = 20000h
-
- FLAT_DATA_sel :Data descriptor for a flat memory model
- Base = 0
- Limit = FFFFFFFFh
-
- FLAT_CODE32_sel :32 bit code descriptor for a flat memory model
- Base = 0
- Limit = FFFFFFFFh
-
-
-
- The first instruction of you program will be executed is
- at offset "start32:" in your program segment with interrupts
- DISABLED.
-
- Your program is initially started with undefined selectors in
- all the data segemnt registers ( ES,DS,FS,GS,SS).
- Thus your program must load valid selectors into ES,FS,GS,DS,SS if
- it's going to use any of them.
- The stack pointer is also need to be loaded to a stack area.
- Initially there is a *SMALL* stack but I recomend to set your own.
-
-
- Example of initalize with the stack in your program segment.
- ;----------------------------------------
- CODE32 SEGMENT USE32
- start32: ; starting point
- mov ds,cs:[ Data_Sel] ; Load all data Segment registers
- mov gs,cs:[ Flat_Sel]
- mov es,cs:[ Flat_Sel]
- mov fs,cs:[ XMS_Sel]
- mov ss,cs:[ Data_Sel]
- mov esp,OFFSET your_stack
- sti ; Can now enable interrupts safely
- ...
- ... You program
- ...
- ...
-
- mov ah,4ch ; terminate
- int 21h
-
- db 1000h (?) ; set up some stack area
- your_stack:
- CODE32 ENDS
- ;----------------------------------------
-
- One more feature with DOS32.ASM is that in the program segment
- there are four labels with usful information about memory.
-
- 1) "Base_Segment" will contain a real mode segment value
- of the start of free base memory. i.e The value stored in
- this label * 16 = the base address of the BASE_sel descriptor.
-
- 2) "PSP_segment". The real mode segment vlaue of the
- program segment prefix.
-
- 3) "XMS_base". Contains the linear base address of the
- allocated extended memory block.
-
- 4) "XMS_usage". This location contains the number of bytes
- of the allocated extended memory block required by your program.
- DOS32.ASM will read the value of this Label and attempt to
- allocate that amount of memory. If there isn't a enough free
- memory then DOS32 will allocate as mush as it can and
- return what was actually allocated back into this Label.
-
- Notes
- o The XMS_sel descriptor Limit is set to this value.
- o The Memory allocated will never be greater than
- lockable memory when in a virtual disk environment.
- o If the XMS driver nor DPMI is available then the
- entire extended memory will be allocated by the xms
- descriptor. base = 0100000h , limit = available ram.
- o If XMS_usage is zero then no memory will be
- allocated and the XMS_sel will point to a invalid
- descriptor.
-
-
-
-
-
-
- Calling a Real mode interrupt:
-
- This is one of the most useful features of DOS32.ASM. The
- way the interrupt is called is through the macro "DOSINT"
- followed by the interrupt number. This macro actually consists
- of three instructions ( see DOS32.INC).
- When the real mode interrupt is called, all the
- 32bit general registers and the 16bit flags ( except for ESP )
- are loaded with the same values they were in protected mode.
- Because in protected mode the segment registers cant be loaded
- with any value (except for valid selectors) a different method
- is used to pass the segment register values.
- The segment registers values MUST be passed from
- protected mode to the called real mode interrupt through several
- labels in your program segment. See the file DOS32.INC for the
- declearation of these labes ( or locations ).
- They are named:
- Real_DS ; holds the DS register when in V86 mode.
- Real_ES ; holds the ES register when in V86 mode.
- Real_FS ; and so on
- Real_GS
- Real_SS ; These are already loaded by DSO32 with
- Real_SP ; V86 stack area. See below.
-
-
- This is the easiest and most versatile way I could
- think how to do it.
-
-
- eg . to print a string using dos func 9 int 21h
- ;---------------------------------------------------------
- mov [Real_DS] ,seg test_message ; pass DS register
- mov ah,9
- mov dx,offset test_message
- dosint 21h
-
- mov ah,4ch ; Terminate program
- int 21h
-
- db test_mesg ' String message using dos func ah = 9'
- db ' in protected mode.',10,13,36
- ;---------------------------------------------------------
-
- Just like using a real mode INT, all the general registers,
- flags and segment registers(stored in you program segment) will be
- returned with the values after the real mode interrupt call.
-
-
- V86 MODE STACK AREA
-
- The only thing to left to say about the called real
- mode interrupt is that the stack is initaly set up by DOS32.ASM.
- Although you can set the V86 mode stack by simply loading the lables
- [Real_SP] and [Real_SS], DOS32 already sets aside some a stack area .
- The real mode stack space is defined by an equate in DOS32.ASM
- called "V86_stack_size". It is initially set to 200h and shouldn't
- need to be changed. I thought this should be a safe value.
-
-
-
-
- **** I don't ever want to here of people complaining
- about the 640K limit for there own assembly programs !
-