;
; ä㭪樨 ¤«ï à ¡®âë á ç¨á« ¬¨ float
;

; Š®«¨ç¥á⢮ §­ ª®¢ ç¨á«  ¯®á«¥ § ¯ï⮩ (1-17)
NumberSymbolsAD DW 5
; Š®­áâ ­âë (10 ¢ á⥯¥­¨ N)
MConst: DQ 1.0E1,1.0E2,1.0E3,1.0E4,1.0E5
       DQ 1.0E6,1.0E7,1.0E8,1.0E9,1.0E10
       DQ 1.0E11,1.0E12,1.0E13,1.0E14,1.0E15
       DQ 1.0E16,1.0E17,1.0E18,1.0E19,1.0E20
       DQ 1.0E21,1.0E22,1.0E23,1.0E24,1.0E25
       DQ 1.0E26,1.0E27,1.0E28,1.0E29,1.0E30
       DQ 1.0E31,1.0E32,1.0E33,1.0E34,1.0E35
       DQ 1.0E36,1.0E37,1.0E38,1.0E39,1.0E40
       DQ 1.0E41,1.0E42,1.0E43,1.0E44,1.0E45
       DQ 1.0E46,1.0E47,1.0E48,1.0E49,1.0E50
       DQ 1.0E51,1.0E52,1.0E53,1.0E54,1.0E55
       DQ 1.0E56,1.0E57,1.0E58,1.0E59,1.0E60
       DQ 1.0E61,1.0E62,1.0E63,1.0E64,1.0E65
       DQ 1.0E66,1.0E67,1.0E68,1.0E69,1.0E70
       DQ 1.0E71,1.0E72,1.0E73,1.0E74,1.0E75
       DQ 1.0E76,1.0E77,1.0E78,1.0E79,1.0E80
       DQ 1.0E81,1.0E82,1.0E83,1.0E84,1.0E85
       DQ 1.0E86,1.0E87,1.0E88,1.0E89,1.0E90
       DQ 1.0E91,1.0E92,1.0E93,1.0E94,1.0E95
       DQ 1.0E96,1.0E97,1.0E98,1.0E99,1.0E100
       DQ 1.0E101,1.0E102,1.0E103,1.0E104,1.0E105
       DQ 1.0E106,1.0E107,1.0E108,1.0E109,1.0E110
       DQ 1.0E111,1.0E112,1.0E113,1.0E114,1.0E115
       DQ 1.0E116,1.0E117,1.0E118,1.0E119,1.0E120
       DQ 1.0E121,1.0E122,1.0E123,1.0E124,1.0E125
       DQ 1.0E126,1.0E127,1.0E128
.end:
; —¨á«® á ¯« ¢ î饩 § ¯ï⮩ ¤¢®©­®© â®ç­®áâ¨
Data_Double   DQ ?
; —¨á«® ¢ BCD-ä®à¬ â¥ 
Data_BCD      DT ?
; ‚ᯮ¬®£ â¥«ì­ë© ä« £
Data_Flag     DB ?
; ‡­ ª १ã«ìâ â  (¥á«¨ ­¥ 0 - ®âà¨æ â¥«ì­®¥ ç¨á«®)
Data_Sign     DB ?
; ‡­ ª १ã«ìâ â  - 0 ¤«ï ..e+.. ¨ 1 ¤«ï ..e-..
Data_Sign_Exp DB ?

align 4
; ‘âப  ¤«ï åà ­¥­¨ï ç¨á«  ¢ ª®¤¥ ASCII
Data_String   DB 32 DUP (?)



