;EasyCodeName=BinToAsci32,1
;Programmed by Pavlů Zdeněk
;www.zpavlu.cz
;29.08.2021 - 19:17:04

;Tuto proceduru FpuFLtoA napsal Raymond Filiatreault, prosinec 2002
;a upraven v dubnu 2003. Drobná chyba byla opravena v červenci 2003.
;Upraveno v březnu 2004, aby se předešlo případné ztrátě dat z FPU.
;Proceduru upravil Zdeněk Pavlů v roce 2021 pro JWasm .

;This procedure FpuFLtoA was written by Raymond Filiatreault, December 2002
; and modified April 2003. A minor flaw was corrected in July 2003.
; Modified March 2004 to avoid any potential data loss from the FPU.
;The procedure was modified by Zdeněk Pavlů in 2021 for JWasm.

;The FpuFLtoA function converts an 80-bit REAL number to its alphanumeric decimal representation (either in decimal format or scientific notation) and returns the result as a null-terminated string at the specified destination.
;
;FpuFLtoA (
;
;lpSrc1    // pointer to an 80-bit REAL number
;lpSrc2    // pointer to, or value of, 2nd parameter
;lpszDest  // pointer to destination of result
;uID       // ID flags FOR sources AND format

;Parameters
;
;lpSrc1
;This POINTS to an 80 - bit REAL number.(This parameter is ignored IF uID indicates that The value is already on The FPU.)
;
;lpSrc2
;This either points to a DWORD integer in memory, or is an immediate DWORD integer according to the content of uID.
;The Low Byte of The Low Word of The integer indicates The number of decimal digits to be returned In The Result.
;The total number of integer digits AND decimal digits cannot exceed 16.Otherwise, The number of decimal digits will be reduced accordingly.
;(Note that at least one integer digit is always returned.)
;The High Byte of The Low Word of The integer indicates The number of characters before The decimal POINT, spaces being used FOR padding.
;This number cannot exceed 17 (16 digits + sign); it would otherwise be reduced to 17.
;(This byte is ignored if uID indicates that the result must be returned in the scientific format.)
;The high word of this parameter is ignored.
;
;lpszDest
;This POINTS to a Memory location where The Result will be returned.
;It must be large enough to hold The number of characters returned.
;At most, it may have 17 characters before the decimal point, one decimal point, 15 decimal digits, and the terminating zero (for a maximum of 34 characters).
;
;uID
;One of the SRC1_? flags must be OR'ed with only one of the SRC2_? flags and OR’ed with one of the STR_? flags. (The STR_REG flag does not need to be OR’ed if the string must be returned in decimal format; that is the default.)
;
;uID Flag     Meaning
;SRC1_FPU     Src1 is already on the FPU
;SRC1_REAL    Src1 is a pointer to an 80-bit REAL number
;SRC2_DMEM    Src2 is a pointer to a 32-bit signed integer
;SRC2_DIMM    Src2 is a 32-bit signed integer
;STR_REG      The string must be returned in decimal format
;STR_SCI      The string must be returned in scientific notation
;
;
;Return Values:
;If the source is considered a valid REAL number, the converted string will be transferred to the specified destination and EAX will be non-zero.
;If the function fails, EAX will be zero and the null-terminated string ERROR will be placed at the specified destination.
;The source is never modified, whether it is in memory or on the FPU.
;IF the number is greater than OR equal to 1016, The Result will be returned In scientific notation (with The specified number of decimals)
;regardless of The Str flag.IF The number is equal to zero, It is simply returned as an ASCII “0" and a terminating zero regardless of the STR flag."
;
;All the FPU registers and all the CPU registers (except EAX) are preserved.


;lpDecimal
;To buď ukazuje na celé číslo DWORD v paměti, nebo je to okamžité celé číslo DWORD podle obsahu uID.
;Nízký bajt nízkého slova celého čísla udává počet desetinných číslic, které mají být vráceny ve výsledku. 
;Celkový počet celočíselných a desetinných číslic nesmí překročit 16. Jinak se počet desetinných číslic odpovídajícím způsobem sníží. 
;(Všimněte si, že vždy je vrácena alespoň jedna celá číslice.)
;Vysoký bajt nízkého slova celého čísla udává počet znaků před desetinnou čárkou, přičemž mezery se používají pro odsazení. 
;Toto číslo nesmí překročit 17 (16 číslic + znak); jinak by byl snížen na 17. (Tento bajt je ignorován, pokud uID naznačuje, že výsledek musí být vrácen ve vědeckém formátu.)
;Vysoké slovo tohoto parametru Je ignorováno.

;Význam vlajky uID
;SRC1_FPU Src1 je již na FPU
;SRC1_REAL Src1 je ukazatel na 80bitové SKUTEČNÉ číslo
;SRC2_DMEM Src2 je ukazatel na 32bitové celé číslo se znaménkem
;SRC2_DIMM Src2 je 32bitové celé číslo se znaménkem
;STR_REG Řetězec musí být vrácen v desítkovém formátu
;STR_SCI Řetězec musí být vrácen ve vědecké notaci

.Const
	FOREGROUND_BLUE			Equ		1H	;modrá barva textu (blue color text)
	FOREGROUND_GREEN		Equ		2H	;zelená barvy textu (green color text)
	FOREGROUND_RED			Equ		4H	;červená barva textu (red color text)
	FOREGROUND_INTENSITY	Equ		8H	;zvýšená intenzita barvy textu
	FOREGROUND_WHITE		Equ		FOREGROUND_BLUE + FOREGROUND_GREEN + FOREGROUND_RED
	Barva1					Equ		FOREGROUND_WHITE + FOREGROUND_INTENSITY		;barva bílá výrazná (strong white color)
	Barva2					Equ		FOREGROUND_RED + FOREGROUND_INTENSITY		;červená výrazná (distinctive red)
	Barva3					Equ		FOREGROUND_GREEN + FOREGROUND_INTENSITY		;zelená výrazná (distinctive green)


.Data?
	inbuf					DB 100 Dup (?)	;prostor pro 100 byte
	ResultAsci 				DB 200 Dup (?)

	;poloha kursoru (cursor position)
	COOR	Struc
				X	DW	?
				Y	DW	?
	COOR EndS
	CRD		COOR	<?>

.Data

	hInst			HINSTANCE	NULL
	Output_Handle	DD			NULL		;handle bufferu obrazovky konzoly, zde budeme zapisovat (console screen buffer handle, here we will write)
	;pro testy 
	REalx4   		Real4    	314.15926535897932384
	Realx8			Real8    	314.15926535897932384
	Realx10			Real10	  	-0.00000314159265358979323846
	REalx4c   		Real4    	-314159265.3589793238426433832795
	Realx8c			Real8    	3141592653589.793238426433832795
	Realx10c		Real10	  	-314159265358979.32384626433832795
	Dword4			DWord		314.15926535897932384
	Dword8			QWord		314.15926535897932384
	TByte1			TByte		-314159265358979.32384626433832795

	Result 			Real10 		0.0

;	Str1Cz			DB			"Ukázky převodu reálného čísla na Asci.", 0
	Str1Cz			DB			" Examples of real number conversion to Asci.", 0
	Str2Cz			DB			"Real10 To String --> ", 0
	Str3Cz			DB			"Real8  To String --> ", 0
	Str4Cz			DB			"Real4  To String --> ", 0
	Str5Cz			DB			"DWord  To String --> ", 0
	Str6Cz			DB			"QWord  To String --> ", 0
	Str7Cz			DB			"TByte  To String --> ", 0
;	Str8Cz			DB			"Konec ukázky převodu Real4, Real8, Real10, Dword, Qword a TByte.", 0AH, 0DH, 0
	Str8Cz			DB			"End of Real4, Real8, Real10, Dword, Qword and TByte conversion example. ", 0AH, 0DH, 0
;	Str9Cz			DB			" Ukončete stiskem ENTER.", 0
	Str9Cz			DB			" Exit by pressing ENTER.", 0
;	titl1			DB			"Prevod BinToAsci32", 0
	titl1			DB			"Convert BinToAsci32", 0


.Code
	FpuFLtoA Proto :DWord,:DWord,:DWord,:DWord

;Makro na nastavení pozice kurzoru a barvy písma
Set_Kurzor Macro OutHandle:Req, pX:Req, pY:Req
	Mov CRD.X, pX
	Mov CRD.Y, pY
	Invoke SetConsoleCursorPosition, OutHandle, CRD
EndM

start Proc
	Invoke GetModuleHandle, NULL
	Mov hInst, Eax
	Invoke SetConsoleOutputCP, 1250				;nastavení národního prostředí CZ (locale setting CZ)
	Invoke SetConsoleTitle, Addr titl1
	Invoke GetStdHandle, STD_OUTPUT_HANDLE		;handle bufferu obrazovky konzoly, do tohoto budeme zapisovat (console screen buffer handle, here we will write)
	Mov [Output_Handle], Eax					;uložím handle bufferu obrazovky
	Invoke SetConsoleTextAttribute, Eax, Barva3
	Invoke StdOut, Addr Str1Cz
	Invoke FBinToAsci
	Invoke StdIn, Addr inbuf, LengthOf inbuf	;čeká na stisk klávesnice Enter (waits for the Enter key to be pressed)
	Invoke ExitProcess, 0
	Ret
start EndP

Real8ToReal10 Proc Public lpSrc:QWord
	Fld QWord Ptr lpSrc
	Fstp TByte Ptr Result
	Ret
Real8ToReal10 EndP

Real4ToReal10 Proc Public lpSrc:DWord
	Fld DWord Ptr lpSrc
	Fstp TByte Ptr Result
	Ret
Real4ToReal10 EndP

FBinToAsci Proc
	Set_Kurzor Output_Handle, 1, 2
	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str2Cz
	Invoke FpuFLtoA, Addr Realx10, 5, Addr ResultAsci, STR_SCI OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 4

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str3Cz
	Invoke Real8ToReal10, Realx8
	Invoke FpuFLtoA, Addr Result, 16, Addr ResultAsci, STR_SCI OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 6

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str4Cz
	Invoke Real4ToReal10, REalx4
	Invoke FpuFLtoA, Addr Result, 6, Addr ResultAsci, STR_SCI OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci

	;desetiná část bude uříznuta
	Set_Kurzor Output_Handle, 1, 8
	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str2Cz
	Invoke FpuFLtoA, Addr Realx10c, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 10

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str3Cz
	Invoke Real8ToReal10, Realx8c
	Invoke FpuFLtoA, Addr Result, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 12

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str4Cz
	Invoke Real4ToReal10, REalx4c
	Invoke FpuFLtoA, Addr Result, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 14

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str5Cz
	Invoke Real4ToReal10, REalx4c
	Invoke FpuFLtoA, Addr Result, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 16

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str6Cz
	Invoke Real8ToReal10, Realx8c
	Invoke FpuFLtoA, Addr Result, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 18

	Invoke SetConsoleTextAttribute, Output_Handle, Barva1
	Invoke StdOut, Addr Str7Cz
	Invoke FpuFLtoA, Addr TByte1, 0, Addr ResultAsci, STR_REG OR SRC1_REAL
	Invoke SetConsoleTextAttribute, Output_Handle, Barva2
	Invoke StdOut, Addr ResultAsci
	Set_Kurzor Output_Handle, 1, 22

	Invoke SetConsoleTextAttribute, Output_Handle, Barva3
	Invoke StdOut, Addr Str8Cz
	Invoke StdOut, Addr Str9Cz
	Ret
FBinToAsci EndP

End start
