Category : Assembly Language Source Code
Archive   : PICALC.ZIP
Filename : PICALC.ASM

 
Output of file : PICALC.ASM contained in archive : PICALC.ZIP
; File: PICALC.ASM System: PI Calc Version: 1.00 Date: 10-01-94 ;

;-----------------------------------------------------------------------------
; PICALC.COM computes and displays number PI using spigot algorithm (due to S.
; Rabinowitz). Accuracy here is determined by size of spigot array: 32786
; words => 32768*log(2) = 9864 digits => 2466 iterations. Output may be
; redirected to file. For radix 10000 and array size here, each output word
; is luckily in range [0, radix-1]. For smaller radix or larger (dword)
; array, output word (dword) will sometimes match radix exactly, implying
; zeroes and bump by one of previously output digits.
;
; Program takes 2 minutes on a 486/66 MHz machine. See PI386.COM for a faster
; version algorithm, using double word array elements and capable of finding
; several million digits of pi. PICALC.COM is 85 bytes. Goal here was
; smallest possible COM file (with no command-line arguments) capable of
; calculating and displaying nearly 10K decimal digits of pi.
;
; C. Hessel/ER Support/DOE/Germantown MD
;-----------------------------------------------------------------------------

Code_Seg SEGMENT ; Assume 128K free and AH zero from DOS
ASSUME cs:Code_Seg

ORG 100h
Begin: mov dx,cs ; Get segment 64K forward, insuring
add dh,10h ; past stack
mov es,dx ; Save as buffer segment for 64K spigot
std ; Work backwards for duration
xor di,di ; Buffer start
mov al,2 ; Store word 2's to buffer, with wrap
mov cx,8001h ; leaving DI pointing to last word and
rep stosw ; zeroing CX for main loop entry
mov si,10000 ; Fix at largest 10-power fitting word
mov bp,2466 ; Maximum iteration value with BX slop
jmp SHORT iterloop ; Best BX is 20000, but any ok--also could
; zero BX and make last array word 4
bufloop: inc di ; 2*k+1
div di ; temp <- temp/(2*k+1)
mov bx,dx ; a[k] <- remainder
shr di,1 ; k
mul di ; temp <- k*temp
add di,di ; 2*k
xchg bx,ax ; q <- temp and ready a[k] for store
mov cx,dx
stosw ; Store a[k], decrementing k
iterloop: mov ax,es:[di] ; Fetch next a[k]
mul si ; temp <- a[k]*10000
add ax,bx ; temp <- temp+q
adc dx,cx
test di,di ; Test if k = 0
jne bufloop ; No? Loop

div si ; Output word <- temp/10000
xchg ax,dx ; a[0] <- remainder
stosw ; Store a[0], resetting k to buffer end
xchg ax,dx ; Output word back to AX (0-9999)
mov cl,4 ; CX was zero on inner loop exit
mov bx,10 ; Divisor 10 to extract digits
pushloop: cwd ; Zeroes DX since AX < 32768
div bx
add dl,'0' ; Make remainder ASCII digit
push dx ; Save, since must reverse order
loop pushloop

mov cl,4
poploop: pop dx ; Pop digits in reverse order
mov ah,2
int 21h ; DOS display character DL
loop poploop

dec bp ; Should zero CX:BX, but 10 ok
jne iterloop ; Not about 10K digits yet? Loop

ret ; Exit via int 20h at PSP start

Code_Seg ENDS
END Begin


  3 Responses to “Category : Assembly Language Source Code
Archive   : PICALC.ZIP
Filename : PICALC.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/