;*******************************************************
;*  …Ž€‡Ž‚€ˆ… —ˆ‘‹€ ‘ ‹€‚€ž™…‰ ‡€Ÿ’Ž‰ ‚ ‘’ŽŠ“  *
;* —¨á«® ¨¬¥¥â ä®à¬ â á 㤢®¥­­®© â®ç­®áâìî, १ã«ìâ â *
;* ¢ë¤ ¥âáï ¢ ¤¥áïâ¨ç­®¬ ª®¤¥, ¢ "¡ë⮢®¬" ä®à¬ â¥ á   *
;* 䨪á¨à®¢ ­­ë¬ ª®«¨ç¥á⢮¬ §­ ª®¢ ¯®á«¥ § ¯ï⮩.     *
;* ‚室­ë¥ ¯ à ¬¥âàë:                                  *
;* Data_Double - ¯à¥®¡à §ã¥¬®¥ ç¨á«®;                  *
;* NumberSymbolsAD - ª®«¨ç¥á⢮ §­ ª®¢ ¯®á«¥           *
;*                   § ¯ï⮩ (0-17).                   *
;* ‚ë室­ë¥ ¯ à ¬¥âàë:                                 *
;* Data_String - áâப -१ã«ìâ â.                     *
;*******************************************************
align 4
DoubleFloat_to_String:
	pushad
	; ¥§ã«ìâ â § ¯¨á뢠âì ¢ áâபã Data_String
	mov	EDI, Data_String

	; ‘¤¢¨£ ¥¬ ç¨á«® ¢«¥¢® ­  NumberSymbolsAD
	; ¤¥áïâ¨ç­ëå à §à冷¢
	fninit		       ;á¡à®á ᮯà®æ¥áá®à 
	fld	[Data_Double]  ;§ £à㧨âì ç¨á«®
	xor ebx,ebx
	mov	BX,[NumberSymbolsAD]
	cmp	BX, 0
	je	.NoShifts     ;­¥â æ¨äà ¯®á«¥ § ¯ï⮩
	jl	.Error	      ;®è¨¡ª 
	dec	BX
	lea ebx,[MConst+8*ebx]
	fmul	qword [EBX] ;㬭®¦¨âì ­  ª®­áâ ­âã
.NoShifts:
	; ˆ§¢«¥çì ç¨á«® ¢ ª®¤¥ BCD
	fbstp	[Data_BCD]
; à®¢¥à¨âì १ã«ìâ â ­  ¯¥à¥¯®«­¥­¨¥
	mov	AX,word [Data_BCD + 8]
	cmp	AX,0FFFFh  ;"¤¥áïâ¨ç­®¥" ¯¥à¥¯®«­¥­¨¥?
	je	.Overflow
; ‚뤥«¨âì §­ ª ç¨á«  ¨ § ¯¨á âì ¥£® ¢ ASCII-ª®¤¥
	mov	AL, byte [Data_BCD + 9]
	and	AL,AL
	jz	.NoSign
	mov	AL,'-'
	stosb
.NoSign:
;  á¯ ª®¢ âì ç¨á«® ¢ ª®¤ ASCII
	mov	ebx,8	 ;ᬥ饭¨¥ ¯®á«¥¤­¥© ¯ àë æ¨äà
	mov	ecx,9	 ;áç¥â稪 ¯ à æ¨äà
	; Ž¯à¥¤¥«¨âì ¯®§¨æ¨î ¤¥áïâ¨ç­®© â®çª¨ ¢ ç¨á«¥
	mov	DX,18
	sub	DX,[NumberSymbolsAD]
	js	.Error	;®è¨¡ª , ¥á«¨ ®âà¨æ â¥«ì­ ï
	jz	.Error	;¨«¨ ­ã«¥¢ ï ¯®§¨æ¨ï
.NextPair:
	; ‡ £à㧨âì ®ç¥à¥¤­ãî ¯ àã à §à冷¢
	mov	AL, byte [ebx + Data_BCD]
	mov	AH,AL
	; ‚뤥«¨âì, ¯¥à¥¢¥á⨠¢ ASCII ¨
	; á®åà ­¨âì áâ àèãî â¥âà ¤ã
	shr	AL,4
	add	AL,'0'
	stosb
	dec	DX
	jnz	.N0
	mov	AL,'.'
	stosb
.N0:   ; ‚뤥«¨âì, ¯¥à¥¢¥á⨠¢ ASCII ¨
	; á®åà ­¨âì ¬« ¤èãî â¥âà ¤ã
	mov	AL,AH
	and	AL,0Fh
	add	AL,'0'
	stosb
	dec	DX
	jnz	.N1
	mov	AL,'.'
	stosb
.N1:
	dec  BX
	loop .NextPair
	mov  AL,0
	stosb

