home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
ddjmag
/
ddj8712.arc
/
MARIELLA.ARC
/
R32FAIL.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-12-21
|
7KB
|
230 lines
; R32fail.ASM - 32 bit integer test program REPT macros
; looks for the first time that Newton fails 0,-1
; By Ray Mariella, April 87
page ,96
.8087
;
crlf macro
mov dl,13
call char_out
mov dl,10
call char_out
endm
;
time_print macro byte_var, byte_string
local plenty
mov dl,byte_string ;output a colon or period
call char_out
cmp byte_var,9
ja plenty
mov dl,'0' ;space holder if var<10
call char_out
plenty: mov al,byte_var ;minutes, secs, or hnds
xor ah,ah
call dec_out
endm
;
;
data segment word public 'DATA'
base dw 10 ;base to print the numbers in
BIGGUN dq ?
rootp dd ?
contwd dw ?
uper db ?
secs db ?
hnds db ?
announc db 'incr. lower 16 from 1 ',13,10,'$'
intermed db ' passed 65535 ',13,10,'$'
data ends
;
;
stack segment stack
dw 64 dup(?)
stack ends
;
;
code segment word public 'code'
assume cs:code, ds:data, ss:stack
;
sqrt: push bp
mov ax,data
mov ds,ax
mov bp,offset biggun
fclex ;clear 8087 exceptions, if any
fstcw contwd ;get control word
and contwd,1111001111111111B ;round to nearest
fldcw contwd ;load changed control word
crlf
mov dx,offset announc
mov ah,9 ;print string function
int 21h ;DOS interrrupt
mov dl,13
call char_out
;
herald: crlf
;
rolling: xor bx,bx
xor ax,ax
mov si,1 ;lower 16, will vary
mov ds:[bp],si ;BIGGUN lower 16
mov di,0 ;upper 16
mov ds:[bp+2],di
;
;
goodies: call update
crlf
start: FILD BIGGUN
;
; square root procedure via 8086/V30
;
;
mov bx,1 ;guess1
mov dx,di ;guess2
mov ax,si
;
REPT 8
or dx,dx
jz halfway
rcr dx,1 ;upper 16/2
rcr ax,1 ;lower 16/2 + carry from upper
shl bx,1 ;guess1*2
endm
jmp short rest
halfway: jmp short words
;
rest:
REPT 8
or dx,dx
jz words
rcr dx,1 ;upper 16/2
rcr ax,1 ;lower 16/2 + carry from upper
shl bx,1 ;guess1*2
endm
;next is for guess1 and guess2 16 bits
words: FSQRT
or bx,bx
jnz checkem ;if all 32 were used, CF is set
mov bx,65535 ;in case all 32 bits were used
;
checkem: mov dx,ax ;guess2 ax,dx
mov cx,bx ;guess1 bx,cx
;
logit:
REPT 8
shl cx,1 ;guess1
jc average ;necessary for 2000:4000 and up
cmp cx,dx ;larger than guess2?
jae average
shr dx,1 ;if not, guess2/2
mov ax,dx
mov bx,cx
endm
;ready for averaging
average: FISTP rootp
add bx,ax
rcr bx,1 ;average value
Newton:
REPT 2
mov ax,si ;lower 16
mov dx,di ;prepare for division, upper 16 in dx
cmp bx,dx ;for FFFE:0000 and up
je quit
div bx ;ax still has target, bx first guess
add bx,ax ;newton
rcr bx,1
endm
FWAIT
done: mov ax,bx ;ax, and bx have approx. root
mov dx,word ptr ds:[bp+8] ;bp+8 is rootp, 8087 root
xor ax,dx ;see if rootp agrees
jz cont
cmp bx,dx
ja quit
;
belo: inc bx
cmp bx,dx
jnz quit
;
;
cont: inc si ;lower 16
jnz notyet
inc di
mov ax,di
call dec_out
mov dx,offset intermed
mov ah,9
int 21h
crlf
notyet: mov ds:[bp+2],di ;biggun upper 16
mov ds:[bp],si ;biggun lower 16
jmp start
;
quit: call update
mov ax,di
call dec_out
mov dl,','
call char_out
mov ax,si
call dec_out
crlf
pop bp
xor al,al
mov ah,4Ch
int 21h
ret
;
; output a hex word in decimal
;
; CX,AX,DX destroyed
;
dec_out proc near
xor cx,cx
another: inc cx
xor dx,dx
div base ;base is 10 decimal!
push dx ;remainder is less sig digits
or ax,ax ;is the quotient zero?
jnz another ;if not, more number to convert
print_dig:
pop dx ;retrive digit from stack
add dl,'0' ;ascii offset
call char_out
loop print_dig ;do all of the digits
ret
dec_out endp
;
; output a single character from dl
;
char_out proc near
mov ah,2 ;output char function
int 21h ;do it
ret
char_out endp
;
;
update proc near
mov ah,2ch ;get dos time
int 21h ;hour in ch, mins in cl,secs in dh
mov uper,cl
mov secs,dh
mov hnds,dl
mov al,ch
xor ah,ah
call dec_out
;
time_print uper,':'
;
time_print secs,':'
;
time_print hnds,'.'
;
crlf
ret
update endp
;
code ends
end sqrt