SETNAME	macro	name
	public	_&name
_&name:
	endm

.586P
.MODEL FLAT

PREMIER_MOT equ 4
MAX_LENGTH	equ	9
NB_MOTS		equ	24

Order	struc
Len		dd	?
Pos		dd	?
Dir		dd	?
Window	dd	?
Croise	dd	6 dup (?)
Memo	db	9+3 dup (?)
Order	ends


Mot		struc
next	dd	?
used	db	?
mot		db	MAX_LENGTH+2 dup (?)
Mot		ends

	extrn	_Solution:near
	extrn	_DisplayStatus:near
	extrn	_THREAD_EVENT:dword
	extrn	_CumulTime:dword
	extrn	_tableau:byte
	extrn	_NbMots:dword
	extrn	_Mots:dword
	extrn	_ordre:dword
	extrn	_value:dword
	extrn	_Record:dword
	extrn	_Window:dword

.DATA?
Store	Order NB_MOTS dup (<,,,,>)
EndStore dd	?

.CODE

	SETNAME	ASMCroise
	;int	3

	pusha
;
; init tables
;
	mov	ecx, NB_MOTS
	mov	esi, offset _ordre
	mov	edi, offset Store
@loop1:
	; longueur
	mov	eax, [esi]
	mov	[edi+Len], eax
	; position
	mov		eax, [esi+4]
	add		eax, offset _tableau
	mov		[edi+Pos], eax
	; direction
	mov	eax, [esi+8]
	mov	[edi+Dir], eax

	add esi, 12
	; croisements
	mov		ebx, 5
	lea		ebp,[edi+Croise]
@crois:
	mov	eax, [esi]
	add	esi,4
	inc	eax
	je	@zero
	dec	eax
	mov	edx, size Order
	mul	edx
	add	eax, offset Store
@zero:
	mov [ebp], eax
	add ebp,4
	dec	ebx
	jne	@crois

	mov [ebp], ebx		;0

	add		edi, size Order
	dec		ecx
	jne		@loop1

	mov	ecx, NB_MOTS
	mov	edi, offset Store
	mov	esi, offset _Window
@wind:
	mov	eax, [esi]
	add	esi, 4
	mov	[edi + Window], eax
	add	edi, size Order
	dec	ecx
	jne	@wind

	mov		edi, offset Store
	call	recurse
	popa
@ret:
	ret

solution:
	xor	eax, eax
	mov	ebx, offset _tableau
	mov	ecx, offset _value
	xor	edx,edx
nn	=	0
	rept 13*13
	mov	al,[ebx+nn]
	add	edx,[eax*4+ecx]
nn	= nn+1
	endm
	cmp	edx,[_Record]
	jb	@nosol
	mov	[_Record],edx
	jmp	_Solution

@nosol:
	ret

recurse:
	cmp	edi, offset EndStore
	jae	solution
	test	BYTE PTR [_THREAD_EVENT], 1
	jne	@ret

;	cmp edi, offset Store + (16 * size Order)
;	jne	@pasatteint
;	int	3
;@pasatteint:


	cmp	edi, offset Store + (PREMIER_MOT * (size Order))
	ja	@noclear
	xor	eax, eax
	mov	[_CumulTime], eax
	mov	[_THREAD_EVENT], eax
@noclear:
	test	BYTE PTR [_THREAD_EVENT], 2
	jne	@ret

	mov	ecx, [edi+Len]
	mov	ebx, [edi+Pos]
	mov	edx, [edi+Dir]
@store:
	mov	al, [ebx]
	add	ebx, edx
	mov	[edi+Memo+ecx-1],al
	dec	ecx
	jne	@store	

	mov	ecx, [edi+Len]
	mov	ebp, DWORD PTR [_NbMots + ecx*4]
	mov	esi, DWORD PTR [_Mots + ecx*4]


@explore:
	cmp	byte ptr [esi+used], 0
	jne	@nextword

	push	ebp

	mov	ecx, [edi+Len]
	mov	ebx, [edi+Pos]
	lea	edx, [esi+mot]
@checkeword:
	mov	al, [ebx]
	or	al, al
	je	@nextchar
	cmp	al, [edx]
	jne	@nextword2
@nextchar:
	add	ebx, [edi+Dir]
	inc	edx
	dec	ecx
	jne	@checkeword
;
; le mot rentre
;
	mov	eax, esi
@nextptr1:
	mov	byte ptr [eax+used], 1		;used
	mov	eax, [eax+next]
	or	eax,eax
	jne	@nextptr1

	mov	ecx, [edi+Len]
	mov	ebx, [edi+Pos]
	lea	edx, [esi+mot]
@rentre:
	mov	al, [edx]
	inc	edx
	mov	[ebx], al
	add	ebx, [edi+Dir]
	dec	ecx
	jne	@rentre


	cmp	edi, offset Store
	jne	@not0
;
; checke if stop
;
	test	BYTE PTR [_THREAD_EVENT], 1
	jne	@not0

	lea	eax, [esi+mot]
	push	eax
	call	_DisplayStatus
	pop	eax
@not0:
;
; on vérifie qu'on peut rentrer les autres mots...
;
	push	esi
	lea	ebp, [edi+Croise]
	push	edi
@verifyword:
	mov	edi, [ebp]
	or	edi, edi
	je	@null
;
; on vérifie qu'un mot rentre
;
	push	ebp
	mov	ecx, [edi+Len]
	mov	ebp, DWORD PTR [_NbMots + ecx*4]
	mov	esi, DWORD PTR [_Mots + ecx*4]
@motrentre:
	cmp	byte ptr [esi+used], 0
	jne	@motsuivant

	mov	ecx, [edi+Len]
	mov	ebx, [edi+Pos]
	lea	edx, [esi+mot]
@checkeword1:
	mov	al, [ebx]
	or	al, al
	je	@nextcaractere
	cmp	al, [edx]
	jne	@motsuivant
@nextcaractere:
	add	ebx, [edi+Dir]
	inc	edx
	dec	ecx
	jne	@checkeword1

	pop	ebp
	add	ebp, 4
	jmp	@verifyword
@motsuivant:
	add	esi, size Mot
	dec	ebp
	jne	@motrentre

; aucun mot ne rentre !!!
	pop	ebp
	pop	edi
	jmp	@restaure
@null:
;
; c'est bon, on passe au niveau suivant !!!
;
	pop	edi
;
; avant d'aller plus loin, on vérifie que le total reste correct
;
	xor	eax, eax
	mov	ebx, offset _tableau
	mov	ecx, offset _value
	xor	edx,edx
nn	=	0
	rept 13*13
	mov	al,[ebx+nn]
	add	edx,[eax*4+ecx]
nn	= nn+1
	endm
	add	edx, [edi+Window]
	cmp	edx,[_Record]
	jb	@restaure

	add	edi, size Order
	call	recurse
	sub	edi, size Order
;
; on restaure le mot
;
@restaure:
	pop	esi

	mov	eax, esi
@nextptr2:
	mov	byte ptr [eax+used], 0		;used
	mov	eax, [eax+next]
	or	eax,eax
	jne	@nextptr2

	mov	ecx, [edi+Len]
	mov	ebx, [edi+Pos]
	mov	edx, [edi+Dir]
@restore:
	mov	al, [edi+Memo+ecx-1]
	mov	[ebx], al
	add	ebx, edx
	dec	ecx
	jne	@restore	

@nextword2:
	pop	ebp
@nextword:
	add	esi, size Mot
	dec	ebp
	jne	@explore
	ret
	end
