code 'bytes', bytes
   upop ecx
.1 push ecx
   embed 'db,'
   pop ecx
   loop .1
next
code 'call,', $call
     mov ebx, eax
     drop
     call ebx
next
; ( source dest count -- )
code 'cmove', $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
code '@', fetch
     mov eax,[eax]
next
code '+',plus
  add eax,[esi]			; +
  add esi,byte 4
next
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 'rot', rot
	xchg eax,[esi]
	xchg eax,[esi+4]
next
s_dest dd 0
code 's', 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
code '!', store
  upop edx			; !
  mov [edx],eax
  drop
next
code 'type',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 'word',$word
        mov edi,[tin]           ; Pointer into TIB
        mov ecx,[tp]
        sub ecx,edi
        inc ecx
        repe scasb
        dec edi
        inc ecx
        dup
        mov [esi],edi           ;a
        repne scasb
        mov eax,edi
        dec eax
        sub eax,[esi]           ;n
        mov [tin],edi
next

; ---------------------------------------------------
; Runtime Debugger for RetroForth
; ---------------------------------------------------
%ifdef ENABLE_DEBUGGER
code "depth?", depth
    cmp esi,esp
    jbe .1
.3    cmp esi,esp
    jbe .2

        mov esi,esp
        upsh .text
        upsh 17
        call $type
        jmp .2
.1 mov ecx,esp
   sub ecx,esi
   upsh ecx
   upsh 4
   embed '/'
.2 next
.text db 10,"STACK UNDERFLOW "
code ".s", stack
      call depth.3
	push ecx
	dup
	mov eax,esp
        sub eax, 4
	mov ecx,eax
	sub ecx,esi
	jz .done
	shr ecx,2
.1	  sub eax,byte 4
	  dup
	  mov eax,[eax]
	  call print
	  loop .1
.done   drop
	pop ecx
next
code 'words',words
        push ebx
        mov ebx, [last]
.1	  mov ebx,[ebx]
	  or ebx,ebx
	  jz .end
	  dup
	  lea eax,[ebx+8]
      dup
	movzx eax,byte [eax]
	inc dword [esi]
	  call $type
	  upsh 32
        call emit
	  jmp short .1
.end	pop ebx
next
%endif