; “¡à âì ­¥§­ ç é¨¥ ­ã«¨ á«¥¢ 
	mov	EDI, Data_String
	mov	ESI, Data_String
	; à®¯ãáâ¨âì §­ ª ç¨á« , ¥á«¨ ®­ ¥áâì
	cmp	byte [ESI],'-'
	jne	.N2
	inc	ESI
	inc	EDI
.N2:   ; ‡ £à㧨âì ¢ áç¥â稪 横«  ª®«¨ç¥á⢮ à §à冷¢
	; ç¨á«  ¯«îá 1 (¡ ©â ¤¥áïâ¨ç­®© â®çª¨)
	mov	ecx,18+1+1
	; à®¯ãáâ¨âì ­¥§­ ç é¨¥ ­ã«¨
.N3:
	cmp byte [ESI],'0'
	jne .N4
	cmp byte [ESI+1],'.'
	je .N4
	inc ESI
	loop .N3
	; Žè¨¡ª  - ­¥â §­ ç é¨å æ¨äà
	jmp	.Error
; ‘ª®¯¨à®¢ âì §­ ç éãî ç áâì ç¨á«  ¢ ­ ç «® áâப¨
align 4
.N4:	rep movsb
	jmp    .End
; Žè¨¡ª 
align 4
.Error:
	mov	AL,'E'
	stosb
	mov	AL,'R'
	stosb
	mov	AL,'R'
	stosb
	xor	AL,AL
	stosb
	jmp	.End
; ¥à¥¯®«­¥­¨¥ à §à來®© á¥âª¨
align 4
.Overflow:
	mov	AL,'#'
	stosb
	xor	AL,AL
	stosb
; Š®­¥æ ¯à®æ¥¤ãàë
align 4
.End:
	popad
	ret

;****************************************************
;* …Ž€‡Ž‚€’œ ‘’ŽŠ“ ‚ —ˆ‘‹Ž ‘ ‹€‚€ž™…‰ ‡€Ÿ’Ž‰ *
;*      (ç¨á«® ¨¬¥¥â ®¡ëç­ë©, "¡ë⮢®©" ä®à¬ â)     *
;* ‚室­ë¥ ¯ à ¬¥âàë:                               *
;* Data_String - ç¨á«® ¢ ª®¤¥ ASCII.                *
;* ‚ë室­ë¥ ¯ à ¬¥âàë:                              *
;* Data_Double - ç¨á«® ¢ ¤¢®¨ç­®¬ ª®¤¥.             *
;****************************************************
align 4
String_to_DoubleFloat:
	pushad
	cld
	; Žç¨é ¥¬ Data_BCD 
	mov dword [Data_BCD],0
	mov dword [Data_BCD+4],0
	mov  word [Data_BCD+8],0
	; Žç¨é ¥¬ ¡ ©â §­ ª 
	mov	[Data_Sign],0
	; ‡ ­®á¨¬ ¢ esi 㪠§ â¥«ì ­  áâபã
	mov	esi, Data_String
	; à®¯ã᪠¥¬ ¯à®¡¥«ë ¯¥à¥¤ ç¨á«®¬
	mov	ecx,64 ;§ é¨â  ®â § æ¨ª«¨¢ ­¨ï
.ShiftIgnore:
	lodsb
	cmp	al,' '
	jne .ShiftIgnoreEnd
	loop .ShiftIgnore
	jmp .Error
align 4
.ShiftIgnoreEnd:
	; à®¢¥à塞 §­ ª ç¨á« 
	cmp	al,'-'
	jne	.Positive
	mov	[Data_Sign],80h
	lodsb
.Positive:
	mov	[Data_Flag],0 ;¯à¨§­ ª ­ «¨ç¨ï â®çª¨
	xor	edx,edx	      ;¯®§¨æ¨ï â®çª¨
	mov	ecx,18	      ;¬ ªá. ç¨á«® à §à冷¢
align 4
.ASCIItoBCDConversion:
	cmp	al,'.'	      ;â®çª ?
	jne	.NotDot
	cmp	[Data_Flag],0 ;â®çª  ­¥ ¢áâà¥ç « áì?
	jne	.Error        ;¥á«¨ â®çª  㦥 ¡ë« 
	mov	[Data_Flag],1
	lodsb
	or al,al	      ;ª®­¥æ áâப¨?
	jnz	.NotDot
	jmp	.ASCIItoBCDConversionEnd
