;
; ä㭪樨 ¤«ï à ¡®âë á ç¨á« ¬¨ 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
; —¨á«® á ¯« ¢ î饩 § ¯ï⮩ ¤¢®©­®© â®ç­®áâ¨
Data_Double   DQ ?
; —¨á«® ¢ BCD-ä®à¬ â¥ 
Data_BCD      DT ?
; ‚ᯮ¬®£ â¥«ì­ë© ä« £
Data_Flag     DB ?
; ‡­ ª १ã«ìâ â  (¥á«¨ ­¥ 0 - ®âà¨æ â¥«ì­®¥ ç¨á«®)
Data_Sign     DB ?


db 0 ;㪠§ â¥«ì ­  ᤢ¨£ ¢ ¯ ¬ïâ¨
; ‘âப  ¤«ï åà ­¥­¨ï ç¨á«  ¢ ª®¤¥ ASCII
Data_String   DB 32 DUP (?)



;*******************************************************
;*  …Ž€‡Ž‚€ˆ… —ˆ‘‹€ ‘ ‹€‚€ž™…‰ ‡€Ÿ’Ž‰ ‚ ‘’ŽŠ“  *
;* —¨á«® ¨¬¥¥â ä®à¬ â á 㤢®¥­­®© â®ç­®áâìî, १ã«ìâ â *
;* ¢ë¤ ¥âáï ¢ ¤¥áïâ¨ç­®¬ ª®¤¥, ¢ "¡ë⮢®¬" ä®à¬ â¥ á   *
;* 䨪á¨à®¢ ­­ë¬ ª®«¨ç¥á⢮¬ §­ ª®¢ ¯®á«¥ § ¯ï⮩.     *
;* ‚室­ë¥ ¯ à ¬¥âàë:                                  *
;* Data_Double - ¯à¥®¡à §ã¥¬®¥ ç¨á«®;                  *
;* NumberSymbolsAD - ª®«¨ç¥á⢮ §­ ª®¢ ¯®á«¥           *
;*                   § ¯ï⮩ (0-17).                   *
;* ‚ë室­ë¥ ¯ à ¬¥âàë:                                 *
;* Data_String - áâப -१ã«ìâ â.                     *
;*******************************************************
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
	shl	BX, 3		;㬭®¦ ¥¬ ­  8
	add	EBX, MConst
	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
; ‘ª®¯¨à®¢ âì §­ ç éãî ç áâì ç¨á«  ¢ ­ ç «® áâப¨
.N4:	rep movsb
	jmp    .End

; Žè¨¡ª 
.Error:
	mov	AL,'E'
	stosb
	mov	AL,'R'
	stosb
	mov	AL,'R'
	stosb
	xor	AL,AL
	stosb
	jmp	.End
; ¥à¥¯®«­¥­¨¥ à §à來®© á¥âª¨
.Overflow:
	mov	AL,'#'
	stosb
	xor	AL,AL
	stosb
; Š®­¥æ ¯à®æ¥¤ãàë
.End:
	popad
	ret

;****************************************************
;* …Ž€‡Ž‚€’œ ‘’ŽŠ“ ‚ —ˆ‘‹Ž ‘ ‹€‚€ž™…‰ ‡€Ÿ’Ž‰ *
;*      (ç¨á«® ¨¬¥¥â ®¡ëç­ë©, "¡ë⮢®©" ä®à¬ â)     *
;* ‚室­ë¥ ¯ à ¬¥âàë:                               *
;* Data_String - ç¨á«® ¢ ª®¤¥ ASCII.                *
;* ‚ë室­ë¥ ¯ à ¬¥âàë:                              *
;* Data_Double - ç¨á«® ¢ ¤¢®¨ç­®¬ ª®¤¥.             *
;****************************************************
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
	; ‡ ­®á¨¬ ¢ SI 㪠§ â¥«ì ­  áâபã
	mov	ESI, Data_String
	; à®¯ã᪠¥¬ ¯à®¡¥«ë ¯¥à¥¤ ç¨á«®¬
	mov	ecx,64 ;§ é¨â  ®â § æ¨ª«¨¢ ­¨ï
