;***********************************
;*                                 *
;*             PENTE               *
;*                                 *
;*         implemented by          *
;*           Tis Veugen            *
;*         NL-Waalre,1988          *
;*                                 *
;*    Amiga 500                    *
;*    file  Pente:PenteCalc.s      *
;*                                 *
;***********************************
;
code
	bra	INITCALC
data
;
RBRDR = 2	; reduction border
BRDR  = 3	; evaluation border
BXDIM = 19
BYDIM = 19
BXMAX = BRDR + BXDIM + BRDR
BYMAX = BRDR + BYDIM + BRDR
BSIZE = BXMAX * BYMAX
EXMAX = BRDR + 1 + BRDR
EYMAX = BRDR + 1 + BRDR
ESIZE = EXMAX * EYMAX

rdcsq = -1
brdrsq= -[2*BRDR]
empsq = 0
white = $30
black = $34
whbl  = white!black	; white OR black

NOMV  = -1
KPLY  = 16		; number of plies per move-generation
NPLY  = 128		; number of plies per game
KMOVS = BXDIM*BYDIM	; number of moves per position
NMOVS = KPLY*KMOVS/2	; total number of moves/2

TableCLEN  = $10000
TableEVLEN = $20000
TableLEN   = TableCLEN + TableEVLEN

TakeBit = 9	; Evaluation taken stones = 2^TakeBit

ZCEVI = -$7800
ZAEVI =  ZCEVI
ZBEVI = -ZAEVI
ZWIN  =  $5800
ZBEV  =  $0001

;	History
HcolME = 0
HcolOP = HcolME + 2
HWEVBRD= HcolOP + 2
HBEVBRD= HWEVBRD + 4
HTGMV  = HBEVBRD + 4
HPLYNR = HTGMV + 4
HWIN   = HPLYNR + 2
HWMEV  = HWIN + 2
HBMEV  = HWMEV + 1
HPEV   = HBMEV + 1
HAEV   = HPEV + 2
HBEV   = HAEV + 2
HCEV   = HBEV + 2
HMV0   = HCEV + 2
HMV1   = HMV0 + 4
HMV2   = HMV1 + 4
HTQS   = HMV2 + 4
HRCP   = HTQS + 1 + 1
; this part only for game-history
HSBRD  = HRCP + 4
HPEV0  = HSBRD + 4
HPEV1  = HPEV0 + 2
LHST   = HPEV1 + 2
;
;	Move
MPEV0  = 0
MPEV   = 2
MSQ    = 4
MTK    = 6
MMEV   = 7
LMOV   = 8
MTQS   = 2
;
;	PSN
PXA     = 0		; help-array
PYA     = PXA + BXMAX	; help-array
PXMAX   = PYA + BXMAX
PYMAX   = PXMAX + 4
PXDIM   = PYMAX + 4
PYDIM   = PXDIM + 2
PXLO1   = PYDIM + 2
PYLO1   = PXLO1 + 2
PXHI1   = PYLO1 + 2
PYHI1   = PXHI1 + 2
RXLO    = PYHI1 + 2
RXLO1   = RXLO  + 2
RXLO2   = RXLO1 + 2
RYLO    = RXLO2 + 2
RYLO1   = RYLO  + 2
RYLO2   = RYLO1 + 2
RXHI    = RYLO2 + 2
RXHI1   = RXHI  + 2
RXHI2   = RXHI1 + 2
RYHI    = RXHI2 + 2
RYHI1   = RYHI  + 2
RYHI2   = RYHI1 + 2
RXDIM   = RYHI2 + 2
RYDIM   = RXDIM + 2
REBRD   = RYDIM + 2
PRDC    = REBRD + 2
PROW    = PRDC + 2
PCOL    = PROW + 2
PMEV    = PCOL + 2
PPLYCNT = PMEV  + 2
PGMVS   = PPLYCNT + 2	; Pointer to moves to be generated (A6)
PMEVLIM = PGMVS + 4	; Limit number taken pairs of stones
PMVAL   = PMEVLIM + 2	; (positional) Evaluation of taken stone
PESC    = PMVAL + 2	; escape Evaluation
PTQS    = PESC + 2	; allowed QS-code
PIQS    = PTQS + 2	; integral QS-code
PMTQS   = PIQS + 2	; previous move's QS-code
PREGS   = PMTQS + 2	; all registers at start-up
PREG0   = PREGS + 64	; cleared data
PEVPAT  = PREG0 + 32		; Pev pattern
RWEVBRD = PEVPAT + ESIZE + 1	; Pointer reduced Pev board white
RBEVBRD = RWEVBRD + 4		; Pointer reduced Pev board black
WHEVBRD = RBEVBRD + 4		; Pev board white
BLEVBRD = WHEVBRD + BSIZE	; Pev board black
RPBRD   = BLEVBRD + BSIZE	; Pointer reduced Pev board white
PBRD    = RPBRD + 4		; position board
PTableC = PBRD + BSIZE + 1	; table of Codes
PTableEV= PTableC + 4		; table of Evaluations
PHST    = PTableEV + 4		; A4
PMVS    = PHST + [ NPLY * LHST ]
PTable  = PMVS + [ NMOVS * LMOV ]
LPSN    = PTable + TableLEN
;
; bit patterns :
;
PATempty  = %00
PATwhite  = %01
PATblack  = %10
PATborder = %11
;
; codes :
;
EVC5   = %10000000	; pente
EVCn   = %01000000	; normal move
EVC5t  = %00100000	; pente threat
EVC5s  = %00010000	; pente threat solved
EVCtkt = %00001000	; take threat
EVCtks = %00000100	; take threat solved
EVCtkl = %00000010	; take left
EVCtkr = %00000001	; take right
EVCs5t = %10010011	; mask for solving pente threat
EVCrds = %10110011	; mask for reduced moves (no take solve)
EVCrdt = %10110111	; mask for reduced moves (no take threat)
EVCrdn = %10111111	; mask for reduced moves (no normal)
EVCall = %11111111	; mask for all moves
EVCQSI = %00101000	; mask for QS initialization
;
EVCbit5s = 4		; bit 4 indicates pente solve
EVCbit5t = 5		; bit 5 indicates pente threat
EVCbitn  = 6		; bit 6 indicates normal move
;
JEVesc =  4
JEVs5t =  8
JEVrds = 12
JEVrdt = 16
JEVrdn = 20
JEVall = 24
JQSesc = 28
JQSs5t = 32
JQSrds = 36
JQSrdt = 40
JQSrdn = 44
JQSall = 48
JEVQSmax = 52
;
code
;
DIRS:	dc.w	1,BXMAX+1,BXMAX,BXMAX-1,-1,-BXMAX-1,-BXMAX,-BXMAX+1,0
;
DPEVPAT:
	dc.b	 3,  1,  2,  4,  2,  1,  3
	dc.b	 1,  7,  5,  8,  5,  7,  1
	dc.b	 2,  5,  1,  1,  1,  5,  2
	dc.b	 4,  8,  1,  0,  1,  8,  4
	dc.b	 2,  5,  1,  1,  1,  5,  2
	dc.b	 1,  7,  5,  8,  5,  7,  1
	dc.b	 3,  1,  2,  4,  2,  1,  3
;
ZRCPcode:
	dc.b	JEVall,JQSrdn,JQSrdt,JQSrds
	dc.b	JQSrds,JQSrds,JQSrds,JQSrds
	dc.b	JQSrds,JQSrds,JQSrds,JQSrds
	dc.b	JQSrds,JQSrds,0,0
	even
ZRCPSR:
	dc.l	ZEVesc
	dc.l	ZEVesc, ZEV,    ZEV,    ZEV,    ZEV,    ZEV
	dc.l	ZQSesc, ZQS,    ZQS,    ZQS,    ZQS,    ZQS
	dc.l	EVCall	; offset=JEVQSmax
	dc.l	EVCall, EVCs5t, EVCrds, EVCrdt, EVCrdn, EVCall
	dc.l	EVCall, EVCs5t, EVCrds, EVCrdt, EVCrdn, EVCall
;
RCPescape:	; subroutine for escape,
		; to be called by high-level program
	lea	MIRQPort(PC),A0	; read message
	move.l	ExecBase,A6
	jsr	GetMsg(A6)
	move.l	D0,-(SP)
;
	moveq	#0,D1		; clear MIRQ-signal
	lea	TM_sigBit(PC),A0
	move.b	(A0),D0
	bset	D0,D1
	moveq	#0,D0
	move.l	ExecBase,A6
	jsr	SetSignal(A6)
;
	move.l	(SP)+,A1
	cmpi.w	#CMD_Escape,QIcmd(A1)
	bne.s	RCPstrategy
	lea	RCPMIRQesc(PC),A0
	move.l	(A0),D0		; D0=address(ZEVesc)
	lea	RCPMIRQA4(PC),A0
	move.l	(A0),A0		; A0 points to A4-0
RCPescL:
	move.l	D0,HRCP(A0)
	lea	LHST(A0),A0
	tst.l	HRCP(A0)
	bne.s	RCPescL
	rts
;
RCPstrategy:
	cmpi.w	#CMD_Strategy,QIcmd(A1)
	bne.s	RCPerror
	move.l	QIstrat(A1),A0
	lea	ZRCPcode(PC),A2
RCPstratL:
	move.w	(A0)+,D0
	move.b	D0,(A2)+
	bne.s	RCPstratL
RCPerror:
	rts
;
RCPMIRQA4:
	dc.l	0	; used as store for A4-0
RCPMIRQesc:
	dc.l	0	; used as store for ZEVesc
