MagneticSensorChessBoard1987: Difference between revisions
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 04: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
