program chessboard;

//---------------------- LIBRARES ----------------------------------------------

uses crt, graph;


//---------------------- GLOBAL VARIABLES --------------------------------------

var
  bmpAdr                : word;
  color                 : byte;

  {* White square, invert Black square *}
  wSquare               : array[0..56] of byte = (
    $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,
    $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,
    $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$ff
  );
  {* White pawn on black, invert Black pawn on white *}
  pawnSe                : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$00,$00,
    $3C,$00,$00,$3C,$00,$00,$18,$00,$00,$3C,$00,$00,$7E,$00,$00,$7E,$00,$00,$3C,
    $00,$00,$18,$00,$00,$18,$00,$00,$3C,$00,$00,$3C,$00,$01,$FF,$80,$01,$FF,$80
  );
  {* Black pawn on black, invert White pawn on white *}
  pawnEe                : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$00,$00,$24,$00,$00,
    $42,$00,$00,$42,$00,$00,$24,$00,$00,$42,$00,$00,$81,$00,$00,$81,$00,$00,$42,
    $00,$00,$24,$00,$00,$24,$00,$00,$42,$00,$01,$C3,$80,$02,$00,$40,$02,$00,$40
  );  
  {* White king on black, invert Black king on white *}
  kingSe                : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$18,$00,$00,$18,$00,$00,$18,$00,$00,$7E,$00,$00,
    $7E,$00,$06,$18,$60,$0F,$18,$F0,$1F,$DB,$F8,$1F,$C3,$F8,$1E,$FF,$78,$0D,$7E,
    $B0,$06,$FF,$60,$07,$FF,$E0,$02,$00,$40,$03,$FF,$C0,$01,$00,$80,$01,$FF,$80
  );
  {* Black king on black, invert White king on white *}
  kingEe                : array[0..56] of byte = (
    $00,$00,$00,$00,$18,$00,$00,$24,$00,$00,$24,$00,$00,$66,$00,$00,$81,$00,$06,
    $81,$60,$09,$24,$90,$10,$E7,$08,$20,$24,$04,$20,$3C,$04,$21,$00,$84,$12,$81,
    $48,$09,$00,$90,$08,$00,$10,$05,$FF,$A0,$04,$00,$20,$02,$FF,$40,$02,$00,$40
  );
  {* White queen on black, invert Black queen on white *}
  queenSe               : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81,$00,$09,$C3,$90,$1C,$81,$38,$0A,
    $81,$50,$0A,$C3,$50,$0D,$E7,$B0,$0D,$E7,$B0,$0F,$FF,$F0,$0F,$FF,$F0,$0F,$FF,
    $F0,$0C,$00,$30,$07,$FF,$E0,$06,$00,$60,$03,$FF,$C0,$03,$00,$C0,$01,$FF,$80
  );
  {* Black queen on black, invert White queen on white *}
  queenEe               : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$81,$00,$09,$42,$90,$16,$24,$68,$23,$42,$C4,$15,
    $42,$A8,$15,$24,$A8,$12,$18,$48,$12,$18,$48,$10,$00,$08,$10,$00,$08,$10,$00,
    $08,$13,$FF,$C8,$08,$00,$10,$09,$FF,$90,$04,$00,$20,$04,$FF,$20,$02,$00,$40
  );  
  {* White rook on black, invert Black rook on white *}
  rookSe                : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03,$99,$C0,$03,$99,$C0,$03,
    $99,$C0,$03,$FF,$C0,$01,$FF,$80,$00,$FF,$00,$00,$FF,$00,$00,$FF,$00,$00,$FF,
    $00,$00,$FF,$00,$00,$FF,$00,$01,$FF,$80,$01,$FF,$80,$07,$FF,$E0,$07,$FF,$E0
  );
  {* Black rook on black, invert White rook on withe *}
  rookEe                : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$07,$BD,$E0,$04,$A5,$20,$04,$A5,$20,$04,
    $E7,$20,$06,$00,$60,$03,$00,$C0,$01,$00,$80,$01,$00,$80,$01,$00,$80,$01,$00,
    $80,$01,$00,$80,$03,$00,$C0,$02,$00,$40,$0E,$00,$70,$08,$00,$10,$08,$00,$10
  );
  {* White knight on black, invert Black knight on white *}
  knightSe              : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$48,$00,$00,$6C,$00,$00,$FE,$00,$01,
    $BD,$00,$01,$FE,$80,$03,$FE,$80,$07,$FE,$80,$06,$DE,$80,$05,$BE,$80,$03,$7E,
    $80,$00,$7E,$C0,$00,$FF,$40,$00,$FF,$40,$01,$FF,$60,$03,$FF,$E0,$03,$FF,$E0
  );
  {* Black knight on black, invert White knight on withe *}
  knightEe              : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$48,$00,$00,$B4,$00,$00,$92,$00,$01,$01,$00,$02,
    $42,$80,$02,$01,$40,$04,$01,$40,$08,$01,$40,$09,$21,$40,$0A,$41,$40,$04,$81,
    $40,$03,$81,$20,$01,$00,$A0,$01,$00,$A0,$02,$00,$90,$04,$00,$10,$04,$00,$10
  );
  {* White bishop on black, invert Black bishop on white *}
  bishopSe              : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$3C,$00,$00,$7E,$00,$00,$66,$00,$00,
    $E7,$00,$01,$E7,$80,$03,$E7,$C0,$03,$18,$C0,$03,$E7,$C0,$01,$E7,$80,$00,$E7,
    $00,$00,$E7,$00,$00,$7E,$00,$00,$66,$00,$00,$7E,$00,$0F,$66,$F0,$19,$DB,$98
  );
  {* Black bishop on black, invert White bishop on withe *}
  bishopEe              : array[0..56] of byte = (
    $00,$00,$00,$00,$00,$00,$00,$3C,$00,$00,$42,$00,$00,$81,$00,$00,$99,$00,$01,
    $18,$80,$02,$18,$40,$04,$18,$20,$04,$E7,$20,$04,$18,$20,$02,$18,$40,$01,$18,
    $80,$01,$18,$80,$00,$81,$00,$00,$99,$00,$0F,$81,$F0,$10,$99,$08,$26,$24,$64
  );

