📄 lyapunov.asm
字号:
fsubp st(2),st ; Rate Population-Population^2
; =Population*(1-Population)
fmul ; Rate*Population*(1-Population)
dec dx ; decrement overflowcheck counter
jnz filter_cycles_skip_overflow_check ; can we skip check?
fld st ; NewPopulation NewPopulation
fabs ; Take absolute value
fcomp BigNum ; Compare to 100000.0
fstsw status_word ;
fwait
mov dx,overflowcheck ; reset overflowcheck counter
mov ax,status_word ;
sahf ; NewPopulation
ja overflowed_with_Pop
filter_cycles_skip_overflow_check:
add di,2 ; di += sizeof(*lyaRxy)
loop filter_cycles_count_top ; if --cx > 0 then loop
inc si
jmp filter_cycles_top ; let's do it again
filter_cycles_bottom:
; total = 1.0;
; lnadjust = 0;
fld1
fstp total
mov lnadjust,0
; for (i=0; i < maxit/2; i++) {
; for (count = 0; count < lyaLength; count++) {
; Rate = lyaRxy[count] ? a : b;
; if (curfractalspecific->orbitcalc()) {
; overflow = TRUE;
; goto jumpout;
; }
; temp = fabs(Rate-2.0*Rate*Population);
; if ((total *= (temp))==0) {
; overflow = TRUE;
; goto jumpout;
; }
; }
; while (total > 22026.4657948) {
; total *= 0.0000453999297625;
; lnadjust += 10;
; }
; while (total < 0.0000453999297625) {
; total *= 22026.4657948;
; lnadjust -= 10;
; }
; }
; don't forget Population is still on stack
mov ax,maxit ; calculate halfmax
shr ax,1
mov halfmax,ax
xor si, si ; using si for i
halfmax_top:
cmp si, halfmax ; si < halfmax ?
; too far for a short jump, need a near jump here
jl init_halfmax_count ; yes, continue on with loop
jmp halfmax_bottom ; if not, end loop
init_halfmax_count:
mov cx, lyaLength ; using cx for count
mov di,OFFSET lyaRxy ; use di as lyaRxy[] index
; no need to compare cx with lyaLength at top of loop
; since lyaLength is guaranteed to be > 0
halfmax_count_top:
cmp WORD PTR [di],0 ; lyaRxy[count] ?
jz halfmax_use_b
fld a ; if lyaRxy[count]==true, use a
jmp SHORT halfmax_used_a
halfmax_use_b:
fld b ; if lyaRxy[count]==false, use b
halfmax_used_a:
; save Rate, but leave it on stack for use in BifurcLambdaMacro
fst Rate ; save for not_overflowed use
;BifurcLambdaMacro ; returns in flag register
fld st(1) ; Population Rate Population
fmul st,st ; Population^2 Rate Population
fsubp st(2),st ; Rate Population-Population^2
; =Population*(1-Population)
fmul ; Rate*Population*(1-Population)
dec dx ; decrement overflowcheck counter
jnz not_overflowed ; can we skip overflow check?
fld st ; NewPopulation NewPopulation
fabs ; Take absolute value
fcomp BigNum ; Compare to 100000.0
fstsw status_word ;
fwait
mov dx,overflowcheck ; reset overflowcheck counter
mov ax,status_word ;
sahf ;
jbe not_overflowed
; putting overflowed_with_Pop: here saves 2 long jumps in inner loops
overflowed_with_Pop:
fstp Population ; save Population and clear stack
jmp color_zero ;
not_overflowed: ; Population
fld st ; Population Population
; slightly faster _not_ to fld Rate here
fmul Rate ; Rate*Population Population
fadd st,st ; 2.0*Rate*Population Population
fsubr Rate ; Rate-2.0*Rate*Population Population
fabs ; fabs(Rate-2.0*Rate*Population) Population
fmul total ; total*fabs(Rate-2.0*Rate*Population) Population
ftst ; compare to 0
fstp total ; save the new total
fstsw status_word ; Population
fwait
mov ax,status_word
sahf
jz overflowed_with_Pop ; if total==0, then treat as overflow
add di,2 ; di += sizeof(*lyaRxy)
loop halfmax_count_top ; if --cx > 0 then loop
fld total ; total Population
too_big_top:
fcom e_10 ; total Population
fstsw status_word
fwait
mov ax,status_word
sahf
jna too_big_bottom
fmul e_neg10 ; total*e_neg10 Population
add lnadjust,10
jmp SHORT too_big_top
too_big_bottom:
too_small_top: ; total Population
fcom e_neg10 ; total Population
fstsw status_word
fwait
mov ax,status_word
sahf
jnb too_small_bottom
fmul e_10 ; total*e_10 Population
sub lnadjust,10
jmp SHORT too_small_top
too_small_bottom:
fstp total ; save as total
inc si
jmp halfmax_top ; let's do it again
halfmax_bottom:
; better make another check, just to be sure
; NewPopulation
cmp dx,overflowcheck ; was overflow just checked?
jl last_overflowcheck ; if not, better check one last time
fstp Population ; save Population and clear stack
jmp short jumpout ; skip overflowcheck
last_overflowcheck:
fst Population ; save new Population
fabs ; |NewPopulation|
fcomp BigNum ; Compare to 100000.0
fstsw status_word ;
fwait
mov ax,status_word
sahf
ja color_zero ; overflowed
jumpout:
; if (overflow || total <= 0 || (temp = log(total) + lnadjust) > 0)
; color = 0;
; else {
; if (LogFlag)
; lyap = -temp/((double) lyaLength*i);
; else
; lyap = 1 - exp(temp/((double) lyaLength*i));
; color = 1 + (int)(lyap * (colors-1));
; }
; return color;
;}
; no use testing for the overflow variable as you
; cannot get here and have overflow be true
fld total ; total
ftst ; is total <= 0 ?
fstsw status_word
fwait
mov ax,status_word
sahf
ja total_not_neg ; if not, continue
fstp st ; pop total from stack
jmp SHORT color_zero ; if so, set color to 0
total_not_neg: ; total is still on stack
fldln2 ; ln(2) total
fxch ; total ln(2)
fyl2x ; ln(total)=ln(2)*log_2(total)
fiadd lnadjust ; ln(total)+lnadjust
ftst ; compare against 0
fstsw status_word
fwait
mov ax,status_word
sahf
jbe not_positive
fstp st ; pop temp from stack
color_zero:
xor ax,ax ; return color 0
jmp thats_all
not_positive: ; temp is still on stack
fild lyaLength ; lyaLength temp
fimul halfmax ; lyaLength*halfmax temp
fdiv ; temp/(lyaLength*halfmax)
cmp LogFlag,0 ; is LogFlag set?
jz LogFlag_not_set ; if !LogFlag goto LogFlag_not_set:
fchs ; -temp/(lyaLength*halfmax)
jmp calc_color
LogFlag_not_set: ; temp/(lyaLength*halfmax)
OneMinusExpMacro ; 1-exp(temp/(lyaLength*halfmax))
calc_color:
; what is now left on the stack is what the C code calls lyap
; lyap
mov ax,colors ; colors
dec ax ; colors-1
mov i,ax ; temporary storage
fimul i ; lyap*(colors-1)
; the "half" makes ASM round like C does
fsub half ; sub 0.5 for rounding purposes
fistp i ; temporary = (int)(lyap*(colors-1))
fwait ; one moment please...
mov ax,i ; ax = temporary
inc ax ; ax = 1 + (int)(lyap * (colors-1));
thats_all:
mov color, ax
ret
lyapunov_cycles endp
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -