home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / DOS / UTILITY / GEHEUGEN / USE_UMBS / USE!UMBS.ASM < prev    next >
Assembly Source File  |  1991-11-27  |  15KB  |  404 lines

  1. ;-------------------------------------------------------------------
  2. ;
  3. ; PROGRAM   Use!UMBs.sys - UMB manager for PC/XT/ATs
  4. ;
  5. ; PURPOSE   This program creates a device driver that will handle
  6. ;           calls for Upper Memory Blocks. In doing so, it gives
  7. ;           you the possibility to save conventional memory by
  8. ;           storing device drivers and resident programs in the
  9. ;           UMBs and hence save conventional memory.
  10. ;
  11. ; REQUIRES  It will work on any PC/XT/AT or higher, either with or
  12. ;           without extended memory. What you obviously *must* have
  13. ;           are UMBs, and MS-DOS Version 5.0.
  14. ;
  15. ; AUTHOR    Marco van Zwetselaar    Phone: **-31-30-313128
  16. ;           Oorsprongpark 5         FidoNet: Marco van.Zwetselaar
  17. ;           3581 ES Utrecht                  NetMail 2:281/701
  18. ;           The Netherlands         Utrecht, 7 Nov 1991
  19. ;
  20. ;-------------------------------------------------------------------
  21. ;
  22. ; IMPORTANT NOTE to the programmer
  23. ;
  24. ; I am only a beginner in assembly language, and haven't found out
  25. ; as yet how to create a .com file. When you recompile this program,
  26. ; take care you do that as a com file, and then rename it to a .sys
  27. ; file.
  28. ;
  29. ; I used an alternative method that you may use as well: I compiled
  30. ; it to .exe format and then removed the first (half?) sector. In
  31. ; fact, the first bytes in the final file should be:
  32. ;
  33. ; FF FF FF FF 00 E0 ...
  34. ;
  35. ; which are the bytes that start at nextDev. (Almost any device
  36. ; driver file should start with the first two words being FFFF (-1)).
  37. ;
  38. ;====================================================================
  39. ;
  40. ; THE ACTUAL ASSEMBLY CODE
  41. ;
  42. ;---------------------------------------------
  43. ; This is the structure of the request header; not stored in file
  44. ;
  45. rh              segment at 0
  46.                 org     02h
  47. rh_cmd          db      ?               ;command-code
  48. rh_status       dw      ?               ;return-code
  49.                 org     0Eh
  50. rh0_brk_ofs     dw      ?               ;end of driver offset
  51. rh0_brk_seg     dw      ?               ;end of driver segment
  52. rh              ends
  53. ;
  54. ;--------------------------------------------
  55. ; The driverheader
  56.  
  57.                 org     0h
  58. zwetsUMB        segment public
  59.                 assume  cs:zwetsumb, es:rh, ds:nothing
  60.  
  61. ; any device driver will start with the following info:
  62.  
  63. next_dev        dd      -1
  64. attribute       dw      0E000h
  65. strategy        dw      strat
  66. interrupt       dw      intr
  67. dev_name        db      'I_LOVE_M'
  68.  
  69. ;--------------------------------------------
  70. ; Storage space for pointer to Request Header
  71.  
  72. hdrptr  label   word
  73.         dw      ?,?
  74.  
  75. ;--------------------------------------------
  76. ; Strategy: store pointer to Request Header:
  77.  
  78. strat   proc    far
  79.         mov     [hdrptr],bx
  80.         mov     [hdrptr]+2,es
  81.         retf
  82. strat   endp
  83.  
  84. ;--------------------------------------------
  85. ; Interrupt: The routine that fires the installrequest
  86.  
  87. intr    proc    far
  88.  
  89.         push    ax
  90.         push    bx
  91.         push    es
  92.         pushf
  93.  
  94.         les     bx, dword ptr [hdrptr]  ;point es:bx to ReqHeader
  95.         mov     [bx].rh0_brk_seg, cs    ;and already return the seg
  96.  
  97. ; Remember that the device will only answer the init-request
  98. ; which is called by dos as it installs the driver.
  99. ; Any later calls will be ignored - they are not needed anyway.
  100.  
  101.         mov     al, es:[bx].rh_cmd      ;commandcode into al
  102.         or      al, al                  ;is it 0 (=init)?
  103.         jnz     other                   ;   no => get off
  104.         jmp     inst                    ;   yes => install
  105.  
  106. other:  cmp     al, 10h                 ;is it legal call?
  107.         jbe     short dos               ;   yes => "Sorry"
  108.         mov     ax, 8003h               ;   no => "Unknown command"
  109.         jmp     short exit
  110.  
  111. dos:    xor     ax, ax                  ;"Sorry - not implememented"
  112.  
  113. exit:   or      ax, 0100h               ;Set done bit
  114.         mov     es:[bx].rh_status, ax   ;set return code
  115.  
  116.         popf
  117.         pop     es
  118.         pop     bx
  119.         pop     ax
  120.  
  121.         retf                            ; back to dos
  122.  
  123. intr    endp
  124.  
  125. ;------------------------------------------------------
  126. ; Storage space for the addresses of free umb blocks
  127.  
  128. umb     struc
  129. start   dw      ?
  130. len     dw      ?
  131. umb     ends
  132.  
  133. ;you can add to the following list, as long as the last one is 0,0
  134.  
  135. free    umb     <0D000h, 1FFFh>   ;my only block (at d000, length 1fff)
  136.         umb     <0, 0>            ;space for extra block
  137.         umb     <0, 0>            ;and another block
  138.         umb     <0, 0>            ;The end of the blocks is marked
  139.                                   ; with 0,0 DON'T REMOVE THIS!!!!!
  140.  
  141. ;------------------------------------------------------
  142. ; This is the code for the actual UMB memory provider
  143.  
  144. umbreq  proc    near
  145.  
  146.         push    ds
  147.         push    si
  148.         push    cx
  149.         push    bx
  150.  
  151.         push    cs
  152.         pop     ds
  153.  
  154.         mov     si, offset free
  155.         xor     cx, cx                  ;clear dx and use it to compare
  156.         xchg    dx, cx                  ;to largest found as yet - cx=size
  157.  
  158. search: lodsw                           ;read startsegment into ax
  159.         or      ax, ax                  ;is it 0
  160.         jz      fini                    ;   then buzz off
  161.         mov     bx, ax                  ;   otherwise store into bx
  162.         lodsw                           ;read length in ax
  163.         cmp     bx, 0FFFFh              ;is startsegm=ffff=given away
  164.         je      search                  ;   yes: then find next block
  165.         cmp     dx, ax                  ;   no: larger than largest upto now?
  166.         jae     szchk                   ;       no: check size
  167.         mov     dx, ax                  ;       yes: mark as largest
  168.  
  169. szchk:  cmp     cx, ax                  ;will it fit?
  170.         ja      search                  ;   no: search next
  171.  
  172.         ; YEAH! Found a block
  173.  
  174.         mov     [si-4], 0FFFFh          ; mark as used
  175.         mov     dx, ax                  ; put blocksize in dx
  176.         mov     ax, 1                   ;say Succes
  177.         pop     cx                      ;still had bx on stack
  178.         jmp     short return
  179.  
  180. fini:   xor     ax, ax                  ;no fitting UMB
  181.         or      dx, dx                  ;is dx=0?, so largest found=0
  182.         jnz     sizerr                  ;   if not: problem with size
  183.         pop     bx                      ;   if yes: BH should stay intact
  184.         mov     bl, 0B1h                ;       and BL signals: out of UMBs
  185.         jmp     short return
  186.  
  187. sizerr: pop     bx                      ;BH remains intact
  188.         mov     bl, 0B0h                ;BL signals: there are smaller ones
  189.  
  190. return: pop     cx
  191.         pop     si
  192.         pop     ds
  193.         popf
  194.         retf
  195.  
  196. umbreq  endp
  197.  
  198. ;------------------------------------------------------
  199. ; Storage space for old XMS-handler. The first byte stores WHETHER there
  200. ; was an XMS handler already (that didn't provide UMB services).
  201. ; The next two words specify its location.
  202.  
  203. isoldx  db      00h
  204.  
  205. oldxms  label word
  206.         dw ?,?
  207.  
  208. ;------------------------------------------------------
  209. ; This is the small XMS manager that we install. It will only react
  210. ; to requests for UMBs (so when AH=10h). If not, it *should* pass
  211. ; control to the existing XMS manager - provided there is one. Or
  212. ; otherwise inform the caller that there is no eXt memory.
  213.  
  214.         assume es:nothing, ds:nothing
  215.  
  216. umbctrlr:
  217.  
  218.         jmp     short hookch            ;MUST be a *short* jmp
  219.         nop                             ; The nops are there because
  220.         nop                             ; a himem handler always start
  221.         nop                             ; with 5 special bytes.
  222.  
  223. hookch: pushf
  224.         cmp     ah, 10h                 ;is it a UMB request?
  225.         je      umbreq                  ;  yes: execute it
  226.         cmp     [isoldx], 0h            ;  no: is there an XMS-handler?
  227.         jz      Xreq1                   ;     no: give response like it
  228.         popf                            ;     yes: jump to old handler
  229.         jmp     dword ptr cs:[oldxms]
  230.  
  231. ; Below is the code that will respond to non-UMB (and thus XMS-)
  232. ; requests when no XMS-manager is present. To nearly all requests
  233. ; (there are 11h) it will answer with AX=0000, meaning failure
  234. ; and BL=80, which gives the errormessage: not implemented.
  235. ; Only fns 00h and 08h are treated specially (as well as fn 10h, but
  236. ; that has been filtered out above - it's the UMB-request).
  237.  
  238. Xreq1:  cmp     ah, 0h                  ;req 00h = get XMS version
  239.         jnz     Xreq2
  240.         mov     bx, 0h                  ; ->internal revision nr=0
  241.         mov     dx, 0h                  ; ->HMA not present
  242.         jmp     short byebye
  243.  
  244. Xreq2:  cmp     ah, 08h                 ;req 08h = query extended mem
  245.         jnz     Xreq3
  246.         mov     dx, 0h                  ; ->0k extended memory
  247.  
  248. Xreq3:  mov     bl, 80h                 ; ->error: not implemented
  249.         
  250. byebye: mov     ax, 00h                 ; ->failure (always the case)
  251.         popf
  252.         retf
  253.  
  254. ;------------------------------------------------------
  255. ; Storage space for old interrupt vector 2f
  256.  
  257. old2f   label   word
  258.         dw      ?,?
  259.  
  260. ;-------------------------------------------------------
  261. ; This is the code that is chained to the front of interrupt 2f.
  262. ; It will handle requests nrs. 4300 and 4310, and leave all others
  263. ;    to the existing code.
  264.  
  265. handl:  pushf
  266.  
  267.         cmp     ah, 43h                 ;is request for HIMEM?
  268.         jne     not4me                  ; no: pass on
  269.  
  270.         cmp     al, 10h                 ; is request: where is handler?
  271.         jne     mustbe                  ;    if not, then must be al=00
  272.  
  273.         mov     bx, offset umbctrlr     ; put handler's ofs in bx
  274.         push    cs                      ; and its segment
  275.         pop     es                      ; in es
  276.         jmp     short getout
  277.  
  278. mustbe: mov     al, 80h                 ;al <>10 so must be 00, so request
  279.                                         ;is: is there handler? Yes => 80h
  280. getout: popf
  281.         iret
  282.  
  283. not4me: popf                            ;request wasn't for me
  284.         jmp     dword ptr cs:[old2f]    ;so give back to old handl
  285.  
  286. ;=================================================================
  287. ;
  288. ; NON-RESIDENT PART
  289. ;
  290. ; The part that follows now will not remain resident. It will be
  291. ; executed only once: at the time the driver is installed by
  292. ; DOS' bootprocedures.
  293. ;
  294. ; This code takes care of (1) hooking our intercepting code to
  295. ; int 2f, (2) hooking our small XMS-manager to the already installed
  296. ; one - provided there is one, (3) and if not, installing the
  297. ; the response-robot that will inform callers that there's no eXt
  298. ; memory.
  299. ;
  300.  
  301. ;-------------------------------------------------------
  302. ; Installation routine. Called once.
  303.  
  304.         assume  ds:zwetsUMB, es:rh
  305.  
  306.  
  307. inst:   push    cx                      ;save em
  308.         push    dx
  309.         push    ds
  310.  
  311.         push    cs                      ;and set ds to cs
  312.         pop     ds
  313.  
  314.         mov     ah, 09h
  315.         mov     dx, offset hello1$      ;say welcome
  316.         int     21h
  317.         mov     dx, offset empty$
  318.         int     21h
  319.         mov     dx, offset hello2$
  320.         int     21h
  321.         mov     dx, offset empty$
  322.         int     21h
  323.         mov     dx, offset hello3$
  324.         int     21h
  325.         mov     dx, offset hello4$
  326.         int     21h
  327.         mov     dx, offset empty$
  328.         int     21h
  329.         mov     dx, offset autho1$
  330.         int     21h
  331.         mov     dx, offset autho2$
  332.         int     21h
  333.         mov     dx, offset empty$
  334.         int     21h
  335.  
  336.         mov     ax, 4300h               ;check if there is an XMShandler
  337.         int     2Fh                     ;already
  338.         cmp     al, 080h                ;is it there?
  339.         jne     SetVec                  ;  no: go further
  340.  
  341.         mov     [isoldx],01h            ;signal yourself there is one
  342.         mov     ax, 4310h               ;get its address
  343.         int     2Fh
  344.         mov     [oldxms], bx            ;and store it
  345.         mov     [oldxms+2], es
  346.  
  347.         mov     ah, 09h                 ;tell user
  348.         mov     dx, offset found$
  349.         int     21h
  350.         mov     dx, offset empty$
  351.         int     21h
  352.  
  353.         mov     ah, 10h                 ;check if it services UMBs by
  354.         mov     dx, 0FFFFh              ;trying to allocate FAR TOO much
  355.         call    dword ptr [oldxms]
  356.         cmp     bl, 80h                 ;error: not implemented?
  357.         jz      SetVec                  ; then good - continue
  358.  
  359.         mov     ah, 09h                 ;otherwise: get off,
  360.         mov     dx, offset oops$        ;you're not needed.
  361.         int     21h
  362.         les     bx, dword ptr [hdrptr]
  363.         xor     ax,ax
  364.         mov     es:[bx].rh0_brk_ofs, ax
  365.         jmp     short dexit
  366.  
  367. SetVec: mov     ax, 352Fh               ; get vector 2f
  368.         int     21h
  369.         mov     [old2f], bx             ;and store it
  370.         mov     [old2f]+2, es
  371.  
  372.         mov     ax, 252Fh               ;set it to our own
  373.         mov     dx, offset handl
  374.         int     21h
  375.  
  376.         mov     ah, 09h
  377.         mov     dx, offset instok$      ;say we did it
  378.         int     21h
  379.  
  380.         mov     ax, offset inst         ;upto inst it should stay
  381.         les     bx, dword ptr [hdrptr]  ;  resident, which we tell
  382.         mov     es:[bx].rh0_brk_ofs, ax ;  dos via the rqhdr.
  383.         xor     ax,ax                   ;0 no errors
  384.  
  385. dexit:  pop     ds
  386.         pop     dx
  387.         pop     cx
  388.         jmp     exit
  389.  
  390. hello1$ db  0Dh,0Ah,'╒══════════════╡   Use!UMBs   ╞═════════════╕',0Dh,0Ah,'$'
  391. empty$  db          '│                                           │',0Dh,0Ah,'$'
  392. hello2$ db          '│        Upper Memory Block - Manager       │',0Dh,0Ah,'$'
  393. hello3$ db          '│   Works on any PC/XT/AT, either with or   │',0Dh,0Ah,'$'
  394. hello4$ db          '│    without Extended or Expanded Memory!   │',0Dh,0Ah,'$'
  395. found$  db          '│     * found extended memory manager *     │',0Dh,0Ah,'$'
  396. autho1$ db          '│        Author: Marco van Zwetselaar       │',0Dh,0Ah,'$'
  397. autho2$ db          "│   dedicated it to the Public Domain 1991  │",0Dh,0Ah,'$'
  398. instok$ db          '╘══╡ Version 2.0 ╞══════════╡ Installed! ╞══╛',0Dh,0Ah,0Ah,'$'
  399. oops$   db          '╘═╡ Not Installed!  UMBs Managed Already! ╞═╛',0Dh,0Ah,0Ah,'$'
  400.  
  401. zwetsUMB   ends
  402.            end
  403.  
  404.