align 4
.NotDot:
	; “¢¥«¨ç¨âì ­  1 §­ ç¥­¨¥ ¯®§¨æ¨¨ â®çª¨,
	; ¥á«¨ ®­  ¥é¥ ­¥ ¢áâà¥ç « áì
	cmp	[Data_Flag],0
	jnz	.Figures
	inc	edx
.Figures:
	cmp al,'e'
	je .exp_form
	cmp al,'E'
	jne @f
	.exp_form:
		call string_ExpForm ;¥á«¨ ç¨á«® ¢ ä®à¬ â¥ ..e..
		or al,al
		jnz .Error
		jmp	.ASCIItoBCDConversionEnd
	@@:
	; ‘¨¬¢®«ë ç¨á«  ¤®«¦­ë ¡ëâì æ¨äà ¬¨
	cmp	al,'0'
	jb	.Error
	cmp	al,'9'
	ja	.Error
	; ¨è¥¬ ®ç¥à¥¤­ãî æ¨äàã ¢ ¬« ¤èãî â¥âà ¤ã BCD
	and	al,15 ;ᨬ¢®«ë 0-9 ¯¥à¥¢®¤¨¬ ¢ ç¨á«®
	or	byte [Data_BCD],al
	; à®¢¥àª  ­  ª®­¥æ áâப¨
	cmp	byte [esi],0
	je	.ASCIItoBCDConversionEnd
	; ‘¤¢¨£ ¥¬ BCD ­  4 à §à鸞 ¢«¥¢®
	; (ᤢ¨£ ¥¬ áâ à訥 2 ¡ ©â )
	mov	ax,word [Data_BCD+6]
	shld	word [Data_BCD+8],ax,4
	; (ᤢ¨£ ¥¬ á।­¨¥ 4 ¡ ©â )
	mov	eax,dword [Data_BCD]
	shld	dword [Data_BCD+4],eax,4
	; (ᤢ¨£ ¥¬ ¬« ¤è¨¥ 4 ¡ ©â )
	shl	dword [Data_BCD],4
	; ‡ £à㦠¥¬ á«¥¤ãî騩 ᨬ¢®« ¢ AL
	lodsb
	loop .ASCIItoBCDConversion ;¥á«¨ ­¥ ª®¬¯¨«. â® ¯®áâ ¢¨âì dec ecx, jnz ...
	; …᫨ 19-© ᨬ¢®« ­¥ 0 ¨ ­¥ â®çª ,
	; â® ®è¨¡ª  ¯¥à¥¯®«­¥­¨ï
	cmp	al,'.'
	jne	.NotDot2
	inc	ecx ;¯à®¯ã᪠â®çª¨ ¢ ª®­æ¥ ®ç¥­ì ¡®«ì讣® ç¨á« 
	lodsb
.NotDot2:
	or al,al	;¯¥à¥¯®«­¥­¨¥ à §à來®© á¥âª¨?
	jz	.ASCIItoBCDConversionEnd
align 4
.Error: ; à¨ «î¡®© ®è¨¡ª¥ ®¡­ã«¨âì १ã«ìâ â
	fldz	;§ ­¥á⨠­®«ì á á⥪ ᮯà®æ¥áá®à 
	fstp	[Data_Double]
	jmp	.End

; …Ž€‡Ž‚€’œ —ˆ‘‹Ž ˆ‡ ŠŽ„€ BCD ‚ ‚…™…‘’‚…Ž… —ˆ‘‹Ž
.ASCIItoBCDConversionEnd:
	; ‚¯¨á âì §­ ª ¢ áâ à訩 ¡ ©â
	mov	al,[Data_Sign]
	mov	byte [Data_BCD+9],al
	; ‘¡à®á¨âì ॣ¨áâàë ᮯà®æ¥áá®à 
	fninit
	; ‡ £à㧨âì ¢ ᮯà®æ¥áá®à ç¨á«® ¢ BCD-ä®à¬ â¥
	fbld	[Data_BCD]
	; ‚ëç¨á«¨âì ­®¬¥à ¤¥«¨â¥«ï ¨«¨ ¬­®¦¨â¥«ï
	lea ebx,[ecx+edx-18]
	cmp ebx,0
	jle .NoMul ;¥á«¨ ç¨á«® e-..
	dec ebx
	jz .NoDiv ;¥á«¨ ç¨á«® e+0
	dec ebx
	lea ebx,[MConst+8*ebx]
	cmp ebx,MConst.end
	jl @f
		ffree st0
		fincstp
		jmp .Error ;¥á«¨ ®ç¥­ì ¡®«ì讥 ç¨á«® e+**
	@@:
	fmul qword [ebx] ;㬭®¦¨âì ­  ª®­áâ ­âã (¤«ï ç¨á¥« á ¯à¨áâ ¢ª®© e+..)
	jmp .NoDiv
