Difference between revisions of "MagneticSensorChessBoard1987"

From BITPlan Wiki
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

UniChess87-0044.JPG

Hardware

Front

UniChess87-0035.JPG

Back

UniChess87-0036.JPG

Connectors

UniChess87-0037.JPG UniChess87-0038.JPG UniChess87-0039.JPG

Schematics

Parts:

  1. TTL 74151 8 to 1 Multiplexer TTL74151 Pins.jpeg
  2. TTL 74154 4 to 16 Demultiplexer TTL74154 pins.png

Unichess87-Schematics.JPG

Partlist

  1. chess plan 35 mm fields
  2. 64 Reed Contacts
  3. 16 Black Chess Pieces
  4. 16 White Chess Pieces
  5. 32 magnets
  6. 17 red LEDs
  7. On/Off switch
  8. Male Sub-D Connector 15
  9. Adapter cable Centronics - SUB-D 15 Female
  10. Copper Tape
  11. Aluminum Frame
  12. 1 TTL 74151
  13. 1 TTL 74154
  14. 330 Ohm Resistor
  15. 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