;
data
	QLmsg     = 20
	Qcmd      = QLmsg
	Qstatus   = Qcmd + 2
	Qmovenr   = Qstatus + 2
	Qrow      = Qmovenr + 2
	Qcol      = Qrow + 2
	Qtakes    = Qcol + 2
	QmevPL    = Qtakes + 2
	QmevAM    = QmevPL + 2
	Qresult   = QmevAM + 2

	QIcmd     = QLmsg
	QIstrat   = QIcmd + 2

	IPROG     =  4	; cmd's
	IGAME     =  8
	DOMV      = 12
	CAMV      = 16
	EPROG     = 20
	ECALC     = 24

	CMD_Escape   =  4
	CMD_Strategy =  8

	RESULT_OK     = 0
	RESULT_WIN    = 1

	status_OK     =  0
	status_ERROR  =  1

	NT_INTERRUPT  = 2
	NT_MSGPORT    = 4
	PA_SIGNAL     = 0
	PA_SOFTINT    = 1
	MEMF_CLEAR    = $10000
	MODE_OLD      = 1005
	MODE_NEW      = 1006

	ExecBase    = 4
	OpenLib     = -552
	CloseLib    = -414
	Open        =  -30
	Close       =  -36
	Read        =  -42
	Write       =  -48
	Output      =  -60
	Execute     = -222
	AllocMem    = -198
	FreeMem     = -210
	FindTask    = -294
	SetSignal   = -306
	AllocSignal = -330
	FreeSignal  = -336
	AddPort     = -354
	RemPort     = -360
	PutMsg      = -366
	GetMsg      = -372
	ReplyMsg    = -378
	WaitPort    = -384
	FindPort    = -390
code
;
MsgPTR:	dc.l	0
;
PC_name:
	dc.b	"PenteCalc",0
	even
PM_name:
	dc.b	"PenteMIRQ",0
	even
INITCALC:
	lea	PC_name(PC),A1
	move.l	ExecBase,A6
	jsr	FindPort(A6)
	tst.l	D0
	bne	ENDCALCSGNL
;
	moveq	#-1,D0		; Port Signal
	move.l	ExecBase,A6
	jsr	AllocSignal(A6)
	lea	TC_sigBit(PC),A0
	move.b	D0,(A0)
	cmpi.b	#-1,D0
	beq	ENDCALCSGNL
;
	suba.l	A1,A1
	move.l	ExecBase,A6
	jsr	FindTask(A6)
	lea	TC_SigTask(PC),A0
	move.l	D0,(A0)
;
	lea	CalcPort(PC),A1
	move.l	ExecBase,A6
	jsr	AddPort(A6)
;
INITMIRQ:
	lea	RCPescape(PC),A0
	lea	TMi_Code(PC),A1
	move.l	A0,(A1)
;
	lea	PM_name(PC),A1
	move.l	ExecBase,A6
	jsr	FindPort(A6)
	tst.l	D0
	bne	ENDMIRQSGNL
;
	moveq	#-1,D0		; Port Signal
	move.l	ExecBase,A6
	jsr	AllocSignal(A6)
	lea	TM_sigBit(PC),A0
	move.b	D0,(A0)
	cmpi.b	#-1,D0
	beq	ENDMIRQSGNL
;
	lea	MIRQinterrupt(PC),A0
	lea	TM_SigTask(PC),A1
	move.l	A0,(A1)
;
	lea	MIRQPort(PC),A1
	move.l	ExecBase,A6
	jsr	AddPort(A6)
;
	lea	QSst(PC),A0
	clr.w	(A0)
;
MAINL:	move.l	A6,-(SP)
	lea	CalcPort(PC),A0
	move.l	ExecBase,A6
	jsr	WaitPort(A6)
;
	lea	CalcPort(PC),A0
	move.l	ExecBase,A6
	jsr	GetMsg(A6)
	lea	MsgPTR(PC),A0
	move.l	D0,(A0)
	move.l	(SP)+,A6
;
	move.l	D0,A0
	move.w	Qcmd(A0),D0
	cmpi.w	#ECALC,D0
	beq.s	QSECALC
;
	lea	QSUBS(PC),A1
	move.l	0(A1,D0.w),A1
	jsr	(A1)
;
	bra.s	MAINL
;
GETMSGPTR: macro
	lea	MsgPTR(PC),A0
	move.l	(A0),A1
	endm
;
QSECALC:
	moveq	#status_ERROR,D0
	lea	QSst(PC),A0
	tst.w	(A0)
	bne.s	ENDCALCERR
	GETMSGPTR
	move.w	#status_OK,Qstatus(A1)
	move.l	ExecBase,A6
	jsr	ReplyMsg(A6)
ENDCALC:
	bsr	SUBENDCALC
ENDMIRQSGNL:
	bsr	SUBENDMIRQ
ENDCALCSGNL:
	moveq	#0,D0
ENDCALCERR:
	rts
;
SUBENDCALC:
	lea	CalcPort(PC),A1
	move.l	ExecBase,A6
	jsr	RemPort(A6)
;
SUBENDCALCPORT:
	lea	TC_sigBit(PC),A0
	move.b	(A0),D0
	move.l	ExecBase,A6
	jsr	FreeSignal(A6)
	rts
;
SUBENDMIRQ:
	lea	MIRQPort(PC),A1
	move.l	ExecBase,A6
	jsr	RemPort(A6)
;
SUBENDMIRQPORT:
	lea	TM_sigBit(PC),A0
	move.b	(A0),D0
	move.l	ExecBase,A6
	jsr	FreeSignal(A6)
	rts
;
QSUBS:	dc.l	0,QSIPROG,QSIGAME,QSDOMV,QSCAMV,QSEPROG,QSECALC
QSst:	dc.w	0
;
QSIPROG:
	moveq	#status_ERROR,D0
	lea	QSst(PC),A0
	tst.w	(A0)
	bne.s	QSREPLYs
	bsr	INITPROG
	cmpi.w	#status_OK,D0
	bne.s	QSREPLYs
	lea	QSst(PC),A0
	move.w	#1,(A0)
QSREPLYs:
	GETMSGPTR
	move.w	D0,Qstatus(A1)
;
QSREPLY:
	move.l	A6,-(SP)
	move.l	ExecBase,A6
	jsr	ReplyMsg(A6)
	move.l	(SP)+,A6
	rts
;	
CKQSst:	macro
	moveq	#status_ERROR,D0
	lea	QSst(PC),A0
	tst.w	(A0)
	beq.s	QSREPLYs
	endm
;
QSEPROG:
	CKQSst
	bsr	ENDPROG
	cmpi.w	#status_OK,D0
	bne.s	QSREPLYs
	lea	QSst(PC),A0
	clr.w	(A0)
	bra.s	QSREPLYs
;
QSIGAME:
	CKQSst
	bsr	INITGAME
	bra.s	QSREPLYs
;
QSDOMV:	CKQSst
	bsr	CHECKMOVENR
	bne.s	QSRTMV		; error!
	GETMSGPTR
	move.w	Qrow(A1),PROW(A3)
	move.w	Qcol(A1),PCOL(A3)
	bsr	DOEMOVE
	move.l	HMV0(A4),A6
	bra.s	QSRTMV
;
QSCAMV:	CKQSst
	bsr	CHECKMOVENR
	bne.s	QSRTMV		; error!
	move.w	#-1,PRDC(A3)	; reduce
	bsr	INITMOVE
	bsr	CALCMOVE
	bsr	EXECMOVE
	bsr	GETMOVE
	moveq	#status_OK,D0
QSRTMV:
	GETMSGPTR
	move.w	D0,Qstatus(A1)
	move.w	PROW(A3),Qrow(A1)
	move.w	PCOL(A3),Qcol(A1)
;
	moveq	#RESULT_OK,D0
	move.w	HWIN(A4),D1
	cmp.w	HPEV1(A4),D1
	bne.s	QSRTMVR
	moveq	#RESULT_WIN,D0
QSRTMVR:
	move.w	D0,Qresult(A1)
;
	moveq	#0,D0
	move.b	MMEV(A6),D0
	move.w	D0,QmevAM(A1)
	move.b	HBMEV(A4),D0
	move.w	D0,QmevPL(A1)
	move.b	MTK(A6),D0
	move.w	D0,Qtakes(A1)
	bra	QSREPLY
;
GETMOVE:
	move.l	HMV0(A4),A6	; calculate position according to
	moveq	#0,D7
	move.w	MSQ(A6),D7	; normal board
	divu	D3,D7
	add.w	RYLO(A3),D7
	subq.w	#BRDR,D7
	move.w	D7,PROW(A3)
	swap	D7
	add.w	RXLO(A3),D7
	subq.w	#BRDR,D7
	move.w	D7,PCOL(A3)
	rts
;
CHECKMOVENR:
	GETMSGPTR
	move.w	Qmovenr(A1),D0
	cmp.w	HPLYNR(A4),D0
	beq.s	CHECKMOVENROK
	bgt.s	CHECKMOVENRERR
	move.w	D0,-(SP)
	bsr	EXECBACK
	move.w	(SP)+,D0
	bra.s	CHECKMOVENRN
CHECKMOVENRL:
	move.w	D0,-(SP)
	bsr	BACKMOVE
	move.w	(SP)+,D0
CHECKMOVENRN:
	cmp.w	HPLYNR(A4),D0
	blt.s	CHECKMOVENRL
CHECKMOVENROK:
	moveq	#status_OK,D0
	rts
CHECKMOVENRERR:
	moveq	#status_ERROR,D0
	rts
;
PTRDOS:
	dc.l	0
PTRFILEH:
	dc.l	0
DosName:
	dc.b	"dos.library",0
	even
NameTable:
	dc.b	"Pente:PenteTable",0
	even
StringExecTable:
	dc.b	"Pente:PenteCalcTable",0
	even
;
INITOPEN:
	move.l	PTRDOS(PC),A6
	lea	NameTable(PC),A0
	move.l	A0,D1
	move.l	#MODE_OLD,D2
	jsr	Open(A6)
	lea	PTRFILEH(PC),A0
	move.l	D0,(A0)
	rts
;
INITPROG:
	move.l	ExecBase,A6
	lea	DosName(PC),A1
	moveq	#0,D0
	jsr	OpenLib(A6)
	lea	PTRDOS(PC),A0
	move.l	D0,(A0)
	beq	INITPROGERDOS
;
	bsr	INITOPEN
	bne.s	INITPROGREAD
	move.l	PTRDOS(PC),A6
	lea	StringExecTable(PC),A0
	move.l	A0,D1
	moveq	#0,D2
	moveq	#0,D3
	jsr	Execute(A6)
	bsr	INITOPEN
	beq	INITPROGERFO
INITPROGREAD:
	move.l	#LPSN,D0
	move.l	#MEMF_CLEAR,D1
	move.l	ExecBase,A6
	jsr	AllocMem(A6)
	move.l	D0,A3
	beq	INITPROGERFO
