PIC micro Tetris game

8,606

Circuit Image

The game Tetris is implemented using a PIC16F84 microcontroller operating at 12MHz. Tetris is a classic Russian computer game where players fit blocks into a playfield. In this implementation, the video signal is generated through software, utilizing only two resistors to form a 2-bit digital-to-analog converter (DAC). Typically, video signals in games are produced by dedicated video chips that read image data from graphics memory. However, in this project, the microprocessor calculates the video signal in real-time as the electron beam sweeps across the screen. The initial screen allows players to select their mode of play using a joystick: DOWN for Human vs. Human (H-H), LEFT for Human vs. Computer (H-C), or RIGHT for Computer vs. Computer (C-C). The game starts with a FIRE button press. It is noted that defeating the computer is impossible due to limitations in the design, leading to a perpetual game state in the computer vs. computer mode until a reset switch is activated. Players can serve the ball by pressing FIRE, and they can also adjust the ball's direction and speed. Points are awarded to the player who serves, and if the serving player misses the ball, the serve transfers to the opponent. A winning screen displays the victor at the end of a game. Given the processor's performance of 3 MIPS, generating a video signal in software is challenging, as each instruction takes 1/3 microsecond to execute. Each scan line on the screen lasts 64 microseconds, with 52 microseconds of visible display time, allowing for 156 visible clock cycles per line. The maximum achievable resolution is 156 pixels along the x-axis if one pixel is set per clock cycle, but additional programming complexity, such as loops, reduces this to a resolution of 52 pixels. Tetris, being a relatively simple game with low resolution and no motion, primarily involves turning pixel blocks on and off. The most complex aspect is displaying the score at the bottom of the screen, which is achieved by loading PORTB with the bitmap for the score and shifting it out one pixel at a time. In addition to graphic generation, a video signal requires synchronization pulses. Each scan line begins with a 4-microsecond sync pulse, followed by an 8-microsecond black screen, and then the 52 microseconds of graphics. Horizontal sync pulses inform the TV when a scan line starts, while vertical sync signals indicate the start of a new image. Vertical sync is divided into two patterns to minimize flickering, and although both images are identical in Tetris, this design choice does not fully utilize the y-resolution. The game field is stored in a 32-byte array (16x16 bits), where each bit represents a pixel block on the screen. The upper left section shows the next block, utilizing the same drawing routines as the game field to conserve memory. Each frame, the falling block is removed from the game field, movement is tested based on player input, and then the block is redrawn at its new position. Before testing a block for placement, it must be generated by decompressing data, rotating it, and storing its relative coordinates.

The Tetris game circuit utilizes a PIC16F84 microcontroller, which is programmed to handle both game logic and video signal generation. The microcontroller is clocked at 12MHz, providing sufficient processing speed for the game's requirements. The software-based video generation involves creating a 2-bit DAC using two resistors, which allows the microcontroller to output analog signals for video display. The game logic is structured to manage player interactions, block movements, and scoring efficiently.

The joystick input is read by the microcontroller to determine the selected game mode and control the movement of the blocks. The game field is represented in memory as a 32-byte array, allowing for efficient storage and manipulation of the pixel data. The implementation of the scoring system involves careful bitmap management, ensuring that the score is displayed accurately and promptly on the screen.

The video output is synchronized using horizontal and vertical sync pulses, which are essential for maintaining proper timing with the television display. The horizontal sync pulse indicates the start of each scan line, while the vertical sync pulse signals the beginning of a new frame. This synchronization is crucial for creating a stable visual experience, despite the limitations of the resolution.

In summary, the Tetris game implemented on the PIC16F84 microcontroller demonstrates an innovative approach to software-based video generation, utilizing a minimalistic hardware setup while achieving functional gameplay. The design effectively combines game logic, user input, and video output within the constraints of the microcontroller's capabilities, resulting in a playable and engaging experience.The game Tetris using a PIC16F84 running @ 12MHz. Tetris is an old Russian computer game where you should try to fit in block into a play-field, quite simple but really fun. In my version, the video signal is generated in softw1are. The only hardware used for the video generation is tw1o resistors forming a 2-bit DA converter. Usuallythe video signal is generated in video games is created with a dedicated video chips, reading the image data from a graphics memory. In this project the video signal is calculated in real-time by the microprocessor as the electron beam sweeps over the screen. The first screen is where you select how you want to play by moving the joystick: DOWN: Human vs. Human (H-H), LEFT: Human vs. Computer (H-C) or RIGHT: Computer vs. Computer (C-C). Start with FIRE. Unfortunately it is impossible to beat the computer, since there was not enough room to make the computer beatable.

That makes the computer vs. computer game to play forever until someone reset the game using the reset switch. You start serving by pressing fire, it is also possible to change direction and speed of the ball using fire. The player who has the serve will get points. If the player with the serve miss the ball, then the serve goes over to the other player. When someone wins a game over picture will show and tell who won. With a processor performing 3MIPS, it is not easy to make a video signal in softw1are. Each instruction performed takes 1/3 us. Each scan-line on the screen takes 64us, where 52us are visible, so it gives 52*3=156 visible clock cycles per line.

Maximum resolution that can be obtained is 156 pixels in x-axis if the softw1are is setting one pixel per clock (using for example only bcf and bsf), but more is needed to make a game, like loops and such. A loop quantifies the time to 3-clock pieces, giving a resolution of 52 pixels. (One could obtain a kind of 156pixels resolution with one or tw1o offset nops, but the code to select this would eat to many clock cycles to do any good).

However Tetris is quite simple, the resoluton is quite low, and there is no motion, the blocks of pixels are just turned on and off. The most demanding part of the game is to show the score at the bottom of the screen, it is shown in the bottom of the screen.

It obtains higher resolution by loading the PORTB with the bitmap for the number and shift it out one pixel per clock cycle. So far I`ve only talked about the graphic generation. But there is more to it to get a video signal. All scan-lines first have a 4us-sync pulse, then black for 8us, then the 52us graphic comes. These horizontal sync-pulses makes the TV understand when a scan-line starts, but there is needed to send information about when a new picture starts too, it is called vertical sync, and is a special pattern that tells the TV that a new image is coming.

There are tw1o kinds of vertical sync, because the image is divided into tw1o part images, showing even and odd lines, to get less flickering. In Tetris, the tw1o images are identical, so the game is not using the full y-resolution possible, but it doesn`t matter because it is way better than the x-resolution anyway, making the x-resolution the biggest problem.

The game-field is kept in memory as a 32byte array, 16x16 bits, where one bit is one pixel-block on the screen. The area to the upper left is for showing the next block, and by making it a part of the game field it is possible to use the same block-drawing routines as for the game, and thereby saving memory.

Each frame, the falling block is first removed from the game-field, and then tests are performed if the block can move, as the player wants it to. Then the block is drawn back to the screen at the new position. When a block is to be tested, put or removed, it first must be generated. To generate a block means compressing it from the compressed data, rotating it and then store the relative coord

🔗 External reference