.MODEL TINY
;----------
;PLAYING WITH FIBONACCI NUMBERS BY YSS (MAY 2005)
;
;F(N+2)=F(N+1)+F(N)
;		       F(0)=0, F(1)=1
;
;MAX TERMS = (60000 - LOG(SQR(5))/(LOG(1+SQR(5)/2))) / (LOG(1+SQR(5)/2))
;	   = 287090 APPROX.
;
;WHERE '60000' IS THE TOTAL NUMBER OF POSSIBLE DIGITS.
;
;THIS PROGRAM CALCS AND OUTPUTS THE 'FIBONACCI' SERIES TO STDOUT UP TO
;ABOUT 287000+ TERMS.	IT'S A LITTLE FASTER THAN F7.ASM BUT THESE ISSUES
;REMAIN:
;
; - NO OR LITTLE OPTIMIZATION (THIS CODE WAS WRITTEN 'ON THE FLY')
; - THE COMPRESSION OF THE DIGITS:
;		     EACH BYTE HOLDS TWO DECIMAL DIGITS IN LO-HI ORDER,
;			  THAT TAKES A LITTLE EXTRA TIME.

; SPEED WAS OBTAINED OVER F7.ASM BY SOLVING THIS ISSUE:
;   IN F7.ASM :
; - EACH DIGIT IS OUTPUT TO STDOUT ONE AT A TIME.
;	       A SPEED INCREASE OF OVER 30% CAN BE GAINED IF A FULL STRING
;	       IS OUTPUT INSTEAD.
;
;
;TWO ACCUMULATORS ARE USED, X1 AND X2, EACH CAPABLE OF HANDLING UP TO 60000
;DIGITS (30000 BYTES LONG EACH).
;
;USE:
;SET TL = MAX # OF TERMS -> ASSEMBLE -> F7 TO SEE RESULTS TO STDOUT
;
;

TL EQU 287000 ;TOTAL TERMS TO CALC

CSEG SEGMENT
ORG 100H
	ASSUME CS:CSEG,DS:CSEG
START:
	MOV DI,OFFSET A+X0
	MOV X0FS,DI
	MOV DI,OFFSET A+X1

	MOV CX,60000/2
	REP STOSW      ;CLR ALL

	INC AX
	MOV X1CT,AX
	MOV [A+X1],AX	;
	MOV BP,TL ;575;00 ;TOTAL # TERMS [ F(X) ] CALC'D
S00:
	MOV DI,OFFSET A+X2
	MOV SI,OFFSET A+X1
	TEST BL,1
	JNE S001
	XCHG DI,SI
S001:
	CALL LOUT
ADD12:
	PUSH DI
	PUSH SI
	PUSH BP
	XOR BP,BP
	MOV CX,X1CT
	CLC

	ACXMRE:
	MOV AL,[DI]
	MOV DL,[SI]

	MOV AH,DL
	PUSH AX
	CALL AAB1
	MOV DH,AL
	POP AX
	PUSHF
	SHR AX,1
	SHR AX,1
	SHR AX,1
	SHR AX,1
	POPF
	CALL AAB1
	PUSHF
	AND DH,0FH
	SHL AL,1
	SHL AL,1
	SHL AL,1
	SHL AL,1
	OR AL,DH
	POPF


	MOV [SI],AL
	JNB ADOK
	CMP CX,1
	STC
	JNE ADOK
	INC CX
	ADOK:
	INC DI
	INC SI
	INC BP
	LOOP ACXMRE
	MOV X1CT,BP
	POP BP
	POP SI
	POP DI

	DEC BL
	DEC BP
	JNE S00
	CMP X0CT,0
	JE S0010
	CALL X01
S0010:
	RET

LOUT:
       MOV DX,X1CT
       PUSH DI
       PUSH SI
       MOV AH,2
       MOV SI,DI
       DEC SI
       ADD DI,DX
       MOV CX,000FEH  ;CH=0 FOR LEADING 0'S NOT OUT

LN0001:
       MOV DL,[DI]
       TEST CL,1
       JNE LN0000

       SHR DL,1
       SHR DL,1
       SHR DL,1
       SHR DL,1
       JMP SHORT LN0002
LN0000:
       DEC DI
LN0002:
       AND DL,0FH
       OR DL,30H
       CMP DL,30H
       JE LN00201
       OR CH,1
       JMP LN0020
LN00201:
       TEST CH,1
       JE LN00202
LN0020:
       PUSH CX
       CALL X0OUT
       POP CX
LN00202:

       DEC CL
       CMP DI,SI
       JNE LN0001
       POP SI
       POP DI

ODOAH:
	MOV AH,2
	MOV DL,13
	CALL X0OUT
	MOV DL,10

X0OUT:
	CMP X0FS,OFFSET A+X0+XN
	JB X0DIOK
	MOV X0FS,OFFSET A+X0
X01:
	PUSH BX
	PUSH DX
	MOV BX,1
	MOV AH,40H
	MOV DX,OFFSET A+X0
	MOV CX,X0CT
	INT 21H
	POP DX
	POP BX

	MOV X0CT,0
X0DIOK:
	PUSH DI
	MOV DI,X0FS
	MOV [DI],DL
	POP DI
	INC X0FS
	INC X0CT
	RET

AAB1:
	PUSHF
	AND AX,0F0FH
	POPF
	ADC AL,AH
	AAA
	RET
	RET
	RET
	RET
	RET
	RET
	RET
	RET
	RET

X1CT DW 0   ;#DIGITS SO FAR
X0FS DW 0
X0CT DW 0
A LABEL WORD
XN EQU 2048+1500
X0 EQU 0
X1 EQU X0 + XN
X2 EQU X1 + 30000
;-------------------------------
;http://www.oocities.org/yssmlp
;pixelrat@hotmail.com
;or google around for "yssmlp"! :)
;-------------------------------
CSEG ENDS
     END START