;
	move.l	A3,A0
	adda.l	#PTable,A0
	move.l	A0,PTableC(A3)
	adda.l	#TableCLEN,A0
	move.l	A0,PTableEV(A3)
;
	move.l	PTRDOS(PC),A6
	move.l	PTRFILEH(PC),D1
	move.l	PTableC(A3),D2
	move.l	#TableLEN,D3
	jsr	Read(A6)
;
	move.l	PTRDOS(PC),A6
	move.l	PTRFILEH(PC),D1
	jsr	Close(A6)
;
	lea	PHST(A3),A4
	lea	PBRD(A3),A5
	lea	PMVS(A3),A6
;
	move.w	#BXDIM,PXDIM(A3)
	move.w	#BYDIM,PYDIM(A3)
	move.l	#BXMAX,PXMAX(A3)
	move.l	#BYMAX,PYMAX(A3)
;
	move.w	#5,PMEVLIM(A3)
	moveq	#TakeBit,D0
	moveq	#0,D1
	bset	D0,D1
	move.w	D1,PMVAL(A3)
;
	lea	DPEVPAT(PC),A0
	lea	PEVPAT(A3),A1
	moveq	#ESIZE-1,D0
INITPROGPAT:
	move.b	(A0)+,(A1)+
	dbra	D0,INITPROGPAT
;
	moveq	#black,D1	; black/white indication
	swap	D1
	move.w	#white,D1
	moveq	#0,D2		; ply count
	lea	TWGMV(PC),A0	; WTable pair of bits
	move.l	A0,D5
	lea	TBGMV(PC),A0	; BTable pair of bits
	move.l	A0,D4
	move.l	A4,A0
	moveq	#NPLY-1,D0
INITPROGHSTL:
	move.l	D1,HcolME(A0)
	swap	D1
	move.w	D2,HPLYNR(A0)
	move.w	#ZWIN,D3
	sub.w	D2,D3
	move.w	D3,HWIN(A0)
	addq.w	#1,D2
	move.l	D4,HTGMV(A0)
	exg	D4,D5
	lea	LHST(A0),A0
	dbra	D0,INITPROGHSTL
;
	lea	ZEVesc(PC),A0	; interface to interrupt-routine
	lea	RCPMIRQesc(PC),A1
	move.l	A0,(A1)
;
	movem.l	PREG0(A3),D0-D7	; clear data-registers
	movem.l	A0-A7/D0-D7,PREGS(A3)
	moveq	#status_OK,D0
	rts
;
INITPROGERFO:
	bsr	ENDPROGDOS
INITPROGERDOS:
	moveq	#status_ERROR,D0
	rts
;
ENDPROG:
ENDPROGPSN:
	move.l	A3,A1
	move.l	#LPSN,D0
	move.l	ExecBase,A6
	jsr	FreeMem(A6)
ENDPROGDOS:
	move.l	ExecBase,A6
	move.l	PTRDOS(PC),A1
	jsr	CloseLib(A6)
ENDPROGE:
	moveq	#status_OK,D0
	rts
;
CalcPort:
TC_Node_Succ:	dc.l	0
TC_Node_Pred:	dc.l	0
TC_Node_Type:	dc.b	NT_MSGPORT
TC_Node_Pri:	dc.b	0
TC_Node_Name:	dc.l	PC_name
TC_Flags:	dc.b	PA_SIGNAL
TC_sigBit:	dc.b	0
TC_SigTask:	dc.l	0
TC_lh_Head:	dc.l	0
TC_lh_Tail:	dc.l	0
TC_lh_TailPred:	dc.l	0
TC_lh_Type:	dc.b	0
TC_lh_pad:	dc.b	0
;
MIRQPort:
TM_Node_Succ:	dc.l	0
TM_Node_Pred:	dc.l	0
TM_Node_Type:	dc.b	NT_MSGPORT
TM_Node_Pri:	dc.b	0
TM_Node_Name:	dc.l	PM_name
TM_Flags:	dc.b	PA_SOFTINT
TM_sigBit:	dc.b	0
TM_SigTask:	dc.l	MIRQinterrupt
TM_lh_Head:	dc.l	0
TM_lh_Tail:	dc.l	0
TM_lh_TailPred:	dc.l	0
TM_lh_Type:	dc.b	0
TM_lh_pad:	dc.b	0
;
MIRQinterrupt:
TMi_Node_Succ:	dc.l	0
TMi_Node_Pred:	dc.l	0
TMi_Node_Type:	dc.b	NT_INTERRUPT
TMi_Node_Pri:	dc.b	16
TMi_Node_Name:	dc.l	0
TMi_Data:	dc.l	0
TMi_Code:	dc.l	RCPescape
;
DUMMY_MOVE:
	move.l	A6,HMV0(A4)
	move.w	#-1,MSQ(A6)
	clr.b	MMEV(A6)
	clr.w	MPEV0(A6)
	lea	LMOV(A6),A6
	move.l	A6,HMV2(A4)
	move.l	A6,PGMVS(A3)
	rts
;
INITGAME:
	movem.l	PREGS(A3),A0-A7/D0-D7
	move.l	A6,PGMVS(A3)
;
	move.w	#BRDR-1,PXLO1(A3)
	move.w	#BRDR-1,PYLO1(A3)
	move.w	PXDIM(A3),PXHI1(A3)
	addi.w	#BRDR,PXHI1(A3)
	move.w	PYDIM(A3),PYHI1(A3)
	addi.w	#BRDR,PYHI1(A3)

	move.l	PXMAX(A3),D3
	lea	DIRS(PC),A0	; fill DIRS
	moveq	#1,D0
	move.w	D0,(A0)+
	add.w	D3,D0
	move.w	D0,(A0)+
	subq.w	#1,D0
	move.w	D0,(A0)+
	subq.w	#1,D0
	move.w	D0,(A0)+
	moveq	#-1,D0
	move.w	D0,(A0)+
	sub.w	D3,D0
	move.w	D0,(A0)+
	addq.w	#1,D0
	move.w	D0,(A0)+
	addq.w	#1,D0
	move.w	D0,(A0)+
	clr.w	(A0)
;
	bsr	INITBRD
	move.l	PGMVS(A3),A6
	bsr	DUMMY_MOVE
;
	moveq	#status_OK,D0
INITGAMEE:
	rts
;
INITMOVE:
	lea	LHST(A4),A4	; increment A4
	tst.w	PRDC(A3)
	beq.s	INITMOVEBA	; skip RDC ?
	bsr	RDCSIZE		; also determines start RDCboard
	bsr	INRDC
	bra.s	INITMOVERDC
INITMOVEBA:
	move.w	#BRDR,RXLO(A3)
	move.w	#BRDR,RYLO(A3)
	move.w	PXDIM(A3),RXDIM(A3)
	move.w	PYDIM(A3),RYDIM(A3)
	bsr	BRDADDS
INITMOVERDC:
	lea	RCPMIRQA4(PC),A0	; interface to interrupt-routine
	move.l	A4,(A0)
;
	move.l	A4,A0		; fill History with Pointers
	move.w	#NPLY-1,D7
	sub.w	HPLYNR(A0),D7	; Maximum available moves
;
	move.l	RWEVBRD(A3),D0
	move.l	RBEVBRD(A3),D1
	cmpi.w	#white,HcolME(A0)
	beq.s	INITMOVEHSTL
	exg	D0,D1
INITMOVEHSTL:
	move.l	D0,HWEVBRD(A0)
	move.l	D1,HBEVBRD(A0)
	exg	D0,D1
	lea	LHST(A0),A0
	dbra	D7,INITMOVEHSTL
;
	move.l	A4,A2	; initialize recipes
	lea	ZRCPcode(PC),A0
	lea	ZRCPSR(PC),A1
	moveq	#TakeBit,D0
	moveq	#0,D1
	bset	D0,D1
	lsr.l	#1,D1
	move.w	D1,PESC(A3)
	moveq	#0,D0
INITMOVESRL:
	move.b	(A0)+,D0
	move.l	0(A1,D0.w),HRCP(A2)
	move.l	JEVQSmax(A1,D0.w),D1
	move.b	D1,HTQS(A2)
	lea	LHST(A2),A2
	neg.w	PESC(A3)
	tst.b	D0
	bgt.s	INITMOVESRL
	clr.l	HRCP(A2)	; stop-indication for MIRQ
;
	move.w	HcolME(A4),D4
	move.w	HcolOP(A4),D5
	move.w	#ZAEVI,HAEV(A4)
	move.w	#ZBEVI,HBEV(A4)
	move.l	RPBRD(A3),A5
	move.l	HMV0-LHST(A4),A6	; previous move
	rts
;
SOXPEVM: macro
	movem.l	A0-A4/D0-D6,-(SP)
	lea	?1(PC),A4
	bsr	SOMOV
	movem.l	(SP)+,A0-A4/D0-D6
	endm
;
MRECIPE: macro
	move.l	HRCP(A4),A0
	jsr	(A0)
	endm
;
CALCMOVE:
	moveq	#0,D0
	MRECIPE
	move.l	HMV0(A4),A0
	move.l	HMV2(A4),D6
	sub.l	A0,D6
	lsr.w	#3,D6
	SOXPEVM	SEWPEV
	bsr	RNDMOVE
	rts
;
RNDMOVE:
	move.l	HMV0(A4),A0	; search equivalent moves
	move.w	MPEV(A0),D0
RNDMOVEL:
	cmp.w	MPEV(A0),D0
	bne.s	RNDMOVER
	lea	LMOV(A0),A0
	cmpa.l	HMV2(A4),A0
	bne.s	RNDMOVEL
RNDMOVER:
	lea	RNDSEED(PC),A1	; update seed
	move.w	(A1),D1
	mulu	#141,D1
	addi.w	#1357,D1
	move.w	D1,(A1)
	move.l	A0,D0		; calculate move
	sub.l	HMV0(A4),D0
	lsr.l	#3,D0
	mulu	D1,D0
	swap	D0
	andi.l	#$FFFF,D0
	lsl.w	#3,D0
	move.l	HMV0(A4),A0
	movem.l	(A0),D1-D2
	move.l	0(A0,D0.w),(A0)
	move.l	4(A0,D0.w),4(A0)
	movem.l	D1-D2,0(A0,D0.w)
	rts
RNDSEED:
	dc.w	12345
