Ideal
Include Kernel.ash
Include Forth.inc

Segment KernelCode
  KernelOffset		=	$
		dd 0,0,0,0	; Circular null pointer

; See ~moose/info/OSL.info for more info about this.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; Minimal instruction set for a FORTH-like machine... ;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Registers:
; caller-saved: eax,ecx,edx
; callee-saved: ebx,esi,edi,ebp,esp
; constant:	cs,ds,es,ss,fs,gs
;  eax		scratch; not saved upon a thread switch.
;  edx		scratch; not saved upon a thread switch.
;  ebx		buffered top of stack; saved upon a thread switch.
;  ecx		scratch; not saved upon a thread switch.
;  esi		data stack pointer (growing down)
;		If the stack is declared garbage-collection aware
;		all values on the stack may be corrected according to the
;		garbage collection on a "PAUSE", a "YIELD", a memory
;		allocation call or any such thing.
;		 And the thread will be unavailable during garbage
;		collection. Else, no relocatable address may be remembered
;		from a previous yield (), and none may be used at all if the
;		thread is preemptible.
;		Due to buffering, the stack must contain a ghost element
;		to be loaded into ebx when empty.
;  edi		return stack pointer (growing up)
;  ebp		données globales de la tâche.
;  esp		pointe sur l'adresse de l'instruction suivante
;		pile d'éxécution.
;
;
;
; Values:
; - de -1GB à +1GB-1
; - sinon, temporaire.
; pointeurs:
; - de +1GB à +3GB-1
; - sinon, non relogeable.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;; Integer Arithmetics ;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


	CSTK_SUB:
			neg ebx
;			add ebx,[esi]
;			add esi,4
;			Next
	CSTK_ADD:
			add ebx,[esi]
			add esi,4
			Next
	CSTK_RSUB:
			sub ebx,[esi]
			add esi,4
			Next
	CSTK_SHR:
			shr [dword esi],1
			Next
	CSTK_NEG:
			neg ebx
	 cstk_Next:	Next
	CSTK_ABS:
			test ebx,ebx
			jns short cstk_Next
			neg ebx
			;cwd
			;xor ax, dx
			;sub ax, dx
			Next
	CSTK_INC:
			inc ebx
			Next
	CSTK_IMUL:
			mov eax,[esi]
			imul ebx
			mov ebx,eax
			add esi,4
			Next
	CSTK_IDIVREM:
			xor edx,edx
			mov eax,[esi]
			idiv ebx
			mov [esi],eax
			mov ebx,edx
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;; Pointer Arithmetics ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	CSTK_INCCELL:
			add ebx,4
			Next
	CSTK_CELLS:
			shl ebx,2
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; Integer as boolean arrays Arithmetics ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	CSTK_NOT:
			not ebx
			Next
	CSTK_AND:
			and ebx,[esi]
			add esi,4
			Next
	CSTK_OR:
			or ebx,[esi]
			add esi,4
			Next
	CSTK_XOR:
			xor ebx,[esi]
			add esi,4
			Next
	CSTK_FLAG:
			test ebx,ebx
			setnz bl
			movsx ebx,bl
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; USING POINTERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	CSTK_STO:
			mov eax,[esi]
			mov [ebx],eax
			mov ebx,[esi+4]
			add esi,8
			Next
	CSTK_LOD:
			mov ebx,[ebx]
			Next
	CSTK_CSTO:
			mov eax,[esi]
			mov [ebx],al
			mov ebx,[esi+4]
			add esi,8
			Next
	CSTK_CLOD:
			xor ebx,ebx
			mov bl,[ebx]
			Next
	CSTK_WSTO:
			mov eax,[esi]
			mov [ebx],ax
			mov ebx,[esi+4]
			add esi,8
			Next
	CSTK_WLOD:
			xor ebx,ebx
			mov bx,[ebx]
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;; NUMBER COMPARISON ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Equality
	CSTK_0EQ:
			test ebx,ebx
			setz bl
			movsx ebx,bl
			Next
	CSTK_EQ:
			cmp ebx,[esi]
			sete bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_0NEQ	=	CSTK_FLAG
	CSTK_NEQ:
			cmp ebx,[esi]
			setne bl
			movsx ebx,bl
			add esi,4
			Next

