Difference between revisions of "MagneticSensorChessBoard1987"
Jump to navigation
Jump to search
Line 33: | Line 33: | ||
[[Category:Chess]] | [[Category:Chess]] | ||
= Software = | = Software = | ||
+ | == SCHFELD.PAS == | ||
+ | <source lang='pascal'> | ||
+ | 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. | ||
+ | </source> | ||
== Centronics Port Check == | == Centronics Port Check == | ||
<source lang='asm'> | <source lang='asm'> |
Revision as of 05:41, 21 October 2019
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