//We start using only sample video code //Set "Optimize for Speed", reduce the Data Stack size to 100 bytes, and turn off the "char is unsigned" option. //D.5 is sync:1000 ohm + diode to 75 ohm resistor //D.6 is video:330 ohm + diode to 75 ohm resistor void ChangeTurn(void); void MakePiece(int, int, int); void PutPiece(int, int, int); void video_smallchar(char, char, char); void video_pt(char, char, char); signed char IsMoveValid(signed char, signed char, signed char, signed char); signed char IsMovePossible(signed char, signed char, signed char, signed char); #pragma regalloc- //I allocate the registers myself #define GLASSBOARD 0; char GlassBoard = GLASSBOARD; #define PLAYINGWHITE 1; char PlayingWhite = PLAYINGWHITE; #include "ECE476Lab6ChessCode.h" #include "Lab6Video.h" #include #pragma regalloc+ //I allocate the registers myself int l, m; char FirstScan = 1; char BoardMove = 0; unsigned char MovePiece_MovingPiece; unsigned char MovePiece_Offset; unsigned char PrintOffset_X = 100; unsigned char PrintOffset_Y = 4; unsigned char PrintOffset_Y_Base = 4; unsigned char TurnNumberOnes = 1; unsigned char TurnNumberTens = 0; unsigned char TurnNumberHundreds = 0; signed char Main_x1; signed char Main_y1; signed char Main_x2; signed char Main_y2; signed char BoardChanges; signed char Change_x1; signed char Change_y1; signed char Change_x2; signed char Change_y2; unsigned char ValidMove; unsigned char PutPiece_X; unsigned char PutPiece_Y; unsigned char PutPiece_C; unsigned char Main_ActingPiece; unsigned char Main_SavedPiece; unsigned char Main_SavedPiece2; unsigned char Main_ActingTarget; unsigned char CFC_ActingPiece; unsigned char IsMovePossibleActor; unsigned char IsMovePossibleTarget; unsigned char IsMoveValidActor; unsigned char IsMoveValidTarget; unsigned char HypotheticalBoard = 0; unsigned char Buttons; unsigned char ButtonSelect; unsigned char LastButtonSelect = 0; unsigned char NeedsCorrecting = 0; unsigned char GoodMove = 0; unsigned char Correcting_X; unsigned char Correcting_Y; int IntroCounter = 0; unsigned char RecievedChar;//Most recently recieved char. //This is unlike CharRecieved, which indicates that a char was recieved. unsigned char TransmittedChar;//Char most recently sent to the USART buffer. //This is unlike CharRecieved, which indicates that a char was recieved. char CharRecieved = 0; char CharSent = 0; char RecievedMove[5]; char TransmittedMove[10]; int PollUSART_INDEX = 0;//Points to the locations in Recieved move where the NEXT character will be placed. int SendUSART_INDEX = 0;//Points to the location in TransmittedMove where the NEXT character will be placed. char RecieveComplete = 0; char TransmitComplete = 0; int WhiteTurn = 1; char WhiteInCheck = 0; char BlackInCheck = 0; char WhiteKingHasMoved = 0; char BlackKingHasMoved = 0; char WhiteKingSideRookHasMoved = 0; char WhiteQueenSideRookHasMoved = 0; char BlackKingSideRookHasMoved = 0; char BlackQueenSideRookHasMoved = 0; char WhiteCastleKingSide = 0; char WhiteCastleQueenSide = 0; char BlackCastleKingSide = 0; char BlackCastleQueenSide = 0; signed char WhiteKingX = 4; signed char BlackKingX = 4; signed char WhiteKingY = 0; signed char BlackKingY = 7; signed char WhitePawnDoubleMove = 8; signed char BlackPawnDoubleMove = 8; /**********************************************************/ // -- Move piece located at (x1, y1) to (x2, y2) and // updates display. // Note: does not check legality. If there is a piece at // (x2, y2), it is deleted. // Warning: does not check inputs. Make sure that all // inputs range from 0 to 7! void MovePiece(int x1, int y1, int x2, int y2) begin //We use the PutPiece function to draw the piece to its new location. //PutPiece takes the location (x,y) and the INDEX of the TYPE of PIECE to //be drawn, the INDEX is incremented by 2 to signify a WHITE PIECE. This //is done by checking with the 'IsWhite' macro and shifting the result by //two before adding it to the index. //PAWN, KNIGH, ... , KING (and TILE) are INDICIES. //NOTE: the PutPiece function choose the appropriate background //MovePiece_MovingPiece is a local variable of the MovePiece function. //Naming is to avoid conflicts in variable name. //printf("Entered MovePiece.\n\r"); MovePiece_MovingPiece = board[x1, y1]; MovePiece_Offset = (IsWhite(MovePiece_MovingPiece) << 1); //printf("I'm alive!\n\r"); if(IsPawn(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (PAWN + MovePiece_Offset)); if(IsKnight(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (KNIGHT + MovePiece_Offset)); if(IsBishop(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (BISHOP + MovePiece_Offset)); if(IsRook(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (ROOK + MovePiece_Offset)); if(IsQueen(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (QUEEN + MovePiece_Offset)); if(IsKing(MovePiece_MovingPiece)) PutPiece(x2, y2, (unsigned char) (KING + MovePiece_Offset)); board[x2, y2] = MovePiece_MovingPiece; board[x1, y1] = 0; //printf("Calling PutPiece.\n\r"); PutPiece(x1, y1, TILE); //printf("Exiting MovePiece.\n\r"); end /**********************************************************/ /**********************************************************/ // -- Make piece at (x1, y1). // NOTE: If there is a piece at (x1, x2), it is drawn over // // WARNING: does not check inputs. Make sure that x1 // and x2 range from 0 to 7! Also, make sure that // INDEX ranges from 0 to 25. MakePiece DOES choose the // background color of the tile automatically. Piece // color is specified in INDEX, see array PIECES in // header file ECE376Lab6ChessCode.h void InitializePiece(int x, int y) begin //We use the MakePiece function to draw the piece to its initial location. //InitializePiece takes the location (x,y) of the PIECE to be drawn if(y == 0) begin if(x == 0) MakePiece(0, 0, ROOK + 2); else if(x == 1) MakePiece(1, 0, KNIGHT + 2); else if(x == 2) MakePiece(2, 0, BISHOP + 2); else if(x == 3) MakePiece(3, 0, QUEEN + 2); else if(x == 4) MakePiece(4, 0, KING + 2); else if(x == 5) MakePiece(5, 0, BISHOP + 2); else if(x == 6) MakePiece(6, 0, KNIGHT + 2); else if(x == 7) MakePiece(7, 0, ROOK + 2); end else if(y == 1) MakePiece(x, y, PAWN + 2); else if(y == 6) MakePiece(x, y, PAWN); else if(y == 7) begin if(x == 0) MakePiece(0, 7, ROOK); else if(x == 1) MakePiece(1, 7, KNIGHT); else if(x == 2) MakePiece(2, 7, BISHOP); else if(x == 3) MakePiece(3, 7, QUEEN); else if(x == 4) MakePiece(4, 7, KING); else if(x == 5) MakePiece(5, 7, BISHOP); else if(x == 6) MakePiece(6, 7, KNIGHT); else if(y == 7) MakePiece(7, 7, ROOK); end end /**********************************************************/ /**********************************************************/ // -- Make piece at (x1, y1). // NOTE: If there is a piece at (x1, x2), it is drawn over // // WARNING: does not check inputs. Make sure that x1 // and x2 range from 0 to 7! Also, make sure that // INDEX ranges from 0 to 25. MakePiece DOES choose the // background color of the tile automatically. Piece // color is specified in INDEX, see array PIECES in // header file ECE376Lab6ChessCode.h void MakePiece(int x, int y, int INDEX) begin //We use the PutPiece function to draw the piece to its new location. //PutPiece takes the location (x,y) and the INDEX of the TYPE of PIECE to //be drawn, the INDEX is incremented by 1 to signify a WHITE PIECE. //PAWN, KNIGH, ... , KING (and TILE) are INDICIES. //NOTE: the PutPiece function choose the appropriate background //NOTE: the board we are using a board laid out from (4,4) to (99,99) //Each square is 12 by 12 units. Pieces are drawn ofset (2,2) from //the upper-left corner of the tile edge. //board[0,0] = A1, corresponds to drawing at (6,90) //board[0,7] = A8, corresponds to drawing at (6,6) //board[7,0] = H1, corresponds to drawing at (90,90) //board[7,7] = H8, corresponds to drawing at (90,6) //Formula: board[a,b] corresponds to drawing at (6 + a * 12, 90 - b * 12) //The code below is a reproduction of video_putchar, modified to draw //a 8 by 7 character instead of 5 by 7. It work like the following call: //video_putBIGchar(6 + x1 * 12, 90 - y1 * 12, INDEX) //Note: INDEX incremented by one if background tile is white, tested by: //(x+y) & 0x01 == 1 board[x,y] = INDEXtoPIECES[INDEX]; PutPiece(x, y, INDEX); end /**********************************************************/ /**********************************************************/ // -- Draw piece located to (x1, y1) to. // NOTE: does not check legality, and does not check or // update board data. If there is a piece at (x1, x2), // it is drawn over // (x2, y2), it is deleted. // Warning: does not check inputs. Make sure that x1 // and x2 range from 0 to 7! Also, make sure that // INDEX ranges from 0 to 25. PutPiece DOES choose the // background color of the tile automatically. Piece // color is specified in INDEX, see array PIECES in // header file ECE376Lab6ChessCode.h void PutPiece(int x, int y, int INDEX) begin //PutPiece takes the location (x,y) and the INDEX of the TYPE of PIECE to //be drawn, the INDEX is incremented by 1 to signify a WHITE PIECE. //PAWN, KNIGH, ... , KING (and TILE) are INDICIES. //NOTE: the PutPiece function choose the appropriate background //NOTE: the board we are using a board laid out from (4,4) to (99,99) //Each square is 12 by 12 units. Pieces are drawn ofset (2,2) from //the upper-left corner of the tile edge. //board[0,0] = A1, corresponds to drawing at (6,90) //board[0,7] = A8, corresponds to drawing at (6,6) //board[7,0] = H1, corresponds to drawing at (90,90) //board[7,7] = H8, corresponds to drawing at (90,6) //Formula: board[a,b] corresponds to drawing at (6 + a * 12, 90 - b * 12) //The code below is a reproduction of video_putchar, modified to draw //a 8 by 7 character instead of 5 by 7. It work like the following call: //video_putBIGchar(6 + x1 * 12, 90 - y1 * 12, INDEX) //Note: INDEX incremented by one if background tile is white, tested by: //(x+y) & 0x01 == 1 PutPiece_X = 6 + x * 12; PutPiece_Y = 90 - y * 12; PutPiece_C = INDEX + (((x+y) & 0x01)); v7 = PutPiece_X; for (v6=0;v6<7;v6++) begin v1 = PIECES[PutPiece_C][v6]; v8 = PutPiece_Y+v6; video_pt(v7, v8, (v1 & 0x80)==0x80); video_pt(v7+1, v8, (v1 & 0x40)==0x40); video_pt(v7+2, v8, (v1 & 0x20)==0x20); video_pt(v7+3, v8, (v1 & 0x10)==0x10); video_pt(v7+4, v8, (v1 & 0x08)==0x08); video_pt(v7+5, v8, (v1 & 0x04)==0x04); video_pt(v7+6, v8, (v1 & 0x02)==0x02); video_pt(v7+7, v8, (v1 & 0x01)==0x01); end end /**********************************************************/ /**********************************************************/ //CheckForCheck scans the board, from [0,0] to [7,7], and //looks for a valid move to the location of the opposing //King. If one is found, check! //If white is in check, WhiteInCheck =1 ; //If black is in check, BlackInCheck = 1; //These are not exclusive. void CheckForCheck(void) begin //printf("Entered CheckForCheck. "); WhiteInCheck = 0; BlackInCheck = 0; for(l = 0; l < 8; l++) begin for(m = 0; m < 8; m++) begin CFC_ActingPiece = board[l,m]; if((!BlackInCheck)&&IsWhite(CFC_ActingPiece)) begin if(IsMovePossible(l, m, BlackKingX, BlackKingY)) begin BlackInCheck = 1; end end else if((!WhiteInCheck)&&IsBlack(CFC_ActingPiece)) begin if(IsMovePossible(l, m, WhiteKingX, WhiteKingY)) begin WhiteInCheck = 1; end end end end end /**********************************************************/ /**********************************************************/ //If move is possible, WITHOUT CHECKING COLOR, returns 1. //If move is not possible, WITHUT CHECKING COLOR, returns 0. //Note IsMovePossible does check color for, and only for, //pawns taking other pieces. signed char IsMovePossible(signed char x1, signed char y1, signed char x2, signed char y2) begin IsMovePossibleActor = board[x1,y1]; IsMovePossibleTarget = board[x2,y2]; //Check if move is possible if(IsPawn(IsMovePossibleActor)) begin if((x1==x2)&&(((y2-1)==y1)^IsBlack(IsMovePossibleActor))&&(((y2+1)==y1)^IsWhite(IsMovePossibleActor))&&(board[x2,y2]==EmptyTile))//Move ahead one begin return 1; end else if((x1==x2)&&((y2-2)==y1)&&IsWhite(IsMovePossibleActor)&&(board[x2,y2]==EmptyTile)&&(board[x2,(y2-1)]==EmptyTile)&&(y1==1))//Move ahead two white begin return 1; //printf("White pawn moves forward two.\n\r"); end else if((x1==x2)&&((y2+2)==y1)&&IsBlack(IsMovePossibleActor)&&(board[x2,y2]==EmptyTile)&&(board[x2,(y2+1)]==EmptyTile)&&(y1==6))//Move ahead two black begin return 1; //printf("Black pawn moves forward two.\n\r"); end else if(((x1-1) == x2)&&((y1+1) == y2)&&(IsWhite(IsMovePossibleActor)&&IsBlack(IsMovePossibleTarget)))//Take Piece White begin return 1; //printf("White pawn takes a piece above and to the left.\n\r"); end else if(((x1+1) == x2)&&((y1+1) == y2)&&(IsWhite(IsMovePossibleActor)&&IsBlack(IsMovePossibleTarget)))//Take Piece White begin return 1; //printf("White pawn takes a piece above and to the right.\n\r"); end else if(((x1-1) == x2)&&((y1-1) == y2)&&(IsBlack(IsMovePossibleActor)&&IsWhite(IsMovePossibleTarget)))//Take Piece Black begin return 1; //printf("Black pawn takes a piece below and to the left.\n\r"); end else if(((x1+1) == x2)&&((y1-1) == y2)&&(IsBlack(IsMovePossibleActor)&&IsWhite(IsMovePossibleTarget)))//Take Piece Black begin return 1; //printf("Black pawn takes a piece below and to the right.\n\r"); end else if(((x1-1) == x2)&&(y1==4)&&(y2==5)&&(IsWhite(IsMovePossibleActor))&&(IsMovePossibleTarget==EmptyTile)&&(x2 == BlackPawnDoubleMove))//En passant! White pawn takes a piece above and to the left. begin return 1; end else if(((x1+1) == x2)&&(y1==4)&&(y2==5)&&(IsWhite(IsMovePossibleActor))&&(IsMovePossibleTarget==EmptyTile)&&(x2 == BlackPawnDoubleMove))//En passant! White pawn takes a piece above and to the right. begin return 1; end else if(((x1-1) == x2)&&(y1==2)&&(y2==1)&&(IsBlack(IsMovePossibleActor))&&(IsMovePossibleTarget==EmptyTile)&&(x2 == WhitePawnDoubleMove))//En passant! Black pawn takes a piece below and to the left. begin return 1; end else if(((x1+1) == x2)&&(y1==2)&&(y2==1)&&(IsBlack(IsMovePossibleActor))&&(IsMovePossibleTarget==EmptyTile)&&(x2 == WhitePawnDoubleMove))//En passant! Black pawn takes a piece below and to the right. begin return 1; end else begin return 0; end end//Pawn else if(IsKnight(IsMovePossibleActor)) begin//NOTE: We aren't worried about moving off the board if(((x1-2)==x2)&&((y1-1)==y2)) return 1; else if(((x1-2)==x2)&&((y1+1)==y2)) return 1; else if(((x1-2)==x2)&&((y1+1)==y2)) return 1; else if(((x1-1)==x2)&&((y1-2)==y2)) return 1; else if(((x1-1)==x2)&&((y1+2)==y2)) return 1; else if(((x1+1)==x2)&&((y1-2)==y2)) return 1; else if(((x1+1)==x2)&&((y1+2)==y2)) return 1; else if(((x1+2)==x2)&&((y1-1)==y2)) return 1; else if(((x1+2)==x2)&&((y1+1)==y2)) return 1; else begin return 0; end end//Knight else if(IsKing(IsMovePossibleActor)) begin if((-1 <= (x1-x2)) && (1 >= (x1-x2)) && (-1 <= (y1-y2)) && (1 >= (y1-y2))) begin return 1; end else if(IsWhite(IsMovePossibleActor)&&(!WhiteKingHasMoved)) begin if((x2 == 6)&&(y2 == 0)&&(board[5,0] == EmptyTile)&&(board[6,0] == EmptyTile)&&(board[7,0] == WhiteRook)&&(!WhiteKingSideRookHasMoved)) begin WhiteCastleKingSide = 1; return 1; end else if((x2 == 1)&&(y2 = 0)&&(board[1,0] == EmptyTile)&&(board[2,0] == EmptyTile)&&(board[3,0] == EmptyTile)&&(board[0,0] == WhiteRook)&&(!WhiteQueenSideRookHasMoved)) begin WhiteCastleQueenSide = 1; return 1; end else begin return 0; end end else if(IsBlack(IsMovePossibleActor)&&(!BlackKingHasMoved)) begin if((x2 == 6)&&(y2 == 0)&&(board[5,7] == EmptyTile)&&(board[6,7] == EmptyTile)&&(board[7,7] == BlackRook)&&(!BlackKingSideRookHasMoved)) begin BlackCastleKingSide = 1; return 1; end else if((x2 == 1)&&(y2 = 0)&&(board[1,7] == EmptyTile)&&(board[2,7] == EmptyTile)&&(board[3,7] == EmptyTile)&&(board[0,7] == BlackRook)&&(!BlackQueenSideRookHasMoved)) begin BlackCastleQueenSide = 1; return 1; end begin return 0; end end else begin return 0; = end end//King else//Everyone Else begin if(IsQueen(IsMovePossibleActor)||IsBishop(IsMovePossibleActor)) begin if((x2-x1)==(y2-y1))//A1 to H8 begin if(x2>x1)//Right and Up begin j = x1+1; k = y1+1; while((jx2)&&(k>y2)&&(board[j,k] == EmptyTile)) begin j--; k--; end if((j == x2) && (k == y2)) begin return 1; end else if(IsBishop(IsMovePossibleActor)) begin return 0; end end//Down and Left end//A1 to H8 else if((x2-x1)==(y1-y2)) begin//A8 to H1 if(x2>x1)//Right and Down begin j = x1+1; k = y1-1; while((jy2)&&(board[j,k] == EmptyTile)) begin j++; k--; end if((j == x2) && (k == y2)) begin return 1; end else if(IsBishop(IsMovePossibleActor)) begin return 0; end end//Right and Down else begin//Up and Left j = x1-1; k = y1+1; while((j>x2)&&(ky1)) begin//Up j = y1+1; while((jy2)) begin//Down j = y1-1; while((j>y2)&&(board[x1,j] == EmptyTile)) begin j--; end if(j==y2) return 1; else begin return 0; end end//Down else if ((y1 == y2)&&(x1 > x2)) begin//Left j = x1-1; while((j>x2)&&(board[j,y1] == EmptyTile)) begin j--; end if(j==x2) return 1; else begin return 0; end end//Left else begin return 0; end end//Rook or Queen end//Everyone Else end//IsMovePossible /**********************************************************/ /**********************************************************/ //ValidMove = 1 if move is valid, ValidMove = 0 if move is not. //ValidMove DOES CHECK FOR COLOR, but DOES NOT CHECK FOR MOVING INTO CHECK! signed char IsMoveValid(signed char x1, signed char y1, signed char x2, signed char y2) begin IsMoveValidActor = board[x1,y1]; IsMoveValidTarget = board[x2,y2]; //Check player if((IsWhite(IsMoveValidActor) == WhiteTurn)&&((x1!=x2)||(y1!=y2))) begin //Check for correct colors if((IsMoveValidTarget == EmptyTile)||(IsBlack(IsMoveValidTarget)==WhiteTurn)) begin //Check if move is possible if(IsMovePossible(x1, y1, x2, y2)) begin return 1; end else begin return 0; end end else begin //printf("Wrong color target.\n\r"); return 0; end end else begin //printf("Wrong color piece!\n\r"); return 0; end end /**********************************************************/ /**********************************************************/ void PollUSART(void) begin CharRecieved = 0; if(UCSRA.7) begin RecievedChar = getchar(); //printf("Got Char: %c", RecievedChar); if((RecievedChar == 0x08) && (PollUSART_INDEX > 0))//Backspace begin CharRecieved = 1; RecievedMove[--PollUSART_INDEX] = 0;//Delete the LAST character TransmittedMove[SendUSART_INDEX++] = 0x08;//Send a backspace to hyperterm TransmittedMove[SendUSART_INDEX++] = 0x08;//Send a space to hyperterm //NOTE: Main will copy the last character recieved back to hyperterm, this means that TWO backspaces will be sent. This is correct behavior. RecievedChar = ' '; end if((0x41 <= RecievedChar)&&(RecievedChar <= 0x48))//Capital Letter, from A to H begin RecievedChar = RecievedChar + 32;//Convert to lower case end if (((0x30 <= RecievedChar)&&(RecievedChar <= 0x39)) || ((0x61 <= RecievedChar)&&(RecievedChar <= 0x68)) || (RecievedChar == ' '))//Good Text, a lower case letter from a to h, a number from 1 to 8, or a space. begin CharRecieved = 1; RecievedMove[PollUSART_INDEX++] = RecievedChar; end end if(PollUSART_INDEX == 5) begin RecieveComplete = 1; PollUSART_INDEX = 0; end // else // begin // RecieveComplete = 0; // end end /**********************************************************/ /**********************************************************/ void PollBoard(void) begin for(j = 0; j < 8; j++) begin DDRA = (0x01< 0) begin video_smallchar(PrintOffset_X - 8, PrintOffset_Y, TurnNumberHundreds); video_smallchar(PrintOffset_X - 4, PrintOffset_Y, TurnNumberTens); video_smallchar(PrintOffset_X, PrintOffset_Y, TurnNumberOnes); end else if(TurnNumberTens > 0) begin video_smallchar(PrintOffset_X - 4, PrintOffset_Y, TurnNumberTens); video_smallchar(PrintOffset_X, PrintOffset_Y, TurnNumberOnes); end else begin video_smallchar(PrintOffset_X, PrintOffset_Y, TurnNumberOnes); end video_smallchar(PrintOffset_X + 4, PrintOffset_Y, RecievedMove[0] - 'a' + 13); video_smallchar(PrintOffset_X + 8, PrintOffset_Y, RecievedMove[1] - 0x30); video_smallchar(PrintOffset_X + 12, PrintOffset_Y, 12); video_smallchar(PrintOffset_X + 16, PrintOffset_Y, RecievedMove[3] - 'a' + 13); video_smallchar(PrintOffset_X + 20, PrintOffset_Y, RecievedMove[4] - 0x30); PrintOffset_Y = PrintOffset_Y + 8; end else begin video_smallchar(PrintOffset_X + 4, PrintOffset_Y, RecievedMove[0] - 'a' + 13); video_smallchar(PrintOffset_X + 8, PrintOffset_Y, RecievedMove[1] - 0x30); video_smallchar(PrintOffset_X + 12, PrintOffset_Y, 12); video_smallchar(PrintOffset_X + 16, PrintOffset_Y, RecievedMove[3] - 'a' + 13); video_smallchar(PrintOffset_X + 20, PrintOffset_Y, RecievedMove[4] - 0x30); PrintOffset_Y = PrintOffset_Y + 8; if(PrintOffset_Y >80) begin PrintOffset_Y = PrintOffset_Y_Base; end end end//PrintMove /**********************************************************/ /**********************************************************/ void ChangeTurn(void) begin WhiteTurn = (WhiteTurn^1); if(WhiteTurn) begin TurnNumberOnes++; if(TurnNumberOnes == 10) begin TurnNumberOnes = 0; TurnNumberTens++; end if(TurnNumberTens == 10) begin TurnNumberTens = 0; TurnNumberHundreds++; end if((TurnNumberOnes == 0)&&(TurnNumberTens == 1)&&(TurnNumberHundreds == 0)) begin PrintOffset_X = PrintOffset_X + 4; end if((TurnNumberOnes == 0)&&(TurnNumberTens == 0)&&(TurnNumberHundreds == 1)) begin PrintOffset_X = PrintOffset_X + 4; end end end//ChangeTurn /**********************************************************/ /**********************************************************/ void SendUSART(void) begin if(UCSRA.5 && (SendUSART_INDEX > 0)) begin CharSent = 1; TransmittedChar = TransmittedMove[0]; //printf("putchar: %c\n\r", TransmittedChar); putchar(TransmittedChar); TransmittedChar = 122; putchar(TransmittedChar); TransmittedChar = TransmittedMove[0]; SendUSART_INDEX--; for(j = 0; j < SendUSART_INDEX; j++) begin TransmittedMove[j] = TransmittedMove[j+1]; end for(j = SendUSART_INDEX; j < 10; j++) begin TransmittedMove[j] = 0; end end else begin CharSent = 0; end if(SendUSART_INDEX > 0) begin TransmitComplete = 0; end else begin TransmitComplete = 1;\ GoodMove = 0; end end /**********************************************************/ /**********************************************************/ // set up the ports and timers void main(void) begin //init the UART UCSRB = 0x18; UBRRL = 103; //using a 16 MHz crystal (9600 baud) DDRA = 0xFF; PORTA = 0x00;//Sinks current DDRB = 0x00;//PortB is Input. Sources current PORTB = 0xFF;//PortB pull-up resistors active DDRC = 0x00;//PortC is Input InitializeVideoCrap(); MCUCR = 0b10000000; #asm ("sei"); SendUSART_INDEX = 0; IntroCounter = 180; while(1) begin //stall here until next line starts //sleep enable; mode=idle //use sleep to make entry into sync ISR uniform time #asm ("sleep"); //The following code executes during the vertical blanking //Code here can be as long as //a total of 60 lines x 63.5 uSec/line x 8 cycles/uSec if (LineCount==231) begin #asm ("cli"); if(GoodMove == 1) begin SendUSART(); end else begin if(SendUSART_INDEX < 9)//If we have room to send back what we recieve begin PollUSART(); end if(CharRecieved) begin CharRecieved = 0; end BoardMove = 0; PollBoard(); if(FirstScan == 1) { FirstScan = 0; for(j = 0; j < 8; j++) begin for(k = 0; k < 2; k++) begin if((OldBoard[j,k]==0)||(PlayingWhite == 0)) begin InitializePiece(j,k); end end for(k = 6; k < 8; k++) begin if((OldBoard[j,k]==0)||(PlayingWhite == 1)) begin InitializePiece(j,k); end end end } if((BoardChanges == 1)&&(RecieveComplete==0)) begin if(PollUSART_INDEX == 0) begin SendUSART_INDEX = 0; TransmittedMove[SendUSART_INDEX++] = Change_x1 + 'a'; TransmittedMove[SendUSART_INDEX++] = Change_y1 + '1'; TransmittedMove[SendUSART_INDEX++] = ' '; RecievedMove[0] = Change_x1 + 'a'; RecievedMove[1] = Change_y1 + '1'; RecievedMove[2] = ' '; RecieveComplete = 0; PollUSART_INDEX = 3; TransmitComplete = 0; end else if(PollUSART_INDEX == 3) begin SendUSART_INDEX = 3; TransmittedMove[SendUSART_INDEX++] = Change_x2 + 'a'; TransmittedMove[SendUSART_INDEX++] = Change_y2 + '1'; RecievedMove[3] = Change_x2 + 'a'; RecievedMove[4] = Change_y2 + '1'; RecieveComplete = 1; PollUSART_INDEX = 0; TransmitComplete = 0; BoardMove = 1; end for(j = 0; j < 8; j++) begin for(k = 0; k < 8; k++) begin OldBoard[j,k] = ScanBoard[j,k]; end end PollBoard(); end /*PollButtons(); if((ButtonSelect != 0)&&TransmitComplete) begin if(PollUSART_INDEX == 0) begin TransmittedMove[SendUSART_INDEX++] = ('a' - 1) + ButtonSelect; RecievedMove[0] = ('a' - 1) + ButtonSelect; PollUSART_INDEX = 1; RecieveComplete = 0; TransmitComplete = 0; end else if(PollUSART_INDEX == 1) begin TransmittedMove[SendUSART_INDEX++] = '0' + ButtonSelect; TransmittedMove[SendUSART_INDEX++] = ' '; RecievedMove[1] = '0' + ButtonSelect; RecievedMove[2] = ' '; PollUSART_INDEX = 3; RecieveComplete = 0; TransmitComplete = 0; end else if(PollUSART_INDEX == 3) begin TransmittedMove[SendUSART_INDEX++] = ('a' - 1) + ButtonSelect; RecievedMove[3] = ('a' - 1) + ButtonSelect; PollUSART_INDEX = 4; RecieveComplete = 0; TransmitComplete = 0; end else if(PollUSART_INDEX == 4) begin SendUSART_INDEX = 0; TransmittedMove[SendUSART_INDEX++] = '0' + ButtonSelect; RecievedMove[4] = '0' + ButtonSelect; RecieveComplete = 1; PollUSART_INDEX = 0; TransmitComplete = 0; end end*/ if(RecieveComplete) begin //#asm("cli"); RecieveComplete = 0; TransmitComplete = 0; Main_x1 = (RecievedMove[0]-0x61); Main_y1 = (RecievedMove[1]-0x31); Main_x2 = (RecievedMove[3]-0x61); Main_y2 = (RecievedMove[4]-0x31); ValidMove = 1; if(Main_x1 < 0 || Main_x1 > 7) begin ValidMove = 0; end if(Main_y1 < 0 || Main_y1 > 7) begin ValidMove = 0; end if(Main_x2 < 0 || Main_x2 > 7) begin ValidMove = 0; end if(Main_y2 < 0 || Main_y2 > 7) begin ValidMove = 0; end if(ValidMove) begin Main_ActingPiece = board[Main_x1, Main_y1]; Main_ActingTarget = board[Main_x2, Main_y2]; end WhiteCastleKingSide = 0; WhiteCastleQueenSide = 0; BlackCastleKingSide = 0; BlackCastleQueenSide = 0; ValidMove = IsMoveValid(Main_x1, Main_y1, Main_x2, Main_y2); if(ValidMove) begin if(IsKing(Main_ActingPiece)) { if(WhiteCastleKingSide) begin CheckForCheck(); if(WhiteInCheck) begin ValidMove = 0; end if(ValidMove) begin board[5,0] = board[4,0]; WhiteKingX = 5; CheckForCheck(); end if(WhiteInCheck) begin ValidMove = 0; WhiteKingX = 4; end if(ValidMove) begin board[6,0] = board[5,0]; WhiteKingX = 6; CheckForCheck(); end if(WhiteInCheck) begin ValidMove = 0; WhiteKingX = 4; end if(ValidMove) begin //NONSTANDARD: White castles kingside board[4,0] = board[6,0]; MovePiece(4,0,6,0); MovePiece(7,0,5,0); ValidMove = 0; WhiteKingX = 6; WhiteKingHasMoved = 1; if(OldBoard[7,0] == 0) begin OldBoard[7,0] = 1; OldBoard[5,0] = 0; HypotheticalBoard = 1; end PrintMove(); ChangeTurn(); end else begin WhiteKingX = 4; end end//White castles kingside else if(WhiteCastleQueenSide) begin CheckForCheck(); if(WhiteInCheck) begin ValidMove = 0; end if(ValidMove) begin board[3,0] = board[4,0]; WhiteKingX = 3; CheckForCheck(); end if(WhiteInCheck) begin ValidMove = 0; WhiteKingX = 4; end if(ValidMove) begin board[2,0] = board[3,0]; WhiteKingX = 2; CheckForCheck(); end if(WhiteInCheck) begin ValidMove = 0; WhiteKingX = 4; end if(ValidMove) begin board[4,0] = board[2,0]; MovePiece(4,0,2,0); MovePiece(0,0,3,0); ValidMove = 0; WhiteKingX = 2; WhiteKingHasMoved = 1; if(OldBoard[0,0] == 0) begin OldBoard[0,0] = 1; OldBoard[3,0] = 0; HypotheticalBoard = 1; end PrintMove(); ChangeTurn(); end end//White castles queenside else if(BlackCastleKingSide) begin CheckForCheck(); if(BlackInCheck) begin ValidMove = 0; end if(ValidMove) begin board[5,7] = board[4,7]; BlackKingX = 5; CheckForCheck(); end if(BlackInCheck) begin ValidMove = 0; BlackKingX = 4; end if(ValidMove) begin board[6,7] = board[5,7]; BlackKingX = 6; CheckForCheck(); end if(BlackInCheck) begin ValidMove = 0; end if(ValidMove) begin //NONSTANDARD: Black castles kingside board[4,7] = board[6,7]; MovePiece(4,7,6,7); MovePiece(7,7,5,7); ValidMove = 0; BlackKingX = 7; BlackKingHasMoved = 1; if(OldBoard[7,7] == 0) begin OldBoard[7,7] = 1; OldBoard[5,7] = 0; HypotheticalBoard = 1; end PrintMove(); ChangeTurn(); end end//Black castles kingside else if(BlackCastleQueenSide) begin CheckForCheck(); if(BlackInCheck) begin ValidMove = 0; end if(ValidMove) begin board[3,7] = board[4,7]; BlackKingX = 3; CheckForCheck(); end if(BlackInCheck) begin ValidMove = 0; BlackKingX = 4; end if(ValidMove) begin board[2,7] = board[3,7]; BlackKingX = 3; CheckForCheck(); end if(BlackInCheck) begin ValidMove = 0; BlackKingX = 4; end if(ValidMove) begin //NONSTANDARD: black castles queenside board[4,7] = board[2,7]; MovePiece(4,7,2,7); MovePiece(0,7,3,7); ValidMove = 0; BlackKingX = 2; BlackKingHasMoved = 1; if(OldBoard[0,7] == 0) begin HypotheticalBoard = 1; OldBoard[0,7] = 1; OldBoard[3,7] = 0; end PrintMove(); ChangeTurn(); end end//Black castles queenside }//King move if(ValidMove);//Is a valid, non-castling move, before testing for check. begin Main_SavedPiece = Main_ActingTarget; if(IsPawn(Main_ActingPiece)&&(Main_ActingTarget == EmptyTile)&&(Main_x1 != Main_x2)) begin if(IsWhite(Main_ActingPiece)) begin Main_SavedPiece2 = board[Main_x2,(Main_y2-1)]; board[Main_x2,(Main_y2-1)] = EmptyTile; end else begin Main_SavedPiece2 = board[Main_x2,(Main_y2+1)]; board[Main_x2,(Main_y2+1)] = EmptyTile; end end else begin Main_SavedPiece2 = 0; end board[Main_x2, Main_y2] = Main_ActingPiece; board[Main_x1, Main_y1] = EmptyTile; if(IsKing(Main_ActingPiece)) begin if(IsWhite(Main_ActingPiece)) begin WhiteKingX = Main_x2; WhiteKingY = Main_y2; end else begin BlackKingX = Main_x2; BlackKingY = Main_y2; end end CheckForCheck(); if((WhiteTurn && WhiteInCheck)||((!WhiteTurn) && BlackInCheck)) begin ValidMove = 0; if(IsWhite(Main_ActingPiece)&&IsKing(Main_ActingPiece)) begin WhiteKingX = Main_x1; WhiteKingY = Main_y1; end else if(IsBlack(Main_ActingPiece)&&IsKing(Main_ActingPiece)) begin BlackKingX = Main_x1; BlackKingY = Main_y1; end else if(IsPawn(Main_ActingPiece)) begin board[Main_x2,(Main_y2-1)] = Main_SavedPiece2; end end if(ValidMove) { board[Main_x2, Main_y2] = EmptyTile; board[Main_x1, Main_y1] = Main_ActingPiece; //NONSTANDARD: Pawn promotion //Remember, TILE and QUEEN are indicies, (index+1) indicates white piece. if(IsPawn(Main_ActingPiece)&&IsWhite(Main_ActingPiece)&&(Main_y2==7)) begin PutPiece(Main_x1, Main_y1, TILE); PutPiece(Main_x2, Main_y2, QUEEN + 1); end else if(IsPawn(Main_ActingPiece)&&IsBlack(Main_ActingPiece)&&(Main_y2 == 1)) begin PutPiece(Main_x1, Main_y1, TILE); PutPiece(Main_x2, Main_y2, QUEEN); end else begin MovePiece(Main_x1, Main_y1, Main_x2, Main_y2); end //NONSTANDARD: En Passant if(IsPawn(Main_ActingPiece)&&(Main_ActingTarget == EmptyTile)&&(Main_x1 != Main_x2)) begin if(IsWhite(Main_ActingPiece)) begin MakePiece(Main_x2,(Main_y2-1), TILE); if(OldBoard[Main_x2,(Main_y2-1)] == 0) begin OldBoard[Main_x2,(Main_y2-1)] = 1; HypotheticalBoard = 1; end end else begin MakePiece(Main_x2,(Main_y2+1), TILE); if(OldBoard[Main_x2,(Main_y2+1)] == 0) begin OldBoard[Main_x2,(Main_y2+1)] = 1; HypotheticalBoard = 1; end end end else begin if((BoardMove == 0)&&(OldBoard[Main_x2,Main_y2] == 0)) begin OldBoard[Main_x2,Main_y2] = 1; HypotheticalBoard = 1; end end PrintMove(); ChangeTurn(); if(IsPawn(Main_ActingPiece)) begin if(IsWhite(Main_ActingPiece)&&(Main_y2==3)&&(Main_y1==1)) begin WhitePawnDoubleMove = Main_x1; BlackPawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. end else if(IsBlack(Main_ActingPiece)&&(Main_y2==4)&&(Main_y1==6)) begin WhitePawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. BlackPawnDoubleMove = Main_x1; end else begin WhitePawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. BlackPawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. end end//IsPawn else begin WhitePawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. BlackPawnDoubleMove = 8;//Cannot reset to zero, zero implies A rank move. end if(IsKing(Main_ActingPiece)) begin if(IsWhite(Main_ActingPiece)) begin WhiteKingHasMoved = 1; WhiteKingX = Main_x2; WhiteKingY = Main_y2; end else begin BlackKingHasMoved = 1; BlackKingX = Main_x2; BlackKingY = Main_y2; end end//King Moves (non-castle) if(((Main_x1 == 0)&&(Main_y1==0))||((Main_x2 == 0)&&(Main_y2==0))) begin WhiteQueenSideRookHasMoved = 1; end if(((Main_x1 == 7)&&(Main_y1==0))||((Main_x2 == 7)&&(Main_y2==0))) begin WhiteKingSideRookHasMoved = 1; end if(((Main_x1 == 0)&&(Main_y1==7))||((Main_x2 == 0)&&(Main_y2==7))) begin BlackQueenSideRookHasMoved = 1; end if(((Main_x1 == 7)&&(Main_y1==7))||((Main_x2 == 7)&&(Main_y2==7))) begin BlackKingSideRookHasMoved = 1; end }//ValidMove else//Not a valid move, after checking for check and stuff. { board[Main_x1, Main_y1] = Main_ActingPiece; board[Main_x2, Main_y2] = Main_SavedPiece; } end end end //RecieveComplete end #asm("sei"); end //line 231 end //while end //main /**********************************************************/