; ==== malloc ====
min_caml_malloc proc
	PUSH	[ESP+4]
	CALL	Alloc
	CMP		EAX, 	0
	JNE		malloc_ok
	print	"Out of memory!"
	PUSH	1
	CALL	ExitProcess
malloc_ok:
	RET
min_caml_malloc endp

; ====  min_caml_print_newline ====
min_caml_print_newline proc
	MOV 	AL,		0Ah
	MOV		[Txt],	AL
	print	ADDR Txt
	RET
min_caml_print_newline endp
	
; ==== min_caml_print_int ====
; x: int
;.global min_caml_print_int
min_caml_print_int proc 
	MOV		EBX, 	[ESP+4]
	PUSH	0	; end symbol
	MOV 	ECX, 	10	
	CMP 	EBX, 	0
	JGE		non_negative
	MOV		AL, 	2Dh
	MOV		[Txt], AL
	print 	ADDR Txt
	MOV 	ECX, 	10 		; restore values
	MOV		EBX, 	[ESP+8]	; restore values
	NEG		EBX
; push characters to stack
non_negative:
	XOR		EDX, 	EDX
	MOV		EAX, 	EBX
	DIV		ECX				; DL has already correct value	
	MOV		EBX, 	EAX
	ADD		DL, 	30h
	PUSH	EDX
	CMP		EBX,	0
	JNZ		non_negative
	; print characters from stack
printing_loop:
	POP		EAX
	CMP		EAX,	0
	JE		printing_exit
	MOV		[Txt], 	AL
	print	ADDR Txt
	JMP		printing_loop
printing_exit:
	CALL min_caml_print_newline ; matter of taste
	RET
min_caml_print_int endp
	
; ==== min_caml_print_byte ====
; ==== min_caml_prerr_int ====
; ==== min_caml_prerr_byte ====
; ==== min_caml_prerr_float ====
; ==== min_caml_read_int ====
; ==== min_caml_read_float ====

; ==== min_caml_create_array ====
; n: int
; v: int
;.global min_caml_create_array
min_caml_create_array proc
	MOV		ECX,	dword ptr [ESP+4]
	SHL     ECX,    2
	PUSH    ECX
	CALL	min_caml_malloc
	ADD		ESP, 	4
	MOV		EDI, 	EAX
	MOV		EBX, 	dword ptr [ESP+8]
	MOV		ECX,	dword ptr [ESP+4]
create_array_loop:
	JECXZ	create_array_exit
	DEC		ECX
	MOV		[EDI], 	EBX
	ADD		EDI, 	4
	JMP		create_array_loop
create_array_exit:
	RET
min_caml_create_array endp
	
; ==== min_caml_create_float_array ====
; n: int
; v: double
;.global min_caml_create_float_array
min_caml_create_float_array proc
	MOV		ECX,	dword ptr [ESP+4]
	SHL     ECX,    3
	PUSH    ECX
	CALL	min_caml_malloc
	ADD		ESP,	4
	MOV		EDI, 	EAX
	FLD		qword ptr [ESP+8]
	MOV		ECX,	dword ptr [ESP+4]
create_float_array_loop:
	JECXZ	create_float_array_exit
	DEC		ECX
	FST		qword ptr [EDI]
	ADD		EDI, 	8
	JMP		create_float_array_loop
create_float_array_exit:
	FDECSTP
	RET
min_caml_create_float_array endp
	
; ==== min_caml_abs_float ====
; x: double
;.global min_caml_abs_float
;min_caml_abs_float proc
;	FLD		qword ptr [ESP+4]
;	FABS
;	RET
;min_caml_abs_float endp
	
; ==== min_caml_sqrt ====
; x: double
;.global min_caml_sqrt
;min_caml_sqrt proc
;	FLD		qword ptr [ESP+4]
;	FSQRT
;	RET
;min_caml_sqrt endp
	
; ==== min_caml_floor ====
; NOT IMPLEMENTED !!!

; ==== min_caml_int_of_float ====
; x: double
;.global min_caml_int_of_float
min_caml_int_of_float proc
	FLD		qword ptr [ESP+4]
	FIST	dword ptr [ESP-4]
	MOV		EAX, dword ptr [ESP-4]
	RET
min_caml_int_of_float endp
	
; ==== min_caml_float_of_int ====
; x: int
;.global min_caml_float_of_int
min_caml_float_of_int proc 
	FILD	dword ptr [ESP+4]
	RET
min_caml_float_of_int endp
	
; ==== min_caml_cos ====
; x: double
;.global min_caml_cos
;min_caml_cos proc
;	FLD		qword ptr [ESP+4]
;	FCOS
;	RET
;min_caml_cos endp
	
; ==== min_caml_sin ====
; x: double
;.global min_caml_sin
;min_caml_sin proc
;	FLD		qword ptr [ESP+4]
;	FSIN
;	RET
;min_caml_sin endp
	
; ==== min_caml_atan ====
; x: double
; y: double
;.global min_caml_atan
;min_caml_atan:
;	FLD		qword [ESP+10]
;	FLD		qword [ESP+2]
;	FATAN
;	RET