;;; Signed number comparison to zero
	CSTK_0LT:
			or ebx,ebx
			setl bl
			movsx ebx,bl
			Next
	CSTK_0LE:
			or ebx,ebx
			setle bl
			movsx ebx,bl
			Next
	CSTK_0GT:
			or ebx,ebx
			setg bl
			movsx ebx,bl
			Next
	CSTK_0GE:
			or ebx,ebx
			setge bl
			movsx ebx,bl
			Next
;;; Signed number comparison
	CSTK_LT:
			cmp [esi],ebx
			setl bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_LE:
			cmp [esi],ebx
			setg bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_GT:
			cmp [esi],ebx
			setg bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_GE:
			cmp ebx,[esi]
			setge bl
			movsx ebx,bl
			add esi,4
			Next
;;; Unsigned number comparison
	CSTK_ULT:
			cmp ebx,[esi]
			setb bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_ULE:
			cmp ebx,[esi]
			setbe bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_UGT:
			cmp ebx,[esi]
			seta bl
			movsx ebx,bl
			add esi,4
			Next
	CSTK_UGE:
			cmp ebx,[esi]
			setae bl
			movsx ebx,bl
			add esi,4
			Next




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CONSTANTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Macro def_CSTK_		constant
	CSTK_&constant:
			sub esi,4
			mov [esi],ebx
			mov ebx,constant
			Next
EndM

	MINUS1 = -1
	MINUS2 = -2
	MINUS4 = -4
	MAXINT = (1 SHL 30) -1
	MININT = - (1 SHL 30)

	num=0
	rept 32
	  def_CSTK_ %num
	  num=num+1
	endm
	def_CSTK_ MINUS1
	def_CSTK_ MINUS2
	def_CSTK_ MINUS4
	def_CSTK_ MAXINT
	def_CSTK_ MININT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;; STACK MANIPULATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	CSTK_SWAP:
			xchg ebx,[esi]
;			Next		; not necessary as another Next follows
	CSTK_NOP:
			Next
	CSTK_OVER:
			sub esi,4
			mov [esi],ebx
			mov ebx,[esi+4]
			Next
	CSTK_DUP:
			sub esi,4
			mov [esi],ebx
			Next
	CSTK_PICK:
			mov ebx,[esi+ebx*4]
			Next
	CSTK_ROT:
			mov eax,[esi]
			mov [esi],ebx
			mov ebx,[esi+4]
			mov [esi+4],eax
			Next
	CSTK_ROTROT:
			mov eax,[esi+4]
			mov [esi+4],ebx
			mov ebx,[esi]
			mov [esi],eax
			Next

	CSTK_ROLL:
			mov ecx,ebx
			jecxz CSTK_DROP
			mov ebx,edi
			mov edi,esi
			mov eax,[esi]
		cstk_roll_0:
			xchg eax,[edi]
			add edi,4
			loop cstk_roll_0
			mov edi,ebx
;			mov ebx,eax		; DROP follows
;			add esi,4
;			Next
	CSTK_DROP:
			mov ebx,[esi]
;			add esi,4
;			Next
	CSTK_NIP:
			add esi,4
			Next

	CSTK_ROLLD:
			mov ecx,ebx
			jecxz CSTK_NOP
			mov ebx,[esi+ecx+4]
			mov eax,[esi]
		cstk_rolld_0:
			xchg eax,[esi+ecx*4]
			loop cstk_rolld_0
			add esi,4
			Next
	CSTK_2DROP:
			mov ebx,[esi+4]
			add esi,8
			Next
	CSTK_2NIP:
			mov ebx,[esi+4]
			mov eax,[esi]
			add esi,8
			mov [esi],eax
			Next
	CSTK_2SWAP:
			xchg ebx,[esi+4]
			mov eax,[esi]
			xchg eax,[esi+8]
			mov [esi],eax
			Next
	CSTK_2DUP:
			mov eax,[esi]
			sub esi,8
			mov [esi],eax
			mov [esi+4],ebx
			Next
	CSTK_2OVER:
			mov eax,[esi+8]
			sub esi,8
			mov [esi],eax
			mov [esi+4],ebx
			mov ebx,[esi+12]
			Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; PROGRAM CONTROL, RET-based Threading ;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Words with different behaviour when using a control loop
