;---------------------------------------------------------------------
; Standard file descriptors
;
%define stdin	0
%define stdout	1
%define stderr	2

SECTION .text

;---------------------------------------------------------------------
; putc(c)	;Put char in EAX into output buffer
	align 4
putc:
	push ebx,ecx,edx
	mov edx,1
	push eax
	mov ecx,esp
	mov ebx,stdout
	mov eax,4	;sys.write
	int 80h
	pop eax
	pop ebx,ecx,edx
	ret

;---------------------------------------------------------------------
; print(str, length)	;Print a counted string
	align 4
print:
	push ebx,ecx,edx
	mov edx,[esp+16]
	mov ecx,eax
	mov ebx,stdout
	mov eax,4	;sys.write
	int 80h
	pop ebx,ecx,edx
	ret

;---------------------------------------------------------------------
; Puts(str)	-- Put ASCIIZ string pointed to by EAX into outbuf
;			Special tokens:
;			0	end-of-string
;			1,addr	
;			2,num	display a number (NOT DONE YET)
;
	align 4
_puts:
	push esi

	mov esi,eax
.1	xor eax,eax
	lodsb
	cmp al,1
	  jbe .jump
	call putc
	jmp short .1
.jump	jmp [.jtable + 4*eax]
.jtable	dd .j0, .j1
.j0	pop esi
	ret
.j1	lodsd
	call _puts
	jmp short .1

%macro puts 1
section .data
%%1	db %1,0
section .text
	mov eax,%%1
	call _puts
%endmacro


;---------------------------------------------------------------------
;Print a number in EAX, in current base
;
	section .text
	align 4
putn:
	push edx,edi
	mov edi,.outbuf+32

	or eax,eax	;Negative?
	if s
	  neg eax
	  push eax	;print a '-'
	  mov al,'-'
	  call putc
	  pop eax
	endif

.1                      ;Convert
	xor edx,edx
	div dword [base]
	add dl,'0'
	cmp dl,'9'
	  jbe .2
	add dl,7	;hex digits over 9
.2
	dec edi
	mov [edi],dl
	or eax,eax
	  jnz .1

	mov eax,edi	;Print
	mov edi,.outbuf+32
	sub edi,eax
	push edi
	call print
	add esp,byte 4

	pop edx,edi
	ret

	section .bss
.outbuf	resb	32

	section .data
	align 4
base	dd	10

	section .text


;---------------------------------------------------------------------
;A basic 'printf'
;	EAX = format string (pointer)
;	Push parameters on stack IN REVERSE ORDER!!
;
;  Just use the macro, eg: printf {"string %d %s etc..",10,0}, 123, a_string
;
	align 4
_printf:
	push ebp,esi
	mov esi,eax	;String pointer
	lea ebp,[esp+8]	;Stack frame
.1	lodsb
	or al,al
	  jz .end
	cmp al,'%'
	  je .parm
	cmp al,'\'
	  je .esc
.2
	call putc
	jmp short .1

.end	pop ebp,esi
	ret

.esc	lodsb
	cmp al,'n'
	  je .bn
	cmp al,'t'
	  je .bt
.echo	call putc
	  jmp .1
.bn	mov al,10
	  jmp short .echo
.bt	mov al,9
	  jmp short .echo

.parm	add ebp,byte 4	;get next parameter
	lodsb		;get next char
	cmp al,'s'
	  je .str
	cmp al,'d'
	  je .int
	cmp al,'c'
	  je .char
	jmp short .2	;if not matched, just print the char, i guess.
.str
	mov eax,[ebp]
	call _puts
	jmp short .1
.int
	mov eax,[ebp]
	call putn
	jmp short .1
.char
	mov eax,[ebp]
	call putc
	jmp short .1


%macro printf 1-*
section .data
%%1	db %1,0
section .text
%rep %0 - 1
%rotate -1
	push dword %1
%endrep
	mov eax,%%1
	call _printf
	add esp, 4*(%0 - 1)
%endmacro

;---------------------------------------------------------------------
;END
