home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
vrac
/
pmw100.zip
/
PMODEWE.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-11-21
|
55KB
|
2,162 lines
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; PMODE DOS Extender Stub Module For Watcom C/C++ LE Format Executables v3.06
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
.386p
locals
STACKLEN = 40h ; size of stub stack in paragraphs
EXTMAX = 7fffffffh
EXTMIN = 0
LOWMIN = 0ffffh
OPENTYPE = 1
VARTYPE = 1
;DEBUG=1
PM_PMSTACKLEN = 200h
PM_RMSTACKLEN = 100h
PM_PMSTACKS = 8
PM_RMSTACKS = 8
PM_MODE = 1
PM_CALLBACKS = 32
PM_SELECTORS = 256
PM_PAGETABLES = 4
PMODE_TEXT segment para public use16 'CODE'
;db 'PMODE DOS Extender Stub Module v1.0 - Copyright (c)1994 Daredevil/Tran'
PMODE_TEXT ends
pmcode16 segment para public use16 'CODE'
pmcode16 ends
pmstack segment para stack use16 'STACK'
pmstack ends
extrn _pm_info:far, _pm_init:far, _pm_cleanup:far
extrn _pm_pagetables:byte, _pm_selectors:word
extrn _pm_rmstacklen:word, _pm_pmstacklen:word
extrn _pm_rmstacks:byte, _pm_pmstacks:byte
extrn _pm_callbacks:byte
extrn _pm_mode:byte
pmcode16 segment para public use16 'CODE'
assume cs:pmcode16,ds:pmcode16
ifdef DEBUG
include debug.inc
endif
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
align 4
errmsgtbl dw errmsg0,errmsg1,errmsg2,errmsg3
dw errmsg4,errmsg5,errmsg6,errmsg7
dw errmsg8,errmsg9,errmsg10,errmsg11
pmodemsg db '[PMODE]: $'
errmsg0 db 'Not Enough Memory Available!',13,10,36
errmsg1 db '80386+ 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
errmsg7 db 'Error Loading LE!',13,10,36
errmsg8 db 'Unrecognized Data In LE!',13,10,36
errmsg9 db 'Cannot Address Above 1 MB From Real Mode Segment!',13,10,36
errmsg10 db 'Unable To Initialize DOS Extender!',13,10,36
errmsg11 db 'Error Allocating DPMI Memory!',13,10,36
_extmin dd ?
_extmax dd ?
_lowmin dw ?
_selbuf dw ?
_selcode dw ?
_selzero dw ?
_selpsp dw ?
_selfixup dw ?
_pmreqpara dw ?
_exehandle dw ?
_pspseg dw ?
_envseg dw ?
_selrights dw ?
_cr0valuerm dd ?
_cr0valuepm dd ?
_membase dd ?
_memtop dd ?
FIXUPBUFMIN = 2000h
_fixupbufptr dd ?
_fixupbufsize dd ?
_dtabufptr dd ?
_dtabufsize dd 200h
_lowbufptr dd ?
_lowbufsize dd 1000h ; MUST Be A Multiple Of 4 Or You Will Suffer!
; (1000h Bytes Is The Suggested Minimum)
_exebaseoffset dd ?
MAXOBJECTS = 16
_objectlocs dd MAXOBJECTS dup (?)
_objectlens dd MAXOBJECTS dup (?)
_objectpageidx dd MAXOBJECTS dup (?)
_objectpagenum dd MAXOBJECTS dup (?)
_objectflags dd MAXOBJECTS dup (?)
_objectsels dd MAXOBJECTS dup (?)
_nextobjectloc dd ?
_numobjects dd ?
_currentobject dd ?
_oldfilepos1 dd ?
_datapagesloc dd ?
__D16Infoseg dw ?
__PMODE_systype db ?
_inpmode db 0
_oldint31off dd ?
_oldint31sel dw ?
pushd macro reg
db 66h
push ®
endm
popd macro reg
db 66h
pop ®
endm
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; 16-BIT REAL MODE CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
_pm16start:
push cs
pop ds
cld
mov _pspseg,es
mov ax,es:[2ch]
mov _envseg,ax
xor eax,eax
mov ax,es:[2]
mov _memtop,eax
mov ax,STACKLEN
mov cx,ss
add ax,cx
mov _membase,eax
mov eax,_lowbufsize
call _getmem
jc _memoryerr
mov _lowbufptr,eax
mov eax,_dtabufsize
call _getmem
jc _memoryerr
mov _dtabufptr,eax
call _openexe1
call _openexe2
call _pm_info
jc _pmstartuperr
mov _pmreqpara,bx
mov __PMODE_systype,ch
xor ax,ax
mov ebx,_memtop
sub ebx,_membase
cmp bx,_pmreqpara
jb _pmstartuperr
mov es,_membase
movzx ebx,_pmreqpara
add _membase,ebx
mov eax,cr0
mov _cr0valuerm,eax
call _pm_init
jc _pmstartuperr
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; BEGINNING OF 16-BIT PROTECTED MODE CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
mov eax,cr0
mov _cr0valuepm,eax
mov _inpmode,0ffh
mov _selpsp,es
xor edi,edi
or ecx,-1
mov ax,cs
lar dx,ax
mov dl,dh
and dl,60h
or dl,9ah
mov dh,0c0h
call _initdescriptor
jc _descriptorerr
mov _selcode,ax
and dl,NOT 8
mov _selrights,dx
call _initdescriptor
jc _descriptorerr
mov fs,ax ; Set FS,GS To Data Selector
mov gs,ax ; (ES Left Intact As PSP Selector)
mov _selzero,ax
mov edi,_dtabufptr
shl edi,4
call _initdescriptor
jc _descriptorerr
mov _selbuf,ax
mov edi,_lowbufptr
shl edi,4
call _initdescriptor
jc _descriptorerr
mov __D16Infoseg,ax
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; PROTECTED MODE STARTUP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
mov ebx,_dtabufptr
mov ecx,_lowbufsize
mov edx,_lowbufptr
push fs
mov fs,__D16Infoseg
call _initdosext
pop fs
jc _exiterror
cmp __PMODE_systype,3
jz short _nomeminit1
mov edx,cs:_extmax
mov ax,5ffh
int 31h
jc _DPMImemoryerr
_nomeminit1:
mov ax,204h
mov bl,31h
int 31h
jc _exiterror
mov _oldint31sel,cx
mov _oldint31off,edx
mov ax,205h
mov cx,cs
mov edx,offset _int310A00
int 31h
jc _exiterror
shl _dtabufptr,4
push fs gs
call _loadexe ; Load LE EXE Into Memory
pop gs fs
mov ebx,_dtabufptr
mov edx,gs:[ebx+20h]
mov edx,_objectlocs[edx*4-4]
add edx,gs:[ebx+24h]
mov ax,gs
mov ss,ax ; Set Up Stack Selector
mov esp,edx ; And ESP
mov ebx,_dtabufptr
mov edx,gs:[ebx+18h]
mov edx,_objectlocs[edx*4-4]
add edx,gs:[ebx+1ch]
movzx ebp,_selcode
push ebp ; 4G 32bit CS
push edx ; 32bit EIP For Program Start
mov ebx,_membase
sub bx,_pspseg
mov es,_selpsp
mov ah,4ah
int 21h
mov es,_selpsp
mov ax,gs
mov ds,ax
db 66h ; 32bit RETF To New CS
retf
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; INT 31H HANDLER
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
_int310A00:
cmp ax,0a00h
jnz short _int31not0A00
and dword ptr [esp+8],NOT 1
iretd
_int31not0A00:
jmp fword ptr cs:_oldint31off
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; SUBROUTINES
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
IF OPENTYPE EQ 1
_openexe1:
mov edx,_lowbufptr ; Get EXE Name and Open It
push ds
mov ds,dx
shr edx,16
call _getexe
mov ax,3dc0h
int 21h
pop ds
jc _loaderror
ret
ENDIF
IF OPENTYPE EQ 2
_openexe1:
push ds
xor ax,ax
mov ds,ax
mov dx,4c0h
mov ax,3dc0h
int 21h
pop ds
jc _loaderror
ret
ENDIF
IF OPENTYPE EQ 3
_filename db 128 dup (?)
_openexe1:
cld
push es ds
mov ds,cs:_pspseg
mov ax,cs
mov es,ax
mov di,offset _filename
mov si,80h
lodsb
or al,al
jz _openexe3err
_openexe3a1:
lodsb
cmp al,20h
jz _openexe3a1
mov cx,-1
jmp _openexe3b
_openexe3a:
lodsb
_openexe3b:
cmp al,20h
jz _openexe3c
cmp al,0dh
jz _openexe3c
stosb
dec cx
jnz _openexe3a
jmp _openexe3err
_openexe3c:
xor al,al
stosb
xor bl,bl
dec si
mov ax,ds
mov es,ax
mov di,81h
_openexe3d:
lodsb
or al,al
cmp al,0dh
jz _openexe3e
inc bl
stosb
jmp _openexe3d
_openexe3e:
stosb
mov es:[80h],bl
mov dx,offset _filename
push cs
pop ds
mov ax,3dc0h
int 21h
pop ds es
jc _loaderror
ret
_openexe3err:
pop ds es
jmp _loaderror
ret
ENDIF
IF VARTYPE EQ 1
_openexe2:
mov _exehandle,ax
push ds
mov bx,ax
mov cx,40h+21
mov eax,_dtabufptr
mov ds,ax
xor dx,dx
mov ah,3fh
int 21h
jc _loaderror
push es
mov si,40h
mov ax,PMODE_TEXT
mov es,ax
mov di,offset _pm_pagetables
mov cx,11
rep movsb
mov ax,pmcode16
mov es,ax
mov di,offset _extmin
mov cl,10
rep movsb
pop es
pop ds
ret
ENDIF
IF VARTYPE EQ 2
_openexe2:
mov _exehandle,ax
mov _extmin,EXTMIN
mov _extmax,EXTMAX
mov _lowmin,LOWMIN
push ds
mov bx,ax
mov cx,40h
mov eax,_dtabufptr
mov ds,ax
xor dx,dx
mov ah,3fh
int 21h
jc _loaderror
mov ax,PMODE_TEXT
mov ds,ax
mov _pm_pmstacklen,PM_PMSTACKLEN
mov _pm_rmstacklen,PM_RMSTACKLEN
mov _pm_pmstacks,PM_PMSTACKS
mov _pm_rmstacks,PM_RMSTACKS
mov _pm_mode,PM_MODE
mov _pm_selectors,PM_SELECTORS
mov _pm_callbacks,PM_CALLBACKS
mov _pm_pagetables,PM_PAGETABLES
pop ds
ret
ENDIF
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Load The EXE (LE Format) Into Memory
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
db 'C' XOR 66h ,'.' XOR 66h ,' ' XOR 66h ,'S' XOR 66h ,'C' XOR 66h ,'H' XOR 66h ,'E' XOR 66h ,'F' XOR 66h ,'F' XOR 66h ,'O' XOR 66h ,'L' XOR 66h ,'D' XOR 66h ,'/' XOR 66h
db 'T' XOR 66h ,'.' XOR 66h ,' ' XOR 66h ,'P' XOR 66h ,'Y' XOR 66h ,'T' XOR 66h ,'E' XOR 66h ,'L' XOR 66h
_loadexe:
; mov ecx,40h ; Read In EXE Header To Temp Buffer
; mov edx,_dtabufptr
; call _readfile
mov dx,_selbuf ; Get LE Location From EXE Header
mov gs,dx ; And Seek To It
mov edx,gs:[3ch]
mov _exebaseoffset,edx
call _seekfile
mov ecx,0c4h ; Read In LE Header To Temp Buffer
mov edx,_dtabufptr
call _readfile
cmp word ptr gs:[0],'EL' ; Check LE Sig Just For The Hell Of It
jnz _loaderror
mov eax,gs:[80h] ; Get Beginning Offset Of Object Data
mov _datapagesloc,eax
mov ebp,gs:[44h] ; Get Number Of Objects
or ebp,ebp
jz _loaderror
mov _numobjects,ebp
mov edx,gs:[40h] ; Seek To The Object Table
add edx,_exebaseoffset
call _seekfile
xor ebp,ebp
_loadobjects:
mov ecx,18h ; Read Info For This Object
mov edx,_dtabufptr
add edx,100h
call _readfile
call _filepos ; Save File Position For Later
mov _oldfilepos1,eax
mov eax,gs:[100h] ; Allocate Some Memory For This Object
movzx edx,_lowmin
mov edi,_memtop
sub edi,_membase
mov ecx,eax
add ecx,15
shr ecx,4
sub edi,ecx
jc _loadtryhimem
cmp edi,edx
jae _loadtrylowmem
test dword ptr gs:[108h],1000000000000b
jnz _loadtrylowmem
call _gethimem
jnc _loadlowmemok
_loadtrylowmem:
call _getmem
jc short _loadtryhimem
shl eax,4
jmp short _loadlowmemok
_loadtryhimem:
test dword ptr gs:[108h],1000000000000b
jnz _memoryerr
mov eax,gs:[100h]
call _gethimem
jc _memoryerr
_loadlowmemok:
mov edi,eax
mov edx,_datapagesloc ; Seek To Current Object Page Location
call _seekfile
mov ecx,gs:[100h] ; Read Object Into Memory
mov eax,gs:[110h]
shl eax,12
mov edx,eax
sub edx,ecx
jnc short _nozerobss1
push es eax ecx edi
sub ecx,eax
add edi,eax
mov es,_selzero
xor al,al
rep stos byte ptr es:[edi]
pop edi ecx eax es
mov edx,ecx
sub edx,eax
sub ecx,edx
jz _noreadobject1
_nozerobss1:
mov edx,edi
call _readfile
_noreadobject1:
mov eax,ecx
mov edx,ecx
and eax,0fffff000h
and edx,0fffh
jz short _loadobj1
add eax,1000h
_loadobj1:
add _datapagesloc,eax ; Update Information For Object Pages
mov bx,bp
shl bx,2
mov _objectlocs[bx],edi
mov _objectlens[bx],ecx
mov eax,gs:[108h]
mov _objectflags[bx],eax
test eax,10000000000000b
jz _loadobj1a
mov ax,_selcode
mov word ptr _objectsels[bx],ax
mov ax,_selzero
mov word ptr _objectsels[bx+2],ax
jmp short _loadobj1b
_loadobj1a:
or ecx,-1
mov dx,_selrights
call _initdescriptor
jc _descriptorerr
mov word ptr _objectsels[bx+2],ax
or dl,8
call _initdescriptor
jc _descriptorerr
mov word ptr _objectsels[bx],ax
_loadobj1b:
mov eax,gs:[10ch]
mov _objectpageidx[bx],eax
mov eax,gs:[110h]
mov _objectpagenum[bx],eax
mov edx,_oldfilepos1
call _seekfile
inc ebp
cmp ebp,_numobjects
jnz _loadobjects
;------------------------------------------------------------------------------
mov edi,_membase ; Allocate Buffer For Fixup Information
shl edi,4 ; Which Will Be Discarded Later
mov _fixupbufptr,edi
or ecx,-1
mov dx,_selrights
call _initdescriptor
jc _loaderror
mov _selfixup,ax
mov fs,ax
mov eax,_memtop
sub eax,_membase
shl eax,4
mov _fixupbufsize,eax
cmp eax,FIXUPBUFMIN
jb _memoryerr
mov ax,_selzero
mov es,ax
xor ebp,ebp
_relocateobjects:
mov edx,gs:[48h] ; Seek To The First Page Table Index
add edx,_exebaseoffset ; For This Object
cmp dword ptr ds:_objectpagenum[ebp*4],0
jz _norelocate2
mov eax,ds:_objectpageidx[ebp*4]
lea edx,[edx+eax*4-4]
call _seekfile
xor ebx,ebx
_relocate1:
mov ecx,4 ; Read Next Object Page Map Entry
mov edx,_dtabufptr
add edx,100h
call _readfile
call _filepos ; Save File Position For Later
mov _oldfilepos1,eax
movzx eax,word ptr gs:[101h] ; Skip If No Relocation On This Page
or ax,ax
jz _norelocate1
xchg al,ah
mov edx,gs:[68h] ; Seek To Fixup Page Table
add edx,_exebaseoffset
lea edx,[edx+eax*4-4]
call _seekfile
mov ecx,8 ; Read 2 Fixup Entries
mov edx,_dtabufptr
add edx,100h
call _readfile
mov eax,gs:[100h]
cmp eax,gs:[104h]
jz _norelocate1
mov esi,gs:[100h]
mov edx,gs:[6ch]
add edx,_exebaseoffset
add edx,esi
call _seekfile
mov ecx,gs:[104h]
sub ecx,gs:[100h]
cmp ecx,_fixupbufsize
ja _loaderror
mov edx,_fixupbufptr
call _readfile
mov edi,ds:_objectlocs[ebp*4]
mov eax,ebx
shl eax,12
add edi,eax
mov _nextobjectloc,ecx
mov _currentobject,ebp
push ebx ebp
xor esi,esi
_relocate2:
lods word ptr fs:[esi]
mov dx,ax
test dh,3
jnz _unknownerror
test dl,20h
jnz _unknownerror
test dh,4
jnz _unknownerror
lods word ptr fs:[esi] ; ES:[EBX+EDI] -> Source
movsx ebx,ax
xor eax,eax
lods byte ptr fs:[esi]
test dh,40h
jz short _relocate2a
mov ah,fs:[esi]
inc esi
_relocate2a:
mov ecx,eax
mov ebp,_objectlocs[ecx*4-4]
mov al,dl
and al,0fh
cmp al,2
jz _relocate2b
xor eax,eax
lods word ptr fs:[esi]
test dh,10h
jz short _relocate2b
rol eax,16
lods word ptr fs:[esi]
rol eax,16
_relocate2b:
call _relocateitem
cmp esi,_nextobjectloc
jnz _relocate2
pop ebp ebx
_norelocate1:
mov edx,_oldfilepos1
call _seekfile
inc ebx
cmp ebx,ds:_objectpagenum[ebp*4]
jnz _relocate1
_norelocate2:
inc ebp
cmp ebp,_numobjects
jnz _relocateobjects
;------------------------------------------------------------------------------
mov ah,3eh ; Close EXE File
mov bx,_exehandle
int 21h
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; REAL MODE - Relocate One Item
; In:
; EAX - Target Offset
; EBP - Zero Based Target Begining Offset
; DL - Fixup Type
; DH - Fixup Flags
; ECX - Target Object Number
; ES:EBX -> Pointer To Relocation Source
; Out:
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_r_table dw offset _r_byteoffset
dw offset _r_unknown
dw offset _r_wordsegment
dw offset _r_16bitfarptr
dw offset _r_unknown
dw offset _r_16bitoffset
dw offset _r_32bitfarptr
dw offset _r_32bitoffset
dw offset _r_nearcalljmp
_relocateitem:
push eax ebp esi
movzx esi,dl
and esi,15
cmp esi,8
ja _unknownerror
jmp _r_table[esi*2]
_r_byteoffset:
jmp _r_unknown
_r_wordsegment:
or ebx,ebx
js _r_done
call _r_segmentfixup
mov es:[edi+ebx],bp
jmp _r_done
_r_16bitfarptr:
or ebx,ebx
js _r_done
call _r_segmentfixup
mov es:[ebx+edi],ax
mov es:[ebx+edi+2],bp
jmp _r_done
_r_16bitoffset:
or ebx,ebx
js _r_done
mov es:[ebx+edi],ax
jmp _r_done
_r_32bitfarptr:
jmp _r_unknown
_r_32bitoffset:
or ebx,ebx
js _r_done
add eax,ebp
mov es:[ebx+edi],eax
jmp _r_done
_r_nearcalljmp:
jmp _r_unknown
_r_unknown:
jmp _unknownerror
_r_done:
pop esi ebp eax
ret
_r_segmentfixup:
mov esi,_currentobject
test word ptr _objectflags[esi*4-4],1000000000000b
jnz _r_wordsegment2
test word ptr _objectflags[ecx*4-4],100b
jz _r_wordsegment1
mov bp,word ptr _objectsels[ecx*4-4]
jmp short _r_wordsegment3
_r_wordsegment1:
mov bp,word ptr _objectsels[ecx*4-2]
jmp short _r_wordsegment3
_r_wordsegment2:
shr ebp,4
; test dl,10h
; jz _r_wordsegment3
test ebp,0ffff0000h
jnz _16biterror
_r_wordsegment3:
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Setup A New Descriptor
; In:
; EDI - Base Address
; DX - Access Rights
; ECX - Limit
; Out:
; AX - Selector
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_initdescriptor:
push ebx ecx edx ebp
mov ebp,ecx
xor ax,ax
mov cx,1
int 31h
jc _initdescerr
xchg bx,ax
mov ax,9
mov cx,dx
int 31h
jc _initdescerr
mov ax,7
mov ecx,edi
mov dx,cx
shr ecx,16
int 31h
jc _initdescerr
mov ax,8
mov ecx,ebp
mov dx,cx
shr ecx,16
int 31h
jc _initdescerr
mov ax,bx
clc
_initdescerr:
pop ebp edx ecx ebx
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Quickie Read To Buffer
; In:
; ECX - Number Of Bytes To Read
; EDX - Zero Based Buffer Offset
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_readfile:
push eax bx ds
mov ah,3fh
mov ds,cs:_selzero
mov bx,cs:_exehandle
int 21h
pop ds bx eax
jc _loaderror
ret
_seekfile:
push ax bx ecx dx
mov ecx,edx
shr ecx,16
mov ax,4200h
mov bx,cs:_exehandle
int 21h
pop dx ecx bx ax
jc _loaderror
ret
_filepos:
push bx cx dx
xor cx,cx
xor dx,dx
mov ax,4201h
mov bx,cs:_exehandle
int 21h
jc _loaderror
rol eax,16
mov ax,dx
rol eax,16
pop dx cx bx
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Get Some Low Memory
; In:
; EAX - Number Of Bytes To Get
; Out:
; EAX - SEG:OFF Pointer (Offset Always 0)
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_getmem:
add eax,15
shr eax,4
add eax,_membase
cmp eax,_memtop
ja _getmemerr
xchg eax,_membase
clc
jmp short $+3
_getmemerr:
stc
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Get Some High Memory
; In:
; EAX - Number Of Bytes To Get
; Out:
; EAX - Absolute Address Of Block
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gethimem:
push bx cx si di
mov cx,ax
shr eax,16
mov bx,ax
mov ax,501h
int 31h
jc short _gethimemerr
mov ax,bx
shl eax,16
mov ax,cx
clc
_gethimemerr:
pop di si cx bx
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; REAL MODE - Get EXE Name
; In:
; DS:DX -> Buffer For ASCIIZ String
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_getexe:
push ax cx dx si di es
mov di,cs:_envseg
mov es,di
xor di,di
or cx,-1
xor al,al
@@00l:
repne scasb
scasb
jne @@00l
add di,2
mov si,di
or cx,-1
repne scasb
not cx
mov di,dx
mov ax,es
mov dx,ds
mov ds,ax
mov es,dx
mov ax,di
rep movsb
mov cx,es
mov ds,cx
pop es di si dx cx ax
ret
_16biterror:
mov ax,9
jmp short _pmstartuperr
_descriptorerr:
mov ax,6
jmp short _pmstartuperr
_exiterror:
mov ax,10
jmp short _pmstartuperr
_unknownerror:
mov ax,8
jmp short _pmstartuperr
_DPMImemoryerr:
mov ax,11
jmp short _pmstartuperr
_memoryerr:
xor ax,ax
jmp short _pmstartuperr
_loaderror:
mov ax,7
_pmstartuperr:
mov si,ax
add si,ax
mov ax,cs
mov ds,ax
mov dx,offset pmodemsg
call _pmsg
mov dx,errmsgtbl[si]
call _pmsg
mov ax,4cffh
int 21h
_pmsg:
cmp _inpmode,0ffh
jz _pmerr1
mov ah,9
int 21h
ret
_pmerr1:
sub esp,32h
mov ebp,esp
mov byte ptr [ebp+_eax+1],9
mov word ptr [ebp+_ds],pmcode16
mov word ptr [ebp+_edx],dx
call _realmodeint21
add esp,32h
ret
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; PMODE v3.x - DOS INT 21h Extensions (c)1994 Daredevil/Renaissance
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
_int21lowbufseg dw ?
_int21lowbufptr dd ?
_int21lowbufsize dd ?
_int23rmvect dd ?
_int21vectoff dd ?
_int21vectsel dw ?
_int21datasel dw ?
_int21datasel64 dw ?
_int21lowdtaseg dw ?
_int21dtaoff dd ?
_int21dtasel dw ?
_int21infosel dw ?
_edi equ 0
_esi equ 4
_ebp equ 8
_ebx equ 10h
_edx equ 14h
_ecx equ 18h
_eax equ 1ch
_flags equ 20h
_es equ 22h
_ds equ 24h
_fs equ 26h
_gs equ 28h
_ip equ 2ah
_cs equ 2ch
_sp equ 2eh
_ss equ 30h
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Initialize INT 21h Extensions
; In:
; GS - Zero-Based 4G Data Selector
; FS - Extender Info Selector
; DS - Data Selector Based At Current Segment
; BX - Segment Of Low Memory DTA Buffer
; DX - Segment Of Low Memory Buffer
; ECX - Size Of Low Memory Buffer In Bytes
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_initdosext:
pushad
cld
sub esp,32h
mov ebp,esp
mov _int21datasel,gs
mov _int21infosel,fs
mov _int21datasel64,ds
mov _int21lowdtaseg,bx
mov _int21lowbufseg,dx
movzx edx,dx
shl edx,4
mov _int21lowbufptr,edx
mov _int21lowbufsize,ecx
mov dx,_int21lowdtaseg
mov byte ptr [ebp+_eax+1],1ah
mov [ebp+_ds],dx
mov word ptr [ebp+_edx],0
movzx edx,dx
shl edx,4
mov _int21dtaoff,edx
mov _int21dtasel,gs
call _realmodeint21
mov ax,204h
mov bl,21h
int 31h
jc _initdosexterror
mov _int21vectsel,cx
mov _int21vectoff,edx
mov ax,205h
mov cx,cs
mov edx,offset _int21handler
int 31h
jc _initdosexterror
mov eax,dword ptr gs:[23h*4]
mov _int23rmvect,eax
cli
mov word ptr gs:[23h*4],offset _int23handler
mov word ptr gs:[23h*4+2],pmcode16
sti
add esp,32h
clc
jmp _initdosextnoerror
_initdosexterror:
add esp,32h
stc
_initdosextnoerror:
popad
ret
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; New INT 21h Handler
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
_int21handler:
pushad
pushd es
cld
cmp ah,40h
jb short _int21t1
ja short _int21t2
jz _int2140
_int21t1:
cmp ah,39h
jb short _int21t1a
ja short _int21t1b
jz _int2139
_int21t1a:
cmp ah,9
jz _int2109
cmp ah,1ah
jz _int211A
cmp ah,25h
jz _int2125
cmp ah,2fh
jz _int212F
cmp ah,35h
jz _int2135
jmp _int21tend
_int21t1b:
cmp ah,3ah
jz _int213A
cmp ah,3bh
jz _int213B
cmp ah,3ch
jz _int213C
cmp ah,3dh
jz _int213D
cmp ah,3fh
jz _int213F
jmp short _int21tend
_int21t2:
cmp ah,4ah
jb short _int21t2a
ja short _int21t2b
jz _int214A
_int21t2a:
cmp ah,41h
jz _int2141
cmp ah,43h
jz _int2143
cmp ah,47h
jz _int2147
cmp ah,48h
jz _int2148
cmp ah,49h
jz _int2149
jmp short _int21tend
_int21t2b:
cmp ah,4bh
jz _int214B
cmp ah,4ch
jz _int214C
cmp ah,4eh
jz _int214E
cmp ah,4fh
jz _int214F
cmp ah,56h
jz _int2156
cmp ah,5bh
jz _int213C
cmp ah,0ffh
jz _int21FF
_int21tend:
popd es
popad
jmp fword ptr cs:_int21vectoff
_int23handler:
call _pm_cleanup
cli
mov eax,cr0
cmp eax,cs:_cr0valuerm
jz _int23nocr0
mov eax,cs:_cr0valuerm
mov cr0,eax
_int23nocr0:
push ds eax
xor ax,ax
mov ds,ax
mov eax,cs:_int23rmvect
mov ds:[23h*4],eax
pop eax ds
stc
retf
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 9 - Output Character String
; In:
; DS:EDX -> $ Terminated String
; Out:
; None
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2109:
sub esp,32h
mov ebp,esp
mov ax,ds
mov es,ax
mov edi,edx
or ecx,-1
mov al,'$'
repnz scas byte ptr es:[edi]
not ecx
cmp ecx,cs:_int21lowbufsize
jae _int2109a
call _int2109sub1
jmp short _int2109end
_int2109a:
mov edi,cs:_int21lowbufsize
dec edi
xchg ecx,ebx
_int2109b:
mov ecx,edi
push edi ebx
call _int2109sub1
pop ebx edi
add edx,edi
sub ebx,edi
cmp ebx,edi
ja _int2109b
mov ecx,ebx
call _int2109sub1
_int2109end:
add esp,32h
jmp _endint21handler
_int2109sub1:
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
mov esi,edx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
mov byte ptr es:[edi],'$'
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov byte ptr [ebp+_eax+1],9
mov word ptr [ebp+_edx],0
call _realmodeint21
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 1Ah - Set Disk Transfer Area
; In:
; AH - 1Ah
; DS:EDX -> Buffer For DTA
; Out:
; None
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int211A:
mov es,cs:_int21datasel64
mov es:_int21dtasel,ds
mov es:_int21dtaoff,edx
jmp _endint21handler
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 25h - Set Interrupt Vector
; In:
; AH - 25h
; AL - Interrupt Number
; DS:EDX -> Interrupt Routine
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2125:
mov bl,al
mov ax,205h
mov cx,ds
int 31h
jmp _endint21handler
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 2Fh - Get Disk Transfer Area
; In:
; AH - 2Fh
; Out:
; ES:EBX -> DTA
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int212F:
mov ebx,cs:_int21dtaoff
movzx eax,cs:_int21dtasel
mov [esp],eax
mov [esp+20],ebx
jmp _endint21handler
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 35h - Get Interrupt Vector
; In:
; AH - 35h
; AL - Interrupt Number
; Out:
; CF=0 Success
; CF=1 Error
; ES:EBX -> Interrupt Routine
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2135:
mov bl,al
mov ax,204h
int 31h
jc _endint21error
mov [esp+20],edx
and ecx,0ffffh
mov [esp],ecx
jmp _endint21handler
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 39h - Create Subdirectory
; In:
; AH - 39h
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2139:
sub esp,32h
mov ebp,esp
_int2139a:
mov byte ptr [ebp+_eax+1],ah
_int2139b:
call _int21bufferpath
jmp _endint21error_eax52h_0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 3Ah - Remove Subdirectory
; In:
; AH - 3Ah
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int213A:
jmp _int2139
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 3Bh - Set Directory
; In:
; AH - 3Bh
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int213B:
jmp _int2139
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 3Ch - Create File
; In:
; AH - 3Ch
; CX - Attribute
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Handle or Error Code If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int213C:
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_ecx],cx
jmp short _int213Da
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 3Dh - Open File
; In:
; AH - 3Dh
; AL - Open Code
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Handle or Error Code If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int213D:
sub esp,32h
mov ebp,esp
_int213Da:
mov word ptr [ebp+_eax],ax
call _int21bufferpath
movzx eax,word ptr [ebp+_eax]
mov dword ptr [ebp+52h],eax
test word ptr [ebp+_flags],1
jnz _int213Derr
add esp,32h
jmp _endint21handler
_int213Derr:
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 3Fh - Read File
; In:
; AH - 3Fh
; BX - File Handle
; ECX - Number Of Bytes To Read
; DS:EDX -> Buffer To Read To
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Number Of Bytes Read or Error Code If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int213F:
pushd ds
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_ebx],bx
mov ax,ds
mov es,ax
mov edi,edx
mov ds,cs:_int21datasel
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov word ptr [ebp+_edx],0
cmp ecx,cs:_int21lowbufsize
ja _int213Fa
mov byte ptr [ebp+_eax+1],3fh
mov word ptr [ebp+_ecx],cx
push edi
call _realmodeint21
pop edi
movzx eax,word ptr [ebp+_eax]
mov [ebp+32h+8+28],eax
test word ptr [ebp+_flags],1
jnz _int213Ferr
mov ecx,eax
mov esi,cs:_int21lowbufptr
rep movs byte ptr es:[edi],byte ptr ds:[esi]
jmp _int213Fend
_int213Fa:
mov ebx,ecx
xor edx,edx
_int213Fb:
mov byte ptr [ebp+_eax+1],3fh
mov eax,cs:_int21lowbufsize
mov word ptr [ebp+_ecx],ax
push ebx edi
call _realmodeint21
pop edi ebx
movzx eax,word ptr [ebp+_eax]
test word ptr [ebp+_flags],1
jz _int213Fc
mov [ebp+32h+8+28],eax
jmp _int213Ferr
_int213Fc:
add edx,eax
mov esi,cs:_int21lowbufptr
mov ecx,eax
jecxz _int213Fd
rep movs byte ptr es:[edi],byte ptr ds:[esi]
sub ebx,eax
cmp ebx,cs:_int21lowbufsize
jae _int213Fb
or ebx,ebx
jz _int213Fd
mov byte ptr [ebp+_eax+1],3fh
mov word ptr [ebp+_ecx],bx
push edi
call _realmodeint21
pop edi
movzx eax,word ptr [ebp+_eax]
test word ptr [ebp+_flags],1
jz _int213Fc1
mov [ebp+32h+8+28],eax
jmp _int213Ferr
_int213Fc1:
add edx,eax
mov esi,cs:_int21lowbufptr
mov ecx,eax
jecxz _int213Fd
rep movs byte ptr es:[edi],byte ptr ds:[esi]
_int213Fd:
mov [ebp+32h+8+28],edx
_int213Fend:
add esp,32h
popd ds
jmp _endint21handler
_int213Ferr:
add esp,32h
popd ds
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 40h - Write File
; In:
; AH - 40h
; BX - File Handle
; ECX - Number Of Bytes To Write
; DS:EDX -> Buffer To Write From
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Number Of Bytes Written or Error Code If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2140:
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_ebx],bx
mov esi,edx
mov es,cs:_int21datasel
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov word ptr [ebp+_edx],0
cmp ecx,cs:_int21lowbufsize
ja _int2140a
mov byte ptr [ebp+_eax+1],40h
mov word ptr [ebp+_ecx],cx
movzx ecx,cx
mov edi,cs:_int21lowbufptr
rep movs byte ptr es:[edi],byte ptr ds:[esi]
call _realmodeint21
movzx eax,word ptr [ebp+_eax]
mov [ebp+32h+4+28],eax
test word ptr [ebp+_flags],1
jnz _int2140err
jmp _int2140end
_int2140a:
mov ebx,ecx
xor edx,edx
_int2140b:
mov byte ptr [ebp+_eax+1],40h
mov eax,cs:_int21lowbufsize
mov word ptr [ebp+_ecx],ax
movzx ecx,ax
mov edi,cs:_int21lowbufptr
rep movs byte ptr es:[edi],byte ptr ds:[esi]
push ebx
call _realmodeint21
pop ebx
movzx eax,word ptr [ebp+_eax]
test word ptr [ebp+_flags],1
jz _int2140c
mov [ebp+32h+4+28],eax
jmp _int2140err
_int2140c:
add edx,eax
sub ebx,eax
cmp ebx,cs:_int21lowbufsize
jae _int2140b
or ebx,ebx
jz _int2140d
mov byte ptr [ebp+_eax+1],40h
mov word ptr [ebp+_ecx],bx
movzx ecx,bx
mov edi,cs:_int21lowbufptr
rep movs byte ptr es:[edi],byte ptr ds:[esi]
call _realmodeint21
movzx eax,word ptr [ebp+_eax]
test word ptr [ebp+_flags],1
jz _int2140c1
mov [ebp+32h+4+28],eax
jmp _int2140err
_int2140c1:
add edx,eax
_int2140d:
mov [ebp+32h+4+28],edx
_int2140end:
add esp,32h
jmp _endint21handler
_int2140err:
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 41h - Delete File
; In:
; AH - 41h
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2141:
jmp _int2139
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 43h - Get/Set File Attributes
; In:
; AH - 43h
; AL - Function Code
; CX - Desired Attributes
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Error Code If CF=1
; CX - Current Attributes
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2143:
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_eax],ax
mov word ptr [ebp+_ecx],cx
call _int21bufferpath
mov cx,word ptr [ebp+_ecx]
mov word ptr [ebp+52h-4],cx
jmp _endint21error_eax52h_0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 47h - Get Directory Path
; In:
; AH - 47h
; DL - Drive Number
; DS:ESI -> Buffer For Path
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Error Code If CF=1
; DS:ESI -> Buffer For Path (Filled If CF=0)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2147:
sub esp,32h
mov ebp,esp
mov byte ptr [ebp+_eax+1],ah
mov byte ptr [ebp+_edx],dl
mov dword ptr [ebp+52h],0
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov word ptr [ebp+_esi],0
call _realmodeint21
test word ptr [ebp+_flags],1
jnz _int2147err
mov edi,cs:_int21lowbufptr
mov es,cs:_int21datasel
or ecx,-1
xor al,al
repnz scas byte ptr es:[edi]
not ecx
push ds
sub edi,ecx
xchg esi,edi
mov ax,es
mov bx,ds
mov es,bx
mov ds,ax
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop ds
add esp,32h
jmp _endint21handler
_int2147err:
movzx eax,word ptr [ebp+_eax]
mov dword ptr [ebp+52h],eax
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 48h - Allocate Memory
; In:
; AH - 48h
; BX - Paragraphs To Allocate
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Selector To Memory If CF=0 or Error Code If CF=1
; EBX - Maximum Paragraphs Available If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2148:
mov ax,100h
int 31h
movzx edx,dx
mov dword ptr [esp+20h],edx
jnc _endint21handler
movzx ebx,bx
mov dword ptr [esp+20h-12],ebx
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 49h - Free Memory
; In:
; AH - 49h
; ES - Selector
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Error Code If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2149:
mov ax,101h
mov dx,es
int 31h
jnc _endint21handler
movzx eax,ax
mov dword ptr [esp+20h],eax
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 4Ah - Change Memory Block Allocation
; In:
; AH - 4Ah
; BX - Total Paragraphs To Allocate
; ES - Selector
; Out:
; CF=0 Success
; CF=1 Error
; EAX - Error Code If CF=1
; EBX - Maximum Paragraphs Available If CF=1
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int214A:
mov ax,102h
mov dx,es
int 31h
jnc _endint21handler
movzx eax,ax
mov dword ptr [esp+20h],eax
movzx ebx,bx
mov dword ptr [esp+20h-12],ebx
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 4Bh, Function 00h - Load Program
; In:
; AH - 4Bh
; AL - 00h
; DS:EDX -> Path Name
; ES:EBX -> Parameter Block
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int214B:
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_eax],ax
or al,al
jnz _int21err_leave_eax
push es
mov ax,ds
mov es,ax
mov edi,edx
or ecx,-1
xor al,al
repnz scas byte ptr es:[edi]
not ecx
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
add edi,2048
mov esi,edx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
mov ecx,22
xor al,al
rep stos byte ptr es:[edi]
sub edi,22
mov ax,cs:_int21lowbufseg
mov word ptr es:[edi+2],22
mov word ptr es:[edi+4],ax
mov word ptr es:[edi+6],5ch
mov word ptr es:[edi+10],6ch
mov ax,cs:_pspseg
mov word ptr es:[edi+8],ax
mov word ptr es:[edi+12],ax
pop es
push es ds
mov ds,es:[ebx+10]
mov esi,es:[ebx+6]
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
add edi,22
movzx ecx,byte ptr [esi]
inc cx
inc cx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop ds es
push ds es
mov edi,es:[ebx]
mov es,es:[ebx+4]
mov esi,edi
or ecx,-1
xor al,al
_int214B00a:
repnz scas byte ptr es:[edi]
dec ecx
scas byte ptr es:[edi]
jnz _int214B00a
not ecx
mov ax,100h
mov ebx,ecx
shr ebx,4
inc bx
int 31h
jc _int214B00err1
mov bx,es
mov ds,bx
mov es,dx
xor edi,edi
rep movs byte ptr es:[edi],byte ptr ds:[esi]
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
mov es:[edi],ax
clc
_int214B00err1:
pop es ds
jc _int21err_leave_eax
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov [ebp+_es],ax
mov word ptr [ebp+_ebx],0
mov word ptr [ebp+_edx],2048
mov eax,cr0
test eax,4
jz _int214Bnocp1
and eax,NOT 4
mov cr0,eax
call _realmodeint21
mov eax,cr0
or eax,4
mov cr0,eax
jmp short _int214Bnocp2
_int214Bnocp1:
call _realmodeint21
_int214Bnocp2:
mov ax,101h
int 31h
jmp _endint21error_eax52h_0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 4Ch - Terminate Process
; In:
; AH - 4Ch
; AL - Return Code
; Out:
; Duh!
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int214C:
mov ax,5feh
int 31h
cli
push ds
mov ds,cs:_int21datasel
mov eax,cs:_int23rmvect
mov ds:[23h*4],eax
pop ds
mov eax,cr0
cmp eax,cs:_cr0valuepm
jz _int21nocr0
mov eax,cs:_cr0valuepm
mov cr0,eax
_int21nocr0:
sti
jmp _int21tend
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 4Eh - Search For First Filename Match
; In:
; AH - 4Eh
; CX - File Attribute
; DS:EDX -> ASCIIZ Path Name
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int214E:
sub esp,32h
mov ebp,esp
mov word ptr [ebp+_ecx],cx
mov byte ptr [ebp+_eax+1],ah
call _int21bufferpath
mov dword ptr [ebp+52h],0
test word ptr [ebp+_flags],1
jnz _int214Eerr
push ds
mov ds,cs:_int21datasel
movzx esi,cs:_int21lowdtaseg
shl esi,4
mov es,cs:_int21dtasel
mov edi,cs:_int21dtaoff
mov ecx,43
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop ds
add esp,32h
jmp _endint21handler
_int214Eerr:
movzx eax,word ptr [ebp+_eax]
mov dword ptr [ebp+52h],eax
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 4Fh - Search For Next Filename Match
; In:
; AH - 4Fh
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int214F:
sub esp,32h
mov ebp,esp
mov byte ptr [ebp+_eax+1],ah
call _realmodeint21
mov dword ptr [ebp+52h],0
test word ptr [ebp+_flags],1
jnz _int214Ferr
push ds
mov ds,cs:_int21datasel
movzx esi,cs:_int21lowdtaseg
shl esi,4
mov es,cs:_int21dtasel
mov edi,cs:_int21dtaoff
mov ecx,43
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop ds
add esp,32h
jmp _endint21handler
_int214Ferr:
mov ax,[ebp+_eax]
mov word ptr [ebp+52h],ax
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service 56h - Rename File
; In:
; AH - 56h
; DS:EDX -> Old Filename
; ES:EDI -> New Filename
; Out:
; CF=0 Success
; CF=1 Error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int2156:
sub esp,32h
mov ebp,esp
mov byte ptr [ebp+_eax+1],ah
or ecx,-1
xor al,al
repnz scas byte ptr es:[edi]
not ecx
sub edi,ecx
push ds
mov esi,edi
mov ax,es
mov ds,ax
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop ds
mov ecx,edi
mov ebx,cs:_int21lowbufptr
sub ecx,ebx
xchg ecx,ebx
mov ax,ds
mov es,ax
mov esi,edx
xchg esi,edi
or ecx,-1
xor al,al
repnz scas byte ptr es:[edi]
not ecx
sub edi,ecx
xchg esi,edi
mov es,cs:_int21datasel
rep movs byte ptr es:[edi],byte ptr ds:[esi]
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov [ebp+_es],ax
mov word ptr [ebp+_edi],0
mov word ptr [ebp+_edx],bx
call _realmodeint21
jmp _endint21error_eax52h_0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; INT 21h Service FFh - DOS Extender Check
; In:
; AH - FFh
; DX - 78h
; Out:
; GS - Info Segment
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int21FF:
cmp dx,78h
jnz _int21FFend
mov gs,cs:_int21infosel
mov byte ptr [esp+20h],0ffh
jmp _endint21handler
_int21FFend:
jmp _int21tend
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; End Of INT 21h Handler
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_endint21handler:
popd es
popad
and dword ptr [esp+8],NOT 1
iretd
_endint21error:
popd es
popad
or dword ptr [esp+8],1
iretd
_endint21error_eax52h_0:
mov dword ptr [ebp+52h],0
_endint21error_eax52h:
test word ptr [ebp+_flags],1
jnz _int21err_eax52h
add esp,32h
jmp _endint21handler
_int21err_eax52h:
movzx eax,word ptr [ebp+_eax]
mov dword ptr [ebp+52h],eax
_int21err_leave_eax:
add esp,32h
jmp _endint21error
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Call Real Mode INT 21h
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_realmodeint21:
push es
mov word ptr [ebp+_ss],0
mov word ptr [ebp+_sp],0
mov word ptr [ebp+_flags],0
mov ax,ss
mov es,ax
mov edi,ebp
mov ax,300h
mov bx,21h
xor cx,cx
int 31h
pop es
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Subroutine For Some INT 21h Functions
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_int21bufferpath:
mov ax,ds
mov es,ax
mov edi,edx
or ecx,-1
xor al,al
repnz scas byte ptr es:[edi]
not ecx
mov es,cs:_int21datasel
mov edi,cs:_int21lowbufptr
mov esi,edx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
mov ax,cs:_int21lowbufseg
mov [ebp+_ds],ax
mov word ptr [ebp+_edx],0
call _realmodeint21
ret
pmcode16 ends
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; STACK
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
pmstack segment para stack use16 'STACK'
db STACKLEN*16 dup(?)
pmstack ends
end _pm16start