;; for indirect threading or debugging
;; direct threading (no debugging control loop):
;;  [esp] is just the direct code pointer
;;  [ebp] is the environment pointer
;; environment is in

	CSTK_R_ENV:
			lea ebx,[ebp+4*ebx]
			Next

	CSTK_R_IMM:
			sub esi,4
			mov [esi],ebx
			pop ebx
			Next
	CSTK_R_GOTO:
			mov esp,ebx
			mov ebx,[esi]
			add esi,4
			Next
	CSTK_R_BRZ:
			pop eax
			test ebx,ebx
			jnz short CSTK_DROP
			mov ebx,[esi]
			add esi,4
			add esp,eax
			Next
	CSTK_R_BRNZ:
			pop eax
			test ebx,ebx
			jz short CSTK_DROP
			mov ebx,[esi]
			add esi,4
			add esp,eax
			Next
	CSTK_R_BRA:
			pop eax
			add esp,eax
			Next
	CSTK_R_SKIP:
			pop eax
			Next
	CSTK_R_JZ:
			pop eax
			test ebx,ebx
			jnz short CSTK_DROP
			mov ebx,[esi]
			add esi,4
			mov esp,eax
			Next
	CSTK_R_JNZ:
			pop eax
			test ebx,ebx
			jz short CSTK_R_DROP
			mov ebx,[esi]
			add esi,4
			mov esp,eax
			Next
	CSTK_R_JMP:
			pop esp
			Next
	CSTK_R_BSR:
			pop eax
			add edi,4
			mov [edi],esp
			add esp,eax
			Next
	CSTK_R_JSR:
			pop eax
			add edi,4
			mov [edi],esp
			mov esp,eax
			Next
	CSTK_R_RET:
			mov esp,[edi]
			sub edi,4
			Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; PROGRAM CONTROL, Bytecode threading ;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Words with different behaviour when using a control loop
;; for indirect threading or debugging
;; Indirect threading:
;;  [esp] is just the usual indirect threading routine
;;  [ebp] is the bytecode pointer
;; environment is in [esp+4]

	CSTK_B_ENV:
			mov edx,[esp+4]
			lea ebx,[edx+ebx*4]
			Next
	CSTK_B_IMM8:
			sub esi,4
			mov [esi],ebx
			movzx ebx,[BYTE ebp]
			inc ebp
			Next
	CSTK_B_IMM16:
			sub esi,4
			mov [esi],ebx
			movzx ebx,[WO ebp]
			inc ebp
			Next
	CSTK_B_IMM32:
			sub esi,4
			mov [esi],ebx
			mov ebx,[ebp]
			add ebp,4
			Next
	CSTK_B_GOTO:
			mov esp,ebx
			mov ebx,[esi]
			add esi,4
			Next
	CSTK_B_BRZ:
			pop eax
			test ebx,ebx
			jnz short CSTK_DROP
			mov ebx,[esi]
			add esi,4
			add esp,eax
			Next
	CSTK_B_BRA:
			pop eax
			add esp,eax
			Next
	CSTK_B_SKIP:
			pop eax
			Next
	CSTK_B_JZ:
			pop eax
			test ebx,ebx
			jnz short CSTK_DROP
			mov ebx,[esi]
			add esi,4
			mov esp,eax
			Next
	CSTK_B_JMP:
			pop esp
			Next
	CSTK_B_BSR:
			pop eax
			sub edi,4
			mov [edi],esp
			add esp,eax
			Next
	CSTK_B_JSR:
			pop eax
			sub edi,4
			mov [edi],esp
			mov esp,eax
			Next
	CSTK_B_RET:
			mov esp,[edi]
			add edi,4
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;; EXECUTION CONTROL ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	CSTK_THREAD:
;			mov [ebp+SAVE_SS],ss
;			mov [ebp+SAVE_ESP],esp
;			mov ss,ds
			pop esp
			Next


	EXEC_MANY:
	;; executes ECX kernel instructions pointed at by EBX
			xchg ebx,esi
			mov edx,edi
			lea eax,[ecx*4]
			sub esp,eax
			mov eax,[ebx]
			@REPEAT
			  push eax
			  add ebx,4
			  mov eax,[ebx]
			  or eax,eax
			@UNTIL z
			Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;; MULTITHREADING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	;NOP_CODE = 90h
	;87 DB is xchg ebx,ebx
	RETN_CODE = 0C3h
	DSOVRR_CODE = 3Eh
	ESOVRR_CODE = 26h
	SSOVRR_CODE = 36h
	CSOVRR_CODE = 2Eh
	FSOVRR_CODE = 64h
	GSOVRR_CODE = 65h
	PUSHIMM_CODE = 69h

	CSTK_PAUSE:
		AbsJmp CSTK_YIELD
	CSTK_YIELD:

		mov [BY CSTK_PAUSE],RETN_CODE

EndS KernelCode
