home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
sysutl
/
emsuit11.arc
/
ERAM.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-02-22
|
9KB
|
294 lines
%TITLE "ERAM"
IDEAL
DOSSEG
MODEL small
STACK 32
; ERAM vers 1.02 by James W. Birdsall, 12/30/89
; portions copyright by Ray Duncan and Ziff Communications Co.
; prints out conventional and EMS RAM free
; Turbo Assembler
CR EQU 0Dh
LF EQU 0Ah
PAGESIZE EQU 16384
DATASEG
conram db CR,LF,'Conventional RAM available: $'
conram2 db CR,LF,'$'
emsram db 'EMS (vers '
emsramvers db 'x.x) RAM available: $'
emsramsize db ' ($'
emsrampages db ' pages)',CR,LF,'$'
emmname db 'EMMXXXX0',0
pages dw (?)
erro db CR,LF,'Unexpected error',CR,LF,'$'
holding db ' $'
NoEMMFound db 'No EMM found or error talking to EMM',CR,LF,'$'
badversion db 'ERAM requires LIM EMS version 3.0 or better',CR,LF,'$'
CODESEG
PROC Ddiv
; double precision unsigned divide for real mode
; this procedure Copyright (C) 1989 Ziff Communications Co.
; PC Magazine * Ray Duncan
; DX:CX:BX:AX dividend, SI:DI divisor
; returns DX:AX quotient, CX:BX remainder
; destroys SI,DI
push bp ; save register
mov bp, cx ; BP = 3sw of dividend
mov cx, 32 ; initialize loop counter
clc ; carry flag initially clear
@@ddiv1:
rcl ax, 1 ; test this bit of dividend
rcl bx, 1
rcl bp, 1
rcl dx, 1
jnc @@ddiv3 ; jump if bit was clear
@@ddiv2:
sub bp, di ; subtract divisor from dividend
sbb dx, si
stc ; force carry flag set
loop @@ddiv1 ; shift it into forming quotient
jmp @@ddiv5
@@ddiv3:
cmp dx, si ; dividend > divisor?
jc @@ddiv4 ; no, jump
jne @@ddiv2 ; yes, subtract divisor
cmp bp, di
jnc @@ddiv2 ; yes, subtract divisor
@@ddiv4:
clc ; force carry flag clear
loop @@ddiv1 ; shift it into forming quotient
@@ddiv5:
rcl ax, 1 ; bring last bit into quotient
rcl bx, 1
mov cx, bp
xchg dx, bx ; put quotient in DX:AX
xchg cx, bx ; put remainder in CX:BX
pop bp ;restore register
ret
ENDP Ddiv
PROC Decimalize
; takes DX:AX and turns into ASCII decimal in HOLDING
; returns index to first character in BX
; destroys AX, DX
push cx ; save registers
push bp
push si
push di
mov bx, 8
@@Init:
dec bx
mov [holding+bx], 20h ; initialize HOLDING with spaces
or bx, bx
jnz @@Init ; loop through buffer
mov si, 7 ; index into HOLDING
push si ; store safely
mov bx, dx ; set up dividend
xor cx, cx
xor dx, dx
mov di, 10 ; divisor
xor si, si
@@LoopTop:
call Ddiv ; divide by 10
or ax, ax ; begin check for quotient zero
jz @@QuarterZero ; if zero, check more quotient
jmp @@NotZero ; otherwise process
@@QuarterZero:
or dx, dx ; finish check for quotient zero
jz @@HalfZero ; if zero, check remainder
jmp @@NotZero ; otherwise process
@@HalfZero:
or bx, bx ; begin check for remainder zero
jz @@AlmostZero ; if zero, check more remainder
jmp @@NotZero ; otherwise process
@@AlmostZero:
or cx, cx ; finish check for remainder zero
jz @@LoopBot ; if also zero, exit loop
@@NotZero:
or bx, 30h ; make into ASCII digit
pop si
mov [holding+si], bl ; and move to holding area
dec si ; decrement index
push si ; and store
mov bx, dx ; reset for next divide
xor cx, cx
xor dx, dx
mov di, 10
xor si, si
jmp @@LoopTop ; and loop
@@LoopBot:
pop bx ; pop index into BX
cmp bx, 7 ; has index changed?
jne @@OutOK ; if it has, everything is OK
mov [holding+bx], 30h ; otherwise move '0' into HOLDING
dec bx ; decrement index in prep for inc
@@OutOK:
inc bx ; increase index to first of string
pop di ; restore registers
pop si
pop bp
pop cx
ret
ENDP Decimalize
Start:
mov ax, @data ; set up data segment
mov ds, ax
mov ax, 4A00h ; set up to change block size
mov bx, 0FFFFh ; excessively large block
; ES already points to PSP
int 21h ; call DOS
jc GotSize ; if error, got size OK
mov ax, 0900h ; set up to print error msg
mov dx, offset erro
int 21h ; call DOS
mov ax, 4C03h ; set up to exit, code 3
int 21h ; call DOS
GotSize:
inc bx ; more accurate this way
mov ax, 0900h ; set up to print
mov dx, offset conram
int 21h ; call DOS
xor dx, dx ; zero DX
mov dl, bh ; move high byte to DL
mov cl, 4 ; prepare to shift
shr dx, cl ; shift so only MSB is in DX
shl bx, cl ; shift BX up; result is mul by 16
mov ax, bx ; set up for divide
call Decimalize ; convert to ASCII string in HOLDING
mov ax, 0900h ; set up to print
mov dx, offset holding
add dx, bx ; index into string
int 21h ; call DOS
mov ax, 0900h ; set up to print
mov dx, offset conram2
int 21h ; call DOS
; this block of code adapted from _MS-DOS_Extensions_ Quick Reference, by
; Ray Duncan, pp. 25-26.
mov dx, offset emmname ; begin search for EMM
mov ax, 3D00h ; open for read only
int 21h ; call DOS
jnc OK1 ; if no carry, OK
jmp NoEMM ; else error
OK1:
mov bx, ax ; move handle to BX
mov ax, 4400h ; IOCTL get dev info
int 21h ; call DOS
jnc OK2 ; if no carry, OK
jmp NoEMM ; else error
OK2:
and dx, 80h ; check MSB (1 = char dev)
jz NotOK ; if zero, it's a file, not EMM
mov ax, 4407h ; IOCTL get status
int 21h ; call DOS
jc NotOK ; if carry, error
or al, al ; check device status
jz NotOK ; if AL=0 EMM not available
mov ah, 3Eh ; prep to close (BX still has handle)
int 21h ; call DOS
jnc FinalOK ; if no carry, OK
NotOK:
jmp NoEMM ; else error
; end of block by Ray Duncan
FinalOK:
mov ax, 4600h ; set up to get EMM LIM version
int 67h ; call EMM
or ah, ah ; check return
jnz NoEMM ; if not zero, error
mov bl, al ; copy version number for processing
mov cl, 4 ; bits to shift
shr bl, cl ; BL has integer of version
shl al, cl
shr al, cl ; strip off high four bits
; AL has fraction of version
cmp bl, 3 ; check version
jge VersionOK ; if >= 3.0, OK
mov ax, 0900h ; set up for printing
mov dx, offset badversion
int 21h ; call DOS
jmp Exit ; and jump to Exit routine
VersionOK:
or al, 30h ; convert to ASCII digit
or bl, 30h
mov [emsramvers], bl ; store for printing
mov [emsramvers+2], al
mov ax, 0900h ; set up for printing
mov dx, offset emsram
int 21h ; call DOS
mov ax, 4200h ; set up to get unallocated page cnt
int 67h ; call EMM
or ah, ah ; check return
jnz NoEMM ; if not zero, error
mov [pages], bx ; store number of free pages
mov cx, PAGESIZE ; set up for multiply
mov ax, [pages]
mul cx ; mul pages by pagesize to get bytes
; in DX:AX
call Decimalize ; convert to ASCII string in HOLDING
mov ax, 0900h ; set up to print
mov dx, offset holding
add dx, bx ; index into HOLDING
int 21h ; call DOS
mov ax, 0900h ; set up to print
mov dx, offset emsramsize
int 21h ; call DOS
mov ax, [pages] ; retrieve number of pages
xor dx, dx ; DX:AX = pages
call Decimalize ; convert to ASCII string in HOLDING
mov ax, 0900h ; set up to print
mov dx, offset holding
add dx, bx ; index into HOLDING
int 21h ; call DOS
mov ax, 0900h ; set up to print
mov dx, offset emsrampages
int 21h ; call DOS
jmp Exit ; jump to Exit routine
NoEMM:
mov ax, 0900h ; set up to print
mov dx, offset NoEMMFound
int 21h ; call DOS
Exit:
mov ax, 0900h ; print one last CR/LF
mov dx, offset conram2
int 21h ; call DOS
mov ax, 4C00h ; set up to exit, code 0
int 21h ; call DOS
END Start