;
DOMOVE:	; execute entered move, first call INITMOVE
;
	move.l	PGMVS(A3),HMV0(A4)
	cmpi.w	#1,HPLYNR(A4)	; check first move
	bne.s	DOMOVEOK
	move.w	PYDIM(A3),D0
	lsr.w	#1,D0
	cmp.w	PROW(A3),D0
	bne	DOMOVEERR
	move.w	PXDIM(A3),D0
	lsr.w	#1,D0
	cmp.w	PCOL(A3),D0
	bne	DOMOVEERR
DOMOVEOK:
	move.w	PROW(A3),D7	; calculate position according to
	addq.w	#BRDR,D7	; reduced boards
	sub.w	RYLO(A3),D7
	mulu	D3,D7
	add.w	PCOL(A3),D7
	addq.w	#BRDR,D7
	sub.w	RXLO(A3),D7
	tst.b	0(A5,D7.w)
	bne.s	DOMOVEERR
;
	move.b	#EVCall,PTQS(A3)
	clr.w	HPEV(A4)
	move.b	MMEV(A6),HBMEV(A4)	; from previous move
	move.b	HBMEV-LHST(A4),HWMEV(A4)
	move.l	HMV0(A4),A6
;
	move.w	REBRD(A3),-(SP)	; adjust end of board
	move.w	D7,REBRD(A3)	; D7 is generated firstly
	bsr	GMVS
	move.w	(SP)+,REBRD(A3)	; restore end of board
;
	tst.b	D0		; check WIN
	bpl.s	DOMOVENOW	; branch when NO WIN
	move.w	HWIN(A4),D0	; update MPEV0 with WIN evaluation
	move.w	D0,MPEV0-LMOV(A6)
DOMOVENOW:
	move.l	HMV0(A4),A6
	move.w	MPEV0(A6),MPEV(A6)
	lea	LMOV(A6),A6
	move.l	A6,HMV2(A4)
	move.l	A6,PGMVS(A3)
	moveq	#status_OK,D0
	rts
;
DOMOVEERR:
	moveq	#status_ERROR,D0
	rts
;
EXECMOVE:
	tst.w	PRDC(A3)
	beq.s	EXECMOVERDC	; skip RDC ?
	bsr	INUNRDC
	bsr	UNRDC
EXECMOVERDC:
	move.l	HMV0(A4),A6
	move.w	MPEV0(A6),HPEV0(A4)	; game-history
	move.w	MPEV(A6),HPEV1(A4)	; game-history
	move.w	MPEV(A6),MPEV0(A6)	; easy overview only
	clr.w	MPEV(A6)		; reset MPEV/MTQS
	bsr	EFMV
	lea	LMOV(A6),A6		; A6 points to new move
	move.l	A6,PGMVS(A3)
	rts
;
BACKMOVE:
	lea	PBRD(A3),A5	; restore board addresses
	adda.l	HSBRD(A4),A5
EXECBACK:
	move.w	HcolME(A4),D4
	move.w	HcolOP(A4),D5
	move.l	HMV0(A4),A6
	bsr	EBMV
	move.l	A6,PGMVS(A3)
	lea	-LHST(A4),A4
	rts
;
DOEMOVE:
	move.w	#0,PRDC(A3)	; reduce not
	bsr	INITMOVE
	bsr	DOMOVE
	cmpi.w	#status_OK,D0
	bne.s	DOEMOVEERR
	bsr	EXECMOVE
	moveq	#status_OK,D0
	rts
DOEMOVEERR:
	tst.w	PRDC(A3)
	beq.s	DOEMOVERDC	; skip RDC ?
	bsr	INUNRDC
	bsr	UNRDC
DOEMOVERDC:
	move.l	HMV0(A4),PGMVS(A3)
	lea	-LHST(A4),A4
	rts
;
INITBRD:
	moveq	#empsq,D0
	move.w	D3,D7
	mulu	D7,D7
	subq.w	#1,D7
;
	lea	WHEVBRD(A3),A0
	move.w	D7,D6
	moveq	#0,D0
INITBRDLW:
	move.b	D0,(A0)+
	dbra	D6,INITBRDLW
;
	lea	BLEVBRD(A3),A0
	move.w	D7,D6
INITBRDLB:
	move.b	D0,(A0)+
	dbra	D6,INITBRDLB
;
	lea	PBRD(A3),A0
	move.w	D7,D6
INITBRDL:
	move.b	D0,(A0)+
	dbra	D6,INITBRDL
	bsr	INITBRDR
;
	rts
;
RDCSIZE:	; reduce size of board by 2 rows out of convex hull
		; fill arrays PXA and PYA with #1 when stone encountered
	movem.l	D0-D7/A0,-(SP)
	moveq	#0,D0
;
	move.w	PXHI1(A3),D6		; initialize array PXA
	move.b	#brdrsq,PXA(A3,D6.w)	; brdrsq<>0
	subq.w	#1,D6
RDCSIZEX0:
	move.b	D0,PXA(A3,D6.w)
	dbra	D6,RDCSIZEX0
	move.w	PXLO1(A3),D6
	move.b	#brdrsq,PXA(A3,D6.w)
;
	move.w	PYHI1(A3),D6	; initialize array PYA
	move.b	#brdrsq,PYA(A3,D6.w)
	subq.w	#1,D6
RDCSIZEY0:
	move.b	D0,PYA(A3,D6.w)
	dbra	D6,RDCSIZEY0
	move.w	PYLO1(A3),D6
	move.b	#brdrsq,PYA(A3,D6.w)
;
	lea	PBRD(A3),A0
	adda.l	D3,A0
	adda.l	D3,A0
	adda.l	D3,A0
	moveq	#BRDR,D5	; Y-index
	move.w	PYDIM(A3),D7
	subq.w	#1,D7
RDCSIZEYL:
	move.w	PXHI1(A3),D6	; X-index
	subq.w	#1,D6
RDCSIZEXL:
	tst.b	0(A0,D6.w)
	beq.s	RDCSIZEXN	; skip empty square
	bmi.s	RDCSIZEXN	; skip border square
	ori.b	#1,PXA(A3,D6.w)
	ori.b	#1,PYA(A3,D5.w)
RDCSIZEXN:
	dbra	D6,RDCSIZEXL
	adda.l	D3,A0
	addq.w	#1,D5
	dbra	D7,RDCSIZEYL
;
	move.w	PXHI1(A3),D6	; determine XHI
	lea	PXA(A3,D6),A0
RDCSIZEXHIL:
	subq.w	#1,D6
	tst.b	-(A0)
	beq.s	RDCSIZEXHIL
	cmp.w	PXLO1(A3),D6
	bgt.s	RDCSIZEXHI2
	move.w	D3,D6
	lsr.w	#1,D6
RDCSIZEXHI2:
	move.w	D6,RXHI2(A3)
	addq.w	#RBRDR+1,D6
	cmp.w	PXHI1(A3),D6
	ble.s	RDCSIZEXHI1
	move.w	PXHI1(A3),D6
RDCSIZEXHI1:
	move.w	D6,RXHI1(A3)
	subq.w	#1,D6
	move.w	D6,RXHI(A3)
;
	moveq	#1,D6	; determine XLO
	add.w	PXLO1(A3),D6
	lea	PXA(A3,D6),A0
	bra.s	RDCSIZEXLON
RDCSIZEXLOL:
	addq.w	#1,D6
RDCSIZEXLON:
	tst.b	(A0)+
	beq.s	RDCSIZEXLOL
	cmp.w	PXHI1(A3),D6
	blt.s	RDCSIZEXLO2
	move.w	D3,D6
	lsr.w	#1,D6
RDCSIZEXLO2:
	move.w	D6,RXLO2(A3)
	subq.w	#RBRDR+1,D6
	cmp.w	PXLO1(A3),D6
	bge.s	RDCSIZEXLO1
	move.w	PXLO1(A3),D6
RDCSIZEXLO1:
	move.w	D6,RXLO1(A3)
	addq.w	#1,D6
	move.w	D6,RXLO(A3)
;
	move.w	RXHI1(A3),D6
	sub.w	RXLO(A3),D6
	move.w	D6,RXDIM(A3)
;
	move.w	PYHI1(A3),D6	; determine YHI
	lea	PYA(A3,D6),A0
RDCSIZEYHIL:
	subq.w	#1,D6
	tst.b	-(A0)
	beq.s	RDCSIZEYHIL
	cmp.w	PYLO1(A3),D6
	bgt.s	RDCSIZEYHI2
	move.w	PYMAX+2(A3),D6
	lsr.w	#1,D6
RDCSIZEYHI2:
	move.w	D6,RYHI2(A3)
	addq.w	#RBRDR+1,D6
	cmp.w	PYHI1(A3),D6
	ble.s	RDCSIZEYHI1
	move.w	PYHI1(A3),D6
RDCSIZEYHI1:
	move.w	D6,RYHI1(A3)
	subq.w	#1,D6
	move.w	D6,RYHI(A3)
;
	moveq	#1,D6	; determine YLO
	add.w	PYLO1(A3),D6
	lea	PYA(A3,D6),A0
	bra.s	RDCSIZEYLON
RDCSIZEYLOL:
	addq.w	#1,D6
RDCSIZEYLON:
	tst.b	(A0)+
	beq.s	RDCSIZEYLOL
	cmp.w	PYHI1(A3),D6
	blt.s	RDCSIZEYLO2
	move.w	PYMAX+2(A3),D6
	lsr.w	#1,D6
RDCSIZEYLO2:
	move.w	D6,RYLO2(A3)
	subq.w	#RBRDR+1,D6
	cmp.w	PYLO1(A3),D6
	bge.s	RDCSIZEYLO1
	move.w	PYLO1(A3),D6
RDCSIZEYLO1:
	move.w	D6,RYLO1(A3)
	addq.w	#1,D6
	move.w	D6,RYLO(A3)
;
	move.w	RYHI1(A3),D6
	sub.w	RYLO(A3),D6
	move.w	D6,RYDIM(A3)
;
	bsr	BRDADDS
	moveq	#rdcsq,D0
	bsr	RDC
;
	movem.l	(SP)+,D0-D7/A0
	rts