.ShiftIgnore:
	lodsb
	cmp	AL,' '
	jne	.ShiftIgnoreEnd
	loop	.ShiftIgnore
	jmp	.Error
.ShiftIgnoreEnd:
	; à®¢¥à塞 §­ ª ç¨á« 
	cmp	AL,'-'
	jne	.Positive
	mov	[Data_Sign],80h
	lodsb
.Positive:
	mov	[Data_Flag],0 ;¯à¨§­ ª ­ «¨ç¨ï â®çª¨
	mov	DX,0	      ;¯®§¨æ¨ï â®çª¨
	mov	ecx,18	      ;¬ ªá. ç¨á«® à §à冷¢
.ASCIItoBCDConversion:
	cmp	AL,'.'	      ;â®çª ?
	jne	.NotDot
	cmp	[Data_Flag],0 ;â®çª  ­¥ ¢áâà¥ç « áì?
	jne	.Error
	mov	[Data_Flag],1
	lodsb
	cmp	AL,0	      ;ª®­¥æ áâப¨?
	jne	.NotDot
	jmp	.ASCIItoBCDConversionEnd
.NotDot:
	; “¢¥«¨ç¨âì ­  1 §­ ç¥­¨¥ ¯®§¨æ¨¨ â®çª¨,
	; ¥á«¨ ®­  ¥é¥ ­¥ ¢áâà¥ç « áì
	cmp	[Data_Flag],0
	jnz	.Figures
	inc	DX
.Figures:
	; ‘¨¬¢®«ë ç¨á«  ¤®«¦­ë ¡ëâì æ¨äà ¬¨
	cmp	AL,'0'
	jb	.Error
	cmp	AL,'9'
	ja	.Error
	; ¨è¥¬ ®ç¥à¥¤­ãî æ¨äàã ¢ ¬« ¤èãî â¥âà ¤ã BCD
	and	AL,0Fh
	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
	; …᫨ 19-© ᨬ¢®« ­¥ 0 ¨ ­¥ â®çª ,
	; â® ®è¨¡ª  ¯¥à¥¯®«­¥­¨ï
	cmp	AL,'.'
	jne	.NotDot2
	inc	ecx
	lodsb
.NotDot2:
	cmp	AL,0
	jne	.Error ;¯¥à¥¯®«­¥­¨¥ à §à來®© á¥âª¨

; …Ž€‡Ž‚€’œ —ˆ‘‹Ž ˆ‡ ŠŽ„€ BCD ‚ ‚…™…‘’‚…Ž… —ˆ‘‹Ž
.ASCIItoBCDConversionEnd:
	; ‚¯¨á âì §­ ª ¢ áâ à訩 ¡ ©â
	mov	AL,[Data_Sign]
	mov	byte [Data_BCD+9],AL
	; ‘¡à®á¨âì ॣ¨áâàë ᮯà®æ¥áá®à 
	fninit
	; ‡ £à㧨âì ¢ ᮯà®æ¥áá®à ç¨á«® ¢ BCD-ä®à¬ â¥
	fbld	[Data_BCD]
	; ‚ëç¨á«¨âì ­®¬¥à ¤¥«¨â¥«ï
	mov	EBX,18+1
	sub	BX,CX
	sub	BX,DX
	cmp	EBX,0
	je	.NoDiv
	dec	EBX
	shl	EBX,3		;㬭®¦ ¥¬ ­  8
	add	EBX, MConst
	fdiv	qword [EBX] ;à §¤¥«¨âì ­  ª®­áâ ­âã
.NoDiv:; ‚ë£à㧨âì ç¨á«® ¢ ¤¢®¨ç­®¬ ä®à¬ â¥
	fstp	[Data_Double]
	jmp	.End

.Error:; à¨ «î¡®© ®è¨¡ª¥ ®¡­ã«¨âì १ã«ìâ â
	fldz	;§ ­¥á⨠­®«ì á á⥪ ᮯà®æ¥áá®à 
	fstp	[Data_Double]
.End:
	popad
	ret

align 4
proc str_cat, str1:dword, str2:dword
	push eax ecx edi esi
	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
	pop esi edi ecx eax
	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