.NoMul:
	neg ebx
	lea ebx,[MConst+8*ebx]
	cmp ebx,MConst.end
	jl @f
		ffree st0
		fincstp
		jmp .Error ;¥á«¨ ®ç¥­ì ¬ «¥­ìª®¥ ç¨á«® e-**
	@@:
	fdiv qword [ebx] ;à §¤¥«¨âì ­  ª®­áâ ­âã
.NoDiv: ;‚ë£à㧨âì ç¨á«® ¢ ¤¢®¨ç­®¬ ä®à¬ â¥
	fstp [Data_Double]
.End:
	popad
	ret

;output:
; eax - 1 if error
; edx += size
align 4
proc string_ExpForm uses ebx
	mov [Data_Sign_Exp],0
	xor eax,eax
	lodsb
	cmp al,'+'
	jne @f
		lodsb
	@@:
	cmp al,'-'
	jne @f
		inc [Data_Sign_Exp]
		lodsb
	@@:
	
	xor ebx,ebx
	.cycle0:
		cmp al,0
		je .cycle0end
		cmp al,9
		je .cycle0end
		cmp al,10
		je .cycle0end
		cmp al,13
		je .cycle0end
		cmp al,' '
		je .cycle0end
		cmp	al,'0'
		jb .Error
		cmp	al,'9'
		ja .Error
	
		imul ebx,10
		and	eax,15 ;ᨬ¢®«ë 0-9 ¯¥à¥¢®¤¨¬ ¢ ç¨á«®
		add ebx,eax
		lodsb
		jmp .cycle0
	.cycle0end:
	
	cmp ebx,328 ;308 - ¬ ªá. à §¬¥à á⥯¥­¨ ¤«ï double + 20 - ç¨á«® à §à冷¢ ¢ BCD
	ja .Error
	cmp [Data_Sign_Exp],0
	je @f
		neg ebx
	@@:
	cmp	[Data_Flag],0 ;â®çª  ­¥ ¢áâà¥ç « áì?
	jne @f
		dec edx
	@@:
	add edx,ebx

	xor eax,eax
	jmp @f
	.Error:
		xor eax,eax
		inc eax
	@@:
	ret
endp

align 4
proc str_cat uses eax ecx edi esi, str1:dword, str2:dword
	mov esi,dword[str2]
	stdcall str_len,esi
	mov ecx,eax
	inc ecx
	mov edi,dword[str1]
	stdcall str_len,edi
	add edi,eax
	cld
	repne movsb
	ret
endp

;output:
; eax = strlen
align 4
proc str_len, str1:dword
	mov eax,[str1]
	@@:
		cmp byte[eax],0
		je @f
		inc eax
		jmp @b
	@@:
	sub eax,[str1]
	ret
endp

align 4
proc String_crop_0 uses eax ebx ecx edi
	mov edi,Data_String
	mov al,'.'
	mov ecx,32
	repne scasb
	mov ebx,edi
	mov edi,Data_String
	xor al,al
	mov ecx,32
	repne scasb
	cmp ebx,edi
	jg .end_f
	dec edi
	.cycle0:
		dec edi
		cmp edi,Data_String
		jle .end_f
		cmp byte[edi],'0'
		jne .cycle0end
		mov byte[edi],0
		jmp .cycle0
	.cycle0end:
	cmp byte[edi],'.'
	jne .end_f
		mov byte[edi],0
	.end_f:
	ret
endp