home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / sysutl / emsuit11.arc / ERAM.ASM < prev    next >
Assembly Source File  |  1990-02-22  |  9KB  |  294 lines

  1. %TITLE "ERAM"
  2. IDEAL
  3. DOSSEG
  4. MODEL small
  5. STACK 32
  6.  
  7. ; ERAM vers 1.02 by James W. Birdsall, 12/30/89
  8. ;   portions copyright by Ray Duncan and Ziff Communications Co.
  9. ; prints out conventional and EMS RAM free
  10. ; Turbo Assembler
  11.  
  12. CR        EQU    0Dh
  13. LF        EQU     0Ah
  14. PAGESIZE    EQU    16384
  15.  
  16. DATASEG
  17. conram        db    CR,LF,'Conventional RAM available: $'
  18. conram2        db    CR,LF,'$'
  19. emsram        db    'EMS (vers '
  20. emsramvers    db    'x.x) RAM available: $'
  21. emsramsize    db    ' ($'
  22. emsrampages    db    ' pages)',CR,LF,'$'
  23. emmname        db    'EMMXXXX0',0
  24. pages        dw    (?)
  25. erro        db    CR,LF,'Unexpected error',CR,LF,'$'
  26. holding        db    '        $'
  27. NoEMMFound    db    'No EMM found or error talking to EMM',CR,LF,'$'
  28. badversion      db      'ERAM requires LIM EMS version 3.0 or better',CR,LF,'$'
  29.  
  30.  
  31. CODESEG
  32.  
  33. PROC    Ddiv
  34.     ; double precision unsigned divide for real mode
  35.         ; this procedure Copyright (C) 1989 Ziff Communications Co.
  36.         ; PC Magazine * Ray Duncan
  37.         ; DX:CX:BX:AX dividend, SI:DI divisor
  38.         ; returns DX:AX quotient, CX:BX remainder
  39.     ; destroys SI,DI
  40.  
  41.         push    bp            ; save register
  42.         mov    bp, cx            ; BP = 3sw of dividend
  43.         mov    cx, 32            ; initialize loop counter
  44.         clc                ; carry flag initially clear
  45.  
  46. @@ddiv1:
  47.     rcl    ax, 1            ; test this bit of dividend
  48.         rcl    bx, 1
  49.         rcl    bp, 1
  50.         rcl    dx, 1
  51.         jnc    @@ddiv3            ; jump if bit was clear
  52.  
  53. @@ddiv2:
  54.     sub    bp, di            ; subtract divisor from dividend
  55.         sbb    dx, si
  56.         stc                ; force carry flag set
  57.         loop    @@ddiv1            ; shift it into forming quotient
  58.         jmp    @@ddiv5
  59.  
  60. @@ddiv3:
  61.     cmp    dx, si            ; dividend > divisor?
  62.         jc    @@ddiv4            ; no, jump
  63.         jne    @@ddiv2            ; yes, subtract divisor
  64.         cmp    bp, di
  65.         jnc    @@ddiv2            ; yes, subtract divisor
  66.  
  67. @@ddiv4:
  68.     clc                ; force carry flag clear
  69.         loop    @@ddiv1            ; shift it into forming quotient
  70.  
  71. @@ddiv5:
  72.     rcl    ax, 1            ; bring last bit into quotient
  73.         rcl    bx, 1
  74.         mov    cx, bp
  75.         xchg    dx, bx            ; put quotient in DX:AX
  76.         xchg    cx, bx            ; put remainder in CX:BX
  77.  
  78.         pop    bp            ;restore register
  79.         ret
  80.  
  81. ENDP    Ddiv
  82.  
  83.  
  84. PROC    Decimalize
  85.     ; takes DX:AX and turns into ASCII decimal in HOLDING
  86.         ; returns index to first character in BX
  87.         ; destroys AX, DX
  88.  
  89.         push    cx            ; save registers
  90.         push    bp
  91.         push    si
  92.         push    di
  93.  
  94.         mov    bx, 8
  95. @@Init:
  96.     dec    bx
  97.         mov    [holding+bx], 20h    ; initialize HOLDING with spaces
  98.         or    bx, bx
  99.         jnz    @@Init            ; loop through buffer
  100.         mov    si, 7            ; index into HOLDING
  101.         push    si            ; store safely
  102.         mov    bx, dx            ; set up dividend
  103.         xor    cx, cx
  104.         xor    dx, dx
  105.         mov    di, 10            ; divisor
  106.         xor    si, si
  107. @@LoopTop:
  108.     call    Ddiv            ; divide by 10
  109.         or    ax, ax            ; begin check for quotient zero
  110.         jz    @@QuarterZero        ; if zero, check more quotient
  111.         jmp    @@NotZero        ; otherwise process
  112. @@QuarterZero:
  113.     or    dx, dx            ; finish check for quotient zero
  114.         jz    @@HalfZero        ; if zero, check remainder
  115.         jmp    @@NotZero        ; otherwise process
  116. @@HalfZero:
  117.     or    bx, bx            ; begin check for remainder zero
  118.         jz    @@AlmostZero        ; if zero, check more remainder
  119.         jmp    @@NotZero        ; otherwise process
  120. @@AlmostZero:
  121.     or    cx, cx            ; finish check for remainder zero
  122.         jz    @@LoopBot        ; if also zero, exit loop
  123. @@NotZero:
  124.     or    bx, 30h            ; make into ASCII digit
  125.         pop    si
  126.         mov    [holding+si], bl    ; and move to holding area
  127.         dec    si            ; decrement index
  128.         push    si            ; and store
  129.         mov    bx, dx            ; reset for next divide
  130.         xor    cx, cx
  131.         xor    dx, dx
  132.         mov    di, 10
  133.         xor    si, si
  134.         jmp    @@LoopTop        ; and loop
  135.  
  136. @@LoopBot:
  137.     pop    bx            ; pop index into BX
  138.         cmp    bx, 7            ; has index changed?
  139.         jne    @@OutOK            ; if it has, everything is OK
  140.         mov    [holding+bx], 30h    ; otherwise move '0' into HOLDING
  141.         dec    bx            ; decrement index in prep for inc
  142. @@OutOK:
  143.            inc    bx            ; increase index to first of string
  144.  
  145.         pop    di            ; restore registers
  146.         pop    si
  147.         pop    bp
  148.         pop    cx
  149.         ret
  150. ENDP    Decimalize
  151.  
  152.  
  153.  
  154. Start:
  155.     mov     ax, @data        ; set up data segment
  156.     mov     ds, ax
  157.  
  158.         mov    ax, 4A00h        ; set up to change block size
  159.         mov    bx, 0FFFFh        ; excessively large block
  160.                         ; ES already points to PSP
  161.         int    21h            ; call DOS
  162.         jc    GotSize            ; if error, got size OK
  163.         mov    ax, 0900h        ; set up to print error msg
  164.         mov    dx, offset erro
  165.         int    21h            ; call DOS
  166.         mov    ax, 4C03h        ; set up to exit, code 3
  167.         int    21h            ; call DOS
  168.  
  169. GotSize:
  170.     inc    bx            ; more accurate this way
  171.     mov    ax, 0900h        ; set up to print
  172.         mov    dx, offset conram
  173.         int    21h            ; call DOS
  174.         xor    dx, dx            ; zero DX
  175.         mov    dl, bh            ; move high byte to DL
  176.         mov    cl, 4            ; prepare to shift
  177.         shr    dx, cl            ; shift so only MSB is in DX
  178.         shl    bx, cl            ; shift BX up; result is mul by 16
  179.         mov    ax, bx            ; set up for divide
  180.         call    Decimalize        ; convert to ASCII string in HOLDING
  181.  
  182.         mov    ax, 0900h        ; set up to print
  183.         mov    dx, offset holding
  184.         add    dx, bx            ; index into string
  185.         int    21h            ; call DOS
  186.         mov    ax, 0900h        ; set up to print
  187.         mov    dx, offset conram2
  188.         int    21h            ; call DOS
  189.  
  190. ; this block of code adapted from _MS-DOS_Extensions_ Quick Reference, by
  191. ; Ray Duncan, pp. 25-26.
  192.  
  193.     mov    dx, offset emmname    ; begin search for EMM
  194.         mov    ax, 3D00h        ; open for read only
  195.         int    21h            ; call DOS
  196.         jnc    OK1            ; if no carry, OK
  197.     jmp    NoEMM            ; else error
  198. OK1:
  199.         mov    bx, ax            ; move handle to BX
  200.         mov    ax, 4400h        ; IOCTL get dev info
  201.         int    21h            ; call DOS
  202.         jnc    OK2            ; if no carry, OK
  203.         jmp    NoEMM            ; else error
  204. OK2:
  205.         and    dx, 80h            ; check MSB (1 = char dev)
  206.         jz    NotOK            ; if zero, it's a file, not EMM
  207.         mov    ax, 4407h        ; IOCTL get status
  208.         int    21h            ; call DOS
  209.         jc    NotOK            ; if carry, error
  210.         or    al, al            ; check device status
  211.         jz    NotOK            ; if AL=0 EMM not available
  212.         mov    ah, 3Eh            ; prep to close (BX still has handle)
  213.         int    21h            ; call DOS
  214.         jnc    FinalOK            ; if no carry, OK
  215. NotOK:
  216.         jmp     NoEMM            ; else error
  217.  
  218. ; end of block by Ray Duncan
  219.  
  220. FinalOK:
  221.         mov    ax, 4600h        ; set up to get EMM LIM version
  222.         int    67h            ; call EMM
  223.         or    ah, ah            ; check return
  224.         jnz     NoEMM            ; if not zero, error
  225.         mov    bl, al            ; copy version number for processing
  226.         mov    cl, 4            ; bits to shift
  227.         shr    bl, cl            ; BL has integer of version
  228.         shl    al, cl
  229.         shr    al, cl            ; strip off high four bits
  230.                         ; AL has fraction of version
  231.     cmp    bl, 3            ; check version
  232.     jge    VersionOK        ; if >= 3.0, OK
  233.     mov    ax, 0900h        ; set up for printing
  234.     mov    dx, offset badversion
  235.     int    21h            ; call DOS
  236.     jmp    Exit            ; and jump to Exit routine
  237.  
  238. VersionOK:
  239.         or    al, 30h            ; convert to ASCII digit
  240.         or    bl, 30h
  241.         mov    [emsramvers], bl    ; store for printing
  242.         mov    [emsramvers+2], al
  243.         mov    ax, 0900h        ; set up for printing
  244.         mov    dx, offset emsram
  245.         int    21h            ; call DOS
  246.  
  247.         mov    ax, 4200h        ; set up to get unallocated page cnt
  248.         int    67h            ; call EMM
  249.         or    ah, ah            ; check return
  250.         jnz    NoEMM            ; if not zero, error
  251.         mov    [pages], bx        ; store number of free pages
  252.  
  253.         mov    cx, PAGESIZE        ; set up for multiply
  254.         mov    ax, [pages]
  255.         mul    cx            ; mul pages by pagesize to get bytes
  256.                         ; in DX:AX
  257.         call    Decimalize        ; convert to ASCII string in HOLDING
  258.         mov    ax, 0900h        ; set up to print
  259.         mov    dx, offset holding
  260.         add     dx, bx            ; index into HOLDING
  261.         int    21h            ; call DOS
  262.         mov    ax, 0900h        ; set up to print
  263.         mov    dx, offset emsramsize
  264.         int    21h            ; call DOS
  265.  
  266.         mov    ax, [pages]        ; retrieve number of pages
  267.         xor    dx, dx            ; DX:AX = pages
  268.         call    Decimalize        ; convert to ASCII string in HOLDING
  269.         mov    ax, 0900h        ; set up to print
  270.         mov    dx, offset holding
  271.         add    dx, bx            ; index into HOLDING
  272.         int    21h            ; call DOS
  273.         mov    ax, 0900h        ; set up to print
  274.         mov    dx, offset emsrampages
  275.         int    21h            ; call DOS
  276.  
  277.         jmp    Exit            ; jump to Exit routine
  278.  
  279.  
  280. NoEMM:
  281.     mov    ax, 0900h        ; set up to print
  282.         mov    dx, offset NoEMMFound
  283.         int    21h            ; call DOS
  284.  
  285. Exit:
  286.     mov    ax, 0900h        ; print one last CR/LF
  287.         mov    dx, offset conram2
  288.         int    21h            ; call DOS
  289.         mov    ax, 4C00h        ; set up to exit, code 0
  290.         int    21h            ; call DOS
  291.  
  292.  
  293. END    Start
  294.