;
BRDADDS:	; calculate board addresses
;
	move.w	RYDIM(A3),D0	; calculate size of reduced boards
	subq.w	#1,D0
	mulu	D3,D0
	add.w	RXDIM(A3),D0
	subq.w	#1,D0
	move.w	D0,REBRD(A3)
	move.w	RYLO(A3),D0	; calculate begin of boards
	mulu	D3,D0
	add.w	RXLO(A3),D0
	move.l	D0,HSBRD(A4)
	lea	WHEVBRD(A3),A0
	adda.l	D0,A0
	move.l	A0,RWEVBRD(A3)
	lea	BLEVBRD(A3),A0
	adda.l	D0,A0
	move.l	A0,RBEVBRD(A3)
	lea	PBRD(A3),A0
	adda.l	D0,A0
	move.l	A0,RPBRD(A3)
	rts
;
BRDRFILL:
	move.b	D0,(A0)
	rts
;
RDC:	; fill reduced border with rdcsq's
	moveq	#rdcsq,D0
	lea	BRDRFILL(PC),A6
RDCGO:
	movem.l	D4-D5,-(SP)
	move.l	RPBRD(A3),A0
	suba.l	D3,A0
	tst.b	-(A0)		; now A0 points to RXLO1,RYLO1
	move.w	RXDIM(A3),D4
	move.w	RYDIM(A3),D5
	bsr	JBRDR
	movem.l	(SP)+,D4-D5
	rts
;
UNRDC:	; fill reduced border with empsq's
	moveq	#empsq,D0
	lea	BRDRFILL(PC),A6
	bsr	RDCGO
INITBRDR:
	moveq	#brdrsq,D0
	lea	BRDRFILL(PC),A6
;
	movem.l	D4-D5,-(SP)
	move.w	PYLO1(A3),D6
	mulu	D3,D6
	add.w	PXLO1(A3),D6
	lea	PBRD(A3),A0
	adda.w	D6,A0
	move.w	PXDIM(A3),D4
	move.w	PYDIM(A3),D5
	bsr	JBRDR
	movem.l	(SP)+,D4-D5
	rts
;
INRDCJ:	; Inner reduce subroutine
;
	lea	-RBRDR(A0),A1
	suba.l	D3,A1		; RBRDR times
	suba.l	D3,A1
	moveq	#2*RBRDR,D1
INRDCJYL:
	moveq	#2*RBRDR,D2
INRDCJXL:
	tst.b	0(A1,D2.w)
	beq.s	INRDCJXN	; check empty square
	bpl.s	INRDCJF		; check stone at square
INRDCJXN:
	dbra	D2,INRDCJXL
	adda.l	D3,A1
	dbra	D1,INRDCJYL
	move.b	D0,(A0)
INRDCJF:
	rts
;
INUNRDCJ: ; Inner unreduce subroutine
;
	tst.b	(A0)
	bpl.s	INUNRDCJE	; test empty square or stone
	move.b	D0,(A0)	; empsq
INUNRDCJE:
	rts
;
INUNRDC: ; Inner unreduce
;
	moveq	#empsq,D0
	lea	INUNRDCJ(PC),A6
	bra.s	INRDCGO
;
INRDC:	; Inner reduce
;
	moveq	#rdcsq,D0
	lea	INRDCJ(PC),A6
INRDCGO:
	movem.l	D4-D5,-(SP)
	move.l	RPBRD(A3),A0
	move.w	RXDIM(A3),D4
	subq.w	#2,D4
	move.w	RYDIM(A3),D5
	subq.w	#2,D5
	move.l	A0,-(SP)	; save for next inner rectangle
	bsr	JBRDR
	move.l	(SP)+,A0
	lea	1(A0,D3.w),A0	; address of next inner rectangle
	subq.w	#2,D4
	subq.w	#2,D5
	bsr	JBRDR
;
	move.w	REBRD(A3),D7	; calculate negative jump values
	move.l	RPBRD(A3),A5
	move.l	A5,A0
	lea	0(A0,D7.w),A0	; A0 points to RXHI,RYHI
	suba.w	RXDIM(A3),A0	; A0 points to RXLO1,RYHI
;
	move.w	RYDIM(A3),D2
	subq.w	#1,D2
INRDCYL:
	move.w	RXDIM(A3),D1
INRDCXL:
	tst.b	0(A0,D1.w)
	bpl.s	INRDCXN
	move.w	D7,D6		; rdcsq found
	bra.s	INRDCRXN
INRDCRYL:
	move.w	RXDIM(A3),D1
INRDCRXL:
	tst.b	0(A0,D1.w)
	bpl.s	INRDCRF
INRDCRXN:
	subq.w	#1,D7
	dbra	D1,INRDCRXL
;
	suba.l	D3,A0
	addq.w	#1,D7		; D1-loop takes RXDIM+1
	add.w	RXDIM(A3),D7
	sub.w	D3,D7
	dbra	D2,INRDCRYL
INRDCRF:
	move.w	D7,D0
	sub.w	D6,D0
	move.b	D0,0(A5,D6.w)
	tst.w	D7
	bmi.s	INRDCE
INRDCXN:
	subq.w	#1,D7
	dbra	D1,INRDCXL
;
	suba.l	D3,A0
	addq.w	#1,D7		; D1-loop takes RXDIM+1
	add.w	RXDIM(A3),D7
	sub.w	D3,D7
	dbra	D2,INRDCYL
INRDCE:
	movem.l	(SP)+,D4-D5
	rts
;
JBRDR:	; general subroutine for border
;			; sequence of filling :
; input registers:	; 1 1 -> 1 2
; D3 : PXMAX		; 3        2
; D4 : Xdim		; 3        |
; D5 : Ydim		; |        V
; A0 : start-address	; V        2
; A6 : subroutine	; 3 4 4 -> 4
;
	move.l	A0,-(SP)
	move.w	D4,D6
JBRDRYLOXL:
	jsr	(A6)
	tst.b	(A0)+
	dbra	D6,JBRDRYLOXL
;
	move.w	D5,D6
JBRDRXHIYL:
	jsr	(A6)
	adda.l	D3,A0
	dbra	D6,JBRDRXHIYL
;
	move.l	(SP)+,A0
	move.w	D5,D6
JBRDRXLOYL:
	adda.l	D3,A0
	jsr	(A6)
	dbra	D6,JBRDRXLOYL
;
	move.w	D4,D6
	tst.b	(A0)+
JBRDRYHIXL:
	jsr	(A6)
	tst.b	(A0)+
	dbra	D6,JBRDRYHIXL
	rts
;
MWR:	macro	; parameters label_empty,label_stop/border,label_black
	add.w	D0,D6
	move.b	0(A5,D6.w),D2
	beq	?1
	bmi	?2
	cmp.b	D4,D2
	bne	?3
	endm
;
MWRE:	macro	; parameters label_empty/border,label_black
	add.w	D0,D6
	move.b	0(A5,D6.w),D2
	ble	?1
	cmp.b	D4,D2
	bne	?2
	endm
;
MWRW:	macro	; parameter label_stop
	add.w	D0,D6
	cmp.b	0(A5,D6.w),D4
	bne	?1
	endm
;
MWRB:	macro	; parameter label_stop
	add.w	D0,D6
	cmp.b	0(A5,D6.w),D5
	bne	?1
	endm
;
MWL:	macro	; parameters label_empty,label_stop/border,label_black
	sub.w	D0,D6
	move.b	0(A5,D6.w),D2
	beq	?1
	bmi	?2
	cmp.b	D4,D2
	bne	?3
	endm
;
MWLE:	macro	; parameters label_empty/border,label_black
	sub.w	D0,D6
	move.b	0(A5,D6.w),D2
	ble	?1
	cmp.b	D4,D2
	bne	?2
	endm
;
MWLW:	macro	; parameter label_stop
	sub.w	D0,D6
	cmp.b	0(A5,D6.w),D4
	bne	?1
	endm
;
MWLB:	macro	; parameter label_stop
	sub.w	D0,D6
	cmp.b	0(A5,D6.w),D5
	bne	?1
	endm
;
QS_WIN:	macro
	moveq	#-1,D0
	rts
	endm
;
QS_tkr: macro	; parameter label_stop
	addq.b	#1,MMEV(A6)
	add.w	D3,MPEV0(A6)
	bset	D1,MTK(A6)
	ori.b	#EVCtkr,MTQS(A6)
	bra	?1
	endm
;
QS_tkl: macro	; parameter label_stop
	addq.b	#1,MMEV(A6)
	add.w	D3,MPEV0(A6)
	subq.w	#4,D1
	bset	D1,MTK(A6)
	addq.w	#4,D1
	ori.b	#EVCtkl,MTQS(A6)
	bra	?1
	endm
;
QS_5t: macro	; parameter label_stop
	ori.b	#EVC5t,MTQS(A6)
	bra	?1
	endm
;
QS_5dt: macro	; parameter label_stop
	ori.b	#EVC5t,MTQS(A6)
	bra	?1
	endm
;
QS_5s: macro	; parameter label_stop
	ori.b	#EVC5s,MTQS(A6)
	bra	?1
	endm
;
QS_tkt: macro	; parameter label_stop
	ori.b	#EVCtkt,MTQS(A6)
	bra	?1
	endm
;
QS_tks: macro	; parameter label_stop
	ori.b	#EVCtks,MTQS(A6)
	bra	?1
	endm
;
QSstart:
; D0 : direction increment
; D1 : direction bit
; D2 : temporary square contents
; D3 : positional evaluation bonus
; D4 : player's color
; D5 : opponent's color
; D6 : temporary square
; D7 : square of move
;
	move.w	D7,D6
