LANG OCTASM,0.1 use32
\OCTASM.SYM
show_regs{
define REP()  # #1 loop <1
pushfd pusha eax=[handler] ecx=36 edi=esp read()
ecx=28+80 edi=fpu_save read() fninit jecxz >1
frstor [edi]
# popa popfd user_code()
pushfd pusha cld
	eax=[handler] ecx=0 edx=0 lseek()
	ecx=36 edi=esp write()
	ecx=28+80 edi=fpu_save
	fnsave [edi] write()
popa
define P1()  prn(d"%nb #1") call prn\n
define PRN1()  eax=#1 P1(%10 #1:) eax=#2 P1( #2:) push eax eax=#3 P1( #3:) pop eax 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 pusha eax='    ' ecx=7
	REP(push eax) cl=31 push ecx
	edi=esp+1 fixtoa() prn(esp)
	add esp,32 popa ret

#fixtoa pusha sub esp,30 esi=esp
	ftoa(esi,30) lodsw and ah,2 jz >1;signo
	b[edi]='-' inc edi
      # 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 esp,30 popa ret
      # dl=1 sub dl,dh ch=dl sar cx,8 sub ax,cx
	push eax subfixtoa() pop eax
	movsx eax,ax xor ecx,ecx b[edi]='E' inc edi ltoa()
	add esp,30 popad ret

#subfixtoa ;esi,edi,dl exp,dh ncifras
	ecx=0 ax='0.' neg dl jz >2 jns >1
	cl=dh
	memmove() sub cl,dl jmp memset
      # cl=dl sub cl,dh jc >2
	stosw memset()
      # cl=dh  jmp memmove
      # neg cl memmove() [edi]=ah inc edi cl=dl jmp memmove

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

ws=4
#ftoa ; (bufer,bufersize) stack
      ; retorna en bufer: b ncifras(18 max),b tiponum,w exp,cadena sin signo
      ; ncifras puede ser mayor que el tamao del bufer,
      ; indicando que el numero puede tener mas digitos
      ; tiponum=byte alto de fstsw
      pusha enter 22,0 edi=esp push >8
      fxam   ;tipo de numero?
      fstsw w[edi] ax=[edi] and ah,1+4+64
      cmp ah,4  ;normal
      w[edi+2]=0 ;exp
      je >2
      cmp ah,64 ;cero
      je >1
      ;error
      esi="error" ecx=5 [edi]=cl ;ncifras
      add edi,4 jmp memmove
    # b[edi+4]='0' b[edi]=1 ret
    # add esp,ws ax=15  ;15-16 cifras
      add edi,4 fconvert() esi=edi+8 fbstp t[esi] ecx=8 ;solo las cifras
      unpackbits4b() add ecx,ecx
	;saltarse los ceros
      esi=edi
    # cmp ch,[esi] jnz >1
      inc esi inc ax ;exp
      loop <1
    # reverseb()
    # ;buscar la primera cifra distinta de cero
      cmp ch,[esi] jnz >1
      inc esi loop <1
    # [edi-4]=cl ;ncifras
      [edi-2]=ax ;exp
    # lodsb add al,'0' stosb loop <1
    # edi=[esp+arg1+22+ws] ;bufer
      ecx=[esp+arg1+26+ws] ;bufersize
      eax=b[esp] add eax,4 cmp ecx,eax jc >1
      ecx=eax
    # esi=esp movedata() leave popa retp 8

#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 ;esi,edi,ecx ncr
	pusha
      # lodsb ah=al shr ah,4 and al,15 stosw loop <1
	popa ret

#reverseb ;esi,ecx ncr
	pusha edi=esi+ecx edx=2 sub edi,edx cmp ecx,edx jc >2
      # ax=[esi] xchg al,ah xchg ax,[edi] sub edi,edx xchg al,ah
	[esi]=ax add esi,edx cmp edi,esi jnc <1
      # popa ret

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

