MagneticSensorChessBoard1987
Hardware
Front
Back
Connectors
Schematics
Parts:
Partlist
- chess plan 35 mm fields
- 64 Reed Contacts
- 16 Black Chess Pieces
- 16 White Chess Pieces
- 32 magnets
- 17 red LEDs
- On/Off switch
- Male Sub-D Connector 15
- Adapter cable Centronics - SUB-D 15 Female
- Copper Tape
- Aluminum Frame
- 1 TTL 74151
- 1 TTL 74154
- 330 Ohm Resistor
- Batteryholder for 3 x AA
Software
SCHFELD.PAS
PROGRAM Schachbrett_Ansteuerung(INPUT,OUTPUT);
TYPE
KBrettTyp= ARRAY [0..7,0..7] OF BOOLEAN;
CONST
BlinkTime = 100;
MaxBlinkTime = 1400;
MaxTime = 1700;
VAR
Pw,
Count,LED1,LED2,
LED3,LED4,MovCount,
FigMovCnt: INTEGER;
MovList : ARRAY[0..500] OF LSTRING(5);
KBrett,SBrett : KBrettTyp;
ZugDatei : TEXT;
(*$include: 'screen.def'*)
(*$include: 'string.def'*)
PROCEDURE ClrLED;
BEGIN
LED1:=#80;
LED2:=LED1;
LED3:=LED1;
LED4:=LED1;
END;
FUNCTION CheckBrett(D,L: INTEGER): BOOLEAN; EXTERN;
PROCEDURE Sound(Freq,Time: INTEGER); EXTERN;
FUNCTION Check(x,y: INTEGER):BOOLEAN;
VAR
Pw,Dw,P1,P2:INTEGER;
BEGIN
CASE (Count MOD 2) OF
0: BEGIN P1:=LED1; P2:=LED3; END;
1: BEGIN P1:=LED2; P2:=LED4; END;
END;
IF Count<MaxBlinkTime THEN
BEGIN
CASE (Count DIV BlinkTime) MOD 4 OF
0,1,2: Pw:=P1;
3: Pw:=P2;
END;
END
ELSE
Pw:=P2;
IF Count<MaxBlinkTime THEN
Count:=SUCC(Count)
ELSE
IF Count<MaxTime THEN
BEGIN
IF FigMovCnt>=1 THEN
Count:=0
ELSE
Count:=SUCC(Count);
END
ELSE
ClrLED;
Dw:=(x * 8) +y;
Check:=CheckBrett(Dw,Pw);
END;
PROCEDURE State(VAR B:KBrettTyp);
VAR
Spalte,Zeile: INTEGER;
BEGIN
FOR Spalte:=0 TO 7 DO
FOR Zeile:=0 TO 7 DO
B[Spalte,Zeile]:=Check(Spalte,Zeile);
END;
PROCEDURE Kontakte;
VAR
Spalte,Zeile: INTEGER;
BEGIN
CLRSCR;
ClrLED;
REPEAT
GOTOXY(1,1);
FOR Spalte:=0 TO 7 DO
BEGIN
FOR Zeile:=0 TO 7 DO
BEGIN
IF KeyPressed THEN RETURN;
IF Check(Spalte,Zeile) THEN WRITE('*') ELSE WRITE('.');
END;
WRITELN;
END;
UNTIL FALSE;
END;
PROCEDURE Scribe(VAR D:TEXT;P:INTEGER);
BEGIN
WRITE(D,MovList[P]);
CASE (P MOD 4) OF
0: BEGIN WRITELN(D);WRITE(D,P DIV 4+1:3,': '); END;
2: WRITE(D,' ');
OTHERWISE
;
END;
END;
PROCEDURE Zuege;
PROCEDURE Accept(X1,Y1,X2,Y2: INTEGER);
PROCEDURE StatePos(Zeile,Spalte: INTEGER);
BEGIN
MovCount:=SUCC(MovCount);
CONCAT(MovList[MovCount],CHR(ORD('A')+Zeile));
CONCAT(MovList[MovCount],CHR(ORD('8')-Spalte));
CASE (MovCount MOD 4) OF
1,3: BEGIN
IF FigMovCnt>=2 THEN
CONCAT(MovList[MovCount],' X ')
ELSE
CONCAT(MovList[MovCount],' - ');
END;
OTHERWISE
;
END;
Scribe(OutPut,MovCount);
END;
BEGIN
StatePos(X1,Y1);
StatePos(X2,Y2);
Count:=0;
State(SBrett);
Sound(800,20);
END;
PROCEDURE ZugVerfolgen;
VAR
AktCheck: BOOLEAN;
P1,P2,P3,P4,Spalte,Zeile: INTEGER;
PROCEDURE GetPos(VAR X,Y,L1,L2: INTEGER);
BEGIN
X:=Zeile;
Y:=Spalte;
L1:=(X+8) * 8;
L2:=Y * 8;
Count:=0;
State(SBrett);
END;
BEGIN
WRITELN('Zug-Anzeige: ');
Scribe(OutPut,0);
MovCount:=0;
State(SBrett);
FigMovCnt:=0;
ClrLED;
REPEAT
FOR Zeile:=0 TO 7 DO
FOR Spalte:=0 TO 7 DO
BEGIN
IF KeyPressed THEN RETURN;
AktCheck:=Check(Spalte,Zeile);
IF (NOT AktCheck) AND Sbrett[Spalte,Zeile] THEN
BEGIN { Figur Entfernt }
IF FigMovCnt=1 THEN
BEGIN
GetPos(P3,P4,LED3,LED4);
FigMovCnt:=FigMovCnt+1;
END
ELSE
BEGIN
GetPos(P1,P2,LED1,LED2);
LED3:=LED1;
LED4:=LED2;
FigMovCnt:=FigMovCnt+1;
END;
END;
IF AktCheck AND (NOT Sbrett[Spalte,Zeile]) THEN
BEGIN { Figur gesetzt }
CASE FigMovCnt OF
0: BEGIN
GetPos(P1,P2,LED1,LED2);
END;
1: BEGIN
IF NOT ((P1=Zeile) AND (P2=Spalte)) THEN { Figur bewegt? }
BEGIN
Accept(P1,P2,Zeile,Spalte);
GetPos(P1,P2,LED3,LED4);
LED1:=LED3;LED2:=LED4;
FigMovCnt:=0;
END
ELSE
BEGIN
ClrLED;
State(SBrett);
FigMovCnt:=0;
END;
END
OTHERWISE
IF (P1=Zeile) AND (P2=Spalte) THEN
BEGIN
Accept(P3,P4,Zeile,Spalte);
GetPos(P1,P2,LED3,LED4);
FigMovCnt:=0;
END
ELSE
BEGIN
Accept(P1,P2,Zeile,Spalte);
GetPos(P1,P2,LED3,LED4);
FigMovCnt:=0;
END;
END; { Case }
END;
END;
UNTIL FALSE;
END;
VAR
Taste: CHAR;
z: INTEGER;
BEGIN
CLRSCR;
ZugVerfolgen;
ASSIGN(ZugDatei,'SCHParti.txt');
REWRITE(ZugDatei);
FOR z:=0 TO MovCount DO
Scribe(ZugDatei,z);
CLOSE(ZugDatei);
END;
VAR
Taste: CHAR;
BEGIN
Window(1,1,80,25);
REPEAT
CLRSCR;
WRITELN('(K)ontakt Matrix');
WRITELN('(Z)ug-Anzeige');
GetKey(Taste);
MovList[0]:=NULL;
Taste:=UpCase(Taste);
CASE Taste OF
'K': Kontakte;
'Z': Zuege;
OTHERWISE
;
END;
UNTIL Taste='E';
END.
Centronics Port Check
DATA SEGMENT PUBLIC 'DATA'
DATA ENDS
DGROUP GROUP DATA
ASSUME CS:ADDS,DS:DGROUP,SS:DGROUP
ADDS SEGMENT 'CODE'
PUBLIC CheckBrett,Sound
Sound PROC FAR ; Freq,Time: INTEGER;
PUSH BP
MOV BP,SP
PUSH DI
MOV DI,8[BP] ; Freq;
MOV BX,6[BP] ; Time;
MOV AL,0B6H ; Zeitgeber Modus-Register schreiben
OUT 43H,AL
MOV DX,14H ; Zeitgeber Divisor =
MOV AX,4F38H ; 1331000/Frequenz
DIV DI
OUT 42H,AL ; Zaehler in niederw. Byte Timer 2
MOV AL,AH
OUT 42H,AL ; Zaehler in hoeherw. Byte Timer 2
IN AL,61H ; Aktuelle Einstellung Port B
MOV AH,AL ; In AH Sichern
OR AL,3 ; Lautsprecher einschalten
OUT 61H,AL
Warte:
MOV CX,2801 ; 10 Millisekunden warten
LS_Ein:
LOOP LS_Ein
DEC BX ; Einschaltzaehler auf 0?
JNZ Warte ; wenn nicht Lautsprecher anlassen
MOV AL,AH ; Port wiederherstellen
OUT 61H,AL
POP DI
POP BP
RET 4
Sound ENDP
CheckBrett PROC FAR ;d,l: INTEGER: BOOLEAN
PUSH BP
MOV BP,SP
CLI
MOV AX,8[BP] ; d
MOV CX,6[BP] ; l
MOV DX,0278h
OUT DX,AL ; Port[Data]:=D
INC DX
IN AL,DX
XCHG AL,CL
DEC DX
OUT DX,AL ; Port[Data]:=l
STI
MOV AX,0
AND CL,080h
JNZ FALSE
INC AX
FALSE:
POP BP
RET 4
CheckBrett ENDP
ADDS ENDS
END