rQS____:	MWR	rQSe___, l____QS,    rQSb___
rQSw___:	MWR	rQSwe__, l____QSw,   l____QSw
rQSww__:	MWR	rQSwwe_, l____QSww,  rQSwwb
rQSwww_:	MWR	rQSwwwe, l____QSwww, l____QSwww
rQSwwww:	QS_WIN
;
rQSe___:	MWRW	l____QSe
rQSew__:	MWRW	l____QSew
rQSeww_:	MWRW	l____QSeww
rQSewww:	QS_5t	l____QS
;
rQSb___:	MWRB	l____QSb
rQSbb__:	MWR	rQSbbe, l____QSbb, rQSbbb_
rQSbbw:		QS_tkr	l____QSbb
;
rQSbbe:		QS_tkt	l____QSbb
;
rQSbbb_:	MWRB	l____QSbbb
rQSbbbb:	QS_5s	l____QS
;
rQSwe__:	MWRW	l____QSwe
rQSwew_:	MWRW	l____QSwew
rQSweww:	QS_5t	l____QSw
;
rQSwwe_:	MWRW	l____QSwwe
rQSwwew:	QS_5t	l____QSww
;
rQSwwb:		QS_tks	l____QSww
;
rQSwwwe:	QS_5t	l____QSwww
;
l____QS:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQS
l___wQS:	MWL	l__ewQS, QSend, QSend
l__wwQS:	MWL	l_ewwQS, QSend, lbwwQS
l_wwwQS:	MWL	lewwwQS, QSend, QSend
lwwwwQS:	QS_WIN
;
l___bQS:	MWLB	QSend
l__bbQS:	MWL	lebbQS, QSend, l_bbbQS
l_wbbQS:	QS_tkl	QSend
;
l_bbbQS:	MWLB	QSend
lbbbbQS:	QS_5s	QSend
;
lebbQS:		QS_tkt	QSend
;
lbwwQS:		QS_tks	QSend
;
l____QSw:	move.w	D7,D6
		MWL	l___eQSw, QSend, l___bQS
l___wQSw:	MWL	l__ewQSw, QSend, QSend
l__wwQSw:	MWL	lewwQSw,  QSend, lbwwQS
lwwwQSw:	QS_WIN
;
l___eQS:	MWLW	QSend
l__ewQS:
l__weQS:
l___eQSw:	MWLW	QSend
l_ewwQS:
l_wewQS:
l_wweQS:
l__ewQSw:
l__weQSw:
l___eQSww:	MWLW	QSend
lewwwQS:
lwwweQS:
lwwwQSe:
lewwQSw:
lwewQSw:
lwweQSw:
lewQSww:
lwwQSew:
lwwQSwe:
leQSwww:
lwQSwwe:
lwQSwew:
lwQSeww:	QS_5t	QSend
;
l____QSe:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQS
l___wQSe:	MWL	l__ewQS, QSend, QSend
l__wwQSe:	MWL	l_ewwQS, QSend, lbwwQS
l_wwwQSe:	QS_5t	l_wwwQS
;
l____QSww:	move.w	D7,D6
		MWL	l___eQSww, QSend, l___bQS
l___wQSww:	MWL	lewQSww,   QSend, QSend
lwwQSww:	QS_WIN
;
l____QSwe:	move.w	D7,D6
		MWL	l___eQSw, QSend,  l___bQS
l___wQSwe:	MWL	l__ewQSw, QSend,  QSend
l__wwQSwe:	QS_5t	l__wwQSw
;
l____QSew:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQS
l___wQSew:	MWL	l__ewQS, QSend, QSend
l__wwQSew:	QS_5t	l__wwQS
;
l____QSwww:	move.w	D7,D6
		MWL	leQSwww, QSend, l___bQS
lwQSwww:	QS_WIN
;
l____QSwwe:	move.w	D7,D6
		MWL	l___eQS,  QSend, l___bQS
l___wQSwwe:	QS_5t	l___wQSww
;
l____QSwew:	move.w	D7,D6
		MWL	l___eQSw, QSend, l___bQS
l___wQSwew:	QS_5t	l___wQSw
;
l____QSeww:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQS
l___wQSeww:	QS_5t	l___wQS
;
l____QSb:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQSb
l___wQSb:	bra	l___wQS
;
l___bQSb:	MWLB	QSend
l__bbQSb:	MWL	lebbQS, QSend, lbbbQSb
lwbbQSb:	QS_tkl	QSend
;
lbQSbbb:
lbbQSbb:
lbbbQSb:	QS_5s	QSend
;
l____QSbb:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQSbb
l___wQSbb:	bra	l___wQS
;
l___bQSbb:	MWLB	QSend
l__bbQSbb:	QS_5s	l__bbQS
;
l____QSbbb:	move.w	D7,D6
		MWL	l___eQS, QSend, l___bQSbbb
l___wQSbbb:	bra	l___wQS
;
l___bQSbbb:	QS_5s	l___bQS
;
QSend:	moveq	#0,D0
	rts
;
GQS:	; generate takes and threats
; D0 : scratch, return 0=noWIN, -1=WIN
; D1 : scratch
; D2 : temporary, original value destroyed
; D3 : original value restored
; D4 : my color
; D5 : opponent color
;
	move.l	D3,-(SP)
	clr.b	PIQS(A3)	; clear integral QS-code
	move.w	PMVAL(A3),D3
	move.w	REBRD(A3),D7
GQSL:
	move.b	0(A5,D7.w),D0
	beq.s	GQSM
	bpl.s	GQSN
	ext.w	D0
	add.w	D0,D7
	bpl.s	GQSL
	bmi.s	GQSEL
GQSM:
	move.w	D7,MSQ(A6)
	move.w	HPEV(A4),MPEV0(A6)
	move.b	HWMEV(A4),MMEV(A6)
;
	move.b	#EVCn,MTQS(A6)	; indicates normal move
	moveq	#4,D1
	clr.b	MTK(A6)
	lea	DIRS+8(PC),A0
	move.w	(A0)+,D0
GQSML:
	bsr	QSstart
	bmi.s	QQWIN
	addq.w	#1,D1
	move.w	(A0)+,D0
	bne.s	GQSML
;
	move.b	MTQS(A6),D0	; pattern of realised move
	and.b	PTQS(A3),D0	; pattern of allowed moves
	beq.s	GQSN
	or.b	D0,PIQS(A3)	; add possibly EVC5s-code
	move.b	MMEV(A6),D0
	cmp.b	PMEVLIM+1(A3),D0
	bge.s	QQWIN
GQSC:
	lea	LMOV(A6),A6
GQSN:
	dbra	D7,GQSL
GQSEL:
	move.l	(SP)+,D3
	moveq	#0,D0
	rts
;
QQWIN:	lea	LMOV(A6),A6
	move.l	(SP)+,D3
	moveq	#-1,D0
	rts
;		    white-code        black-code
	dc.w	%0000000000000000,%0000000000000000	; - 80, $00
	dc.w	%0000000000000000,%0000000000000000	; - 76, $04
	dc.w	%0000000000000000,%0000000000000000	; - 72, $08
	dc.w	%0000000000000000,%0000000000000000	; - 68, $0C
	dc.w	%0000000000000000,%0000000000000000	; - 64, $10
	dc.w	%0000000000000000,%0000000000000000	; - 60, $14
	dc.w	%0000000000000000,%0000000000000000	; - 56, $18
	dc.w	%0000000000000000,%0000000000000000	; - 52, $1C
	dc.w	0,0,0,0,0,0,0,0				; - 48, $20
	dc.w	%0000000001000000,%0000000010000000	; - 32, $30
	dc.w	%0000000010000000,%0000000001000000	; - 28, $34
	dc.w	%0000000000010000,%0000000000100000	; - 24, $38
	dc.w	%0000000000100000,%0000000000010000	; - 20, $3C
	dc.w	%0000000000000100,%0000000000001000	; - 16, $40
	dc.w	%0000000000001000,%0000000000000100	; - 12, $44
	dc.w	%0000000000000001,%0000000000000010	; -  8, $48
	dc.w	%0000000000000010,%0000000000000001	; -  4, $4C
TWGMV:	dc.w	%0000000000000000			; +  0, $50
TBGMV:	dc.w	%0000000000000000			; +  2, $02
	dc.w	%0000000000000000,%0000000000000000	; +  4, $04
	dc.w	%0000000000000000,%0000000000000000	; +  8, $08
	dc.w	%0000000000000000,%0000000000000000	; + 12, $0C
	dc.w	%0000000000000000,%0000000000000000	; + 16, $10
	dc.w	%0000000000000000,%0000000000000000	; + 20, $14
	dc.w	%0000000000000000,%0000000000000000	; + 24, $18
	dc.w	%0000000000000000,%0000000000000000	; + 28, $1C
	dc.w	0,0,0,0,0,0,0,0				; + 32, $20
	dc.w	%0000000100000000,%0000001000000000	; + 48, $30
	dc.w	%0000001000000000,%0000000100000000	; + 52, $34
	dc.w	%0000010000000000,%0000100000000000	; + 56, $38
	dc.w	%0000100000000000,%0000010000000000	; + 60, $3C
	dc.w	%0001000000000000,%0010000000000000	; + 64, $40
	dc.w	%0010000000000000,%0001000000000000	; + 68, $44
	dc.w	%0100000000000000,%1000000000000000	; + 72, $48
	dc.w	%1000000000000000,%0100000000000000	; + 76, $4C
;
MGMVR:	macro	; parameter end-code,displacement
	add.w	D0,D6
	move.b	0(A5,D6.w),D2
	bpl.s	MGMVR?0
	ori.w	#?1,D3
	bra.s	GMVLT
MGMVR?0:
	or.w	?2(A0,D2.w),D3
	endm
;
MGMVL:	macro	; parameter end-code,displacement
	sub.w	D0,D6
	move.b	0(A5,D6.w),D2
	bpl.s	MGMVL?0
	ori.w	#?1,D3
	bra.s	GMVE
MGMVL?0:
	or.w	?2(A0,D2.w),D3
	endm
;
GMVS:
;	assumption : A3 : PSN
;		     A4 : HST, PGMV
;		     A5 : BRD
;		     A6 : MOVS
;		     D7 : stone square
;	usage	     A0 : DIRS
;		     A1 : WEVBRD, TableC
;		     A2 : BEVBRD, TableEV
;		     D0 : scratch, return 0=noWIN, 1=WIN
;		     D1 : scratch
;		     D4 : MY color
;		     D5 : OPPONENT color
;
	move.l	D3,-(SP)	; high-byte = 0
	clr.b	PIQS(A3)	; clear integral QS-code
	move.w	REBRD(A3),D7
GMVSL:
	move.b	0(A5,D7.w),D0
	beq.s	GMVSM
	bpl	GMVSN
	ext.w	D0
	add.w	D0,D7
	bpl.s	GMVSL
	bmi	GMVSEL
