Advertisement
Guest User

Mine Dodger (8051)

a guest
Oct 27th, 2010
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.90 KB | None | 0 0
  1. /* Made by Ben Duncan (C) */
  2.  
  3. // Included header files
  4.  
  5. #include <8051.h>
  6. #include <string.h>
  7. #include <stdio.h>  /* for printf, printf_fast, etc */
  8.  
  9. // Subroutine decleration
  10.  
  11. extern void delay_ms(unsigned char ms);
  12. extern void restart(void);
  13. extern char key_char(void);
  14. extern void lcd_putchar(char c);
  15. extern void lcd_command(unsigned char cmd);
  16. extern void lcd_set_xy_raw(unsigned int x_and_y);
  17. extern char a2d(void);
  18. void delay(int s);          // Integer seconds only delay
  19. void display_rules(void);
  20. void display_countdown(char count); // Displays a countdown from 'count' to 0
  21. void generate_player(void);
  22. void generate_enemies(void);
  23.  
  24. // Memory map locations for TAD board
  25.  
  26. #define DIL_SWITCH 0x0000       // DIL Switch at address 0000h 
  27. #define DAC 0x0600          // DAC at address 0600h
  28. #define LCD_COMMAND_WR 0x0800       // Write LCD Command at address 0800h
  29. #define LCD_STATUS_RD 0x0801        // Read LCD Status at address 0801h
  30. #define LCD_DATA_WR 0x0802      // Write LCD Data at address 0802h
  31. #define LCD_DATA_RD 0x0803      // Read LCD Data at address 0803h
  32. #define COMPARATOR P3_5         // Comparator is set to bit P3.5
  33.  
  34. // External data locations
  35.  
  36. volatile xdata at DAC unsigned char dac;
  37. volatile xdata at LCD_COMMAND_WR unsigned char lcd_command_wr;
  38. volatile xdata at LCD_STATUS_RD unsigned char lcd_status_rd;
  39. volatile xdata at LCD_DATA_WR unsigned char lcd_data_wr;
  40. volatile xdata at LCD_DATA_RD unsigned char lcd_data_rd;
  41.  
  42. // LCD commands
  43.  
  44. #define LCD_CLEAR_CMD 0x01
  45. #define LCD_HOME_CMD 0x02
  46. #define LCD_ON_CMD 0x0C
  47. #define LCD_SHIFT_CMD 0x10
  48. #define LCD_CONFIG_CMD 0x38
  49.  
  50. // Macro to merge two parameters into a single 16-bit parameter
  51.  
  52. #define lcd_set_xy(x, y) (lcd_set_xy_raw((x) + ((y) << 8)))
  53.  
  54. // LCD screen parameters
  55.  
  56. #define LCD_HORIZ_SIZE  16
  57. #define LCD_VERT_SIZE   2
  58. #define LCD_BYTES_PER_LINE  (128 / LCD_VERT_SIZE)
  59.  
  60. // Send serial data to LCD or Serial Port
  61.  
  62. bit print_to_lcd=0;
  63.  
  64. // Interrupt declaration
  65.  
  66. void ex0_isr(void) interrupt 0;
  67. void ex1_isr(void) interrupt 2;
  68.  
  69. // Set the side of the 'track' the player is on
  70.  
  71. bit player_side = 0;                        // Defaults to the right side '0'
  72.  
  73. // Soft-enable/disables interrupts
  74.  
  75. bit enable_interrupts;
  76.  
  77. /* Player and characters */
  78.  
  79. #define PLAYER "X"
  80. #define MINE "*"
  81. #define PLAYER_X 16                     // Sets player to right of screen
  82. #define ENEMY_SPACES 12                     // # spaces enemies can exist in
  83. #define ENEMY_START 0                       // Start position of enemies
  84. #define ENEMY_END_ 11                       // End position of enemies
  85. #define NUM_ENEMY_STR 1                     // Number of enemy strings
  86.  
  87. /* Enemy sprites */
  88.  
  89. char enemy_track1[20] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};  // Sprites of enemies on track 1
  90. char enemy_track2[20] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};  // Sprites of enemies on track 2
  91.  
  92. /* Keyboard character codes */
  93.  
  94. #define BS_KEY 8
  95. #define ESC_KEY 27
  96. #define SPACE_KEY 32
  97. #define DEL_KEY 127
  98.  
  99. /* Main code section */
  100.  
  101. void main(){
  102.     /* Initialise devices */
  103.     enable_interrupts = 0;                  // Disallow interrupt functions to change 'player_side' state
  104.     EA=1;                           // Configure interrupt 0 for falling edge on /INT0 (P3.2)
  105.         EX0 = 1;                            // Enable EX0 Interrupt
  106.         EX1 = 1;                            // Enable EX1 Interrupt
  107.     lcd_command(LCD_HOME_CMD);              // Initialise LCD
  108.     lcd_command(LCD_CLEAR_CMD);             // Clear LCD screen
  109.     print_to_lcd=1;                     // Select LCD
  110.     lcd_set_xy(0,0);                    // Select LCD character
  111.     printf_fast("- Mine Dodger! -");            // Display first line of LCD
  112.     lcd_set_xy(0,1);                    // Select LCD character
  113.     printf_fast(" By Ben Duncan  ");            // Display second line of LCD
  114.     delay(3);                       // Wait for 3 seconds
  115.     lcd_command(LCD_CLEAR_CMD);             // Clear LCD screen
  116.    
  117.     /* Main control loop that exits when 'esc' is pressed on the keyboard */
  118.    
  119.     do{
  120.         enable_interrupts = 1;              // Allow interrupt functions to change 'player_side' state
  121.         generate_player();              // Print player to screen
  122.         generate_enemies();             // Display enemies on LCD screen
  123.     } while(key_char() != ESC_KEY);             // When 'esc' is pressed escape loop
  124. }
  125.  
  126. /* Subroutines for Display */
  127.  
  128. void generate_enemies(void){
  129.     int j,i;
  130.     for(i=0; i<ENEMY_SPACES; i++){
  131.         for(j=0; j<ENEMY_SPACES; j++){
  132.             lcd_set_xy(i, 0);           // Set position of line 1 of enemies
  133.             printf_fast(enemy_track1[j]);
  134.             lcd_set_xy(i, 1);           // Set position of line 2 of enemies
  135.             printf_fast(enemy_track2[j]);
  136.         }
  137.         speed_delay(1);                 // Delay for enemy speed
  138.         i++                     // Move enemies up one place on the screen
  139.         if(i=>ENEMY_SPACES){                // If the next enemy moves past the end position
  140.             i=0;                    // Start at 0 again
  141.         }
  142.     }
  143. }
  144.  
  145. void generate_player(void){
  146.     lcd_set_xy(PLAYER_X, player_side);          // Place player on right of screen on 'player_side'
  147.     printf_fast(PLAYER);                    // Print player (X)
  148.     delay_ms(10);                       // Wait for LCD to refresh
  149. }
  150.  
  151. void display_countdown(char count){             // Passes value of countdown
  152.     int n;                          // Counting variable
  153.     lcd_command(LCD_CLEAR_CMD);             // Clear LCD screen
  154.     for(n=count; n>0; n--){                 // Count 5-0
  155.         lcd_set_xy(0,0);                // Select LCD character
  156.         printf_fast("Start in: %d     ", n);        // Display first line of LCD
  157.         delay(1);                   // Wait for 1 second
  158.     }
  159. }
  160.  
  161. void display_rules(void){
  162.     lcd_command(LCD_CLEAR_CMD);             // Clear LCD screen
  163.     lcd_set_xy(0,0);                    // Select LCD character
  164.     printf_fast("* are the mines ");            // Display first line of LCD
  165.     lcd_set_xy(0,1);                    // Select LCD character
  166.     printf_fast(" & are dangerous");            // Display second line of LCD
  167.     delay(5);                       // Wait for 5 seconds
  168.     lcd_set_xy(0,0);                    // Select LCD character
  169.     printf_fast("X is the vehicle");            // Display first line of LCD
  170.     lcd_set_xy(0,1);                    // Select LCD character
  171.     printf_fast("Avoid the mines!");            // Display second line of LCD
  172.     delay(5);                       // Wait for 5 seconds
  173. }
  174.  
  175. /* Subroutines for Interrupts */
  176.  
  177. void ex0_isr(void)  interrupt 0{                // 'Left' button
  178.     if(enable_interrupts==1){               // If enabled
  179.         if(player_side==1){             // If player on right
  180.             player_side = 0;            // Set player to left side
  181.             lcd_set_xy(PLAYER_X,player_side);   // Select location of player
  182.             printf_fast(PLAYER);            // Display player on screen
  183.         }
  184.     }
  185. }
  186.  
  187. void ex1_isr(void)  interrupt 2{                // 'Right' button
  188.     if(enable_interrupts==1){               // If enabled
  189.         if(player_side==0){             // If player on left
  190.             player_side = 1;            // Set player to right side
  191.             lcd_set_xy(PLAYER_X,player_side);   // Select location of player
  192.             printf_fast(PLAYER);            // Display player on screen
  193.         }
  194.     }
  195. }
  196.  
  197. /* Subroutines to control and communicate with the LCD */
  198.  
  199. void putchar(char c)                        // Write character to lcd or serial port
  200. {
  201.     if (print_to_lcd)                   // If print_to_lcd is set then write to lcd
  202.     {
  203.         lcd_putchar(c);
  204.     }
  205.     else                            // Else write to the serial port
  206.     {
  207.     while(!TI);  /* Wait for ready */
  208.     TI=0;
  209.     SBUF = c;
  210.     }
  211. }
  212.  
  213. char getchar(void)                      // Get character from serial port
  214. {
  215.     char c;
  216.     while(!RI);
  217.     RI =0;
  218.     c = SBUF;
  219.     return c;
  220. }
  221.  
  222. void restart(void)                      // Soft reset, jumps to address 0000h
  223. {
  224.     _asm
  225.     ljmp    0
  226.     _endasm;
  227. }
  228.  
  229. char key_char(void)
  230. {
  231.     char c;
  232.     if (RI)
  233.     {
  234.         RI = 0;
  235.         c = SBUF;
  236.     }
  237.     return c;
  238. }
  239.  
  240. char a2d(void)
  241. {
  242.  
  243.     unsigned char val=0;
  244.    
  245.     dac = 0;
  246.     delay_ms(1);
  247.     while (COMPARATOR == 1)
  248.     {
  249.         val = val + 1;
  250.         dac = val;     
  251.         delay_ms(1);                    // Allow time for DAC to settle
  252.     }
  253.     return (val);
  254. }
  255.  
  256.  
  257. /* This is a simple delay based on a busy loop */
  258. /* with an 11.0592 MHz crystal, the delay lasts */
  259. /* for approximately 1 ms times the number passed */
  260. /* Of course, it will take longer if there are */
  261. /* interrupts occuring... */
  262.  
  263. void delay_ms(unsigned char ms)
  264. {
  265.     ms;
  266.     _asm
  267.             mov     r0, dpl
  268. 00001$:     mov     r1, #250
  269. 00002$:     nop
  270.             djnz    r1, 00002$
  271.             djnz    r0, 00001$
  272.             ret
  273.     _endasm;
  274. }
  275.  
  276. void delay(int s){                      // Wait for 1 second
  277.     int i,j;
  278.     for(j=0; j<4; j++){
  279.         for(i=0; i<s; i++){             // Delays multiple times
  280.             delay_ms(250);              // Quater of a second
  281.         }
  282.     }
  283. }
  284.  
  285. /* This C-only version is easier to read and understand, but it is
  286.  * not as fast and efficient as the assembly version below.  You
  287.  * should normally use the optimized assembly version, but read
  288.  * this one to understand the code.
  289.  */
  290.  
  291. volatile xdata at LCD_COMMAND_WR unsigned char lcd_command_wr;
  292. volatile xdata at LCD_STATUS_RD unsigned char lcd_status_rd;
  293. volatile xdata at LCD_DATA_WR unsigned char lcd_data_wr;
  294. volatile xdata at LCD_DATA_RD unsigned char lcd_data_rd;
  295.  
  296.  
  297. void lcd_busy(void)
  298. {
  299.     while (lcd_status_rd & 0x80)  ;
  300. }
  301.  
  302. void lcd_command(unsigned char cmd)
  303. {
  304.     lcd_busy();
  305.     lcd_command_wr = cmd;
  306. }
  307.  
  308. void lcd_putchar(char c)
  309. {
  310.     lcd_busy();
  311.     if (c=='\n') lcd_command_wr = LCD_CLEAR_CMD;
  312.     else lcd_data_wr = c;
  313. }
  314.  
  315. void lcd_set_xy_raw(unsigned int x_and_y)
  316. {
  317.     unsigned char x, y;
  318.     if ((x = x_and_y & 255) >= LCD_HORIZ_SIZE) x = LCD_HORIZ_SIZE - 1;
  319.     if ((y = x_and_y >> 8) >= LCD_VERT_SIZE) y = LCD_VERT_SIZE - 1;
  320.     lcd_busy();
  321.     lcd_command_wr = (y * LCD_BYTES_PER_LINE + x) | 0x80;
  322. }
  323.  
  324. // End
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement