home *** CD-ROM | disk | FTP | other *** search
- ; Quickie startup code to interface PMODE v3.0 with Borland C++ 4.0 for Win32.
- ; By Tran (a.k.a. Thomas Pytel).
-
- .386p
- locals
-
- STACKLEN = 4000h ; size of stack in bytes
-
- PMODE_TEXT segment para public use16 'CODE'
- PMODE_TEXT ends
- _TEXT segment byte public use32 'CODE'
- _TEXT ends
- _DATA segment dword public use32 'DATA'
- _DATA ends
- _BSS segment dword public use32 'BSS'
- _BSS ends
- EXE_STACK segment para stack use16 'STACK'
- EXE_STACK ends
-
- DGROUP group _DATA, _BSS
- assume cs:_TEXT, ds:DGROUP
-
- extrn _pm_info:far, _pm_init:far
-
- PMODE_TEXT segment para public use16 'CODE'
- assume cs:PMODE_TEXT, ds:PMODE_TEXT
-
- ;═════════════════════════════════════════════════════════════════════════════
- align 2
- errmsgtbl dw errmsg0,errmsg1,errmsg2,errmsg3
- dw errmsg4,errmsg5,errmsg6
-
- errmsg0 db 'Not enough low memory!',13,10,36
- errmsg1 db '80386 or better not detected!',13,10,36
- errmsg2 db 'System already in protected mode and no VCPI or DPMI found!',13,10,36
- errmsg3 db 'DPMI host is not 32bit!',13,10,36
- errmsg4 db 'Could not enable A20 gate!',13,10,36
- errmsg5 db 'Could not enter DPMI 32bit protected mode!',13,10,36
- errmsg6 db 'Could not allocate needed DPMI selectors!',13,10,36
-
- ;═════════════════════════════════════════════════════════════════════════════
- start:
- push cs ; DS = CS
- pop ds
-
- call _pm_info ; get information
- jnc short @@startf0 ; if no error, go on
-
- @@startf1:
- mov si,ax ; print error message for code AX
- add si,ax
- mov dx,errmsgtbl[si]
- mov ah,9
- int 21h
- mov ax,4cffh
- int 21h
-
- @@startf0:
- xor ax,ax ; check low memory and allocate low
- mov cx,ss ; buffer needed for protected mode
- add cx,STACKLEN
- movzx edx,word ptr es:[2]
- sub dx,cx
- cmp dx,bx
- jb @@startf1
- mov es,cx
-
- movzx ecx,cx ; calculate base and size of free low
- shl ecx,4 ; memory and push to stack
- push ecx
- sub dx,bx
- shl edx,4
- push edx
-
- call _pm_init ; enter protected mode
- jc @@startf1 ; if error, go to error message
-
- mov cx,1 ; allocate 1 descriptor
- xor ax,ax
- int 31h
-
- mov bx,ax ; BX = descriptor allocated
-
- mov dx,0ffffh ; set size to 4G
- mov cx,dx
- mov ax,8
- int 31h
-
- mov edx,_TEXT ; base address = 32bit code segment
- shl edx,4
- shld ecx,edx,16
- mov ax,7
- int 31h
-
- mov ax,cs ; set descriptor type to 32bit code
- lar cx,ax ; at the current CPL
- mov cl,ch
- mov ch,0c0h
- mov ax,9
- int 31h
-
- mov bp,bx ; preserve selector
-
- mov bx,ds ; BX = current data selector
-
- mov dx,0ffffh ; set size to 4G
- mov cx,dx
- mov ax,8
- int 31h
-
- mov edx,DGROUP ; base address = 32bit data segment
- shl edx,4
- shld ecx,edx,16
- mov ax,7
- int 31h
-
- cli ; we don't want to be interrupted
- ; while changing SS:ESP
- mov ds,bx ; set all segment registers to data
- mov es,bx ; selector
- mov fs,bx
- mov gs,bx
- mov ss,bx
-
- assume ds:DGROUP
-
- mov eax,EXE_STACK ; adjust ESP for new base of stack
- mov ebx,DGROUP
- sub eax,ebx
- shl eax,4
- add esp,eax
-
- sti
-
- mov _lowbase,edx ; base address of 32bit data segment
- pop _lowheaplen ; relative base of free low memory
- pop _lowheapbase ; size of free low memory
-
- push ebp ; push target CS:EIP in 32bit code
- db 66h,68h
- dd offset start32
-
- db 66h ; 32bit RETF to 32bit code
- retf
-
- PMODE_TEXT ends
-
- extrn _PMmain:near
-
- _TEXT segment byte public use32 'CODE'
- assume cs:_TEXT
-
- ;═════════════════════════════════════════════════════════════════════════════
- start32:
- call _PMmain ; call C code
-
- mov ah,4ch ; exit to DOS
- int 21h
-
- _TEXT ends
-
- public _lowbase, _lowheapbase, _lowheaplen
-
- _BSS segment dword public use32 'BSS'
-
- _lowbase dd ? ; base address of 32bit data segment
- _lowheapbase dd ? ; relative base of free low memory
- _lowheaplen dd ? ; size of free low memory
-
- _BSS ends
-
- EXE_STACK segment para stack use16 'STACK'
- db STACKLEN dup(?)
- EXE_STACK ends
-
- end start
-
-