GMVSM:
	move.w	D7,MSQ(A6)
	move.b	#EVCn,MTQS(A6)
	clr.b	MTK(A6)
	move.b	HWMEV(A4),MMEV(A6)
;
	movem.l	HWEVBRD(A4),A1/A2	; HWEVBRD/HBEVBRD
	move.w	HPEV(A4),D2
	moveq	#0,D3
	move.b	0(A1,D7.w),D3
	add.w	D3,D2
	move.b	0(A2,D7.w),D3
	add.w	D3,D2
	move.w	D2,MPEV0(A6)
;
	move.l	HTGMV(A4),A0		; TXGMV
	movem.l	PTableC(A3),A1/A2	; TableC/TableEV
	move.l	A4,-(SP)
;
	moveq	#0,D2		; temp. neighbour
				; note high-byte(D2)==0!!!
	moveq	#4,D1		; direction-index
	lea	DIRS+8(PC),A4
	move.w	(A4)+,D0
GMVL:
GMVRT:
	moveq	#0,D3		; build neighbour-pattern
	move.w	D7,D6
	MGMVR	%0000000011111111, -80
	MGMVR	%0000000000111111, -72
	MGMVR	%0000000000001111, -64
	MGMVR	%0000000000000011, -56
GMVLT:
	move.w	D7,D6
	MGMVL	%1111111100000000, 0
	MGMVL	%1111110000000000, 8
	MGMVL	%1111000000000000, 16
	MGMVL	%1100000000000000, 24
GMVE:
	move.b	0(A1,D3.l),D2
	bmi.s	GMVSW
	or.b	D2,MTQS(A6)
GMVtkr:
	lsr.b	#1,D2
	bcc.s	GMVtkl
	bset	D1,MTK(A6)
	addq.b	#1,MMEV(A6)
GMVtkl:
	lsr.b	#1,D2
	bcc.s	GMVEV
	subq.b	#4,D1
	bset	D1,MTK(A6)
	addq.b	#4,D1
	addq.b	#1,MMEV(A6)
GMVEV:
	add.l	D3,D3
	move.w	0(A2,D3.l),D3
	add.w	D3,MPEV0(A6)
GMVN:
	addq.w	#1,D1
	move.w	(A4)+,D0
	bne	GMVL
;
	move.l	(SP)+,A4	; restore A4
	move.b	PTQS(A3),D0	; pattern of allowed moves
	and.b	MTQS(A6),D0	; pattern of realised move
	beq.s	GMVSN
;
	or.b	D0,PIQS(A3)	; add possibly EVC5s-code
	move.b	MMEV(A6),D0
	cmp.b	PMEVLIM+1(A3),D0
	bge.s	GMVSWM
;
	lea	LMOV(A6),A6
GMVSN:
	dbra	D7,GMVSL
GMVSEL:
	move.l	(SP)+,D3
	moveq	#0,D0
	rts
;
GMVSW:	move.l	(SP)+,A4		; restore A4
GMVSWM:	lea	LMOV(A6),A6
	move.l	(SP)+,D3
	moveq	#-1,D0
	rts
;
; adjust PEV boards by additions
;
EBBEVBRD:
	move.l	HBEVBRD(A4),A1
	lea	-BRDR(A1,D6.w),A1
	bra.s	EBBEVBRDFW
EFWEVBRD:
	move.l	HWEVBRD(A4),A1
	lea	-BRDR(A1,D7.w),A1
EBBEVBRDFW:
	suba.l	D3,A1
	suba.l	D3,A1
	suba.l	D3,A1
	lea	PEVPAT(A3),A2
	moveq	#0,D2
	moveq	#2*BRDR,D1
EFWEVBRDL1:
	moveq	#2*BRDR,D0
EFWEVBRDL0:
	move.b	(A2)+,D2
	add.b	D2,0(A1,D0.w)
	dbra	D0,EFWEVBRDL0
	adda.l	D3,A1
	dbra	D1,EFWEVBRDL1
	rts
;
; adjust PEV boards by subtractions
;
EFBEVBRD:
	move.l	HBEVBRD(A4),A1
	lea	-BRDR(A1,D6.w),A1
	bra.s	EFBEVBRDBW
EBWEVBRD:
	move.l	HWEVBRD(A4),A1
	lea	-BRDR(A1,D7.w),A1
EFBEVBRDBW:
	suba.l	D3,A1
	suba.l	D3,A1
	suba.l	D3,A1
	lea	PEVPAT(A3),A2
	moveq	#0,D2
	moveq	#2*BRDR,D1
EFBEVBRDL1:
	moveq	#2*BRDR,D0
EFBEVBRDL0:
	move.b	(A2)+,D2
	sub.b	D2,0(A1,D0.w)
	dbra	D0,EFBEVBRDL0
	adda.l	D3,A1
	dbra	D1,EFBEVBRDL1
	rts
;
EFMV:	; Execute Forward Move
;
	move.w	MSQ(A6),D7
	move.b	D4,0(A5,D7.w)
	bsr	EFWEVBRD
	move.b	MTK(A6),D1
	beq.s	EFMVE
;
	lea	DIRS-2(PC),A0
EFMVL:
	tst.w	(A0)+
	lsr.b	#1,D1
	bcc.s	EFMVL
	move.b	D1,-(SP)
	move.w	D7,D6
	add.w	(A0),D6
	move.b	#empsq,0(A5,D6.w)
	bsr	EFBEVBRD
	add.w	(A0),D6
	move.b	#empsq,0(A5,D6.w)
	bsr	EFBEVBRD
	move.b	(SP)+,D1
	bne.s	EFMVL
EFMVE:
	rts
;
EBMV:	; Execute Backward Move
;
	move.w	MSQ(A6),D7
	move.b	#empsq,0(A5,D7.w)
	bsr	EBWEVBRD
	move.b	MTK(A6),D1
	beq.s	EBMVE
;
	lea	DIRS-2(PC),A0
EBMVL:
	tst.w	(A0)+
	lsr.b	#1,D1
	bcc.s	EBMVL
	move.b	D1,-(SP)
	move.w	D7,D6
	add.w	(A0),D6
	move.b	D5,0(A5,D6.w)
	bsr	EBBEVBRD
	add.w	(A0),D6
	move.b	D5,0(A5,D6.w)
	bsr	EBBEVBRD
	move.b	(SP)+,D1
	bne.s	EBMVL
EBMVE:
	rts
;
EFQS:	; Execute Forward Quiescense Search
;
	move.w	MSQ(A6),D7
	move.b	D4,0(A5,D7.w)
	move.b	MTK(A6),D1
	beq.s	EFQSE
;
	lea	DIRS(PC),A0
EFQSL:
	move.w	(A0)+,D0
	lsr.b	#1,D1
	bcc.s	EFQSL
	move.w	D7,D6
	add.w	D0,D6
	move.b	#empsq,0(A5,D6.w)
	add.w	D0,D6
	move.b	#empsq,0(A5,D6.w)
	tst.b	D1
	bne.s	EFQSL
EFQSE:	rts
;
EBQS:	; Execute Backward Quiescense Search
;
	move.w	MSQ(A6),D7
	move.b	#empsq,0(A5,D7.w)
	move.b	MTK(A6),D1
	beq.s	EBQSE
;
	lea	DIRS(PC),A0
EBQSL:
	move.w	(A0)+,D0
	lsr.b	#1,D1
	bcc.s	EBQSL
	move.w	D7,D6
	add.w	D0,D6
	move.b	D5,0(A5,D6.w)
	add.w	D0,D6
	move.b	D5,0(A5,D6.w)
	tst.b	D1
	bne.s	EBQSL
EBQSE:	rts
;
SEYWMOV: macro
; D0.w  EV* to be searched for
; D1.w  MAXrecNR,	ALSO output-recnr
; A0.l  STARTrecAD
;
; v(D3) >= v(D2) >= v(D1)
;
	move.w	D1,D4
	subq.w	#1,D4
	asl.w	#3,D4		; * 8=LMOV
	cmp.w	?1(A0,D4.w),D0
	ble.s	SEYWMOVE?0	; D0 <= v(LASTrec)
;
	if ?1=0
	cmp.w	(A0),D0
	else
	cmp.w	?1(A0),D0
	endif
	blt.s	SEYWMOVL?0
	clr.w	D1
	bra.s	SEYWMOVE?0	; D0 >= v(FIRSTrec)
SEYWMOVL?0:
	clr.w	D3
SEYWMOVL1?0:
	move.w	D1,D2
SEYWMOVL2?0:
	add.w	D3,D2
	asr.w	#1,D2
	cmp.w	D3,D2
	beq.s	SEYWMOVE?0
	move.w	D2,D4
	asl.w	#3,D4		; * 8=LMOV
	cmp.w	?1(A0,D4.w),D0
	beq.s	SEYWMOV2?0
	bgt.s	SEYWMOVLT?0
	move.w	D2,D3		; v(D2) > D0
	bra.s	SEYWMOVL1?0
SEYWMOVLT?0:
	move.w	D2,D1		; D0 > v(D2)
	bra.s	SEYWMOVL2?0
SEYWMOV2?0:
	move.w	D2,D1
	addq.w	#1,D1
SEYWMOVE?0:
	endm
;
SEWPEV0:
	move.w	(A1),D0		; MPEV0 of White move
	SEYWMOV MPEV0
	rts
;
SEWPEV:
	move.w	MPEV(A1),D0	; MPEV of White move
	SEYWMOV MPEV
	rts
;
SEYBMOV: macro
; D0.w  EV* to be searched for
; D1.w  MAXrecNR,	ALSO output-recnr
; A0.l  STARTrecAD
;
; v(D3) <= v(D2) <= v(D1)
;
	move.w	D1,D4
	subq.w	#1,D4
	asl.w	#3,D4		; * 8=LMOV
	cmp.w	?1(A0,D4.w),D0
	bge.s	SEYBMOVE?0	; D0 >= v(LASTrec)
;
	if ?1=0
	cmp.w	(A0),D0
	else
	cmp.w	?1(A0),D0
	endif
	bgt.s	SEYBMOVL?0
	clr.w	D1
	bra.s	SEYBMOVE?0	; D0 <= v(FIRSTrec)
SEYBMOVL?0:
	clr.w	D3
SEYBMOVL1?0:
	move.w	D1,D2