//---------------------- PROCEDURES --------------------------------------------

procedure renderChessman(var chessman: array[0..56] of byte; x, y, invert: byte);
var i0b                 : byte;
    gfxByte             : byte;
    x1w, y1w, tmpBmpAdr : word;
begin
  y1w := y * 760;
  x1w := x * 3;
  tmpBmpAdr := bmpAdr + x1w;
  gfxByte := 0;
  for i0b := 0 to 18 do begin
    poke(tmpBmpAdr + y1w, chessman[gfxByte] xor invert);
    poke(tmpBmpAdr + y1w + 1, chessman[gfxByte + 1] xor invert);
    poke(tmpBmpAdr + y1w + 2, chessman[gfxByte + 2] xor invert);
    gfxByte := gfxByte + 3;
    y1w := y1w + 40;
  end; 
end;

procedure drawRectangle;
var i0b                 : byte;
    tmpBmpAdr           : word;
    y                   : word = 0;
begin
  tmpBmpAdr := bmpAdr + 23;
  for i0b := 0 to 152 do begin
    poke(bmpAdr + y, peek(bmpAdr + y) or %10000000);
    poke(tmpBmpAdr + y, peek(tmpBmpAdr + y) or %00000001);
    y := y + 40;
  end;
  tmpBmpAdr := bmpAdr + 6080; // 19*8*40
  for i0b := 0 to 23 do begin
    poke(bmpAdr + i0b, $ff);
    poke(tmpBmpAdr + i0b, $ff);
  end;  
end;

procedure drawBoard;
var i0b, i1b, coordinate: byte;
begin
  renderChessman(rookSe, 0, 0, $ff);
  renderChessman(rookEe, 7, 0, 0);
  renderChessman(rookSe, 0, 7, 0);
  renderChessman(rookEe, 7, 7, $ff);
  
  renderChessman(knightEe, 1, 0, 0);
  renderChessman(knightSe, 6, 0, $ff);
  renderChessman(knightEe, 1, 7, $ff);
  renderChessman(knightSe, 6, 7, 0);
  
  renderChessman(bishopSe, 2, 0, $ff);
  renderChessman(bishopEe, 5, 0, 0);
  renderChessman(bishopSe, 2, 7, 0);
  renderChessman(bishopEe, 5, 7, $ff);
  
  renderChessman(queenEe, 3, 0, 0);
  renderChessman(queenEe, 3, 7, $ff);

  renderChessman(kingSe, 4, 7, 0);
  renderChessman(kingSe, 4, 0, $ff);

  for i1b := 0 to 1 do begin
    coordinate := 0;
    for i0b := 0 to 7 do begin
      if (i0b and %1 = i1b) then begin
        renderChessman(wSquare, coordinate, 2 + i1b, 0);
        renderChessman(wSquare, coordinate, 5 - i1b, $ff);
        if (i1b = 0) then begin
          renderChessman(pawnEe, coordinate, 1, 0);
          renderChessman(pawnEe, coordinate, 6, $ff);        
        end;
      end else begin
        renderChessman(wSquare, coordinate, 2 + i1b, $ff);
        renderChessman(wSquare, coordinate, 5 - i1b, 0);
        if (i1b = 0) then begin
          renderChessman(pawnSe, coordinate, 1, $ff);
          renderChessman(pawnSe, coordinate, 6, 0);        
        end;        
      end;
      coordinate := coordinate + 1;
    end;
  end;
  
  drawRectangle;
end;

//---------------------- MAIN PROGRAM ------------------------------------------

begin
  // There are 192 rows of 320 dots in the full screen mode.
  InitGraph(8);
  bmpAdr := dpeek(88);
  
  SetColor(1);
  // colors: 2, 4, 80, 82, 96, 98, 112, 130, 132, 144, 146, 148, 150
  color := 2;
  SetBKColor(color);
  TextBackground(color);
  
  drawBoard;
  
  ReadKey;
end.
