Facebook
From Bulky Peccary, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 262
  1. /*
  2.  *      startup.c
  3.  *
  4.  */
  5. #define SIMULATOR
  6. //#define USBDM
  7.  
  8. #include "box.xbm"
  9. #include "box_hit.xbm"
  10. #include "player.xbm"
  11. #include "wall.xbm"
  12.  
  13.  
  14. typedef unsigned int uint32_t;
  15. typedef unsigned short uint16_t;
  16. typedef unsigned char uint8_t;
  17.  
  18. typedef struct {
  19.         uint32_t moder;
  20.         uint16_t otyper; // +0x4
  21.         uint16_t otReserved;
  22.         uint32_t ospeedr; // +0x8
  23.         uint32_t pupdr; // +0xc
  24.         uint8_t idrLow; // +0x10
  25.         uint8_t idrHigh; // +0x11
  26.         uint16_t idrReserved;
  27.         uint8_t odrLow; // +0x14
  28.         uint8_t odrHigh; // +0x15
  29.         uint16_t odrReserved;
  30. } GPIO;
  31.  
  32. typedef volatile GPIO* gpioPtr;
  33.  
  34. #define GPIO_D (*((gpioPtr) 0x40020C00))        /* GPIO HIGH AND LOW Keypad */
  35. #define GPIO_E (*((gpioPtr) 0x40021000))        /* Graphic */
  36.  
  37. #define SYS_TICK 0xE000E010
  38. #define STK_CTRL ((volatile unsigned int *) (SYS_TICK))
  39. #define STK_LOAD ((volatile unsigned int *) (SYS_TICK + 0x4))
  40. #define STK_VAL ((volatile unsigned int *) (SYS_TICK + 0x8))
  41. #define STK_CALIB ((volatile unsigned int *) (SYS_TICK + 0xC))
  42.  
  43. /* MASKS FOR ASCII DISPLAY*/
  44. #define B_E 0x40 /* Enable-signal */
  45. #define B_SELECT 4 /* Select ASCII-display */
  46. #define B_RW 2 /* 0=Write, 1=Read */
  47. #define B_RS 1 /* 0=Control, 1=Data */
  48.  
  49. /* MASKS FOR GRAPHIC DISPLAY */
  50. #define B_RST 0x20
  51. #define B_CS2 0x10
  52. #define B_CS1 0x08
  53.  
  54. #define LCD_ON 0x3F
  55. #define LCD_OFF 0x3E
  56. #define LCD_DISP_START 0xC0
  57. #define LCD_SET_ADD 0x40
  58. #define LCD_SET_PAGE 0xB8
  59. #define LCD_BUSY 0x80
  60.  
  61. typedef unsigned char uint8_t;
  62.  
  63. /* TYPEDEFS FOR SPRITES */
  64. typedef struct tSpriteData{
  65.         unsigned char width;
  66.         unsigned char height;
  67.         unsigned char* data;
  68. }SPRITEDATA, *PSPRITEDATA;
  69.  
  70. typedef struct tSprite{
  71.         char posx, posy;
  72.         char dirx, diry;
  73.         char speedx, speedy;
  74. } SPRITE, *PSPRITE;
  75.  
  76. static void load_sprite(PSPRITEDATA s, unsigned char* data, int width, int height){
  77.         s->width = width;
  78.         s->height = height;
  79.         s->data = data;
  80. }
  81.  
  82.  
  83. unsigned char ascii_read_status (void);
  84.  
  85.  
  86.  
  87. void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
  88.  
  89. void startup ( void )
  90. {
  91. __asm volatile(
  92.         " LDR R0,=0x2001C000\n"         /* set stack */
  93.         " MOV SP,R0\n"
  94.         " BL main\n"                            /* call main */
  95.         "_exit: B .\n"                          /* never return */
  96.         ) ;
  97. }
  98.  
  99. void delay_250ns(void){
  100.         *STK_CTRL = 0;
  101.         *STK_LOAD = ((168/4)-1);        // One micro sec = 168 clock cycles -> 168/4 = 250 nano sec
  102.         *STK_VAL = 0;
  103.         *STK_CTRL = 0x5;
  104.         while((*STK_CTRL & 0x10000) == 0){}
  105.         *STK_CTRL = 0;
  106. }
  107.  
  108. void delay_500ns(void){
  109.         delay_250ns();
  110.         delay_250ns();
  111. }
  112.  
  113. void delay_micro(unsigned int us){
  114.         #ifdef  SIMULATOR
  115.                 us = us/1000;
  116.                 us++;
  117.         #endif
  118.         while(us > 0){
  119.                 delay_250ns();
  120.                 delay_250ns();
  121.                 delay_250ns();
  122.                 delay_250ns();
  123.                 us--;
  124.         }
  125. }
  126.  
  127. void delay_milli(unsigned int ms){
  128.         #ifdef  SIMULATOR
  129.                 ms = ms/1000;
  130.                 ms++;
  131.         #endif
  132.         while(ms > 0){
  133.                 delay_micro(1000);
  134.                 ms--;
  135.         }
  136. }
  137.  
  138. void init_app (void){  
  139.         GPIO_E.moder = 0x55555555;
  140.         GPIO_D.moder = 0x55000000;
  141. }
  142.  
  143. void graphic_ctrl_bit_set(uint8_t x){
  144.         unsigned char c;
  145.         c = GPIO_E.odrLow;
  146.         c |= x;
  147.         GPIO_E.odrLow = c;
  148. }
  149.  
  150. void graphic_ctrl_bit_clear(uint8_t x){
  151.         unsigned char c;
  152.         c = GPIO_E.odrLow;
  153.         c &= ~x;
  154.         GPIO_E.odrLow = c;
  155. }
  156.  
  157. void select_controller(uint8_t controller)
  158. {
  159.         switch(controller)
  160.         {
  161.                 case 0:
  162.                         graphic_ctrl_bit_clear(B_CS1|B_CS2);
  163.                         break;
  164.                 case B_CS1 :
  165.                         graphic_ctrl_bit_set(B_CS1);
  166.                         graphic_ctrl_bit_clear(B_CS2);
  167.                         break;
  168.                 case B_CS2 :
  169.                         graphic_ctrl_bit_set(B_CS2);
  170.                         graphic_ctrl_bit_clear(B_CS1);
  171.                         break;
  172.                 case B_CS1|B_CS2 :
  173.                         graphic_ctrl_bit_set(B_CS1|B_CS2);
  174.                         break;
  175.         }
  176. }
  177.  
  178. void graphic_wait_ready(void){
  179.         graphic_ctrl_bit_clear(B_E);
  180.         GPIO_E.moder = 0x00005555;
  181.         graphic_ctrl_bit_clear(B_RS);
  182.         graphic_ctrl_bit_set(B_RW);
  183.         delay_500ns();
  184.        
  185.         while(GPIO_E.odrLow & 0x1){
  186.                 graphic_ctrl_bit_set(B_E);
  187.                 delay_500ns();
  188.                 graphic_ctrl_bit_clear(B_E);
  189.                 delay_500ns();
  190.         }
  191.         graphic_ctrl_bit_set(B_E);
  192.         GPIO_E.moder = 0x55555555;
  193. }
  194.  
  195. unsigned char graphic_read(uint8_t controller){
  196.         uint8_t c;
  197.         graphic_ctrl_bit_clear(B_E);
  198.         GPIO_E.moder = 0x00005555;
  199.         graphic_ctrl_bit_set(B_RS | B_RW);
  200.         select_controller(controller);
  201.         delay_500ns();
  202.         graphic_ctrl_bit_set(B_E);
  203.         delay_500ns();
  204.         c = GPIO_E.idrHigh; //unsure if this is correct, but it should be (data in the higher bits?)
  205.         graphic_ctrl_bit_clear(B_E);
  206.         GPIO_E.moder = 0x55555555;
  207.        
  208.         if(controller == B_CS1){
  209.                 select_controller(B_CS1);
  210.                 graphic_wait_ready();
  211.         }
  212.         if(controller == B_CS2){
  213.                 select_controller(B_CS2);
  214.                 graphic_wait_ready();
  215.         }
  216.        
  217.         return c; // Hmm?
  218. }
  219.  
  220. static void graphic_write(uint8_t value, uint8_t controller)
  221. {
  222.         GPIO_E.odrHigh = value;
  223.         select_controller(controller);
  224.         delay_500ns();
  225.         graphic_ctrl_bit_set(B_E);
  226.         delay_500ns();
  227.         graphic_ctrl_bit_clear(B_E);
  228.        
  229.         if (controller == B_CS1)
  230.         {
  231.                         select_controller(B_CS1);
  232.                         graphic_wait_ready();
  233.         }
  234.         else if (controller == B_CS2)
  235.         {
  236.                         select_controller(B_CS2);
  237.                         graphic_wait_ready();
  238.         }
  239.         GPIO_E.odrHigh = 0;
  240.         graphic_ctrl_bit_set(B_E);
  241.         select_controller(0);
  242. }
  243.  
  244. void graphic_write_command(uint8_t cmd, uint8_t controller){
  245.         graphic_ctrl_bit_clear(B_E);
  246.         select_controller(controller);
  247.  
  248.         graphic_ctrl_bit_clear(B_RS);
  249.         graphic_ctrl_bit_clear(B_RW);
  250.        
  251.         graphic_write(cmd, controller);
  252. }
  253.  
  254. void graphic_write_data(uint8_t data, uint8_t controller){
  255.         graphic_ctrl_bit_clear(B_E);
  256.         select_controller(controller);
  257.  
  258.         graphic_ctrl_bit_set(B_RS);
  259.         graphic_ctrl_bit_clear(B_RW);
  260.        
  261.         graphic_write(data, controller);
  262. }
  263.  
  264. uint8_t graphic_read_data(unsigned char controller){
  265.         (void) graphic_read(controller); /* returns bullshit */
  266.         return graphic_read(controller); /* returns correct data */
  267. }
  268.  
  269. void graphic_initialize(void){
  270.         graphic_ctrl_bit_set(B_E);
  271.         delay_micro(10);
  272.        
  273.         graphic_ctrl_bit_clear(B_CS1 | B_CS2 | B_RST | B_E);
  274.         delay_milli(30);
  275.        
  276.         graphic_ctrl_bit_set(B_RST);
  277.         graphic_write_command(LCD_OFF, B_CS1 | B_CS2);
  278.         graphic_write_command(LCD_ON, B_CS1 | B_CS2);
  279.         graphic_write_command(LCD_DISP_START, B_CS1 | B_CS2);
  280.         graphic_write_command(LCD_SET_ADD, B_CS1 | B_CS2);
  281.         graphic_write_command(LCD_SET_PAGE, B_CS1 | B_CS2);
  282.         select_controller(0);
  283. }
  284.  
  285. void graphic_clear_screen(void){
  286.         for(int page = 0; page <= 7; page++){
  287.                 graphic_write_command(LCD_SET_PAGE | page, B_CS1 | B_CS2);
  288.                 graphic_write_command(LCD_SET_ADD | 0, B_CS1 | B_CS2);
  289.                 for(int add = 0; add <= 63; add++){
  290.                         graphic_write_data(0, B_CS1 | B_CS2);
  291.                 }
  292.         }
  293. }
  294.  
  295. void graphic_clear_lower(void){
  296.         for(int page = 0; page <= 7; page++){
  297.                 graphic_write_command(LCD_SET_PAGE | page, B_CS1 | B_CS2);
  298.                 graphic_write_command(LCD_SET_ADD | 0, B_CS1 | B_CS2);
  299.                 for(int add = 0; add <= 63; add++){
  300.                         graphic_write_data(0, B_CS1 | B_CS2);
  301.                 }
  302.         }
  303. }
  304.  
  305. void pixel(int x, int y, int set) {
  306.         uint8_t mask, c, controller;
  307.         int index;
  308.        
  309.         if((x < 0) || (y < 0) || (x > 128) || (y > 64)) return;
  310.        
  311.         index = (y-1)/8;
  312.        
  313.         switch( (y-1)%8 ) {
  314.                 case 0: mask = 1; break;
  315.                 case 1: mask = 2; break;
  316.                 case 2: mask = 4; break;
  317.                 case 3: mask = 8; break;
  318.                 case 4: mask = 0x10; break;
  319.                 case 5: mask = 0x20; break;
  320.                 case 6: mask = 0x40; break;
  321.                 case 7: mask = 0x80; break;
  322.         }
  323.         if(set == 0)
  324.                 mask = ~mask;
  325.         if(x > 64){
  326.                 controller = B_CS2;
  327.                 x = x - 65;
  328.         } else {
  329.                 controller = B_CS1;
  330.                 x = x-1;
  331.         }
  332.        
  333.         graphic_write_command(LCD_SET_ADD | x, controller );
  334.         graphic_write_command(LCD_SET_PAGE | index, controller );
  335.         c = graphic_read_data(controller);
  336.         graphic_write_command(LCD_SET_ADD | x, controller);
  337.        
  338.         if(set)
  339.                 mask = mask | c;
  340.         else
  341.                 mask = mask & c;
  342.                
  343.         graphic_write_data(mask, controller);
  344. }
  345.  
  346. //void pixel_buffer(int x, int y) {
  347. //      uint8_t mask;
  348. //      int index = 0;
  349. //      if( (x > 128 ) || (x < 0) || (y > 64) || (y < 0) ) return;
  350. //     
  351. //      mask = 1 << ((y-1)%8);
  352. //     
  353. //      if(x > 64) {
  354. //              x -= 65;
  355. //              index = 512;
  356. //      }
  357. //     
  358. //      index += x + ((y-1)/8)*64;
  359. //      backBuffer[index] |= mask;
  360. //}
  361. //
  362. //
  363. //void graphic_draw_screen(void) {
  364. //      uint8_t i, j, controller, c;
  365. //      unsigned int k = 0;
  366. //      for(c = 0; c <= 1; c++){
  367. //              controller = (c == 0) ? B_CS1 : B_CS2;
  368. //              for(j = 0; j < 8; j++){
  369. //                      graphic_write_command(LCD_SET_PAGE | j, controller);
  370. //                      graphic_write_command(LCD_SET_ADD | 0, controller);
  371. //                      for(i = 0; i < 64; i++, k++){
  372. //                              graphic_write_data(backBuffer[k], controller);
  373. //                      }
  374. //              }
  375. //      }
  376. //}
  377.  
  378. /*----------------------- ASCII -----------------------*/
  379.  
  380. /* Addressera ASCII-display och ettställ de bitar som är 1 i x */
  381. void ascii_ctrl_bit_set(unsigned char x){
  382.         unsigned char c;
  383.         c = GPIO_E.odrLow;
  384.         c |= (B_SELECT | x);
  385.         GPIO_E.odrLow = c;
  386. }
  387.  
  388. void ascii_ctrl_bit_clear(unsigned char x){
  389.         unsigned char c;
  390.         c = GPIO_E.odrLow;
  391.         c &= (B_SELECT | ~x);
  392.         GPIO_E.odrLow = c;
  393. }
  394.  
  395. void ascii_write_controller(unsigned char c){
  396.         ascii_ctrl_bit_set(B_E);
  397.         GPIO_E.odrHigh = c;
  398.         delay_250ns();
  399.         ascii_ctrl_bit_clear(B_E);
  400. }
  401.  
  402. unsigned char ascii_read_controller(void){
  403.         ascii_ctrl_bit_set(B_E);
  404.         delay_250ns();
  405.         delay_250ns();
  406.         unsigned char c = GPIO_E.idrHigh;
  407.         ascii_ctrl_bit_clear(B_E);
  408.         return c;
  409. }
  410.  
  411. void ascii_write_cmd(unsigned char command){
  412.         ascii_ctrl_bit_clear(B_RS | B_RW);
  413.         ascii_write_controller(command);
  414. }
  415.  
  416. void ascii_write_data(unsigned char data){
  417.         ascii_ctrl_bit_set(B_RS);
  418.         ascii_ctrl_bit_clear(B_RW);
  419.         ascii_write_controller(data);
  420. }
  421.  
  422. void ascii_write_char(unsigned char c){
  423.         while((ascii_read_status() & 0x80) == 0x80){}
  424.         delay_micro(8);
  425.         ascii_write_data(c);
  426.         delay_micro(45);
  427. }
  428.  
  429. unsigned char ascii_read_status(void){
  430.         unsigned char c;
  431.         GPIO_E.moder = 0x00005555;
  432.         ascii_ctrl_bit_clear(B_RS);
  433.         ascii_ctrl_bit_set(B_RW);
  434.         c = ascii_read_controller();
  435.         GPIO_E.moder = 0x55555555;
  436.         return c;
  437. }
  438.  
  439. unsigned char ascii_read_data(void){
  440.         GPIO_E.moder = 0x00005555;
  441.         ascii_ctrl_bit_set(B_RS);
  442.         ascii_ctrl_bit_set(B_RW);
  443.         unsigned char c = ascii_read_controller();
  444.         GPIO_E.moder = 0x55555555;
  445.         return c;
  446. }
  447.  
  448. void ascii_init(void){
  449.         while((ascii_read_status() & 0x80) == 0x80){}
  450.         delay_micro(8);
  451.         ascii_write_cmd(0x38); // Rows: 2, Size: 5x8
  452.         delay_micro(40);
  453.         ascii_write_cmd(0x0E); // Display: on, Cursor: constant on
  454.         delay_micro(40);
  455.         ascii_write_cmd(0x06); // Increment, Shift: off
  456.         delay_micro(40);
  457. }
  458.  
  459. void ascii_command (unsigned char command)
  460. {
  461.         while(ascii_read_status() & 0x80 == 0x80){}
  462.         delay_micro(8);                                                         /* Latenstid för kommando */
  463.         ascii_write_cmd(command);                                       /* Kommandot som ska exekveras; t.ex. 1 - Clear Display */
  464.         delay_micro(40);                                                                /* Avrundat uppåt; istället för 1,53ms */
  465.        
  466. }
  467.  
  468.  
  469.  
  470. void ascii_gotoxy(int x, int y){
  471.         unsigned char adress;
  472.        
  473.         if(y != 1)
  474.         {
  475.                 adress = 0x40|(x - 1);
  476.         }
  477.         else
  478.         {
  479.                 adress = x - 1;
  480.         }
  481.         ascii_write_cmd(0x80|adress);
  482.         delay_micro(45);
  483. }
  484.  
  485.  
  486. /*--------------------------- ASCII END ------------------------------*/
  487. /*--------------------------- KEYPAD -----------------------------*/
  488. //void activateRow(unsigned int row){
  489. //      switch(row){
  490. //              case 1: GPIO_D.odrHigh = 0x10; break;
  491. //              case 2: GPIO_D.odrHigh = 0x20; break;
  492. //              case 3: GPIO_D.odrHigh = 0x40; break;
  493. //              case 4: GPIO_D.odrHigh = 0x80; break;
  494. //              case 0: GPIO_D.odrHigh = 0x00; break;
  495. //      }
  496. //}
  497.  
  498. //unsigned char keyb(void){
  499. //      int row, column;
  500. //      unsigned char key[]={1,2,3,0xA,4,5,6,0xB,7,8,9,0xC,0xE,0,0xF,0xD};
  501. //     
  502. //      for(row = 1; row <= 4; row++){
  503. //              activateRow(row);
  504. //              column = readColumn();
  505. //             
  506. //              if(column){
  507. //                      activateRow(0);
  508. //                      return key[4*(row - 1) + column - 1];
  509. //              }
  510. //      }
  511. //      activateRow(0);
  512. //      return 0xFF;
  513. //}
  514.  
  515. /*--------------------------- KEYPAD END-----------------------------*/
  516.  
  517.  
  518. void draw_sprite(PSPRITEDATA sd, PSPRITE s, char set){
  519.        
  520.         int i,j,k, width_in_bytes;
  521.        
  522.         if (sd->width % 8 == 0)
  523.                 width_in_bytes = (sd->width / 8);
  524.         else
  525.                 width_in_bytes = (sd->width / 8 + 1);
  526.        
  527.         for(i = 0; i < sd->height; i++){
  528.                
  529.                 for (j = 0; j < width_in_bytes; j++){
  530.                         unsigned char byte = sd->data[i * width_in_bytes + j];
  531.                        
  532.                         for (k = 0; k < 8; k++){
  533.                                 if (byte & (1 << k))
  534.                                         pixel(8 * j + k + s->posx + 1, i + s->posy + 1, set);
  535.                         }
  536.                 }
  537.         }
  538. }
  539.  
  540. void sprite_move(PSPRITE s, uint8_t player){
  541.         char newPos = s->dirx*s->speedx + s->posx;
  542.        
  543.         if(player == 1){
  544.                 if(newPos > 2 && newPos < 45)
  545.                         s->posx = newPos;
  546.                
  547.         }else if(player == 2){
  548.                 if(newPos < 69 && newPos > 128)
  549.                         s->posx = newPos;
  550.         }
  551.                
  552.         //s->posy += s->speedy*s->diry;
  553. }
  554.  
  555.  
  556. SPRITE box[40];
  557.  
  558. SPRITE player1 = {
  559.         5,60,
  560.         0,0,
  561.         2,2
  562. };
  563.  
  564. SPRITE player2 = {
  565.         90,60,
  566.         0,0,
  567.         2,2
  568. };
  569.  
  570. PSPRITE p1 = &player1;
  571. PSPRITE p2 = &player2;
  572.  
  573. int readColumn(){
  574.         unsigned char c;
  575.         unsigned int r;
  576.         r = 0;
  577.         c = GPIO_D.idrHigh;
  578.         if(c & 0x1)
  579.                 r += 1;
  580.         if(c & 0x2)
  581.                 r += 10;
  582.         if(c & 0x4)
  583.                 r += 100;
  584.         if(c & 0x8)
  585.                 r += 1000;
  586.         return r;
  587. }
  588.  
  589. unsigned char keyb(void){
  590.        
  591.         int r = 0;
  592.        
  593.         GPIO_D.odrHigh = 0x10; // AKTIVERA RAD 1
  594.        
  595.         r = readColumn();
  596.        
  597.         switch(r){
  598.                 case 1: p1->dirx = -1; break;
  599.                 case 10: p1->dirx = 1; break;
  600.                 case 100: p2->dirx = -1; break;
  601.                 case 1000: p2->dirx = 1; break;
  602.                 case 101: p1->dirx = -1; p2->dirx = -1; break;
  603.                 case 1001: p1->dirx = -1; p2->dirx = 1; break;
  604.                 case 110: p1->dirx = 1; p2->dirx = -1; break;
  605.                 case 1010: p1->dirx = 1; p2->dirx = 1; break;
  606.                 default: p2->dirx = 0; p1->dirx = 0;
  607.         }
  608.        
  609.         GPIO_D.odrHigh = 0x00;
  610.         return 0;
  611. }
  612.  
  613. void main(void){
  614.         char c;
  615.         int i, j, k;
  616.        
  617.         k = 0;
  618.         for(i = 0; i < 5; i++){
  619.                 for(j = 0; j < 4; j++){
  620.                         box[k].posx = i * 11 + 2;
  621.                         box[k].posy = j * 4;
  622.                         k++;
  623.                 }
  624.         }
  625.         for(i = 0; i < 5; i++){
  626.                 for(j = 0; j < 4; j++){
  627.                         box[k].posx = i * 11 + 70;
  628.                         box[k].posy = j * 4;
  629.                         k++;
  630.                 }
  631.         }
  632.        
  633.         init_app();
  634.         graphic_initialize();
  635.         ascii_init();
  636.        
  637.         #ifndef SIMULATOR
  638.                 graphic_clear_screen();
  639.         #endif
  640.        
  641.         ascii_ctrl_bit_set(2);
  642.         ascii_gotoxy(1, 1);
  643.        
  644.         char *s;
  645.         char test1[] = "Break Out!";
  646.         char test2[] = "0-Player 1 | Player 2-0";
  647.        
  648.         s = test1;
  649.         while(*s)
  650.                 ascii_write_char(*s++);
  651.         ascii_gotoxy(1, 2);
  652.         s = test2;
  653.         while(*s)
  654.                 ascii_write_char(*s++);
  655.        
  656.         pixel(10, 10, 1);
  657.        
  658.         load_sprite("box.xbm", box_bits, box_width, box_height);
  659.         load_sprite("box_hit.xbm", box_hit_bits, box_hit_width, box_hit_height);
  660.         load_sprite("player.xbm", player_bits, player_width, player_height);
  661.         load_sprite("wall.xbm", wall_bits, wall_width, wall_height);
  662.        
  663.         #ifndef SIMULATOR
  664.         /* WRITE BORDERS */
  665.         for(i = 0; i < 64; i++){
  666.                         pixel(1, i, 1);
  667.                         pixel(60, i, 1);
  668.                         pixel(69, i, 1);
  669.                         pixel(128, i, 1);
  670.         }
  671.         #endif
  672.        
  673.         int count;
  674.         while(1){
  675.                 /* CLEAR THEN WRITE */
  676.                 #ifndef SIMULATOR
  677.                 count++;
  678.                 if(count % 4){
  679.                         for(i = 0; i < 40; i++){
  680.                                 draw_sprite("box.xbm", &box[i], 0);
  681.                                 draw_sprite("box.xbm", &box[i], 1);
  682.                         }
  683.                 }
  684.                 #endif
  685.                
  686.                 draw_sprite("player.xbm", p1, 0);
  687.                 draw_sprite("player.xbm", p2, 0);
  688.                
  689.                 keyb(); /* Read keypad */
  690.                
  691.                 sprite_move(p1, 1);
  692.                 sprite_move(p2, 2);
  693.                
  694.                 draw_sprite("player.xbm", p1, 1);
  695.                 draw_sprite("player.xbm", p2, 1);
  696.                
  697.                 //delay_milli(20);
  698.         }
  699.        
  700.         return;
  701. }
  702.