SEYBMOVL2?0:
	add.w	D3,D2
	asr.w	#1,D2
	cmp.w	D3,D2
	beq.s	SEYBMOVE?0
	move.w	D2,D4
	asl.w	#3,D4		; * 8=LMOV
	cmp.w	?1(A0,D4.w),D0
	beq.s	SEYBMOV2?0
	blt.s	SEYBMOVLT?0
	move.w	D2,D3		; v(D2) < D0
	bra.s	SEYBMOVL1?0
SEYBMOVLT?0:
	move.w	D2,D1		; D0 < v(D2)
	bra.s	SEYBMOVL2?0
SEYBMOV2?0:
	move.w	D2,D1
	addq.w	#1,D1
SEYBMOVE?0:
	endm
;
SEBPEV0:
	move.w	(A1),D0		; MPEV0 of Black move
	SEYBMOV MPEV0
	rts
;
SEBPEV:
	move.w	MPEV(A1),D0	; MPEV of Black move
	SEYBMOV MPEV
	rts
;
SOMOV:
; Sort moves
; D6.w  MAXrecNR
; A0.l  STARTrecAD
; A4.l  SUBROUTINE-AD
;
; D0-D6 : temp. use
;        |A0   |     |     |     |A1   |     |     | ... |#D6
;        |A0   |     |     |     |A2   |A3   |-----
;               #D1               #D5   (D0)
;
	cmpi.w	#1,D6
	ble.s	SOMOVE
	subq.w	#2,D6
	move.l	A0,A1
	clr.w	D5
SOMOVL:	lea	LMOV(A1),A1
	addq.w	#1,D5
	move.w	D5,D1
	jsr	(A4)
	move.w	D5,D4
	sub.w	D1,D4
	beq.s	SOMOVN
	subq.w	#1,D4
	move.l	A1,A2
;
	movem.l	D0-D1,-(SP)	; save original D0-D1
	movem.l	(A2)+,D0-D1	; save 8 bytes
	movem.l	D0-D1,-(SP)	; at (SP)
;
SOMOVR:	movem.l	-16(A2),D0-D1	; get previous 8 bytes, order D0->D1
	movem.l	D0-D1,-(A2)	; copy in order D1-D0, decr A2 by 8 bytes
	dbra	D4,SOMOVR
;
	movem.l	(SP)+,D0-D1	; now copy intended 8 bytes
	movem.l	D0-D1,-(A2)	; to destination
	movem.l	(SP)+,D0-D1	; restore original D0-D1
;
SOMOVN:	dbra	D6,SOMOVL
SOMOVE:	rts
;
MIQS:	macro	; check pente solve/threat
	btst	#EVCbit5t,PMTQS(A3)
	bne.s	MIQSE?0		; branch when already pente threat
	btst	#EVCbit5s,PIQS(A3)
	beq.s	MIQSE?0		; branch when NO pente solve
	move.l	HMV0(A4),A0	; now start filtering
	move.l	A0,A6
MIQSL?0:
	move.b	MTQS(A0),D0
	andi.b	#EVCs5t,D0
	beq.s	MIQSN?0
	move.l	(A0),(A6)+	; copy pente solving move
	move.l	4(A0),(A6)+
MIQSN?0:
	lea	LMOV(A0),A0
	cmpa.l	HMV2(A4),A0
	bne.s	MIQSL?0
	move.l	A6,PGMVS(A3)
	move.l	A6,HMV2(A4)
MIQSE?0:
	endm
;
ZEV:	; White/Black Evaluation
; assumption :
; A4 : pointer to HST
; A6 : pointer to MOVE
; D0 : return-value = PEV
;
	move.w	D0,HPEV(A4)
	move.b	HTQS(A4),PTQS(A3)
	move.b	MTQS(A6),D0
	move.b	D0,PMTQS(A3)
	btst	#EVCbit5t,D0
	beq.s	ZEVno_t
	andi.b	#EVCs5t,PTQS(A3)
ZEVno_t:
	move.b	MMEV(A6),HBMEV(A4)
	move.b	HBMEV-LHST(A4),HWMEV(A4)
	move.l	PGMVS(A3),A6
	move.l	A6,HMV0(A4)
	bsr	GMVS
	move.l	A6,PGMVS(A3)
	move.l	A6,HMV2(A4)
	cmpa.l	HMV0(A4),A6
	beq	ZEVnoMV
	tst.b	D0
	bmi	ZEVWIN
;
	MIQS
	move.l	HMV0(A4),A0
	move.l	A6,D6
	sub.l	A0,D6
	lsr.w	#3,D6
	SOXPEVM	SEWPEV0
ZEVS:
	move.w	#ZCEVI,HCEV(A4)
	move.l	HMV0(A4),A6
ZEVL:	move.l	A6,HMV1(A4)
	bsr	EFMV
	movem.l	D4-D5/A4/A6,-(SP)
	lea	LHST(A4),A4
	move.w	HcolME(A4),D4
	move.w	HcolOP(A4),D5
ZEVNHST:
	move.w	HAEV-LHST(A4),D0
	neg.w	D0
	move.w	D0,HBEV(A4)
	move.w	HBEV-LHST(A4),D0
	neg.w	D0
	move.w	D0,HAEV(A4)
	move.w	MPEV0(A6),D0
	neg.w	D0
	MRECIPE
	movem.l	(SP)+,D4-D5/A4/A6
	neg.w	D0
	move.w	D0,MPEV(A6)
	bsr	EBMV
ZEVTEV:
	move.w	MPEV(A6),D0
	cmp.w	HCEV(A4),D0	; HCEV <= HAEV <= HBEV
	ble.s	ZEVN		; D0 <= HCEV ?
	move.w	D0,HCEV(A4)
	cmp.w	HAEV(A4),D0	; test current-ev
	ble.s	ZEVN		; D0 <= HAEV ?
	move.w	D0,HAEV(A4)
	cmp.w	HBEV(A4),D0	; test beta-window
	bge.s	ZEVEF		; D0 >= HBEV ?
ZEVN:	lea	LMOV(A6),A6
	cmpa.l	HMV2(A4),A6
	bne	ZEVL
ZEVE:	move.w	HCEV(A4),D0
	move.l	HMV0(A4),PGMVS(A3)
	rts
ZEVEF:
	addi.w	#ZBEV,D0	; avoid false ties
	move.l	HMV0(A4),PGMVS(A3)
	rts
;
ZEVWIN:
	move.w	HWIN(A4),D0
	move.l	HMV0(A4),A0
	move.w	D0,(A0)+		; D0 --> MPEV0
	move.w	D0,(A0)+		; D0 --> MPEV
	move.l	4-LMOV(A6),(A0)+	; copy rest
	move.l	A0,HMV2(A4)
	move.l	HMV0(A4),PGMVS(A3)
	rts
ZQSWIN:
	move.w	HWIN(A4),D0
	move.w	D0,MPEV0-LMOV(A6)
	move.w	D0,MPEV-LMOV(A6)
	move.l	A6,HMV2(A4)
	move.l	HMV0(A4),PGMVS(A3)
	rts
ZEVnoMV:
ZQSnoMV:
	move.w	HPEV(A4),D0
	rts
ZEVesc:
ZQSesc:	add.w	PESC(A3),D0
	rts
;
ZQS:	; Z Quiescense Search
; assumption :
; A4 : pointer to HST
; A6 : pointer to MOVE
; D0 : return-value = PEV
;
	move.w	D0,HPEV(A4)
	move.b	HTQS(A4),PTQS(A3)
	move.b	MTQS(A6),D0
	move.b	D0,PMTQS(A3)
	btst	#EVCbit5t,D0
	beq.s	ZQSno_t
	andi.b	#EVCs5t,PTQS(A3)
ZQSno_t:
	move.b	MMEV(A6),HBMEV(A4)
	move.b	HBMEV-LHST(A4),HWMEV(A4)
	move.l	PGMVS(A3),A6
	move.l	A6,HMV0(A4)
	bsr	GQS
	move.l	A6,PGMVS(A3)
	move.l	A6,HMV2(A4)
	cmpa.l	HMV0(A4),A6
	beq.s	ZQSnoMV
	tst.b	D0
	bmi.s	ZQSWIN
;
	MIQS
	move.w	#ZCEVI,HCEV(A4)
	btst	#EVCbitn,PTQS(A3)	; check normal moves generation
	bne.s	ZQSEVI
	move.b	PMTQS(A3),D0		; check previous move's threats
	andi.b	#EVCQSI,D0
	bne.s	ZQSEVI
	move.w	HPEV(A4),HCEV(A4)
ZQSEVI:
	move.l	HMV0(A4),A6
ZQSL:	move.l	A6,HMV1(A4)
	bsr	EFQS
	movem.l	D4-D5/A4/A6,-(SP)
	lea	LHST(A4),A4
	move.w	HcolME(A4),D4
	move.w	HcolOP(A4),D5
	move.w	HAEV-LHST(A4),D0	; negate ALFA
	neg.w	D0
	move.w	D0,HBEV(A4)
	move.w	HBEV-LHST(A4),D0	; negate BETA
	neg.w	D0
	move.w	D0,HAEV(A4)
	move.w	MPEV0(A6),D0
	neg.w	D0
	MRECIPE
	movem.l	(SP)+,D4-D5/A4/A6
	neg.w	D0		; negate return-value
	move.w	D0,MPEV(A6)
	bsr	EBQS
ZQSTEV:
	move.w	MPEV(A6),D0
	cmp.w	HCEV(A4),D0	; HAEV <= HBEV <= HCEV
	ble.s	ZQSN		; D0 <= HCEV ?
	move.w	D0,HCEV(A4)
	cmp.w	HAEV(A4),D0	; test current-ev
	ble.s	ZQSN		; D0 <= HAEV ?
	move.w	D0,HAEV(A4)
	cmp.w	HBEV(A4),D0	; test beta-window
	bge.s	ZQSEF		; D0 >= HBEV ?
ZQSN:	lea	LMOV(A6),A6
	cmpa.l	HMV2(A4),A6
	bne	ZQSL
ZQSE:	move.w	HCEV(A4),D0
	move.l	HMV0(A4),PGMVS(A3)
	rts
ZQSEF:
	addi.w	#ZBEV,D0	; avoid false ties
	move.l	HMV0(A4),PGMVS(A3)
	rts
end
