; ======================================================================
; SEDForth for Linux, Release 0.0.1
; Primitives (for inlining!)
; ======================================================================

code abs
 mov ebx,eax                ;set ebx = sign of n1
 sar ebx,byte 31            ;propogate sign bit if n1 throughout ebx
 xor eax,ebx                ;will invert n1 if n1 was negative
 sub eax,ebx                ;will subtract -1 if n1 was negative
next

code minus
     sub [esi],eax			; -
     drop
next


code mod
        upop ebx			; MOD
        xor edx,edx
        idiv ebx
        mov eax,edx
next

code plus
  add eax,[esi]			; +
  add esi,byte 4
next

code divide
        upop ebx			; /
        xor edx,edx
        idiv ebx
next

code multiply
     mul dword [esi]			; *
     add esi,byte 4
next

code and
	and eax,[esi]
            add esi,byte 4
next

code equals
 sub eax,[esi]                ;subtract n1 from n2
 sub eax,byte 1             ;see if result was 0
 sbb eax,eax
 add esi,byte 4
next

code lessthan
 cmp eax,[esi]                ;compare them
 jl logic_less_1
 xor eax,eax                ;return result
 add esi, byte 4
next
logic_less_1:
 mov eax,dword -1           ;or this one :)
 add esi, byte 4
next

code max
 cmp eax, [esi]               ;which is larger
 jl logic_max_1              
 mov [esi], eax			;n2 is larger
logic_max_1:			;n1 is larger
 mov eax, [esi]
 add esi, byte 4
next

code min
 cmp eax, [esi]               ;which is smaller
 jg logic_min_1              
 mov [esi], eax			;n2 is smaller
logic_min_1:			;n1 is smaller
 mov eax, [esi]
 add esi, byte 4
next

code not
            not eax
next

code or
	      or eax,[esi]
            add esi,byte 4
next

code xor
	xor eax,[esi]
            add esi,byte 4
ret

section .data
base dd 10

code print
	push edx
	push edi
	mov edi,esi	;edi = buffer (in stack space)
	sub edi,4
	or eax,eax	;Negative?
	jns .1
	neg eax
	upsh '-'
	call emit
.1			;Convert
	xor edx,edx
	div dword [base]
	add dl,'0'
	cmp dl,'9'
	jbe .2
	add dl,7+32
.2	dec edi
	mov [edi],dl
	or eax,eax
	jnz .1
	mov eax,edi	;Print
	upsh esi
	sub eax,edi	;# of digits
	call type
	pop edi
	pop edx
	upsh ' '	; And add one space after
	call emit	; the number
next

code type
	push ebx
	push ecx
	upop ecx
	upop ebx
	or ecx,ecx	; Is the count zero?
	jz .done	; If so, we can exit
	.1 	push ecx	; store the count
	dup		; Duplicate it
	xor eax,eax 	; Filter out junk bits
	mov al,[ebx]	; Obtain the byte to show
	inc ebx		; increment to the next byte
	call emit	; Show the character
	pop ecx		; Restore the count
	loop .1		; Loop, decrementing the count
.done	pop ecx
	pop ebx
next


code cstore
	upop edx
	mov [edx], al
	drop
next
code cfetch
	upop edx
	dup
	xor eax,eax
	mov al, [edx]
next
code store
	upop edx
	mov [edx],eax
	drop
next
code callcomma
	mov ebx, eax
	drop
	call ebx
next
code spfetch
	upsh esi
next
code fetch
	mov eax,[eax]
next




section .data
s_dest dd 0
code s
	upop [s_dest]
	mov [tp],dword tib
.0	call key
	cmp al,10
	je .done
	xchg edi,[tp]
	stosb
	xchg [tp],edi
	call emit
	jmp short .0
.done	push ecx	;move string to a safer place...
	push edi
	mov edi,[s_dest]
	mov eax,edi ;push addr
	dup
	push esi
	mov ecx,[tp]
	mov esi,tib
	sub ecx,esi
	mov eax,ecx	;push length
	rep movsb
	pop esi
	pop edi
	pop ecx
	call cr
next

; ( source dest count -- )
code cmove
	mov ecx,eax
	drop
	mov edi,eax
	drop
	push esi
	mov esi,eax
.1	mov edx, [esi] 
	mov [edi], edx
	inc edi
	inc esi
	loop .1
	pop esi
	drop
next



; =======================================================================
; Linux and Driver Specific Words
; =======================================================================
code bye
	sub ebx,ebx	;Return exit status 0
	mov eax,ebx
	inc eax		;1 = sys_exit
	int 80h
code cr
	upsh 10
	call emit
	ret
code emit
	push ebx,ecx,edx
	mov ebx, 1	;stdout
	mov edx, ebx	;count
	lea ecx, [esp-4]
	mov [ecx], eax
	mov eax, 4	;sys_write
	int 80h
	pop ebx,ecx,edx
	drop
	ret
code key
	dup
	push ebx,ecx,edx
	sub ebx,ebx	;0 = stdin
	mov edx, 1	;count
	lea ecx, [esp-4]
	mov eax, 3	;sys_read
	int 80h
	mov eax, [ecx]
	pop ebx,ecx,edx
	ret
; =======================================================================
code dovar
	dup
	pop eax
	ret
;---------------------------------------------------------------
; n SIZE x,

code xcomma
        upop ecx
	mov edx,[h]
	mov [edx],eax
	drop
	add edx,ecx
	mov [h],edx
	ret

section .bss
tib resb 200h
h0 resb 80000h
section .text


tp dd tib
tin dd 0

code buffer
  upsh tib
ret

h call dovar
dd h0
