LANG OCTASM,0.1
\octasm.sym
show_regs{
define REP()  # #1 loop <1
pushfd pushad eax=[handler] ecx=36 edi=esp read()
ecx=14+80 edi=fpu_save read() fninit jecxz >1
frstor [edi]
# popad popfd user_code()
pushfd pushad es=ss ds=ss cld
	eax=[handler] xor ecx,ecx xor edx,edx lseek()
	ecx=36 edi=esp write()
	ecx=14+80 edi=fpu_save
	fnsave [edi] write()
popad
define P1()  prn(d"%nb #1") call prn\n
define PRN1()  eax=#1 P1(%10 #1:) eax=#2 P1( #2:) push ax eax=#3 P1( #3:) pop ax eax=#4 P1( #4:)
define PRN2()  PRN1(e#1x, #1x, #1h, #1l)
PRN2(a,c,d,b)
PRN1(esp,ebp,esi,edi)
pop eax
define PRNF()  test eax,#1 jz >1 prn(d"%nb #2 ") #
PRNF(-1,%10 flags: ,1,C,4H,P,10H,AC,40H,Z,80H,S,100H,T,200H,I,400H,D,800H,O,4000H,NT,10000H,RT,20000H,V86)
  esi=fpu_regs edi="%nb %10 st0:" ecx=8
REP((fninit prn(edi) inc b[edi+4] fld t[esi] add esi,10 escribenumf()))
ret

#escribenumf pushad eax='    ' ecx=7
	REP(push eax) cl=31 push ecx
	edi=esp+1 fixtoa() prn(esp)
	add sp,32 popad ret

#fixtoa pushad sub sp,30 esi=sp
	push si,30 edi=di
	ftoa() lodsw and ah,2 jz >1;signo
	b[di]='-' inc di
      # dh=al lodsw test ax jz >2 js >1             ;ajuste del exponente
	cx=21 sub cl,dh cmp ax,cx jc >2
      # cmp ax,-18 jc >2
      # dl=al subfixtoa() add sp,30 popad ret
      # dl=1 sub dl,dh ch=dl sar cx,8 sub ax,cx
	push ax subfixtoa() pop ax
	movsx eax,ax xor cx,cx b[edi]='E' inc di es=ds ltoa()
	add sp,30 popad ret

#subfixtoa ;si,si,dl exp,dh ncifras  52bytes
	xor ecx,ecx ax='0.' neg dl jz >2 jns >1
	cl=dh rep movsb sub cl,dl rep stosb ret
      # cl=dl sub cl,dh jc >2
	stosw rep stosb
      # cl=dh jmp movedata
      # neg cl movedata() [di]=ah inc di cl=dl jmp movedata


define PROCPL(locals,params) pusha enter ->1,0 virtual org >1->2 # locals # rb 20 params #RETURNS code
define RETURN leave popa retp RETURNS-20


#ftoa { ; (bufer,bufersize) stack
	; retorna en bufer: b ncifras(18 max),b tiponum,w exp,cadena sin signo
	; tiponum=byte alto de fstsw
	;
	PROCPL(rb 22,(enum 2,bufer,bufersize))
	edi=sp push l1
	fxam   ;tipo de numero?
	fstsw w[di] ax=[di] and ah,1+4+64
	cmp ah,4  ;normal
	w[di+2]=0 ;exp
	je >2
	cmp ah,64 ;cero
	je >1
	;error
	esi="error" cx=5 [di]=cl ;ncifras
	add di,4 jmp movedata
      # b[di+4]='0' b[di]=1 ret
      # pop ax ax=15  ;15-16 cifras
	add di,4 fconvert() si=di+8 fbstp t[si] ecx=8 ;solo las cifras
	unpackbits4b() add cx,cx
	;saltarse los ceros
	si=di
	REP((cmp ch,[si] jnz >1 inc si inc ax)) ;exp
      # reverseb()
	;buscar la primera cifra distinta de cero
	REP((cmp ch,[si] jnz >1 inc si))
      # [di-4]=cl ;ncifras
	[di-2]=ax ;exp
	REP((al=[si] inc si add al,'0' [di]=al inc di))
    #l1 di=[bp+bufer]
	si=sp
	cx=[bp+bufersize]
	ch=[si] add ch,4 cmp cl,ch jc >1
	cl=ch
      # ecx=cl rep movsb RETURN
      }

#fconvert  ;ax=ncifras-1(0-17))cr retorna ax=exp
	       ;solo funciona con numeros normales distintos de cero
	;+1n+2n
	fxtract fxch st0,st1
	fldlg2 fmulp st1   ;cambio a exponente decimal
	fist w[di] sub [di],ax ax=[di]   ;ax=exp  ;ajuste de exponente
	fisub w[di]   ;cambio a exponente binario
#fconvert2  ;st0=exp decimal st1=mantisa resultado en st0
	fldl2t fmulp st1 f2ex() fmulp st1 ret

#unpackbits4b ;si,di,cx ncr
	pusha es=ds
	REP((lodsb ah=al shr ah,4 and al,15 stosw))
	popa ret

#reverseb ;si,cx ncr
	pusha di=si add di,cx dx=2 sub di,dx cmp cx,dx jc >2
      # ax=[si] xchg al,ah xchg ax,[di] sub di,dx xchg al,ah
	[si]=ax add si,dx cmp di,si jnc <1
      # popa ret

data
#handler dd \regs.dat
#fpu_save  rb 14
#fpu_regs rb 80
rb 12000
code
#user_code
}

