flat assembler
Message board for the users of flat assembler.

Index > DOS > using windows dpmi for .com program

Thread Post new topic Reply to topic

Joined: 18 Sep 2005
Posts: 106
wht36 17 Oct 2011, 07:04
Hi, I wrote a small include file which allows one to write 32 bit .com programs with 32mb of pre-allocated memory under windows XP. Not sure if it will work under vista or windows 7. The code is minimalistic and DPMI is outdated but comments and advice are welcome. Many thanks.
; minimalistic include file for DPMI under windows XP
; include at start of .com program for 32 bit com file with 32mb memory allocated
; to exit use ret to exit, or call exit
; on entry
; esi/edi points to ~32mb of free memory
; e.g.
; include 'dpmi.inc'
; mov edx,hello
; mov ah,9
; int 21h
; ret
; hello: db 'Hello from Protected mode!$'

org 100h

;----------- Routine to enter protected mode ---------------------------
;   mov bx,sp
;  shr bx,4
;   inc bx
;     mov ah, 4Ah     ;INT 21,4A Modify allocated ES memory block to BX new size in paragraphs
;   int 21h         ;On error: CF set, AX error code, BX maximum possible size if AX=8
;     mov bp,bx
;  sub bp,4        ;allocate 4 paragraphs in stack for DPMI host
;      sub sp,64
   mov bp,(65536-256)/16

get_pmode_entry:       ;INT 2F,1687h return protected mode entry point in ES:DI
        mov ax,1687h    ;AX 0 if success, BX bit 0 set if 32-bit supported
  int 2Fh         ;CL CPU type (02 = 286, 03 = 386, 04 = 486...)
      or ax,ax        ;DH DPMI major version, DL minor ver
        jnz error       ;SI memory paragraphs needed by DPMI host
;       test bl,1
;       jz error

        push es
     push di         ;DPMI switch is called with
 mov es,bp       ; ES allocated segment for DPMI host
        mov bx,sp
   inc ax          ; AX bit 0 = 1 if 32 bit program
    call far [bx]
       jc error        ;On error CF set, program in real mode.
     ;Else we are in protected mode
      ;CS: base of real mode CS, 64K limit
    ;SS: base of real mode SS, 64K limit
    ;DS: base of real mode DS, 64K limit
    ;ES: base of PSP, 256 byte limit (NOT setup to its real mode segment!)
  ;FS and GS = 0 (if 386+)
    ;High word of ESP 0, all other registers preserved


    mov ax,0501h
        mov bx,(32*1024*1024) shr 16    ;allocate 32mb (default maximum that Vista will allocate for DPMI)
  sub cx,cx
   int 31h                 ;INT 31/0501h allocates BX:CX bytes of memory
   mov [mem_handle_si],si  ;return SI:DI memory handle for resizing and freeing block
      mov [mem_handle_di],di  ;       BX:CX = linear address
  jc error                ;CF set if error

       mov dx,cx
   mov cx,bx
   mov bx,es
   mov ax,7        ;INT 31/0007 set CX:DX segment base address for BX selector
     int 31h         ;CF set on error AX = error code

      mov dx,-1
   mov cx,-1
   inc ax          ;INT 31/0008 set CX:DX segment limit for BX selector
    int 31h
    mov cx,1100111111110011b
    inc ax          ;INT 31/0009 Set CX access rights for BX selector
   int 31h

       sub di,di       ;copy program to memory block
       sub si,si
   mov cx,sp
   rep movsb       ;edi, esi = after stack
     mov ds,bx       ;single segment for DS, SS, ES
      mov ss,bx

       mov cx,1100111111111011b
    mov bx,cs       ;switch on 32 bit code
      int 31h
    ;Descriptor details
 ;byte   bit
 ;7              BASE 31..24
 ;6      7       (G) 1 = page granular (segment limit = LIMIT*4096)
  ;       6       (D) 1 = default is 32 bit code/esp
  ;       5       (L) 1 = 64 bit segment (long mode)
  ;       4       AVaiLable for use by operating system = 0
   ;       3..0    LIMIT 19..16
        ;5      7       (P) 1 = present in memory.
  ;               OS sets P=0 when it caches the segment to disk, so access
   ;               sends an exception; OS then loads the segment and sets P=1.
 ;       6..5    Descriptor Privilege Level. Highest=ring 0. Lowest=ring 3.
  ;       4       0 = system descriptor, 1 = code/data descriptor 
    ;       TYPE    Data descriptor         Code descriptor
     ;         3     0 Data                  1 Executable
        ;         2     0 Expand up, 1 down     0 Non-conforming, 1 conforming
      ;         1     0 Read-only, 1 R/W      0 Execute only, 1 readable
  ;       0       (A) Set upon segment access so OS can determine the frequency
       ;                   of use and if it can be cached to disk.
 ;4..2           BASE 23..0
  ;1..0           LIMIT 15..0

    call main

exit:      mov ah,1        ;ask for user input to flush previous DOS calls (otherwise won't display previous output)
  int 21h
     mov si,0        ;INT 31/0502h free SI:DI memory handle (otherwise will crash NTVDM next time we run pgm)
mem_handle_si = $-2
 mov di,0
mem_handle_di = $-2
     mov ax,0502h
        int 31h

error:       mov ah,4Ch      ;quit
       int 21h

;-------------- 32 bit user code goes here -------------------
Post 17 Oct 2011, 07:04
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum

Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.