;;-----------------------------------------------------------------------75
;; File: IO_CLIB.NSM  By: s_dubrovich@yahoo.com
;; ?(c): COPYLEFT
;; Last: Sat 13 Aug 2011 05:55:04 PM CDT
;; Prev: Sat 13 Aug 2011 05:55:04 PM CDT
;; Init: Sat 13 Aug 2011 05:55:04 PM CDT
;; Vers: v.0r0
;;-----------------------------------------------------------------------75
;; Sat 13 Aug 2011 05:55:04 PM CDT - initial.
;;-----------------------------------------------------------------------75
;; !!!!: requires linking to dynamic library..
;; Linking when an external C library is to be used to link externals:
;; ld --dynamic-linker /lib/ld-linux.so.2 -lc -o program program.o
;;
;; /** getc(){;} gets(){;} putc(){;}  **/
;; /** putchar(){;} fopen(){;} fclose(){;}  **/
;;-----------------------------------------------------------------------75
;; -snippets from libc.pdf-
;; 11.1.1 Streams and File Descriptors
;;
;; When you want to do input or output to a file, you have a choice of two
;; basic mechanisms for representing the connection between your program
;; and the file: file descriptors and streams.  File descriptors are
;; represented as objects of type int, (open(), close()), while streams
;; are represented as FILE * objects, (fopen(), fclose()).  File
;; descriptors provide a primitive, low-level interface to input and output
;; operations.
;;
;; Since streams are implemented in terms of file descriptors, you can
;; extract the file descriptor from a stream and perform low-level
;; operations directly on the file descriptor.  You can also initially open
;; a connection as a file descriptor and then make a stream associated
;; with that file descriptor.
;;
;; If you are concerned about portability of your programs to systems other
;; than GNU, you should also be aware that file descriptors are not as
;; portable as streams.  You can expect any system running ISO C to support
;; streams, but non-GNU systems may not support file descriptors at all, or
;; may only implement a subset of the GNU functions that operate on file
;; descriptors. Most of the file descriptor functions in the GNU library
;; are included in the POSIX.1 standard, however.
;;-----------------------------------------------------------------------75
;; NOTE: the FILE * stream functions return NULL on open error.
;;  The int file descriptor functions return -1 on open error.
;;-----------------------------------------------------------------------75
;; It is an error to fopen a file for reading if it doesn't exist.
;; A file is created by fopen'ing one for writing.  If the file already
;; exists, it is destroyed by the fopen.  "The GNU C library defines one
;; additional character for use in opentype: the character ‘x’ insists on
;; creating a new file—if a file filename already exists, fopen fails
;; rather than opening it. (non-destructive open.)
;;-----------------------------------------------------------------------75
;; There are also symbolic constants defined in ‘unistd.h’ for the file
;; descriptors belonging to the standard streams stdin, stdout, and stderr;
;; see Section 12.2 [Standard Streams], page 226.
;;  STDIN_FILENO
;; This macro has value 0, which is the file descriptor for standard input.
;;  STDOUT_FILENO
;; This macro has value 1, which is the file descriptor for standard output.
;;  STDERR_FILENO
;; This macro has value 2, which is the file descriptor for standard error
;; output.
;;-----------------------------------------------------------------------75

_NULL EQU 0
_TRUE EQU 1

;; -= int getc (FILE *stream) `F_INPUT =-

extern getc

_getc:
	mov	ebp, esp
	mov	eax, [ebp + 4]
	push	eax
	call	getc
	mov	ebx, eax
	add	esp, 4
	RET

;; -= int fgetc (FILE *stream) =-
;; This function reads the next character as an unsigned char from the
;; stream 'stream' and returns its value, converted to an int. If an
;; end-of-file condition or read error occurs, EOF is returned instead.

extern fgetc

_fgetc:
	mov	ebp, esp
	mov	eax, [ebp + 4]
	push	eax
	call	fgetc
	mov	ebx, eax
	add	esp, 4
	RET

;; -= char * gets (char *s) `STDIN =-
;; -= int putchar (int c) .eqiv. putc(c,stdout). `STDOUT =-
;; -= int putc (int c, FILE *stream) `F_OUTPUT =-

extern putchar

_putchar:
	mov	ebp, esp
	mov	eax, [ebp + 4]
	push	eax
	call	putchar
	mov	ebx, eax
	add	esp, 4
	RET

