; forth.inc
; macros to build the forth system from assembly.

Macro	deffun		name
Macro	definline	name	; inline function 




;;;;;;;;;;;;;;;;;;;;;;;;; IMPLEMENTATIONS OF "NEXT" ;;;;;;;;;;;;;;;;;;;;;;;;;;;

; PC is the program counter
; DSP is the data stack pointer
; RSP is the return stack pointer
; R0 is a scratch register, R0L is its lower byte
; TOS is a buffer for the top of stack
; INSTRTBL is a table for bytecode threading

;;; BYTECODE, ZERO-BASED CODE ARRAY
;;; -------------------------------
Macro	BCZBCA_Enter
EndM	BCZBCA_Enter
Macro	BCZBCA_Next
	clr R0		; 2, 2  , 1	; or movzx R0,[byte PC] ; 3, 6  , 3
	mov R0L,[PC]	; 2, 4  , 1	; or mov R0H,[PC] !
	inc PC		; 1, 2  , 1
	shl R0,5	; 3, 3  , 2
	jmp R0		; 2, 7+m, 5
EndM	BCZBCA_Next
;TOTAL  BCZBCA:		; 9,18+m,10	; 8 for 256 bytes element array;
					; but then, there may be more cache
					; misses on a small cache, and
					; the interspace may be space costly,
					; and require some hand optimization
					; or writing specifically a automatic
					; optimizer.

;;; RET-based direct threading
;;; --------------------------
Macro	R_Enter
EndM	R_Enter
Macro	R_Next
	ret		; 1,  10+m, 5
EndM	R_Next


;;; BYTECODE, INDIRECT THREADED
;;; ---------------------------
Macro	BCIT_Enter
EndM	BCIT_Enter
Macro	BCIT_Next
	xor R0,R0		; 2, 2  , 1
	mov R0L,[PC]		; 2, 4  , 1; was movzx ebx,[byte esi]; 3, 6, 3
	inc PC			; 1, 2  , 1; was lodsb; movzx eax,al ; 4, 8, 8
	jmp [INSTRTBL+R0*4]	; 7,11+m, 6
EndM	BCIT_Next
	;TOTAL:			;11,19+m, 9		; or 


; External loop for bytecode with rets:
; BCLOOP: push offset BCLOOP ; BCIT_Next (or Whatever_Next)
; or more efficiently, prepend the next code to the whole routine !


Macro	T_Next		; use another register as a threading
EndM	T_Next


;;;;;;;;;;;;;;;;;;;;;;;;; IMPLEMENTATIONS OF A STACK ;;;;;;;;;;;;;;;;;;;;;;;;;;




;;;;;;;;;;;;;;;;;;;;;;; EQUATES FOR DEFAULT BEHAVIOUR ;;;;;;;;;;;;;;;;;;;;;;;;;
Threading	equ	R	; Ret based threading

;;; Generic code
;;; ------------
Macro	Enter
  % Threading&<_Enter>
EndM	Enter
Macro	Next
  % Threading&<_Next>
EndM	Next




;INDIRECT-THREADED
;-----------------
lodsd			; 1, 5
jmp [dword eax]		; 2, 5
; TOTAL			  3,10
; alternatively
mov ebx,[esi]		; 2, 1
add esi,4		; 3, 1
jmp [ebx]		; 2, 5
; TOTAL			  7, 7

;DIRECT-THREADED, SP as index
;----------------------------
ret			; 1, 5
;TOTAL:			  1, 5

;DIRECT-THREADED, SI as index
;----------------------------
lodsd			; 1, 5
jmp eax			; 2, 5
;TOTAL:			  3,10
;alternatively:
;...
add esi,4		; 3, 1
jmp [dword esi]		; 2, 5
;TOTAL:			  5, 6 ; Beware: ++esi instead of esi++
;alternatively:
push [dword esi]	; 2, 4
add esi,4		; 3, 1
ret			; 1, 5
;TOTAL:			; 6,10
;alternatively:

;DIRECT-THREADED, SI as index, 64KB asm code segment
;---------------------------------------------------
lodsw			; 2, 5
jmp ax			; 3, 5
;TOTAL:			  5,10
;alternatively:
add esi,2		; 3, 1 ; or inc esi; inc esi 2, 2
jmp [word esi]		; 3, 5

push [word esi]		; 3, 4
add esi,2		; 3, 1	; or inc esi;inc esi (2,2)
ret			; 1, 5  ;
;TOTAL:			; 7,10 	; or 6,11

ends

end
