.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8 .define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8 .define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8 .define .cmf4, .cmf8 .sect .text; .sect .rom; .sect .data; .sect .bss ! $Id$ ! Implement interface to floating point package for Intel 8087 .sect .rom one: .data2 1 two: .data2 2 bigmin: .data4 -2147483648 .sect .text .adf4: mov bx,sp flds 4(bx) fadds 8(bx) fstps 8(bx) wait ret .adf8: mov bx,sp fldd 4(bx) faddd 12(bx) fstpd 12(bx) wait ret .sbf4: mov bx,sp flds 8(bx) fsubs 4(bx) fstps 8(bx) wait ret .sbf8: mov bx,sp fldd 12(bx) fsubd 4(bx) fstpd 12(bx) wait ret .mlf4: mov bx,sp flds 4(bx) fmuls 8(bx) fstps 8(bx) wait ret .mlf8: mov bx,sp fldd 4(bx) fmuld 12(bx) fstpd 12(bx) wait ret .dvf4: mov bx,sp flds 8(bx) fdivs 4(bx) fstps 8(bx) wait ret .dvf8: mov bx,sp fldd 12(bx) fdivd 4(bx) fstpd 12(bx) wait ret .ngf4: mov bx,sp flds 4(bx) fchs fstps 4(bx) wait ret .ngf8: mov bx,sp fldd 4(bx) fchs fstpd 4(bx) wait ret .fif4: mov bx,sp flds 8(bx) fmuls 12(bx) ! multiply fld st ! copy result ftst ! test sign; handle negative separately fstsw ax wait sahf ! result of test in condition codes jb 1f frndint ! this one rounds (?) fcom st(1) ! compare with original; if <=, then OK fstsw ax wait sahf jbe 2f fisubs (one) ! else subtract 1 jmp 2f 1: ! here, negative case frndint ! this one rounds (?) fcom st(1) ! compare with original; if >=, then OK fstsw ax wait sahf jae 2f fiadds (one) ! else add 1 2: fsub st(1),st ! subtract integer part mov bx,4(bx) fstps (bx) fstps 4(bx) wait ret .fif8: mov bx,sp fldd 8(bx) fmuld 16(bx) ! multiply fld st ! and copy result ftst ! test sign; handle negative separately fstsw ax wait sahf ! result of test in condition codes jb 1f frndint ! this one rounds (?) fcom st(1) ! compare with original; if <=, then OK fstsw ax wait sahf jbe 2f fisubs (one) ! else subtract 1 jmp 2f 1: ! here, negative case frndint ! this one rounds (?) fcom st(1) ! compare with original; if >=, then OK fstsw ax wait sahf jae 2f fiadds (one) ! else add 1 2: fsub st(1),st ! subtract integer part mov bx,4(bx) fstpd (bx) fstpd 8(bx) wait ret .fef4: ! this could be simpler, if only the ! fxtract instruction was emulated properly mov bx,sp mov ax,8(bx) and ax,0x7f800000 je 1f ! zero exponent shr ax,23 sub ax,126 mov cx,ax ! exponent in cx mov ax,8(bx) and ax,0x807fffff or ax,0x3f000000 ! load -1 exponent mov bx,4(bx) mov 4(bx),ax mov (bx),cx ret 1: ! we get here on zero exp mov ax,8(bx) and ax,0x007fffff jne 1f ! zero result mov bx,4(bx) mov (bx),ax mov 4(bx),ax ret 1: ! otherwise unnormalized number mov cx,8(bx) and cx,0x807fffff mov dx,cx and cx,0x80000000 mov ax,-125 2: test dx,0x800000 jne 1f dec ax shl dx,1 or dx,cx jmp 2b 1: mov bx,4(bx) mov (bx),ax and dx,0x807fffff or dx,0x3f000000 ! load -1 exponent mov 4(bx),dx ret .fef8: ! this could be simpler, if only the ! fxtract instruction was emulated properly mov bx,sp mov ax,12(bx) and ax,0x7ff00000 je 1f ! zero exponent shr ax,20 sub ax,1022 mov cx,ax ! exponent in cx mov ax,12(bx) and ax,0x800fffff or ax,0x3fe00000 ! load -1 exponent mov dx,8(bx) mov bx,4(bx) mov 4(bx),dx mov 8(bx),ax mov (bx),cx ret 1: ! we get here on zero exp mov ax,12(bx) and ax,0xfffff or ax,8(bx) jne 1f ! zero result mov bx,4(bx) mov (bx),ax mov 4(bx),ax mov 8(bx),ax ret 1: ! otherwise unnormalized number mov cx,12(bx) and cx,0x800fffff mov dx,cx and cx,0x80000000 mov ax,-1021 2: test dx,0x100000 jne 1f dec ax shl 8(bx),1 rcl dx,1 or dx,cx jmp 2b 1: and dx,0x800fffff or dx,0x3fe00000 ! load -1 exponent mov cx,8(bx) mov bx,4(bx) mov (bx),ax mov 8(bx),dx mov 4(bx),cx ret .cif4: mov bx,sp fildl 8(bx) fstps 8(bx) wait ret .cif8: mov bx,sp fildl 8(bx) fstpd 4(bx) wait ret .cuf4: mov bx,sp fildl 8(bx) cmp 8(bx),0 jge 1f fisubl (bigmin) fisubl (bigmin) 1: fstps 8(bx) wait ret .cuf8: mov bx,sp fildl 8(bx) cmp 8(bx),0 jge 1f fisubl (bigmin) fisubl (bigmin) 1: fstpd 4(bx) wait ret .cfi: mov bx,sp fstcw 4(bx) wait mov dx,4(bx) or 4(bx),0xc00 ! truncating mode wait fldcw 4(bx) cmp 8(bx),4 jne 2f ! loc 4 loc ? cfi flds 12(bx) fistpl 12(bx) 1: mov 4(bx),dx wait fldcw 4(bx) ret 2: ! loc 8 loc ? cfi fldd 12(bx) fistpl 16(bx) jmp 1b .cfu: mov bx,sp fstcw 4(bx) wait mov dx,4(bx) and 4(bx),0xf3ff or 4(bx),0x400 ! to -infinity wait fldcw 4(bx) cmp 8(bx),4 jne 2f ! loc 4 loc ? cfu flds 12(bx) fabs ! ??? fiaddl (bigmin) fistpl 12(bx) wait mov ax,12(bx) sub ax,(bigmin) mov 12(bx),ax 1: mov 4(bx),dx wait fldcw 4(bx) ret 2: ! loc 8 loc ? cfu fldd 12(bx) fabs ! ??? fiaddl (bigmin) fistpl 16(bx) wait mov ax,16(bx) sub ax,(bigmin) mov 16(bx),ax jmp 1b .cff4: mov bx,sp fldd 4(bx) fstcw 4(bx) wait mov dx,4(bx) and 4(bx),0xf3ff ! set to rounding mode wait fldcw 4(bx) fstps 8(bx) mov 4(bx),dx wait fldcw 4(bx) wait ret .cff8: mov bx,sp flds 4(bx) fstpd 4(bx) wait ret .cmf4: mov bx,sp xor cx,cx flds 8(bx) flds 4(bx) fcompp ! compare and pop operands fstsw ax wait sahf je 1f jb 2f dec cx jmp 1f 2: inc cx 1: mov ax,cx ret .cmf8: mov bx,sp xor cx,cx fldd 12(bx) fldd 4(bx) fcompp ! compare and pop operands fstsw ax wait sahf je 1f jb 2f dec cx jmp 1f 2: inc cx 1: mov ax,cx ret