;; -= int fputc (int c, FILE *stream) `F_OUTPUT =-
;; The fputc function converts the character c to type unsigned char, and
;;  writes it to the stream stream. EOF is returned if a write error occurs;
;;  otherwise the character c is returned.

extern fputc			;; resides in c library:

_fputc:
	mov	ebp, esp	;; TOS 0[RET], 4[fp_output], 8[chr]
	mov	eax, [ebp + 8]
	mov	ebx, [ebp + 4]	;; changes argument order & places below return addr
	push	ebx
	push	eax		;; TOS 0[chr], 4[fp_output]
	call	fputc		;; returns FILE * in EAX
	mov	ebx, eax
	add	esp, 8
	RET

;; -= printf(fmt_str,val1);

extern printf

_printf:
	mov	ebp, esp	;; then [ebp + 0] has ret address, and..
	mov	edx, [ebp + 8]	;; format
	mov	eax, [ebp + 4]	;; chr
	and	eax, 0FFh
	push	eax
	push	edx
	call	printf
	mov	ebx, eax
	add	esp, 8
	RET

;;-----------------------------------------------------------------------75
;; -= int fileno (FILE *stream) =-
;; This function returns the file descriptor associated with the stream
;; stream. If an error is detected (for example, if the stream is not
;; valid) or if stream does not do I/O to a file, fileno returns −1

extern fileno

_fileno:
	mov	ebp, esp
	mov	eax, [ebp + 4]
	push	eax
	call	fileno
	mov	ebx, eax
	add	esp, 4
	RET

;; -= FILE * fdopen (int filedes, const char *opentype) =-
;; filedes is a number, 1 for stdout, do this to get its FILE *.

extern fdopen

_fdopen:
	mov	ebp, esp	;; TOS 0[RET], 4[otyp], 8[filedes]
	mov	eax, [ebp + 8]
	mov	ebx, [ebp + 4]
	push	ebx
	push	eax
	call	fdopen		;; returns FILE * in EAX
	mov	ebx, eax
	add	esp, 8
	RET

;; -= FILE * fopen (const char *filename, const char *opentype) =-

extern fopen			;; resides in c library:

_fopen:
	mov	ebp, esp	;; TOS 0[RET], 4[otyp], 8[fname]
	mov	eax, [ebp + 8]
	mov	ebx, [ebp + 4]
	push	ebx
	push	eax
	call	fopen		;; returns FILE * in EAX
	mov	ebx, eax
	add	esp, 8
	RET

;; -= int fclose (FILE *stream) =-
;; returns 0 on successful close, else EOF

extern fclose			;; resides in c library:

_fclose:
	mov	ebp, esp
	mov	eax, [ebp + 4]
	push	eax
	call	fclose
	mov	ebx, eax
	add	esp, 4
	RET

;; -= int puts (const char *c) `STDOUT =-
;; copies null-terminated string to stdout, less null, adds \n.
;; return: success`non-negative, fail`EOF.

extern puts			;; resides in c library: int puts (const char *s)

_puts:				;; ptr in (Primary BX) is passed on the stack.
	mov	ebp, esp	;; TOS 0[ret], 4[str_ptr]
	mov	eax, [ebp + 4]	;; retrieve ptr parameter
	push	eax		;; ptr to string parameter.
	call	puts		;; libc function, puts function corrupts ecx
	add	esp, 4
	RET

;; -= int fputs (const char *s, FILE *stream) =-
;; The function fputs writes the string s to the stream stream. The terminating null
;; character is not written. This function does not add a newline character, either. It
;; outputs only the characters in the string.  This function returns EOF if a write
;; error occurs, and otherwise a non-negative value.


extern fputs

_fputs:
	mov	ebp, esp	;; TOS 0[RET], 4[str_ptr], 8[strm_ptr]
	mov	eax, [ebp + 8]
	mov	ebx, [ebp + 4]
	push	ebx
	push	eax
	call	fputs		;; EAX = EOF if write error.
	mov	ebx, eax
	add	esp, 8
	RET

;;-----------------------------------------------------------------------75
;; File: cond_ops.nsm
;; Conditional Operators compare the Secondary Register against the
;; Primary Register and put a value of 1 in the Primary Register if the
;; condition is true, otherwise they put a value of 0 in the Primary
;; Register indicating a condition that is false.
;;
;; -testing-

cceq:				;; test for equal
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jz	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccne:				;; test for not equal
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jnz	.next
	mov	ebx, 0		;; is false
.next:
	RET

cclt:				;; test for less than (signed)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jl	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccle:				;; test for less than or equal to (signed)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jle	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccgt:				;; test for greater than (signed)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jg	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccge:				;; test for greater than or equal to (signed)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jge	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccult:				;; test for less than (unsigned)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jb	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccule:				;; test for less than or equal to (unsigned)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jbe	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccugt:				;; test for greater than (unsigned)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	ja	.next
	mov	ebx, 0		;; is false
.next:
	RET

ccuge:				;; test for greater than or equal to (unsigned)
	cmp	edx, ebx	;; sets flags
	mov	ebx, 1		;; assume true
	jae	.next
	mov	ebx, 0		;; is false
.next:
	RET

;; -= eo cond_ops.nsm =-

;; - eo_IO_LIB.NSM -