home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / vrac / pmw100.zip / PMODEWE.ASM < prev    next >
Assembly Source File  |  1994-11-21  |  55KB  |  2,162 lines

  1. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  2. ; PMODE DOS Extender Stub Module For Watcom C/C++ LE Format Executables v3.06
  3. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  4.  
  5. .386p
  6. locals
  7.  
  8. STACKLEN        = 40h                    ; size of stub stack in paragraphs
  9. EXTMAX          = 7fffffffh
  10. EXTMIN          = 0
  11. LOWMIN          = 0ffffh
  12.  
  13. OPENTYPE        = 1
  14. VARTYPE         = 1
  15.  
  16. ;DEBUG=1
  17.  
  18. PM_PMSTACKLEN   = 200h
  19. PM_RMSTACKLEN   = 100h
  20. PM_PMSTACKS     = 8
  21. PM_RMSTACKS     = 8
  22. PM_MODE         = 1
  23. PM_CALLBACKS    = 32
  24. PM_SELECTORS    = 256
  25. PM_PAGETABLES   = 4
  26.  
  27. PMODE_TEXT      segment para public use16 'CODE'
  28. ;db 'PMODE DOS Extender Stub Module v1.0 - Copyright (c)1994 Daredevil/Tran'
  29. PMODE_TEXT      ends
  30.  
  31. pmcode16        segment para public use16 'CODE'
  32. pmcode16        ends
  33. pmstack         segment para stack use16 'STACK'
  34. pmstack         ends
  35.  
  36. extrn   _pm_info:far, _pm_init:far, _pm_cleanup:far
  37.  
  38. extrn   _pm_pagetables:byte, _pm_selectors:word
  39. extrn   _pm_rmstacklen:word, _pm_pmstacklen:word
  40. extrn   _pm_rmstacks:byte, _pm_pmstacks:byte
  41. extrn   _pm_callbacks:byte
  42. extrn   _pm_mode:byte
  43.  
  44. pmcode16        segment para public use16 'CODE'
  45.                 assume cs:pmcode16,ds:pmcode16
  46.  
  47. ifdef DEBUG
  48. include debug.inc
  49. endif
  50. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  51. ; DATA
  52. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  53. align 4
  54.  
  55. errmsgtbl       dw errmsg0,errmsg1,errmsg2,errmsg3
  56.                 dw errmsg4,errmsg5,errmsg6,errmsg7
  57.                 dw errmsg8,errmsg9,errmsg10,errmsg11
  58.  
  59. pmodemsg        db '[PMODE]: $'
  60. errmsg0         db 'Not Enough Memory Available!',13,10,36
  61. errmsg1         db '80386+ Not Detected!',13,10,36
  62. errmsg2         db 'System Already In Protected Mode And No VCPI or DPMI found!',13,10,36
  63. errmsg3         db 'DPMI Host Is Not 32bit!',13,10,36
  64. errmsg4         db 'Could Not Enable A20 Gate!',13,10,36
  65. errmsg5         db 'Could Not Enter DPMI 32bit Protected Mode!',13,10,36
  66. errmsg6         db 'Could Not Allocate Needed DPMI Selectors!',13,10,36
  67.  
  68. errmsg7         db 'Error Loading LE!',13,10,36
  69. errmsg8         db 'Unrecognized Data In LE!',13,10,36
  70. errmsg9         db 'Cannot Address Above 1 MB From Real Mode Segment!',13,10,36
  71. errmsg10        db 'Unable To Initialize DOS Extender!',13,10,36
  72. errmsg11        db 'Error Allocating DPMI Memory!',13,10,36
  73.  
  74. _extmin         dd ?
  75. _extmax         dd ?
  76. _lowmin         dw ?
  77.  
  78. _selbuf         dw ?
  79. _selcode        dw ?
  80. _selzero        dw ?
  81. _selpsp         dw ?
  82. _selfixup       dw ?
  83. _pmreqpara      dw ?
  84. _exehandle      dw ?
  85. _pspseg         dw ?
  86. _envseg         dw ?
  87. _selrights      dw ?
  88.  
  89. _cr0valuerm     dd ?
  90. _cr0valuepm     dd ?
  91.  
  92. _membase        dd ?
  93. _memtop         dd ?
  94.  
  95. FIXUPBUFMIN      = 2000h
  96. _fixupbufptr    dd ?
  97. _fixupbufsize   dd ?
  98.  
  99. _dtabufptr      dd ?
  100. _dtabufsize     dd 200h
  101.  
  102. _lowbufptr      dd ?
  103. _lowbufsize     dd 1000h        ; MUST Be A Multiple Of 4 Or You Will Suffer!
  104.                                 ; (1000h Bytes Is The Suggested Minimum)
  105. _exebaseoffset  dd ?
  106.  
  107. MAXOBJECTS       = 16
  108. _objectlocs     dd MAXOBJECTS dup (?)
  109. _objectlens     dd MAXOBJECTS dup (?)
  110. _objectpageidx  dd MAXOBJECTS dup (?)
  111. _objectpagenum  dd MAXOBJECTS dup (?)
  112. _objectflags    dd MAXOBJECTS dup (?)
  113. _objectsels     dd MAXOBJECTS dup (?)
  114.  
  115. _nextobjectloc  dd ?
  116. _numobjects     dd ?
  117. _currentobject  dd ?
  118.  
  119. _oldfilepos1    dd ?
  120. _datapagesloc   dd ?
  121.  
  122. __D16Infoseg    dw ?
  123. __PMODE_systype db ?
  124.  
  125. _inpmode        db 0
  126.  
  127. _oldint31off    dd ?
  128. _oldint31sel    dw ?
  129.  
  130. pushd   macro reg
  131.         db 66h
  132.         push ®
  133. endm
  134.  
  135. popd    macro reg
  136.         db 66h
  137.         pop ®
  138. endm
  139.  
  140. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  141. ; 16-BIT REAL MODE CODE
  142. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  143. _pm16start:
  144.         push cs
  145.         pop ds
  146.         cld
  147.  
  148.         mov _pspseg,es
  149.         mov ax,es:[2ch]
  150.         mov _envseg,ax
  151.  
  152.         xor eax,eax
  153.         mov ax,es:[2]
  154.         mov _memtop,eax
  155.         mov ax,STACKLEN
  156.         mov cx,ss
  157.         add ax,cx
  158.         mov _membase,eax
  159.  
  160.         mov eax,_lowbufsize
  161.         call _getmem
  162.         jc _memoryerr
  163.         mov _lowbufptr,eax
  164.  
  165.         mov eax,_dtabufsize
  166.         call _getmem
  167.         jc _memoryerr
  168.         mov _dtabufptr,eax
  169.  
  170.  
  171.         call _openexe1
  172.         call _openexe2
  173.         call _pm_info
  174.         jc _pmstartuperr
  175.         mov _pmreqpara,bx
  176.         mov __PMODE_systype,ch
  177.  
  178.         xor ax,ax
  179.         mov ebx,_memtop
  180.         sub ebx,_membase
  181.         cmp bx,_pmreqpara
  182.         jb _pmstartuperr
  183.         mov es,_membase
  184.         movzx ebx,_pmreqpara
  185.         add _membase,ebx
  186.  
  187.         mov eax,cr0
  188.         mov _cr0valuerm,eax
  189.  
  190.         call _pm_init
  191.         jc _pmstartuperr
  192.  
  193. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  194. ; BEGINNING OF 16-BIT PROTECTED MODE CODE
  195. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  196.  
  197.         mov eax,cr0
  198.         mov _cr0valuepm,eax
  199.  
  200.         mov _inpmode,0ffh
  201.         mov _selpsp,es
  202.  
  203.         xor edi,edi
  204.         or ecx,-1
  205.         mov ax,cs
  206.         lar dx,ax
  207.         mov dl,dh
  208.         and dl,60h
  209.         or dl,9ah
  210.         mov dh,0c0h
  211.         call _initdescriptor
  212.         jc _descriptorerr
  213.         mov _selcode,ax
  214.  
  215.         and dl,NOT 8
  216.         mov _selrights,dx
  217.         call _initdescriptor
  218.         jc _descriptorerr
  219.  
  220.         mov fs,ax                       ; Set FS,GS To Data Selector
  221.         mov gs,ax                       ; (ES Left Intact As PSP Selector)
  222.         mov _selzero,ax
  223.  
  224.         mov edi,_dtabufptr
  225.         shl edi,4
  226.         call _initdescriptor
  227.         jc _descriptorerr
  228.         mov _selbuf,ax
  229.  
  230.         mov edi,_lowbufptr
  231.         shl edi,4
  232.         call _initdescriptor
  233.         jc _descriptorerr
  234.         mov __D16Infoseg,ax
  235.  
  236. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  237. ; PROTECTED MODE STARTUP
  238. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  239.  
  240.         mov ebx,_dtabufptr
  241.         mov ecx,_lowbufsize
  242.         mov edx,_lowbufptr
  243.         push fs
  244.         mov fs,__D16Infoseg
  245.         call _initdosext
  246.         pop fs
  247.         jc _exiterror
  248.  
  249.         cmp __PMODE_systype,3
  250.         jz short _nomeminit1
  251.         mov edx,cs:_extmax
  252.         mov ax,5ffh
  253.         int 31h
  254.         jc _DPMImemoryerr
  255. _nomeminit1:
  256.  
  257.         mov ax,204h
  258.         mov bl,31h
  259.         int 31h
  260.         jc _exiterror
  261.         mov _oldint31sel,cx
  262.         mov _oldint31off,edx
  263.         mov ax,205h
  264.         mov cx,cs
  265.         mov edx,offset _int310A00
  266.         int 31h
  267.         jc _exiterror
  268.  
  269.         shl _dtabufptr,4
  270.         push fs gs
  271.         call _loadexe                   ; Load LE EXE Into Memory
  272.         pop gs fs
  273.  
  274.         mov ebx,_dtabufptr
  275.         mov edx,gs:[ebx+20h]
  276.         mov edx,_objectlocs[edx*4-4]
  277.         add edx,gs:[ebx+24h]
  278.  
  279.         mov ax,gs
  280.         mov ss,ax                       ; Set Up Stack Selector
  281.         mov esp,edx                     ; And ESP
  282.  
  283.         mov ebx,_dtabufptr
  284.         mov edx,gs:[ebx+18h]
  285.         mov edx,_objectlocs[edx*4-4]
  286.         add edx,gs:[ebx+1ch]
  287.  
  288.         movzx ebp,_selcode
  289.         push ebp                        ; 4G 32bit CS
  290.         push edx                        ; 32bit EIP For Program Start
  291.  
  292.         mov ebx,_membase
  293.         sub bx,_pspseg
  294.         mov es,_selpsp
  295.         mov ah,4ah
  296.         int 21h
  297.  
  298.         mov es,_selpsp
  299.         mov ax,gs
  300.         mov ds,ax
  301.         db 66h                          ; 32bit RETF To New CS
  302.         retf
  303.  
  304. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  305. ; INT 31H HANDLER
  306. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  307. _int310A00:
  308.         cmp ax,0a00h
  309.         jnz short _int31not0A00
  310.         and dword ptr [esp+8],NOT 1
  311.         iretd
  312. _int31not0A00:
  313.         jmp fword ptr cs:_oldint31off
  314.  
  315. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  316. ; SUBROUTINES
  317. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  318. IF OPENTYPE EQ 1
  319. _openexe1:
  320.         mov edx,_lowbufptr              ; Get EXE Name and Open It
  321.         push ds
  322.         mov ds,dx
  323.         shr edx,16
  324.         call _getexe
  325.         mov ax,3dc0h
  326.         int 21h
  327.         pop ds
  328.         jc _loaderror
  329.         ret
  330. ENDIF
  331.  
  332. IF OPENTYPE EQ 2
  333. _openexe1:
  334.         push ds
  335.         xor ax,ax
  336.         mov ds,ax
  337.         mov dx,4c0h
  338.         mov ax,3dc0h
  339.         int 21h
  340.         pop ds
  341.         jc _loaderror
  342.         ret
  343. ENDIF
  344.  
  345. IF OPENTYPE EQ 3
  346. _filename       db 128 dup (?)
  347. _openexe1:
  348.         cld
  349.         push es ds
  350.         mov ds,cs:_pspseg
  351.         mov ax,cs
  352.         mov es,ax
  353.         mov di,offset _filename
  354.         mov si,80h
  355.         lodsb
  356.         or al,al
  357.         jz _openexe3err
  358. _openexe3a1:
  359.         lodsb
  360.         cmp al,20h
  361.         jz _openexe3a1
  362.         mov cx,-1
  363.         jmp _openexe3b
  364. _openexe3a:
  365.         lodsb
  366. _openexe3b:
  367.         cmp al,20h
  368.         jz _openexe3c
  369.         cmp al,0dh
  370.         jz _openexe3c
  371.         stosb
  372.         dec cx
  373.         jnz _openexe3a
  374.         jmp _openexe3err
  375. _openexe3c:
  376.         xor al,al
  377.         stosb
  378.         xor bl,bl
  379.         dec si
  380.         mov ax,ds
  381.         mov es,ax
  382.         mov di,81h
  383. _openexe3d:
  384.         lodsb
  385.         or al,al
  386.         cmp al,0dh
  387.         jz _openexe3e
  388.         inc bl
  389.         stosb
  390.         jmp _openexe3d
  391. _openexe3e:
  392.         stosb
  393.         mov es:[80h],bl
  394.         mov dx,offset _filename
  395.         push cs
  396.         pop ds
  397.         mov ax,3dc0h
  398.         int 21h
  399.         pop ds es
  400.         jc _loaderror
  401.         ret
  402. _openexe3err:
  403.         pop ds es
  404.         jmp _loaderror
  405.         ret
  406. ENDIF
  407.  
  408. IF VARTYPE EQ 1
  409. _openexe2:
  410.         mov _exehandle,ax
  411.         push ds
  412.         mov bx,ax
  413.         mov cx,40h+21
  414.         mov eax,_dtabufptr
  415.         mov ds,ax
  416.         xor dx,dx
  417.         mov ah,3fh
  418.         int 21h
  419.         jc _loaderror
  420.         push es
  421.         mov si,40h
  422.         mov ax,PMODE_TEXT
  423.         mov es,ax
  424.         mov di,offset _pm_pagetables
  425.         mov cx,11
  426.         rep movsb
  427.         mov ax,pmcode16
  428.         mov es,ax
  429.         mov di,offset _extmin
  430.         mov cl,10
  431.         rep movsb
  432.         pop es
  433.         pop ds
  434.         ret
  435. ENDIF
  436.  
  437. IF VARTYPE EQ 2
  438. _openexe2:
  439.         mov _exehandle,ax
  440.         mov _extmin,EXTMIN
  441.         mov _extmax,EXTMAX
  442.         mov _lowmin,LOWMIN
  443.         push ds
  444.         mov bx,ax
  445.         mov cx,40h
  446.         mov eax,_dtabufptr
  447.         mov ds,ax
  448.         xor dx,dx
  449.         mov ah,3fh
  450.         int 21h
  451.         jc _loaderror
  452.         mov ax,PMODE_TEXT
  453.         mov ds,ax
  454.         mov _pm_pmstacklen,PM_PMSTACKLEN
  455.         mov _pm_rmstacklen,PM_RMSTACKLEN
  456.         mov _pm_pmstacks,PM_PMSTACKS
  457.         mov _pm_rmstacks,PM_RMSTACKS
  458.         mov _pm_mode,PM_MODE
  459.         mov _pm_selectors,PM_SELECTORS
  460.         mov _pm_callbacks,PM_CALLBACKS
  461.         mov _pm_pagetables,PM_PAGETABLES
  462.         pop ds
  463.         ret
  464. ENDIF
  465.  
  466. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  467. ; Load The EXE (LE Format) Into Memory
  468. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  469. 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
  470. db 'T' XOR 66h ,'.' XOR 66h ,' ' XOR 66h ,'P' XOR 66h ,'Y' XOR 66h ,'T' XOR 66h ,'E' XOR 66h ,'L' XOR 66h
  471.  
  472. _loadexe:
  473. ;        mov ecx,40h                     ; Read In EXE Header To Temp Buffer
  474. ;        mov edx,_dtabufptr
  475. ;        call _readfile
  476.  
  477.         mov dx,_selbuf                  ; Get LE Location From EXE Header
  478.         mov gs,dx                       ; And Seek To It
  479.         mov edx,gs:[3ch]
  480.         mov _exebaseoffset,edx
  481.         call _seekfile
  482.  
  483.         mov ecx,0c4h                    ; Read In LE Header To Temp Buffer
  484.         mov edx,_dtabufptr
  485.         call _readfile
  486.  
  487.         cmp word ptr gs:[0],'EL'        ; Check LE Sig Just For The Hell Of It
  488.         jnz _loaderror
  489.  
  490.         mov eax,gs:[80h]                ; Get Beginning Offset Of Object Data
  491.         mov _datapagesloc,eax
  492.  
  493.         mov ebp,gs:[44h]                ; Get Number Of Objects
  494.         or ebp,ebp
  495.         jz _loaderror
  496.         mov _numobjects,ebp
  497.         mov edx,gs:[40h]                ; Seek To The Object Table
  498.         add edx,_exebaseoffset
  499.         call _seekfile
  500.  
  501.         xor ebp,ebp
  502. _loadobjects:
  503.         mov ecx,18h                     ; Read Info For This Object
  504.         mov edx,_dtabufptr
  505.         add edx,100h
  506.         call _readfile
  507.         call _filepos                   ; Save File Position For Later
  508.         mov _oldfilepos1,eax
  509.  
  510.         mov eax,gs:[100h]               ; Allocate Some Memory For This Object
  511.         movzx edx,_lowmin
  512.         mov edi,_memtop
  513.         sub edi,_membase
  514.         mov ecx,eax
  515.         add ecx,15
  516.         shr ecx,4
  517.         sub edi,ecx
  518.         jc _loadtryhimem
  519.         cmp edi,edx
  520.         jae _loadtrylowmem
  521.         test dword ptr gs:[108h],1000000000000b
  522.         jnz _loadtrylowmem
  523.         call _gethimem
  524.         jnc _loadlowmemok
  525. _loadtrylowmem:
  526.         call _getmem
  527.         jc short _loadtryhimem
  528.         shl eax,4
  529.         jmp short _loadlowmemok
  530. _loadtryhimem:
  531.         test dword ptr gs:[108h],1000000000000b
  532.         jnz _memoryerr
  533.         mov eax,gs:[100h]
  534.         call _gethimem
  535.         jc _memoryerr
  536. _loadlowmemok:
  537.         mov edi,eax
  538.  
  539.         mov edx,_datapagesloc           ; Seek To Current Object Page Location
  540.         call _seekfile
  541.  
  542.         mov ecx,gs:[100h]               ; Read Object Into Memory
  543.         mov eax,gs:[110h]
  544.         shl eax,12
  545.         mov edx,eax
  546.         sub edx,ecx
  547.         jnc short _nozerobss1
  548.         push es eax ecx edi
  549.         sub ecx,eax
  550.         add edi,eax
  551.         mov es,_selzero
  552.         xor al,al
  553.         rep stos byte ptr es:[edi]
  554.         pop edi ecx eax es
  555.         mov edx,ecx
  556.         sub edx,eax
  557.         sub ecx,edx
  558.         jz _noreadobject1
  559. _nozerobss1:
  560.         mov edx,edi
  561.         call _readfile
  562. _noreadobject1:
  563.  
  564.         mov eax,ecx
  565.         mov edx,ecx
  566.         and eax,0fffff000h
  567.         and edx,0fffh
  568.         jz short _loadobj1
  569.         add eax,1000h
  570. _loadobj1:
  571.         add _datapagesloc,eax           ; Update Information For Object Pages
  572.         mov bx,bp
  573.         shl bx,2
  574.         mov _objectlocs[bx],edi
  575.         mov _objectlens[bx],ecx
  576.         mov eax,gs:[108h]
  577.         mov _objectflags[bx],eax
  578.         test eax,10000000000000b
  579.         jz _loadobj1a
  580.         mov ax,_selcode
  581.         mov word ptr _objectsels[bx],ax
  582.         mov ax,_selzero
  583.         mov word ptr _objectsels[bx+2],ax
  584.         jmp short _loadobj1b
  585. _loadobj1a:
  586.         or ecx,-1
  587.         mov dx,_selrights
  588.         call _initdescriptor
  589.         jc _descriptorerr
  590.         mov word ptr _objectsels[bx+2],ax
  591.         or dl,8
  592.         call _initdescriptor
  593.         jc _descriptorerr
  594.         mov word ptr _objectsels[bx],ax
  595. _loadobj1b:
  596.         mov eax,gs:[10ch]
  597.         mov _objectpageidx[bx],eax
  598.         mov eax,gs:[110h]
  599.         mov _objectpagenum[bx],eax
  600.  
  601.         mov edx,_oldfilepos1
  602.         call _seekfile
  603.  
  604.         inc ebp
  605.         cmp ebp,_numobjects
  606.         jnz _loadobjects
  607.  
  608. ;------------------------------------------------------------------------------
  609.  
  610.         mov edi,_membase                ; Allocate Buffer For Fixup Information
  611.         shl edi,4                       ; Which Will Be Discarded Later
  612.         mov _fixupbufptr,edi
  613.         or ecx,-1
  614.         mov dx,_selrights
  615.         call _initdescriptor
  616.         jc _loaderror
  617.         mov _selfixup,ax
  618.         mov fs,ax
  619.         mov eax,_memtop
  620.         sub eax,_membase
  621.         shl eax,4
  622.         mov _fixupbufsize,eax
  623.         cmp eax,FIXUPBUFMIN
  624.         jb _memoryerr
  625.         mov ax,_selzero
  626.         mov es,ax
  627.  
  628.         xor ebp,ebp
  629. _relocateobjects:
  630.         mov edx,gs:[48h]                ; Seek To The First Page Table Index
  631.         add edx,_exebaseoffset          ; For This Object
  632.         cmp dword ptr ds:_objectpagenum[ebp*4],0
  633.         jz _norelocate2
  634.         mov eax,ds:_objectpageidx[ebp*4]
  635.         lea edx,[edx+eax*4-4]
  636.         call _seekfile
  637.  
  638.         xor ebx,ebx
  639. _relocate1:
  640.         mov ecx,4                       ; Read Next Object Page Map Entry
  641.         mov edx,_dtabufptr
  642.         add edx,100h
  643.         call _readfile
  644.         call _filepos                   ; Save File Position For Later
  645.         mov _oldfilepos1,eax
  646.  
  647.         movzx eax,word ptr gs:[101h]    ; Skip If No Relocation On This Page
  648.         or ax,ax
  649.         jz _norelocate1
  650.         xchg al,ah
  651.  
  652.         mov edx,gs:[68h]                ; Seek To Fixup Page Table
  653.         add edx,_exebaseoffset
  654.         lea edx,[edx+eax*4-4]
  655.         call _seekfile
  656.  
  657.         mov ecx,8                       ; Read 2 Fixup Entries
  658.         mov edx,_dtabufptr
  659.         add edx,100h
  660.         call _readfile
  661.         mov eax,gs:[100h]
  662.         cmp eax,gs:[104h]
  663.         jz _norelocate1
  664.  
  665.         mov esi,gs:[100h]
  666.         mov edx,gs:[6ch]
  667.         add edx,_exebaseoffset
  668.         add edx,esi
  669.         call _seekfile
  670.  
  671.         mov ecx,gs:[104h]
  672.         sub ecx,gs:[100h]
  673.         cmp ecx,_fixupbufsize
  674.         ja _loaderror
  675.         mov edx,_fixupbufptr
  676.         call _readfile
  677.  
  678.         mov edi,ds:_objectlocs[ebp*4]
  679.         mov eax,ebx
  680.         shl eax,12
  681.         add edi,eax
  682.  
  683.         mov _nextobjectloc,ecx
  684.         mov _currentobject,ebp
  685.         push ebx ebp
  686.         xor esi,esi
  687. _relocate2:
  688.         lods word ptr fs:[esi]
  689.         mov dx,ax
  690.         test dh,3
  691.         jnz _unknownerror
  692.         test dl,20h
  693.         jnz _unknownerror
  694.         test dh,4
  695.         jnz _unknownerror
  696.  
  697.         lods word ptr fs:[esi]          ; ES:[EBX+EDI] -> Source
  698.         movsx ebx,ax
  699.  
  700.         xor eax,eax
  701.         lods byte ptr fs:[esi]
  702.         test dh,40h
  703.         jz short _relocate2a
  704.         mov ah,fs:[esi]
  705.         inc esi
  706. _relocate2a:
  707.         mov ecx,eax
  708.         mov ebp,_objectlocs[ecx*4-4]
  709.  
  710.         mov al,dl
  711.         and al,0fh
  712.         cmp al,2
  713.         jz _relocate2b
  714.         xor eax,eax
  715.         lods word ptr fs:[esi]
  716.         test dh,10h
  717.         jz short _relocate2b
  718.         rol eax,16
  719.         lods word ptr fs:[esi]
  720.         rol eax,16
  721. _relocate2b:
  722.  
  723.         call _relocateitem
  724.  
  725.         cmp esi,_nextobjectloc
  726.         jnz _relocate2
  727.         pop ebp ebx
  728. _norelocate1:
  729.  
  730.         mov edx,_oldfilepos1
  731.         call _seekfile
  732.         inc ebx
  733.         cmp ebx,ds:_objectpagenum[ebp*4]
  734.         jnz _relocate1
  735. _norelocate2:
  736.         inc ebp
  737.         cmp ebp,_numobjects
  738.         jnz _relocateobjects
  739.  
  740. ;------------------------------------------------------------------------------
  741.  
  742.         mov ah,3eh                      ; Close EXE File
  743.         mov bx,_exehandle
  744.         int 21h
  745.         ret
  746.  
  747. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  748. ; REAL MODE - Relocate One Item
  749. ; In:
  750. ;   EAX - Target Offset
  751. ;   EBP - Zero Based Target Begining Offset
  752. ;    DL - Fixup Type
  753. ;    DH - Fixup Flags
  754. ;   ECX - Target Object Number
  755. ;   ES:EBX -> Pointer To Relocation Source
  756. ; Out:
  757. ;
  758. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  759. _r_table        dw offset _r_byteoffset
  760.                 dw offset _r_unknown
  761.                 dw offset _r_wordsegment
  762.                 dw offset _r_16bitfarptr
  763.                 dw offset _r_unknown
  764.                 dw offset _r_16bitoffset
  765.                 dw offset _r_32bitfarptr
  766.                 dw offset _r_32bitoffset
  767.                 dw offset _r_nearcalljmp
  768. _relocateitem:
  769.         push eax ebp esi
  770.         movzx esi,dl
  771.         and esi,15
  772.         cmp esi,8
  773.         ja _unknownerror
  774.         jmp _r_table[esi*2]
  775.  
  776. _r_byteoffset:
  777.         jmp _r_unknown
  778. _r_wordsegment:
  779.         or ebx,ebx
  780.         js _r_done
  781.         call _r_segmentfixup
  782.         mov es:[edi+ebx],bp
  783.         jmp _r_done
  784. _r_16bitfarptr:
  785.         or ebx,ebx
  786.         js _r_done
  787.         call _r_segmentfixup
  788.         mov es:[ebx+edi],ax
  789.         mov es:[ebx+edi+2],bp
  790.         jmp _r_done
  791. _r_16bitoffset:
  792.         or ebx,ebx
  793.         js _r_done
  794.         mov es:[ebx+edi],ax
  795.         jmp _r_done
  796. _r_32bitfarptr:
  797.         jmp _r_unknown
  798. _r_32bitoffset:
  799.         or ebx,ebx
  800.         js _r_done
  801.         add eax,ebp
  802.         mov es:[ebx+edi],eax
  803.         jmp _r_done
  804. _r_nearcalljmp:
  805.         jmp _r_unknown
  806. _r_unknown:
  807.         jmp _unknownerror
  808. _r_done:
  809.         pop esi ebp eax
  810.         ret
  811.  
  812. _r_segmentfixup:
  813.         mov esi,_currentobject
  814.         test word ptr _objectflags[esi*4-4],1000000000000b
  815.         jnz _r_wordsegment2
  816.         test word ptr _objectflags[ecx*4-4],100b
  817.         jz _r_wordsegment1
  818.         mov bp,word ptr _objectsels[ecx*4-4]
  819.         jmp short _r_wordsegment3
  820. _r_wordsegment1:
  821.         mov bp,word ptr _objectsels[ecx*4-2]
  822.         jmp short _r_wordsegment3
  823. _r_wordsegment2:
  824.         shr ebp,4
  825. ;        test dl,10h
  826. ;        jz _r_wordsegment3
  827.         test ebp,0ffff0000h
  828.         jnz _16biterror
  829. _r_wordsegment3:
  830.         ret
  831.  
  832. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  833. ; Setup A New Descriptor
  834. ; In:
  835. ;   EDI - Base Address
  836. ;    DX - Access Rights
  837. ;   ECX - Limit
  838. ; Out:
  839. ;    AX - Selector
  840. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  841. _initdescriptor:
  842.         push ebx ecx edx ebp
  843.         mov ebp,ecx
  844.         xor ax,ax
  845.         mov cx,1
  846.         int 31h
  847.         jc _initdescerr
  848.  
  849.         xchg bx,ax
  850.         mov ax,9
  851.         mov cx,dx
  852.         int 31h
  853.         jc _initdescerr
  854.  
  855.         mov ax,7
  856.         mov ecx,edi
  857.         mov dx,cx
  858.         shr ecx,16
  859.         int 31h
  860.         jc _initdescerr
  861.  
  862.         mov ax,8
  863.         mov ecx,ebp
  864.         mov dx,cx
  865.         shr ecx,16
  866.         int 31h
  867.         jc _initdescerr
  868.         mov ax,bx
  869.         clc
  870. _initdescerr:
  871.         pop ebp edx ecx ebx
  872.         ret
  873.  
  874. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  875. ; Quickie Read To Buffer
  876. ; In:
  877. ;   ECX - Number Of Bytes To Read
  878. ;   EDX - Zero Based Buffer Offset
  879. ; Out:
  880. ;   CF=0 Success
  881. ;   CF=1 Error
  882. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  883. _readfile:
  884.         push eax bx ds
  885.         mov ah,3fh
  886.         mov ds,cs:_selzero
  887.         mov bx,cs:_exehandle
  888.         int 21h
  889.         pop ds bx eax
  890.         jc _loaderror
  891.         ret
  892.  
  893. _seekfile:
  894.         push ax bx ecx dx
  895.         mov ecx,edx
  896.         shr ecx,16
  897.         mov ax,4200h
  898.         mov bx,cs:_exehandle
  899.         int 21h
  900.         pop dx ecx bx ax
  901.         jc _loaderror
  902.         ret
  903.  
  904. _filepos:
  905.         push bx cx dx
  906.         xor cx,cx
  907.         xor dx,dx
  908.         mov ax,4201h
  909.         mov bx,cs:_exehandle
  910.         int 21h
  911.         jc _loaderror
  912.         rol eax,16
  913.         mov ax,dx
  914.         rol eax,16
  915.         pop dx cx bx
  916.         ret
  917.  
  918. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  919. ; Get Some Low Memory
  920. ; In:
  921. ;    EAX - Number Of Bytes To Get
  922. ; Out:
  923. ;   EAX - SEG:OFF Pointer (Offset Always 0)
  924. ;   CF=0 Success
  925. ;   CF=1 Error
  926. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  927. _getmem:
  928.         add eax,15
  929.         shr eax,4
  930.         add eax,_membase
  931.         cmp eax,_memtop
  932.         ja _getmemerr
  933.         xchg eax,_membase
  934.         clc
  935.         jmp short $+3
  936. _getmemerr:
  937.         stc
  938.         ret
  939.  
  940. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  941. ; Get Some High Memory
  942. ; In:
  943. ;    EAX - Number Of Bytes To Get
  944. ; Out:
  945. ;   EAX - Absolute Address Of Block
  946. ;   CF=0 Success
  947. ;   CF=1 Error
  948. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  949. _gethimem:
  950.         push bx cx si di
  951.         mov cx,ax
  952.         shr eax,16
  953.         mov bx,ax
  954.         mov ax,501h
  955.         int 31h
  956.         jc short _gethimemerr
  957.         mov ax,bx
  958.         shl eax,16
  959.         mov ax,cx
  960.         clc
  961. _gethimemerr:
  962.         pop di si cx bx
  963.         ret
  964.  
  965. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  966. ; REAL MODE - Get EXE Name
  967. ; In:
  968. ;    DS:DX -> Buffer For ASCIIZ String
  969. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  970. _getexe:
  971.         push ax cx dx si di es
  972.  
  973.         mov di,cs:_envseg
  974.         mov es,di
  975.         xor di,di
  976.  
  977.         or cx,-1
  978.         xor al,al
  979. @@00l:
  980.         repne scasb
  981.         scasb
  982.         jne @@00l
  983.  
  984.         add di,2
  985.         mov si,di
  986.  
  987.         or cx,-1
  988.         repne scasb
  989.         not cx
  990.  
  991.         mov di,dx
  992.         mov ax,es
  993.         mov dx,ds
  994.         mov ds,ax
  995.         mov es,dx
  996.         mov ax,di
  997.  
  998.         rep movsb
  999.  
  1000.         mov cx,es
  1001.         mov ds,cx
  1002.  
  1003.         pop es di si dx cx ax
  1004.         ret
  1005.  
  1006. _16biterror:
  1007.         mov ax,9
  1008.         jmp short _pmstartuperr
  1009. _descriptorerr:
  1010.         mov ax,6
  1011.         jmp short _pmstartuperr
  1012. _exiterror:
  1013.         mov ax,10
  1014.         jmp short _pmstartuperr
  1015. _unknownerror:
  1016.         mov ax,8
  1017.         jmp short _pmstartuperr
  1018. _DPMImemoryerr:
  1019.         mov ax,11
  1020.         jmp short _pmstartuperr
  1021. _memoryerr:
  1022.         xor ax,ax
  1023.         jmp short _pmstartuperr
  1024. _loaderror:
  1025.         mov ax,7
  1026. _pmstartuperr:
  1027.         mov si,ax
  1028.         add si,ax
  1029.         mov ax,cs
  1030.         mov ds,ax
  1031.         mov dx,offset pmodemsg
  1032.         call _pmsg
  1033.         mov dx,errmsgtbl[si]
  1034.         call _pmsg
  1035.         mov ax,4cffh
  1036.         int 21h
  1037.  
  1038. _pmsg:
  1039.         cmp _inpmode,0ffh
  1040.         jz _pmerr1
  1041.         mov ah,9
  1042.         int 21h
  1043.         ret
  1044. _pmerr1:
  1045.         sub esp,32h
  1046.         mov ebp,esp
  1047.         mov byte ptr [ebp+_eax+1],9
  1048.         mov word ptr [ebp+_ds],pmcode16
  1049.         mov word ptr [ebp+_edx],dx
  1050.         call _realmodeint21
  1051.         add esp,32h
  1052.         ret
  1053.  
  1054. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1055. ; PMODE v3.x - DOS INT 21h Extensions (c)1994 Daredevil/Renaissance
  1056. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1057.  
  1058. _int21lowbufseg         dw ?
  1059. _int21lowbufptr         dd ?
  1060. _int21lowbufsize        dd ?
  1061.  
  1062. _int23rmvect            dd ?
  1063.  
  1064. _int21vectoff           dd ?
  1065. _int21vectsel           dw ?
  1066.  
  1067. _int21datasel           dw ?
  1068. _int21datasel64         dw ?
  1069.  
  1070. _int21lowdtaseg         dw ?
  1071.  
  1072. _int21dtaoff            dd ?
  1073. _int21dtasel            dw ?
  1074.  
  1075. _int21infosel           dw ?
  1076.  
  1077. _edi                   equ 0
  1078. _esi                   equ 4
  1079. _ebp                   equ 8
  1080. _ebx                   equ 10h
  1081. _edx                   equ 14h
  1082. _ecx                   equ 18h
  1083. _eax                   equ 1ch
  1084. _flags                 equ 20h
  1085. _es                    equ 22h
  1086. _ds                    equ 24h
  1087. _fs                    equ 26h
  1088. _gs                    equ 28h
  1089. _ip                    equ 2ah
  1090. _cs                    equ 2ch
  1091. _sp                    equ 2eh
  1092. _ss                    equ 30h
  1093.  
  1094. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1095. ; Initialize INT 21h Extensions
  1096. ; In:
  1097. ;    GS - Zero-Based 4G Data Selector
  1098. ;    FS - Extender Info Selector
  1099. ;    DS - Data Selector Based At Current Segment
  1100. ;    BX - Segment Of Low Memory DTA Buffer
  1101. ;    DX - Segment Of Low Memory Buffer
  1102. ;   ECX - Size Of Low Memory Buffer In Bytes
  1103. ; Out:
  1104. ;   CF=0 Success
  1105. ;   CF=1 Error
  1106. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1107. _initdosext:
  1108.         pushad
  1109.         cld
  1110.         sub esp,32h
  1111.         mov ebp,esp
  1112.         mov _int21datasel,gs
  1113.         mov _int21infosel,fs
  1114.         mov _int21datasel64,ds
  1115.         mov _int21lowdtaseg,bx
  1116.         mov _int21lowbufseg,dx
  1117.         movzx edx,dx
  1118.         shl edx,4
  1119.         mov _int21lowbufptr,edx
  1120.         mov _int21lowbufsize,ecx
  1121.  
  1122.         mov dx,_int21lowdtaseg
  1123.         mov byte ptr [ebp+_eax+1],1ah
  1124.         mov [ebp+_ds],dx
  1125.         mov word ptr [ebp+_edx],0
  1126.         movzx edx,dx
  1127.         shl edx,4
  1128.         mov _int21dtaoff,edx
  1129.         mov _int21dtasel,gs
  1130.         call _realmodeint21
  1131.  
  1132.         mov ax,204h
  1133.         mov bl,21h
  1134.         int 31h
  1135.         jc _initdosexterror
  1136.         mov _int21vectsel,cx
  1137.         mov _int21vectoff,edx
  1138.         mov ax,205h
  1139.         mov cx,cs
  1140.         mov edx,offset _int21handler
  1141.         int 31h
  1142.         jc _initdosexterror
  1143.         mov eax,dword ptr gs:[23h*4]
  1144.         mov _int23rmvect,eax
  1145.         cli
  1146.         mov word ptr gs:[23h*4],offset _int23handler
  1147.         mov word ptr gs:[23h*4+2],pmcode16
  1148.         sti
  1149.         add esp,32h
  1150.         clc
  1151.         jmp _initdosextnoerror
  1152. _initdosexterror:
  1153.         add esp,32h
  1154.         stc
  1155. _initdosextnoerror:
  1156.         popad
  1157.         ret
  1158.  
  1159. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1160. ; New INT 21h Handler
  1161. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1162. _int21handler:
  1163.         pushad
  1164.         pushd es
  1165.         cld
  1166.         cmp ah,40h
  1167.         jb short _int21t1
  1168.         ja short _int21t2
  1169.         jz _int2140
  1170. _int21t1:
  1171.         cmp ah,39h
  1172.         jb short _int21t1a
  1173.         ja short _int21t1b
  1174.         jz _int2139
  1175. _int21t1a:
  1176.         cmp ah,9
  1177.         jz _int2109
  1178.         cmp ah,1ah
  1179.         jz _int211A
  1180.         cmp ah,25h
  1181.         jz _int2125
  1182.         cmp ah,2fh
  1183.         jz _int212F
  1184.         cmp ah,35h
  1185.         jz _int2135
  1186.         jmp _int21tend
  1187. _int21t1b:
  1188.         cmp ah,3ah
  1189.         jz _int213A
  1190.         cmp ah,3bh
  1191.         jz _int213B
  1192.         cmp ah,3ch
  1193.         jz _int213C
  1194.         cmp ah,3dh
  1195.         jz _int213D
  1196.         cmp ah,3fh
  1197.         jz _int213F
  1198.         jmp short _int21tend
  1199. _int21t2:
  1200.         cmp ah,4ah
  1201.         jb short _int21t2a
  1202.         ja short _int21t2b
  1203.         jz _int214A
  1204. _int21t2a:
  1205.         cmp ah,41h
  1206.         jz _int2141
  1207.         cmp ah,43h
  1208.         jz _int2143
  1209.         cmp ah,47h
  1210.         jz _int2147
  1211.         cmp ah,48h
  1212.         jz _int2148
  1213.         cmp ah,49h
  1214.         jz _int2149
  1215.         jmp short _int21tend
  1216. _int21t2b:
  1217.         cmp ah,4bh
  1218.         jz _int214B
  1219.         cmp ah,4ch
  1220.         jz _int214C
  1221.         cmp ah,4eh
  1222.         jz _int214E
  1223.         cmp ah,4fh
  1224.         jz _int214F
  1225.         cmp ah,56h
  1226.         jz _int2156
  1227.         cmp ah,5bh
  1228.         jz _int213C
  1229.         cmp ah,0ffh
  1230.         jz _int21FF
  1231. _int21tend:
  1232.         popd es
  1233.         popad
  1234.         jmp fword ptr cs:_int21vectoff
  1235.  
  1236. _int23handler:
  1237.         call _pm_cleanup
  1238.         cli
  1239.         mov eax,cr0
  1240.         cmp eax,cs:_cr0valuerm
  1241.         jz _int23nocr0
  1242.         mov eax,cs:_cr0valuerm
  1243.         mov cr0,eax
  1244. _int23nocr0:
  1245.         push ds eax
  1246.         xor ax,ax
  1247.         mov ds,ax
  1248.         mov eax,cs:_int23rmvect
  1249.         mov ds:[23h*4],eax
  1250.         pop eax ds
  1251.         stc
  1252.         retf
  1253.  
  1254. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1255. ; INT 21h Service 9 - Output Character String
  1256. ; In:
  1257. ;   DS:EDX -> $ Terminated String
  1258. ; Out:
  1259. ;   None
  1260. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1261. _int2109:
  1262.         sub esp,32h
  1263.         mov ebp,esp
  1264.  
  1265.         mov ax,ds
  1266.         mov es,ax
  1267.         mov edi,edx
  1268.  
  1269.         or ecx,-1
  1270.         mov al,'$'
  1271.         repnz scas byte ptr es:[edi]
  1272.         not ecx
  1273.  
  1274.         cmp ecx,cs:_int21lowbufsize
  1275.         jae _int2109a
  1276.         call _int2109sub1
  1277.         jmp short _int2109end
  1278. _int2109a:
  1279.         mov edi,cs:_int21lowbufsize
  1280.         dec edi
  1281.         xchg ecx,ebx
  1282. _int2109b:
  1283.         mov ecx,edi
  1284.         push edi ebx
  1285.         call _int2109sub1
  1286.         pop ebx edi
  1287.         add edx,edi
  1288.         sub ebx,edi
  1289.         cmp ebx,edi
  1290.         ja _int2109b
  1291.         mov ecx,ebx
  1292.         call _int2109sub1
  1293. _int2109end:
  1294.         add esp,32h
  1295.         jmp _endint21handler
  1296.  
  1297. _int2109sub1:
  1298.         mov es,cs:_int21datasel
  1299.         mov edi,cs:_int21lowbufptr
  1300.         mov esi,edx
  1301.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1302.         mov byte ptr es:[edi],'$'
  1303.         mov ax,cs:_int21lowbufseg
  1304.         mov [ebp+_ds],ax
  1305.         mov byte ptr [ebp+_eax+1],9
  1306.         mov word ptr [ebp+_edx],0
  1307.         call _realmodeint21
  1308.         ret
  1309.  
  1310. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1311. ; INT 21h Service 1Ah - Set Disk Transfer Area
  1312. ; In:
  1313. ;   AH - 1Ah
  1314. ;   DS:EDX -> Buffer For DTA
  1315. ; Out:
  1316. ;   None
  1317. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1318. _int211A:
  1319.         mov es,cs:_int21datasel64
  1320.         mov es:_int21dtasel,ds
  1321.         mov es:_int21dtaoff,edx
  1322.         jmp _endint21handler
  1323.  
  1324. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1325. ; INT 21h Service 25h - Set Interrupt Vector
  1326. ; In:
  1327. ;   AH - 25h
  1328. ;   AL - Interrupt Number
  1329. ;   DS:EDX -> Interrupt Routine
  1330. ; Out:
  1331. ;   CF=0 Success
  1332. ;   CF=1 Error
  1333. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1334. _int2125:
  1335.         mov bl,al
  1336.         mov ax,205h
  1337.         mov cx,ds
  1338.         int 31h
  1339.         jmp _endint21handler
  1340.  
  1341. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1342. ; INT 21h Service 2Fh - Get Disk Transfer Area
  1343. ; In:
  1344. ;   AH - 2Fh
  1345. ; Out:
  1346. ;   ES:EBX -> DTA
  1347. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1348. _int212F:
  1349.         mov ebx,cs:_int21dtaoff
  1350.         movzx eax,cs:_int21dtasel
  1351.         mov [esp],eax
  1352.         mov [esp+20],ebx
  1353.         jmp _endint21handler
  1354.  
  1355. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1356. ; INT 21h Service 35h - Get Interrupt Vector
  1357. ; In:
  1358. ;   AH - 35h
  1359. ;   AL - Interrupt Number
  1360. ; Out:
  1361. ;   CF=0 Success
  1362. ;   CF=1 Error
  1363. ;   ES:EBX -> Interrupt Routine
  1364. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1365. _int2135:
  1366.         mov bl,al
  1367.         mov ax,204h
  1368.         int 31h
  1369.         jc _endint21error
  1370.         mov [esp+20],edx
  1371.         and ecx,0ffffh
  1372.         mov [esp],ecx
  1373.         jmp _endint21handler
  1374.  
  1375. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1376. ; INT 21h Service 39h - Create Subdirectory
  1377. ; In:
  1378. ;   AH - 39h
  1379. ;   DS:EDX -> ASCIIZ Path Name
  1380. ; Out:
  1381. ;   CF=0 Success
  1382. ;   CF=1 Error
  1383. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1384. _int2139:
  1385.         sub esp,32h
  1386.         mov ebp,esp
  1387. _int2139a:
  1388.         mov byte ptr [ebp+_eax+1],ah
  1389. _int2139b:
  1390.         call _int21bufferpath
  1391.         jmp _endint21error_eax52h_0
  1392.  
  1393. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1394. ; INT 21h Service 3Ah - Remove Subdirectory
  1395. ; In:
  1396. ;   AH - 3Ah
  1397. ;   DS:EDX -> ASCIIZ Path Name
  1398. ; Out:
  1399. ;   CF=0 Success
  1400. ;   CF=1 Error
  1401. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1402. _int213A:
  1403.         jmp _int2139
  1404.  
  1405. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1406. ; INT 21h Service 3Bh - Set Directory
  1407. ; In:
  1408. ;   AH - 3Bh
  1409. ;   DS:EDX -> ASCIIZ Path Name
  1410. ; Out:
  1411. ;   CF=0 Success
  1412. ;   CF=1 Error
  1413. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1414. _int213B:
  1415.         jmp _int2139
  1416.  
  1417. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1418. ; INT 21h Service 3Ch - Create File
  1419. ; In:
  1420. ;   AH - 3Ch
  1421. ;   CX - Attribute
  1422. ;   DS:EDX -> ASCIIZ Path Name
  1423. ; Out:
  1424. ;   CF=0 Success
  1425. ;   CF=1 Error
  1426. ;   EAX - Handle or Error Code If CF=1
  1427. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1428. _int213C:
  1429.         sub esp,32h
  1430.         mov ebp,esp
  1431.         mov word ptr [ebp+_ecx],cx
  1432.         jmp short _int213Da
  1433.  
  1434. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1435. ; INT 21h Service 3Dh - Open File
  1436. ; In:
  1437. ;   AH - 3Dh
  1438. ;   AL - Open Code
  1439. ;   DS:EDX -> ASCIIZ Path Name
  1440. ; Out:
  1441. ;   CF=0 Success
  1442. ;   CF=1 Error
  1443. ;   EAX - Handle or Error Code If CF=1
  1444. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1445. _int213D:
  1446.         sub esp,32h
  1447.         mov ebp,esp
  1448. _int213Da:
  1449.         mov word ptr [ebp+_eax],ax
  1450.  
  1451.         call _int21bufferpath
  1452.         movzx eax,word ptr [ebp+_eax]
  1453.         mov dword ptr [ebp+52h],eax
  1454.  
  1455.         test word ptr [ebp+_flags],1
  1456.         jnz _int213Derr
  1457.         add esp,32h
  1458.         jmp _endint21handler
  1459. _int213Derr:
  1460.         add esp,32h
  1461.         jmp _endint21error
  1462.  
  1463. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1464. ; INT 21h Service 3Fh - Read File
  1465. ; In:
  1466. ;   AH - 3Fh
  1467. ;   BX - File Handle
  1468. ;   ECX - Number Of Bytes To Read
  1469. ;   DS:EDX -> Buffer To Read To
  1470. ; Out:
  1471. ;   CF=0 Success
  1472. ;   CF=1 Error
  1473. ;   EAX - Number Of Bytes Read or Error Code If CF=1
  1474. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1475. _int213F:
  1476.         pushd ds
  1477.         sub esp,32h
  1478.         mov ebp,esp
  1479.         mov word ptr [ebp+_ebx],bx
  1480.  
  1481.         mov ax,ds
  1482.         mov es,ax
  1483.         mov edi,edx
  1484.         mov ds,cs:_int21datasel
  1485.  
  1486.         mov ax,cs:_int21lowbufseg
  1487.         mov [ebp+_ds],ax
  1488.         mov word ptr [ebp+_edx],0
  1489.  
  1490.         cmp ecx,cs:_int21lowbufsize
  1491.         ja _int213Fa
  1492.         mov byte ptr [ebp+_eax+1],3fh
  1493.         mov word ptr [ebp+_ecx],cx
  1494.         push edi
  1495.         call _realmodeint21
  1496.         pop edi
  1497.         movzx eax,word ptr [ebp+_eax]
  1498.         mov [ebp+32h+8+28],eax
  1499.         test word ptr [ebp+_flags],1
  1500.         jnz _int213Ferr
  1501.         mov ecx,eax
  1502.         mov esi,cs:_int21lowbufptr
  1503.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1504.         jmp _int213Fend
  1505. _int213Fa:
  1506.         mov ebx,ecx
  1507.         xor edx,edx
  1508. _int213Fb:
  1509.         mov byte ptr [ebp+_eax+1],3fh
  1510.         mov eax,cs:_int21lowbufsize
  1511.         mov word ptr [ebp+_ecx],ax
  1512.         push ebx edi
  1513.         call _realmodeint21
  1514.         pop edi ebx
  1515.         movzx eax,word ptr [ebp+_eax]
  1516.         test word ptr [ebp+_flags],1
  1517.         jz _int213Fc
  1518.         mov [ebp+32h+8+28],eax
  1519.         jmp _int213Ferr
  1520. _int213Fc:
  1521.         add edx,eax
  1522.         mov esi,cs:_int21lowbufptr
  1523.         mov ecx,eax
  1524.         jecxz _int213Fd
  1525.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1526.         sub ebx,eax
  1527.         cmp ebx,cs:_int21lowbufsize
  1528.         jae _int213Fb
  1529.         or ebx,ebx
  1530.         jz _int213Fd
  1531.         mov byte ptr [ebp+_eax+1],3fh
  1532.         mov word ptr [ebp+_ecx],bx
  1533.         push edi
  1534.         call _realmodeint21
  1535.         pop edi
  1536.         movzx eax,word ptr [ebp+_eax]
  1537.         test word ptr [ebp+_flags],1
  1538.         jz _int213Fc1
  1539.         mov [ebp+32h+8+28],eax
  1540.         jmp _int213Ferr
  1541. _int213Fc1:
  1542.         add edx,eax
  1543.         mov esi,cs:_int21lowbufptr
  1544.         mov ecx,eax
  1545.         jecxz _int213Fd
  1546.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1547. _int213Fd:
  1548.         mov [ebp+32h+8+28],edx
  1549. _int213Fend:
  1550.         add esp,32h
  1551.         popd ds
  1552.         jmp _endint21handler
  1553. _int213Ferr:
  1554.         add esp,32h
  1555.         popd ds
  1556.         jmp _endint21error
  1557.  
  1558. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1559. ; INT 21h Service 40h - Write File
  1560. ; In:
  1561. ;   AH - 40h
  1562. ;   BX - File Handle
  1563. ;   ECX - Number Of Bytes To Write
  1564. ;   DS:EDX -> Buffer To Write From
  1565. ; Out:
  1566. ;   CF=0 Success
  1567. ;   CF=1 Error
  1568. ;   EAX - Number Of Bytes Written or Error Code If CF=1
  1569. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1570. _int2140:
  1571.         sub esp,32h
  1572.         mov ebp,esp
  1573.         mov word ptr [ebp+_ebx],bx
  1574.  
  1575.         mov esi,edx
  1576.         mov es,cs:_int21datasel
  1577.  
  1578.         mov ax,cs:_int21lowbufseg
  1579.         mov [ebp+_ds],ax
  1580.         mov word ptr [ebp+_edx],0
  1581.  
  1582.         cmp ecx,cs:_int21lowbufsize
  1583.         ja _int2140a
  1584.         mov byte ptr [ebp+_eax+1],40h
  1585.         mov word ptr [ebp+_ecx],cx
  1586.         movzx ecx,cx
  1587.         mov edi,cs:_int21lowbufptr
  1588.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1589.         call _realmodeint21
  1590.         movzx eax,word ptr [ebp+_eax]
  1591.         mov [ebp+32h+4+28],eax
  1592.         test word ptr [ebp+_flags],1
  1593.         jnz _int2140err
  1594.         jmp _int2140end
  1595. _int2140a:
  1596.         mov ebx,ecx
  1597.         xor edx,edx
  1598. _int2140b:
  1599.         mov byte ptr [ebp+_eax+1],40h
  1600.         mov eax,cs:_int21lowbufsize
  1601.         mov word ptr [ebp+_ecx],ax
  1602.         movzx ecx,ax
  1603.         mov edi,cs:_int21lowbufptr
  1604.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1605.         push ebx
  1606.         call _realmodeint21
  1607.         pop ebx
  1608.         movzx eax,word ptr [ebp+_eax]
  1609.         test word ptr [ebp+_flags],1
  1610.         jz _int2140c
  1611.         mov [ebp+32h+4+28],eax
  1612.         jmp _int2140err
  1613. _int2140c:
  1614.         add edx,eax
  1615.         sub ebx,eax
  1616.         cmp ebx,cs:_int21lowbufsize
  1617.         jae _int2140b
  1618.         or ebx,ebx
  1619.         jz _int2140d
  1620.         mov byte ptr [ebp+_eax+1],40h
  1621.         mov word ptr [ebp+_ecx],bx
  1622.         movzx ecx,bx
  1623.         mov edi,cs:_int21lowbufptr
  1624.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1625.         call _realmodeint21
  1626.         movzx eax,word ptr [ebp+_eax]
  1627.         test word ptr [ebp+_flags],1
  1628.         jz _int2140c1
  1629.         mov [ebp+32h+4+28],eax
  1630.         jmp _int2140err
  1631. _int2140c1:
  1632.         add edx,eax
  1633. _int2140d:
  1634.         mov [ebp+32h+4+28],edx
  1635. _int2140end:
  1636.         add esp,32h
  1637.         jmp _endint21handler
  1638. _int2140err:
  1639.         add esp,32h
  1640.         jmp _endint21error
  1641.  
  1642. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1643. ; INT 21h Service 41h - Delete File
  1644. ; In:
  1645. ;   AH - 41h
  1646. ;   DS:EDX -> ASCIIZ Path Name
  1647. ; Out:
  1648. ;   CF=0 Success
  1649. ;   CF=1 Error
  1650. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1651. _int2141:
  1652.         jmp _int2139
  1653.  
  1654. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1655. ; INT 21h Service 43h - Get/Set File Attributes
  1656. ; In:
  1657. ;   AH - 43h
  1658. ;   AL - Function Code
  1659. ;   CX - Desired Attributes
  1660. ;   DS:EDX -> ASCIIZ Path Name
  1661. ; Out:
  1662. ;   CF=0 Success
  1663. ;   CF=1 Error
  1664. ;   EAX - Error Code If CF=1
  1665. ;   CX - Current Attributes
  1666. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1667. _int2143:
  1668.         sub esp,32h
  1669.         mov ebp,esp
  1670.         mov word ptr [ebp+_eax],ax
  1671.         mov word ptr [ebp+_ecx],cx
  1672.         call _int21bufferpath
  1673.         mov cx,word ptr [ebp+_ecx]
  1674.         mov word ptr [ebp+52h-4],cx
  1675.         jmp _endint21error_eax52h_0
  1676.  
  1677. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1678. ; INT 21h Service 47h - Get Directory Path
  1679. ; In:
  1680. ;   AH - 47h
  1681. ;   DL - Drive Number
  1682. ;   DS:ESI -> Buffer For Path
  1683. ; Out:
  1684. ;   CF=0 Success
  1685. ;   CF=1 Error
  1686. ;   EAX - Error Code If CF=1
  1687. ;   DS:ESI -> Buffer For Path (Filled If CF=0)
  1688. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1689. _int2147:
  1690.         sub esp,32h
  1691.         mov ebp,esp
  1692.         mov byte ptr [ebp+_eax+1],ah
  1693.         mov byte ptr [ebp+_edx],dl
  1694.  
  1695.         mov dword ptr [ebp+52h],0
  1696.  
  1697.         mov ax,cs:_int21lowbufseg
  1698.         mov [ebp+_ds],ax
  1699.         mov word ptr [ebp+_esi],0
  1700.         call _realmodeint21
  1701.  
  1702.         test word ptr [ebp+_flags],1
  1703.         jnz _int2147err
  1704.         mov edi,cs:_int21lowbufptr
  1705.         mov es,cs:_int21datasel
  1706.         or ecx,-1
  1707.         xor al,al
  1708.         repnz scas byte ptr es:[edi]
  1709.         not ecx
  1710.         push ds
  1711.         sub edi,ecx
  1712.         xchg esi,edi
  1713.         mov ax,es
  1714.         mov bx,ds
  1715.         mov es,bx
  1716.         mov ds,ax
  1717.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1718.         pop ds
  1719.         add esp,32h
  1720.         jmp _endint21handler
  1721. _int2147err:
  1722.         movzx eax,word ptr [ebp+_eax]
  1723.         mov dword ptr [ebp+52h],eax
  1724.         add esp,32h
  1725.         jmp _endint21error
  1726.  
  1727. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1728. ; INT 21h Service 48h - Allocate Memory
  1729. ; In:
  1730. ;   AH - 48h
  1731. ;   BX - Paragraphs To Allocate
  1732. ; Out:
  1733. ;   CF=0 Success
  1734. ;   CF=1 Error
  1735. ;   EAX - Selector To Memory If CF=0 or Error Code If CF=1
  1736. ;   EBX - Maximum Paragraphs Available If CF=1
  1737. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1738. _int2148:
  1739.         mov ax,100h
  1740.         int 31h
  1741.         movzx edx,dx
  1742.         mov dword ptr [esp+20h],edx
  1743.         jnc _endint21handler
  1744.         movzx ebx,bx
  1745.         mov dword ptr [esp+20h-12],ebx
  1746.         jmp _endint21error
  1747.  
  1748. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1749. ; INT 21h Service 49h - Free Memory
  1750. ; In:
  1751. ;   AH - 49h
  1752. ;   ES - Selector
  1753. ; Out:
  1754. ;   CF=0 Success
  1755. ;   CF=1 Error
  1756. ;   EAX - Error Code If CF=1
  1757. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1758. _int2149:
  1759.         mov ax,101h
  1760.         mov dx,es
  1761.         int 31h
  1762.         jnc _endint21handler
  1763.         movzx eax,ax
  1764.         mov dword ptr [esp+20h],eax
  1765.         jmp _endint21error
  1766.  
  1767. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1768. ; INT 21h Service 4Ah - Change Memory Block Allocation
  1769. ; In:
  1770. ;   AH - 4Ah
  1771. ;   BX - Total Paragraphs To Allocate
  1772. ;   ES - Selector
  1773. ; Out:
  1774. ;   CF=0 Success
  1775. ;   CF=1 Error
  1776. ;   EAX - Error Code If CF=1
  1777. ;   EBX - Maximum Paragraphs Available If CF=1
  1778. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1779. _int214A:
  1780.         mov ax,102h
  1781.         mov dx,es
  1782.         int 31h
  1783.         jnc _endint21handler
  1784.         movzx eax,ax
  1785.         mov dword ptr [esp+20h],eax
  1786.         movzx ebx,bx
  1787.         mov dword ptr [esp+20h-12],ebx
  1788.         jmp _endint21error
  1789.  
  1790. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1791. ; INT 21h Service 4Bh, Function 00h - Load Program
  1792. ; In:
  1793. ;   AH - 4Bh
  1794. ;   AL - 00h
  1795. ;   DS:EDX -> Path Name
  1796. ;   ES:EBX -> Parameter Block
  1797. ; Out:
  1798. ;   CF=0 Success
  1799. ;   CF=1 Error
  1800. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1801. _int214B:
  1802.         sub esp,32h
  1803.         mov ebp,esp
  1804.         mov word ptr [ebp+_eax],ax
  1805.  
  1806.         or al,al
  1807.         jnz _int21err_leave_eax
  1808.  
  1809.         push es
  1810.         mov ax,ds
  1811.         mov es,ax
  1812.         mov edi,edx
  1813.  
  1814.         or ecx,-1
  1815.         xor al,al
  1816.         repnz scas byte ptr es:[edi]
  1817.         not ecx
  1818.  
  1819.         mov es,cs:_int21datasel
  1820.         mov edi,cs:_int21lowbufptr
  1821.         add edi,2048
  1822.         mov esi,edx
  1823.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1824.  
  1825.         mov es,cs:_int21datasel
  1826.         mov edi,cs:_int21lowbufptr
  1827.         mov ecx,22
  1828.         xor al,al
  1829.         rep stos byte ptr es:[edi]
  1830.         sub edi,22
  1831.         mov ax,cs:_int21lowbufseg
  1832.         mov word ptr es:[edi+2],22
  1833.         mov word ptr es:[edi+4],ax
  1834.         mov word ptr es:[edi+6],5ch
  1835.         mov word ptr es:[edi+10],6ch
  1836.         mov ax,cs:_pspseg
  1837.         mov word ptr es:[edi+8],ax
  1838.         mov word ptr es:[edi+12],ax
  1839.         pop es
  1840.  
  1841.         push es ds
  1842.         mov ds,es:[ebx+10]
  1843.         mov esi,es:[ebx+6]
  1844.         mov es,cs:_int21datasel
  1845.         mov edi,cs:_int21lowbufptr
  1846.         add edi,22
  1847.         movzx ecx,byte ptr [esi]
  1848.         inc cx
  1849.         inc cx
  1850.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1851.         pop ds es
  1852.  
  1853.         push ds es
  1854.         mov edi,es:[ebx]
  1855.         mov es,es:[ebx+4]
  1856.         mov esi,edi
  1857.         or ecx,-1
  1858.         xor al,al
  1859. _int214B00a:
  1860.         repnz scas byte ptr es:[edi]
  1861.         dec ecx
  1862.         scas byte ptr es:[edi]
  1863.         jnz _int214B00a
  1864.         not ecx
  1865.         mov ax,100h
  1866.         mov ebx,ecx
  1867.         shr ebx,4
  1868.         inc bx
  1869.         int 31h
  1870.         jc _int214B00err1
  1871.         mov bx,es
  1872.         mov ds,bx
  1873.         mov es,dx
  1874.         xor edi,edi
  1875.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1876.         mov es,cs:_int21datasel
  1877.         mov edi,cs:_int21lowbufptr
  1878.         mov es:[edi],ax
  1879.         clc
  1880. _int214B00err1:
  1881.         pop es ds
  1882.         jc _int21err_leave_eax
  1883.  
  1884.         mov ax,cs:_int21lowbufseg
  1885.         mov [ebp+_ds],ax
  1886.         mov [ebp+_es],ax
  1887.         mov word ptr [ebp+_ebx],0
  1888.         mov word ptr [ebp+_edx],2048
  1889.  
  1890.         mov eax,cr0
  1891.         test eax,4
  1892.         jz _int214Bnocp1
  1893.         and eax,NOT 4
  1894.         mov cr0,eax
  1895.         call _realmodeint21
  1896.         mov eax,cr0
  1897.         or eax,4
  1898.         mov cr0,eax
  1899.         jmp short _int214Bnocp2
  1900. _int214Bnocp1:
  1901.         call _realmodeint21
  1902. _int214Bnocp2:
  1903.         mov ax,101h
  1904.         int 31h
  1905.         jmp _endint21error_eax52h_0
  1906.  
  1907. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1908. ; INT 21h Service 4Ch - Terminate Process
  1909. ; In:
  1910. ;   AH - 4Ch
  1911. ;   AL - Return Code
  1912. ; Out:
  1913. ;   Duh!
  1914. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1915. _int214C:
  1916.         mov ax,5feh
  1917.         int 31h
  1918.         cli
  1919.         push ds
  1920.         mov ds,cs:_int21datasel
  1921.         mov eax,cs:_int23rmvect
  1922.         mov ds:[23h*4],eax
  1923.         pop ds
  1924.         mov eax,cr0
  1925.         cmp eax,cs:_cr0valuepm
  1926.         jz _int21nocr0
  1927.         mov eax,cs:_cr0valuepm
  1928.         mov cr0,eax
  1929. _int21nocr0:
  1930.         sti
  1931.         jmp _int21tend
  1932.  
  1933. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1934. ; INT 21h Service 4Eh - Search For First Filename Match
  1935. ; In:
  1936. ;   AH - 4Eh
  1937. ;   CX - File Attribute
  1938. ;   DS:EDX -> ASCIIZ Path Name
  1939. ; Out:
  1940. ;   CF=0 Success
  1941. ;   CF=1 Error
  1942. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1943. _int214E:
  1944.         sub esp,32h
  1945.         mov ebp,esp
  1946.         mov word ptr [ebp+_ecx],cx
  1947.         mov byte ptr [ebp+_eax+1],ah
  1948.  
  1949.         call _int21bufferpath
  1950.  
  1951.         mov dword ptr [ebp+52h],0
  1952.  
  1953.         test word ptr [ebp+_flags],1
  1954.         jnz _int214Eerr
  1955.         push ds
  1956.         mov ds,cs:_int21datasel
  1957.         movzx esi,cs:_int21lowdtaseg
  1958.         shl esi,4
  1959.         mov es,cs:_int21dtasel
  1960.         mov edi,cs:_int21dtaoff
  1961.         mov ecx,43
  1962.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1963.         pop ds
  1964.         add esp,32h
  1965.         jmp _endint21handler
  1966. _int214Eerr:
  1967.         movzx eax,word ptr [ebp+_eax]
  1968.         mov dword ptr [ebp+52h],eax
  1969.         add esp,32h
  1970.         jmp _endint21error
  1971.  
  1972. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1973. ; INT 21h Service 4Fh - Search For Next Filename Match
  1974. ; In:
  1975. ;   AH - 4Fh
  1976. ; Out:
  1977. ;   CF=0 Success
  1978. ;   CF=1 Error
  1979. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1980. _int214F:
  1981.         sub esp,32h
  1982.         mov ebp,esp
  1983.         mov byte ptr [ebp+_eax+1],ah
  1984.  
  1985.         call _realmodeint21
  1986.  
  1987.         mov dword ptr [ebp+52h],0
  1988.  
  1989.         test word ptr [ebp+_flags],1
  1990.         jnz _int214Ferr
  1991.         push ds
  1992.         mov ds,cs:_int21datasel
  1993.         movzx esi,cs:_int21lowdtaseg
  1994.         shl esi,4
  1995.         mov es,cs:_int21dtasel
  1996.         mov edi,cs:_int21dtaoff
  1997.         mov ecx,43
  1998.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  1999.         pop ds
  2000.         add esp,32h
  2001.         jmp _endint21handler
  2002. _int214Ferr:
  2003.         mov ax,[ebp+_eax]
  2004.         mov word ptr [ebp+52h],ax
  2005.         add esp,32h
  2006.         jmp _endint21error
  2007.  
  2008. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2009. ; INT 21h Service 56h - Rename File
  2010. ; In:
  2011. ;   AH - 56h
  2012. ;   DS:EDX -> Old Filename
  2013. ;   ES:EDI -> New Filename
  2014. ; Out:
  2015. ;   CF=0 Success
  2016. ;   CF=1 Error
  2017. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2018. _int2156:
  2019.         sub esp,32h
  2020.         mov ebp,esp
  2021.         mov byte ptr [ebp+_eax+1],ah
  2022.  
  2023.         or ecx,-1
  2024.         xor al,al
  2025.         repnz scas byte ptr es:[edi]
  2026.         not ecx
  2027.         sub edi,ecx
  2028.         push ds
  2029.         mov esi,edi
  2030.         mov ax,es
  2031.         mov ds,ax
  2032.         mov es,cs:_int21datasel
  2033.         mov edi,cs:_int21lowbufptr
  2034.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  2035.         pop ds
  2036.  
  2037.         mov ecx,edi
  2038.         mov ebx,cs:_int21lowbufptr
  2039.         sub ecx,ebx
  2040.         xchg ecx,ebx
  2041.  
  2042.         mov ax,ds
  2043.         mov es,ax
  2044.         mov esi,edx
  2045.         xchg esi,edi
  2046.         or ecx,-1
  2047.         xor al,al
  2048.         repnz scas byte ptr es:[edi]
  2049.         not ecx
  2050.         sub edi,ecx
  2051.         xchg esi,edi
  2052.         mov es,cs:_int21datasel
  2053.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  2054.  
  2055.         mov ax,cs:_int21lowbufseg
  2056.         mov [ebp+_ds],ax
  2057.         mov [ebp+_es],ax
  2058.         mov word ptr [ebp+_edi],0
  2059.         mov word ptr [ebp+_edx],bx
  2060.         call _realmodeint21
  2061.  
  2062.         jmp _endint21error_eax52h_0
  2063.  
  2064. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2065. ; INT 21h Service FFh - DOS Extender Check
  2066. ; In:
  2067. ;   AH - FFh
  2068. ;   DX - 78h
  2069. ; Out:
  2070. ;   GS - Info Segment
  2071. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2072. _int21FF:
  2073.         cmp dx,78h
  2074.         jnz _int21FFend
  2075.         mov gs,cs:_int21infosel
  2076.         mov byte ptr [esp+20h],0ffh
  2077.         jmp _endint21handler
  2078. _int21FFend:
  2079.         jmp _int21tend
  2080.  
  2081. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2082. ; End Of INT 21h Handler
  2083. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2084. _endint21handler:
  2085.         popd es
  2086.         popad
  2087.         and dword ptr [esp+8],NOT 1
  2088.         iretd
  2089. _endint21error:
  2090.         popd es
  2091.         popad
  2092.         or dword ptr [esp+8],1
  2093.         iretd
  2094.  
  2095. _endint21error_eax52h_0:
  2096.         mov dword ptr [ebp+52h],0
  2097. _endint21error_eax52h:
  2098.         test word ptr [ebp+_flags],1
  2099.         jnz _int21err_eax52h
  2100.         add esp,32h
  2101.         jmp _endint21handler
  2102. _int21err_eax52h:
  2103.         movzx eax,word ptr [ebp+_eax]
  2104.         mov dword ptr [ebp+52h],eax
  2105. _int21err_leave_eax:
  2106.         add esp,32h
  2107.         jmp _endint21error
  2108.  
  2109. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2110. ; Call Real Mode INT 21h
  2111. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2112. _realmodeint21:
  2113.         push es
  2114.         mov word ptr [ebp+_ss],0
  2115.         mov word ptr [ebp+_sp],0
  2116.         mov word ptr [ebp+_flags],0
  2117.         mov ax,ss
  2118.         mov es,ax
  2119.         mov edi,ebp
  2120.         mov ax,300h
  2121.         mov bx,21h
  2122.         xor cx,cx
  2123.         int 31h
  2124.         pop es
  2125.         ret
  2126.  
  2127. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2128. ; Subroutine For Some INT 21h Functions
  2129. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2130. _int21bufferpath:
  2131.         mov ax,ds
  2132.         mov es,ax
  2133.         mov edi,edx
  2134.  
  2135.         or ecx,-1
  2136.         xor al,al
  2137.         repnz scas byte ptr es:[edi]
  2138.         not ecx
  2139.  
  2140.         mov es,cs:_int21datasel
  2141.         mov edi,cs:_int21lowbufptr
  2142.         mov esi,edx
  2143.         rep movs byte ptr es:[edi],byte ptr ds:[esi]
  2144.  
  2145.         mov ax,cs:_int21lowbufseg
  2146.         mov [ebp+_ds],ax
  2147.         mov word ptr [ebp+_edx],0
  2148.         call _realmodeint21
  2149.         ret
  2150.  
  2151. pmcode16        ends
  2152.  
  2153. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  2154. ; STACK
  2155. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  2156. pmstack         segment para stack use16 'STACK'
  2157.                 db      STACKLEN*16 dup(?)
  2158. pmstack         ends
  2159.  
  2160. end _pm16start
  2161.  
  2162.