/ MCUME_teensy / teensyuae / emuapi.cpp
emuapi.cpp
   1  #define KEYMAP_PRESENT 1
   2  
   3  extern "C" {
   4    #include "emuapi.h"
   5    #include "iopins.h"
   6  }
   7  
   8  #include "tft_t_dma.h"
   9  #include "logo.h"
  10  #include "bmpjoy.h"
  11  #include "bmpvbar.h"
  12  #ifdef OLD_LAYOUT    
  13  #include "bmpvga.h"
  14  #include "bmptft.h"
  15  #endif
  16  
  17  
  18  #ifdef HAS_I2CKBD
  19  #include <Wire.h>
  20  #endif
  21  
  22  #ifdef USE_SDFS
  23  #include "uSDFS.h"
  24  static FATFS fatfs;
  25  static FIL file; 
  26  #else
  27  
  28  #ifdef USE_SDFAT
  29  #include "SdFat.h"
  30  #include "sdios.h"
  31  
  32  #ifndef SDCARD_SS_PIN
  33  const uint8_t SD_CS_PIN = SS;
  34  
  35  #else  // SDCARD_SS_PIN
  36  // Assume built-in SD is used.
  37  const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
  38  #endif  // SDCARD_SS_PIN
  39  
  40  #define SD_CONFIG SdioConfig(FIFO_SDIO)
  41  
  42  // Try to select the best SD card configuration.
  43  #if HAS_SDIO_CLASS
  44  #define SD_CONFIG SdioConfig(FIFO_SDIO)
  45  #elif ENABLE_DEDICATED_SPI
  46  #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI)
  47  #else  // HAS_SDIO_CLASS
  48  #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
  49  #endif  // HAS_SDIO_CLASS
  50  //------------------------------------------------------------------------------
  51  
  52  #if SD_FAT_TYPE == 0
  53  #elif SD_FAT_TYPE == 1
  54  #define SdFat SdFat32
  55  #define File File32
  56  #elif SD_FAT_TYPE == 2
  57  #define SdFat SdExFat
  58  #define File ExFile
  59  #elif SD_FAT_TYPE == 3
  60  #define SdFat SdFs
  61  #define File FsFile
  62  #endif  // SD_FAT_TYPE
  63  static SdFat SD;
  64  #else
  65  #include <SD.h>
  66  #endif
  67  static File file;
  68  #endif
  69  
  70  #define CALIBRATION_FILE    "/cal.cfg"
  71  
  72  #define MKEY_L1             1
  73  #define MKEY_L2             2
  74  #define MKEY_L3             3
  75  #define MKEY_L4             4
  76  #define MKEY_L5             5
  77  #define MKEY_L6             6
  78  #define MKEY_L7             7
  79  #define MKEY_L8             8
  80  #define MKEY_L9             9
  81  #define MKEY_UP             20
  82  #define MKEY_DOWN           21
  83  #define MKEY_JOY            22
  84  #define MKEY_TFT            23
  85  #define MKEY_VGA            24
  86  
  87  #define MAX_FILES           64
  88  #define MAX_FILENAME_SIZE   24
  89  #define MAX_MENULINES       (MKEY_L9)
  90  #define TEXT_HEIGHT         16
  91  #define TEXT_WIDTH          8
  92  #define MENU_FILE_XOFFSET   (6*TEXT_WIDTH)
  93  #define MENU_FILE_YOFFSET   (2*TEXT_HEIGHT)
  94  #define MENU_FILE_W         (MAX_FILENAME_SIZE*TEXT_WIDTH)
  95  #define MENU_FILE_H         (MAX_MENULINES*TEXT_HEIGHT)
  96  #define MENU_FILE_BGCOLOR   RGBVAL16(0x00,0x00,0x20)
  97  #define MENU_JOYS_YOFFSET   (12*TEXT_HEIGHT)
  98  #define MENU_VBAR_XOFFSET   (0*TEXT_WIDTH)
  99  #define MENU_VBAR_YOFFSET   (MENU_FILE_YOFFSET)
 100  
 101  #define MENU_TFT_XOFFSET    (MENU_FILE_XOFFSET+MENU_FILE_W+8)
 102  #define MENU_TFT_YOFFSET    (MENU_VBAR_YOFFSET+32)
 103  #define MENU_VGA_XOFFSET    (MENU_FILE_XOFFSET+MENU_FILE_W+8)
 104  #define MENU_VGA_YOFFSET    (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
 105  
 106  extern TFT_T_DMA tft;
 107  
 108  static char romspath[64];
 109  static int nbFiles=0;
 110  static int curFile=0;
 111  static int topFile=0;
 112  static char selection[MAX_FILENAME_SIZE+1]="";
 113  static char files[MAX_FILES][MAX_FILENAME_SIZE];
 114  static bool menuRedraw=true;
 115  
 116  static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
 117  static bool i2cKeyboardPresent = false;
 118  //const uint16_t deflogo[] = {
 119  //  0x0000,0x0000
 120  //};
 121  //static const uint16_t * logo = deflogo;
 122  static unsigned short * keys;
 123  static int keyMap;
 124  
 125  const unsigned short menutouchareas[] = {
 126    TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
 127    TAREA_WH,MENU_FILE_W, TEXT_HEIGHT,
 128    TAREA_NEW_COL,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,
 129    
 130    TAREA_XY,MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,
 131    TAREA_WH,32,48,
 132    TAREA_NEW_COL, 72,72,8,40,
 133  
 134    TAREA_XY,MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,
 135    TAREA_WH,32,37,
 136    TAREA_NEW_COL, 38,38,
 137      
 138    TAREA_END};
 139     
 140  const unsigned short menutouchactions[] = {
 141    MKEY_L1,MKEY_L2,MKEY_L3,MKEY_L4,MKEY_L5,MKEY_L6,MKEY_L7,MKEY_L8,MKEY_L9,
 142    MKEY_UP,MKEY_DOWN,ACTION_NONE,MKEY_JOY,
 143    MKEY_TFT,MKEY_VGA}; 
 144  
 145  
 146  static int keypadval=0; 
 147  static boolean joySwapped = false;
 148  static uint16_t bLastState;
 149  static int xRef;
 150  static int yRef;
 151  static uint8_t prev_zt=0; 
 152  
 153  static bool menuOn=true;
 154  static bool callibrationOn=false;
 155  static int callibrationStep=0;
 156  
 157  
 158  static char captureTouchZone(const unsigned short * areas, const unsigned short * actions, int *rx, int *ry, int *rw, int * rh) {
 159      uint16_t xt=0;
 160      uint16_t yt=0;
 161      uint16_t zt=0;
 162      boolean hDir=true;  
 163    
 164      if (tft.isTouching())
 165      {
 166          if (prev_zt == 0) {
 167              prev_zt =1;
 168              tft.readCal(&xt,&yt,&zt);
 169              if (zt<1000) {
 170                prev_zt=0; 
 171                return ACTION_NONE;
 172              }   
 173              int i=0;
 174              int k=0;
 175              int y2=0, y1=0;
 176              int x2=0, x1=0;
 177              int x=KEYBOARD_X,y=KEYBOARD_Y;
 178              int w=TAREA_W_DEF,h=TAREA_H_DEF;
 179              uint8_t s;
 180              while ( (s=areas[i++]) != TAREA_END ) {
 181                  if (s == TAREA_XY) {
 182                      x = areas[i++];
 183                      y = areas[i++];                    
 184                      x2 = x;
 185                      y2 = y;  
 186                  }
 187                  else if (s == TAREA_WH) {
 188                      w = areas[i++];
 189                      h = areas[i++];
 190                  }                     
 191                  else if (s == TAREA_NEW_ROW) {
 192                    hDir = true;
 193                    y1 = y2;
 194                    y2 = y1 + h;
 195                    x2 = x;
 196                  }  
 197                  else if (s == TAREA_NEW_COL) {
 198                    hDir = false;
 199                    x1 = x2;
 200                    x2 = x1 + w;
 201                    y2 = y;                  
 202                  }
 203                  else { 
 204                      if (hDir) {
 205                        x1 = x2;
 206                        x2 = x1+s;                                                            
 207                      } else {
 208                        y1 = y2;
 209                        y2 = y1+s;                      
 210                      }
 211                      if ( (yt >= y1) && (yt < y2) && (xt >= x1) && (xt < x2)  ) {
 212                          *rx = x1;
 213                          *ry = y1;
 214                          *rw = x2-x1;
 215                          *rh = y2-y1;
 216                          return (actions[k]);  
 217                      }
 218                      k++;
 219                  }                
 220              }
 221          } 
 222          prev_zt =1; 
 223      } else {
 224          prev_zt=0; 
 225      } 
 226    
 227      return ACTION_NONE;   
 228  } 
 229  
 230  
 231  
 232  
 233  
 234  
 235  
 236  
 237  void emu_printf(char * text)
 238  {
 239    Serial.println(text);
 240  }
 241  
 242  void emu_printf(int val)
 243  {
 244    Serial.println(val);
 245  }
 246  
 247  void emu_printi(int val)
 248  {
 249    Serial.println(val,HEX);
 250  }
 251  
 252  void emu_printh(int val)
 253  {
 254    Serial.println(val,HEX);
 255  }
 256  
 257  static int malbufpt = 0;
 258  static char malbuf[EXTRA_HEAP];
 259  
 260  void * emu_Malloc(int size)
 261  {
 262    void * retval =  malloc(size);
 263    if (!retval) {
 264      emu_printf("failled to allocate");
 265      emu_printf(size);
 266      emu_printf("fallback");
 267      if ( (malbufpt+size) < sizeof(malbuf) ) {
 268        retval = (void *)&malbuf[malbufpt];
 269        malbufpt += size;      
 270      }
 271      else {
 272        emu_printf("failure to allocate");
 273      }
 274    }
 275    else {
 276      emu_printf("could allocate dynamic ");
 277      emu_printf(size);    
 278    }
 279    
 280    return retval;
 281  }
 282  
 283  void * emu_MallocI(int size)
 284  {
 285    void * retval =  NULL; 
 286  
 287    if ( (malbufpt+size) < sizeof(malbuf) ) {
 288      retval = (void *)&malbuf[malbufpt];
 289      malbufpt += size;
 290      emu_printf("could allocate static ");
 291      emu_printf(size);          
 292    }
 293    else {
 294      emu_printf("failure to allocate");
 295    }
 296  
 297    return retval;
 298  }
 299  void emu_Free(void * pt)
 300  {
 301    free(pt);
 302  }
 303  
 304  
 305  
 306  
 307  
 308  int emu_ReadAnalogJoyX(int min, int max) 
 309  {
 310    int val = analogRead(PIN_JOY2_A1X);
 311  #if INVX
 312    val = 4095 - val;
 313  #endif
 314    val = val-xRef;
 315    val = ((val*140)/100);
 316    if ( (val > -512) && (val < 512) ) val = 0;
 317    val = val+2048;
 318    return (val*(max-min))/4096;
 319  }
 320  
 321  int emu_ReadAnalogJoyY(int min, int max) 
 322  {
 323    int val = analogRead(PIN_JOY2_A2Y);
 324  #if INVY
 325    val = 4095 - val;
 326  #endif
 327    val = val-yRef;
 328    val = ((val*120)/100);
 329    if ( (val > -512) && (val < 512) ) val = 0;
 330    //val = (val*(max-min))/4096;
 331    val = val+2048;
 332    //return val+(max-min)/2;
 333    return (val*(max-min))/4096;
 334  }
 335  
 336  
 337  static uint16_t readAnalogJoystick(void)
 338  {
 339    uint16_t joysval = 0;
 340  
 341    int xReading = emu_ReadAnalogJoyX(0,256);
 342    if (xReading > 128) joysval |= MASK_JOY2_LEFT;
 343    else if (xReading < 128) joysval |= MASK_JOY2_RIGHT;
 344    
 345    int yReading = emu_ReadAnalogJoyY(0,256);
 346    if (yReading < 128) joysval |= MASK_JOY2_UP;
 347    else if (yReading > 128) joysval |= MASK_JOY2_DOWN;
 348    
 349  #ifdef PIN_JOY2_BTN  
 350    joysval |= (digitalRead(PIN_JOY2_BTN) == HIGH ? 0 : MASK_JOY2_BTN);
 351  #endif
 352    return (joysval);     
 353  }
 354  
 355  
 356  int emu_SwapJoysticks(int statusOnly) {
 357    if (!statusOnly) {
 358      if (joySwapped) {
 359        joySwapped = false;
 360      }
 361      else {
 362        joySwapped = true;
 363      }
 364    }
 365    return(joySwapped?1:0);
 366  }
 367  
 368  int emu_GetPad(void) 
 369  {
 370    return(keypadval/*|((joySwapped?1:0)<<7)*/);
 371  }
 372  
 373  int emu_ReadKeys(void) 
 374  {
 375    uint16_t retval;
 376    uint16_t j1 = readAnalogJoystick();
 377    uint16_t j2 = 0;
 378    
 379    // Second joystick
 380  #if INVY
 381  #ifdef PIN_JOY1_1
 382    if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_DOWN;
 383  #endif
 384  #ifdef PIN_JOY1_2
 385    if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_UP;
 386  #endif
 387  #else
 388  #ifdef PIN_JOY1_1
 389    if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_UP;
 390  #endif
 391  #ifdef PIN_JOY1_2
 392    if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_DOWN;
 393  #endif
 394  #endif
 395  #if INVX
 396  #ifdef PIN_JOY1_3
 397    if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_LEFT;
 398  #endif
 399  #ifdef PIN_JOY1_4
 400    if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_RIGHT;
 401  #endif
 402  #else
 403  #ifdef PIN_JOY1_3
 404    if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_RIGHT;
 405  #endif
 406  #ifdef PIN_JOY1_4
 407    if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_LEFT;
 408  #endif
 409  #endif
 410  #ifdef PIN_JOY1_BTN
 411    if ( digitalRead(PIN_JOY1_BTN) == LOW ) j2 |= MASK_JOY2_BTN;
 412  #endif
 413    if (joySwapped) {
 414      retval = ((j1 << 8) | j2);
 415    }
 416    else {
 417      retval = ((j2 << 8) | j1);
 418    }
 419  
 420  #ifdef PIN_KEY_USER1 
 421    if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
 422  #endif
 423  #ifdef PIN_KEY_USER2 
 424    if ( digitalRead(PIN_KEY_USER2) == LOW ) retval |= MASK_KEY_USER2;
 425  #endif
 426  #ifdef PIN_KEY_USER3 
 427    if ( digitalRead(PIN_KEY_USER3) == LOW ) retval |= MASK_KEY_USER3;
 428  #endif
 429  #ifdef PIN_KEY_USER4 
 430    if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4;
 431  #endif
 432  
 433    //Serial.println(retval,HEX);
 434  
 435    if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
 436       || (retval & MASK_KEY_USER4 ) )
 437    {  
 438  // Reset procedure T3.X and T4.0 by Frank Boesing !!   
 439  #if defined(__IMXRT1052__) || defined(__IMXRT1062__)    
 440      uint32_t tmp = SNVS_LPCR; // save control register
 441      
 442      SNVS_LPSR |= 1;
 443      
 444      // disable alarm
 445      SNVS_LPCR &= ~0x02;
 446      while (SNVS_LPCR & 0x02);
 447      
 448      __disable_irq();
 449      //get Time:
 450      uint32_t lsb, msb;
 451      do {
 452        msb = SNVS_LPSRTCMR;
 453        lsb = SNVS_LPSRTCLR;
 454      } while ( (SNVS_LPSRTCLR != lsb) | (SNVS_LPSRTCMR != msb) );
 455      uint32_t secs = (msb << 17) | (lsb >> 15);
 456      
 457      //set alarm
 458      secs += 2;
 459      SNVS_LPTAR = secs;
 460      while (SNVS_LPTAR != secs);
 461      
 462      SNVS_LPCR = tmp | 0x02; // restore control register and set alarm
 463      while (!(SNVS_LPCR & 0x02));
 464      
 465      SNVS_LPCR |= (1 << 6); // turn off power
 466      while (1) asm("wfi");  
 467  #else
 468      *(volatile uint32_t *)0xE000ED0C = 0x5FA0004;
 469      while (true) {
 470        ;
 471      } 
 472  #endif 
 473    }
 474    
 475    return (retval);
 476  }
 477  
 478  unsigned short emu_DebounceLocalKeys(void)
 479  {
 480    uint16_t bCurState = emu_ReadKeys();
 481    uint16_t bClick = bCurState & ~bLastState;
 482    bLastState = bCurState;
 483  
 484    return (bClick);
 485  }
 486  
 487  int emu_ReadI2CKeyboard(void) {
 488    int retval=0;
 489  #ifdef HAS_I2CKBD
 490    if (i2cKeyboardPresent) {
 491      byte msg[7]={0,0,0,0,0,0,0};
 492      Wire.requestFrom(8, 7);    // request 7 bytes from slave device #8 
 493      int i = 0;
 494      int hitindex=-1;
 495      while (Wire.available() && (i<7) ) { // slave may send less than requested
 496        byte b = Wire.read(); // receive a byte
 497        if (b != 0xff) hitindex=i; 
 498        msg[i++] = b;        
 499      }
 500      
 501      if (hitindex >=0 ) {
 502        /*
 503        Serial.println(msg[0], BIN);
 504        Serial.println(msg[1], BIN);
 505        Serial.println(msg[2], BIN);
 506        Serial.println(msg[3], BIN);
 507        Serial.println(msg[4], BIN);
 508        Serial.println(msg[5], BIN);
 509        Serial.println(msg[6], BIN);
 510        */
 511        unsigned short match = (~msg[hitindex])&0x00FF | (hitindex<<8);
 512        //Serial.println(match,HEX);  
 513        for (i=0; i<sizeof(i2ckeys); i++) {
 514          if (match == i2ckeys[i]) {
 515            //Serial.println((int)keys[i]);      
 516            return (keys[i]);
 517          }
 518        }
 519      }    
 520    }
 521  #endif
 522    return(retval);
 523  }
 524  
 525  void emu_InitJoysticks(void) { 
 526  
 527    // Second Joystick   
 528  #ifdef PIN_JOY1_1
 529    pinMode(PIN_JOY1_1, INPUT_PULLUP);
 530  #endif  
 531  #ifdef PIN_JOY1_2
 532    pinMode(PIN_JOY1_2, INPUT_PULLUP);
 533  #endif  
 534  #ifdef PIN_JOY1_3
 535    pinMode(PIN_JOY1_3, INPUT_PULLUP);
 536  #endif  
 537  #ifdef PIN_JOY1_4
 538    pinMode(PIN_JOY1_4, INPUT_PULLUP);
 539  #endif  
 540  #ifdef PIN_JOY1_BTN
 541    pinMode(PIN_JOY1_BTN, INPUT_PULLUP);
 542  #endif  
 543  
 544  #ifdef PIN_KEY_USER1
 545    pinMode(PIN_KEY_USER1, INPUT_PULLUP);
 546  #endif  
 547  #ifdef PIN_KEY_USER2
 548    pinMode(PIN_KEY_USER2, INPUT_PULLUP);
 549  #endif  
 550  #ifdef PIN_KEY_USER3
 551    pinMode(PIN_KEY_USER3, INPUT_PULLUP);
 552  #endif  
 553  #ifdef PIN_KEY_USER4
 554    pinMode(PIN_KEY_USER4, INPUT_PULLUP);
 555  #endif  
 556  #ifdef PIN_JOY2_BTN
 557    pinMode(PIN_JOY2_BTN, INPUT_PULLUP);
 558  #endif  
 559    analogReadResolution(12);
 560    xRef=0; yRef=0;
 561    for (int i=0; i<10; i++) {
 562      xRef += analogRead(PIN_JOY2_A1X);
 563      yRef += analogRead(PIN_JOY2_A2Y);  
 564      delay(20);
 565    }
 566  
 567  #if INVX
 568    xRef = 4095 -xRef/10;
 569  #else
 570    xRef /= 10;
 571  #endif
 572  #if INVY
 573    yRef = 4095 -yRef/10;
 574  #else
 575    yRef /= 10;
 576  #endif   
 577  }
 578  
 579  
 580  
 581  static bool vkbKeepOn = false;
 582  static bool vkbActive = false;
 583  static bool vkeyRefresh=false;
 584  static bool exitVkbd = false;
 585  static uint8_t keyPressCount=0; 
 586  
 587  
 588  bool virtualkeyboardIsActive(void) {
 589      return (vkbActive);
 590  }
 591  
 592  void toggleVirtualkeyboard(bool keepOn) {
 593         
 594      if (keepOn) {      
 595          tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
 596          //prev_zt = 0;
 597          vkbKeepOn = true;
 598          vkbActive = true;
 599          exitVkbd = false;  
 600      }
 601      else {
 602          vkbKeepOn = false;
 603          if ( (vkbActive) /*|| (exitVkbd)*/ ) {
 604              tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
 605              tft.startDMA();                     
 606              //prev_zt = 0; 
 607              vkbActive = false;
 608              exitVkbd = false;
 609          }
 610          else {         
 611              tft.stopDMA();                  
 612              tft.drawSpriteNoDma(0,0,(uint16_t*)logo);           
 613              //prev_zt = 0;
 614              vkbActive = true;
 615              exitVkbd = false;
 616          }
 617      }   
 618  }
 619  
 620   
 621  void handleVirtualkeyboard() {
 622    int rx=0,ry=0,rw=0,rh=0;
 623  
 624      if (keyPressCount == 0) {
 625        keypadval = 0;      
 626      } else {
 627        keyPressCount--;
 628      }
 629      
 630      if ( (!virtualkeyboardIsActive()) && (tft.isTouching()) && (!keyPressCount) ) {
 631          toggleVirtualkeyboard(false);
 632          return;
 633      }
 634      
 635      if ( ( (vkbKeepOn) || (virtualkeyboardIsActive())  )  ) {
 636          char c = captureTouchZone(keysw, keys, &rx,&ry,&rw,&rh);
 637          if (c) {
 638  
 639              tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR );
 640              if ( (c >=1) && (c <= ACTION_MAXKBDVAL) ) {
 641              
 642                keypadval = c;
 643                keyPressCount = 10;
 644                delay(50);
 645                vkeyRefresh = true;
 646                exitVkbd = true;
 647              }
 648              else if (c == ACTION_EXITKBD) {
 649                vkeyRefresh = true;
 650                exitVkbd = true;  
 651              }
 652          }   
 653       }    
 654       
 655      if (vkeyRefresh) {
 656          vkeyRefresh = false;
 657          tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
 658      }  
 659           
 660      if ( (exitVkbd) && (vkbActive) ) {      
 661          if (!vkbKeepOn) {             
 662              toggleVirtualkeyboard(false);
 663          }
 664          else {         
 665              toggleVirtualkeyboard(true);           
 666          } 
 667      }
 668  }
 669  
 670  int emu_setKeymap(int index) {
 671    if (keyMap == 1) {  
 672      keyMap = 0;     
 673      keys = key_map1;
 674      tft.drawText(0, 0+16, " 1 I 2 I 3 I 4 I 5 I 6 I 7 I 8 I 9 I 10I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
 675      tft.drawText(0,16+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
 676      tft.drawText(0,24+16, " q I w I e I r I t I y I u I i I o I p I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true);
 677      tft.drawText(0,40+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false);
 678      tft.drawText(0,48+16, " a I s I d I f I g I h I j I k I l IRTNI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
 679      tft.drawText(0,64+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
 680      tft.drawText(0,72+16, " z I x I c I v I b I n I m I , IDELISPCI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true);
 681      tft.drawText(0,88+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false);
 682      delay(500);
 683    }
 684    else if (keyMap == 0) {
 685      keyMap = 1;     
 686      keys = key_map2;            
 687      tft.drawText(0, 0+16, "F1 IF2 IF3 IF4 IF5 IF6 IF7 IF8 IF9 IF10I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
 688      tft.drawText(0,16+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
 689      tft.drawText(0,24+16, " q I w I e I r I t I y I u I i I o I p I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true);
 690      tft.drawText(0,40+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false);
 691      tft.drawText(0,48+16, " a I s I d I f I g I h I j I k I l IRTNI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
 692      tft.drawText(0,64+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
 693      tft.drawText(0,72+16, " z I x I c I v I b I n I m I , IDELISPCI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true);
 694      tft.drawText(0,88+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false);
 695      delay(500);     
 696    }
 697  
 698  }
 699  
 700  
 701  
 702  
 703  static int readNbFiles(void) {
 704    int totalFiles = 0;
 705  
 706  #ifdef USE_SDFS
 707    DIR dir;
 708    FILINFO entry; 
 709    f_opendir(&dir, romspath);  
 710    while ( (true) && (totalFiles<MAX_FILES) ) {
 711      f_readdir(&dir, &entry);
 712      if (!entry.fname[0]) {
 713        // no more files
 714        break;
 715      }
 716      char * filename = entry.fname;
 717      Serial.println(filename);     
 718      if ( !(entry.fattrib & AM_DIR) ) {
 719        strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
 720        totalFiles++;
 721      }
 722      else {
 723        if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) {
 724          strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
 725          totalFiles++;
 726        }
 727      }  
 728    } 
 729    f_closedir(&dir);
 730  #else
 731    File entry;    
 732    file = SD.open(romspath);
 733    while ( (true) && (totalFiles<MAX_FILES) ) {
 734      entry = file.openNextFile();
 735      if (! entry) {
 736        // no more files
 737        break;
 738      }
 739  #ifdef USE_SDFAT
 740    char filename[MAX_FILENAME_SIZE];
 741    entry.getName(&filename[0], MAX_FILENAME_SIZE); 
 742  #else
 743    char * filename = entry.name();
 744  #endif 
 745      Serial.println(filename); 
 746      if (!entry.isDirectory())  {
 747        strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
 748        totalFiles++;
 749      }
 750      else {
 751        if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) {
 752          strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
 753          totalFiles++;
 754        }
 755      }  
 756      entry.close();
 757    }
 758    file.close();
 759  #endif  
 760    return totalFiles;  
 761  }  
 762  
 763  
 764  
 765  void backgroundMenu(void) {
 766      menuRedraw=true;  
 767      tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
 768      tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);  
 769      tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
 770  #ifdef OLD_LAYOUT    
 771      tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
 772      tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
 773  #endif      
 774  }
 775  
 776  int handleMenu(uint16_t bClick)
 777  {
 778    int action = ACTION_NONE;
 779  
 780    char newpath[80];
 781    strcpy(newpath, romspath);
 782    strcat(newpath, "/");
 783    strcat(newpath, selection);
 784  
 785    int rx=0,ry=0,rw=0,rh=0;
 786    char c = 0; //captureTouchZone(menutouchareas, menutouchactions, &rx,&ry,&rw,&rh);
 787   
 788    if ( (bClick & MASK_JOY2_BTN) || (c == MKEY_TFT) ) {     
 789        emu_printf(newpath);
 790  #ifdef USE_SDFS
 791        FILINFO entry;
 792        f_stat(newpath, &entry);
 793        if ( (entry.fattrib & AM_DIR) ) {
 794  #else
 795        File file = SD.open(newpath);
 796        if (file.isDirectory())  {
 797  #endif      
 798          strcpy(romspath,newpath);
 799          curFile = 0;
 800          nbFiles = readNbFiles();             
 801        }
 802        else {
 803          action = ACTION_RUNTFT;               
 804        }
 805        menuRedraw=true;
 806    }
 807    else if ( (bClick & MASK_KEY_USER1) || (c == MKEY_VGA) ) {
 808        menuRedraw=true;
 809        action = ACTION_RUNVGA;    
 810    }
 811    else if ( (c >= MKEY_L1) && (c <= MKEY_L9) ) {
 812      if ( (topFile+(int)c-1) <= (nbFiles-1)  )
 813      {
 814        curFile = topFile + (int)c -1;
 815        menuRedraw=true;
 816       //tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR );
 817      }
 818    }
 819    else if (bClick & MASK_JOY2_UP) {
 820      if (curFile!=0) {
 821        menuRedraw=true;
 822        curFile--;
 823      }
 824    }
 825    else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) || (c == MKEY_UP) ) {
 826      if ((curFile-9)>=0) {
 827        menuRedraw=true;
 828        curFile -= 9;
 829      } else if (curFile!=0) {
 830        menuRedraw=true;
 831        curFile--;
 832      }
 833    }  
 834    else if (bClick & MASK_JOY2_DOWN)  {
 835      if ((curFile<(nbFiles-1)) && (nbFiles)) {
 836        curFile++;
 837        menuRedraw=true;
 838      }
 839    }
 840    else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) || (c == MKEY_DOWN) ) {
 841      if ((curFile<(nbFiles-9)) && (nbFiles)) {
 842        curFile += 9;
 843        menuRedraw=true;
 844      }
 845      else if ((curFile<(nbFiles-1)) && (nbFiles)) {
 846        curFile++;
 847        menuRedraw=true;
 848      }
 849    }
 850    else if ( (bClick & MASK_KEY_USER2) || (c == MKEY_JOY) ) {
 851      emu_SwapJoysticks(0);
 852      menuRedraw=true;  
 853    }   
 854      
 855    if (menuRedraw && nbFiles) {
 856      int fileIndex = 0;
 857      tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR);
 858  //    if (curFile <= (MAX_MENULINES/2-1)) topFile=0;
 859  //    else topFile=curFile-(MAX_MENULINES/2);
 860      if (curFile <= (MAX_MENULINES-1)) topFile=0;
 861      else topFile=curFile-(MAX_MENULINES/2);
 862  
 863      //Serial.print("curfile: ");
 864      //Serial.println(curFile);
 865      //Serial.print("topFile: ");
 866      //Serial.println(topFile);
 867      
 868      int i=0;
 869      while (i<MAX_MENULINES) {
 870        if (fileIndex>=nbFiles) {
 871            // no more files
 872            break;
 873        }
 874        char * filename = &files[fileIndex][0];    
 875        if (fileIndex >= topFile) {              
 876          if ((i+topFile) < nbFiles ) {
 877            if ((i+topFile)==curFile) {
 878              tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
 879              strcpy(selection,filename);            
 880            }
 881            else {
 882              tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);      
 883            }
 884          }
 885          i++; 
 886        }
 887        fileIndex++;    
 888      }
 889  
 890      tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);  
 891      tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
 892      menuRedraw=false;     
 893    }
 894  
 895    return (action);  
 896  }
 897  
 898  bool menuActive(void) 
 899  {
 900    return (menuOn);
 901  }
 902  
 903  void toggleMenu(bool on) {
 904    if (on) {
 905      callibrationOn=false;
 906      menuOn=true;
 907      backgroundMenu();
 908    } else {
 909      menuOn = false;    
 910    }
 911  }
 912  
 913  char * menuSelection(void)
 914  {
 915    return (selection);  
 916  }
 917    
 918  
 919  
 920  
 921  static void callibrationInit(void) 
 922  {
 923    callibrationOn=true;
 924    menuOn=false;
 925    callibrationStep = 0;
 926    calMinX=0,calMinY=0,calMaxX=0,calMaxY=0;
 927    tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff));
 928    tft.drawTextNoDma(0,100, "          Callibration process:", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
 929    tft.drawTextNoDma(0,116, "     Hit the red cross at each corner", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
 930    tft.drawTextNoDma(0,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
 931    prev_zt = 1;  
 932  }
 933  
 934  
 935  static void readCallibration(void) 
 936  {
 937    char fileBuffer[64];
 938  
 939  #ifdef USE_SDFS
 940    FIL file;
 941    int retval;          
 942    if( !(f_open(&file, CALIBRATION_FILE, FA_READ)) ) {
 943      if( !(f_read (&file, fileBuffer, 64, &retval)) ) {
 944        if (retval == 64) { 
 945          sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 
 946        }
 947      }
 948      f_close(&file);    
 949    }
 950  #else
 951    File file = SD.open(CALIBRATION_FILE, O_READ);  
 952    if (file) {
 953      if ( file.read(fileBuffer, 64) ) {
 954        sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY);
 955      }
 956      file.close();
 957      Serial.println("Current callibration params:");
 958      Serial.println(calMinX);
 959      Serial.println(calMinY);
 960      Serial.println(calMaxX);
 961      Serial.println(calMaxY);                 
 962    }
 963  #endif  
 964    else {
 965      Serial.println("Callibration read error");
 966    }  
 967    tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);   
 968  }
 969  
 970  static void writeCallibration(void) 
 971  {
 972    tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);
 973  
 974  #ifdef USE_SDFS
 975    FIL file; 
 976    int retval;       
 977    if( !(f_open(&file, CALIBRATION_FILE, FA_WRITE)) ) {
 978      //if( !(f_read (&file, fileBuffer, 64, &retval)) ) {
 979      //  if (retval == 64) { 
 980      //    sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 
 981      //  }
 982      //}
 983      f_close(&file);    
 984    }
 985  #else
 986    File file = SD.open(CALIBRATION_FILE, O_WRITE | O_CREAT | O_TRUNC);
 987    if (file) {
 988      file.print(calMinX);
 989      file.print(" ");
 990      file.print(calMinY);
 991      file.print(" ");
 992      file.print(calMaxX);
 993      file.print(" ");
 994      file.println(calMaxY);
 995      file.close();
 996    }
 997  #endif  
 998    else {
 999      Serial.println("Callibration write error");
1000    }  
1001  }
1002  
1003  
1004  bool callibrationActive(void) 
1005  {
1006    return (callibrationOn);
1007  }
1008  
1009  
1010  
1011  int handleCallibration(uint16_t bClick) {
1012    uint16_t xt=0;
1013    uint16_t yt=0;
1014    uint16_t zt=0;  
1015    if (tft.isTouching()) {
1016      if (prev_zt == 0) {
1017        prev_zt = 1;
1018        tft.readRaw(&xt,&yt,&zt);
1019        if (zt < 1000) {
1020          return 0;
1021        }
1022        switch (callibrationStep) 
1023        {
1024          case 0:
1025            callibrationStep++;
1026            tft.drawTextNoDma(0,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
1027            tft.drawTextNoDma(TFT_REALWIDTH-8,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
1028            calMinX += xt;
1029            calMinY += yt;          
1030            break;
1031          case 1:
1032            callibrationStep++;
1033            tft.drawTextNoDma(TFT_REALWIDTH-8,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
1034            tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
1035            calMaxX += xt;
1036            calMinY += yt;           
1037            break;
1038          case 2:
1039            callibrationStep++;
1040            tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
1041            tft.drawTextNoDma(0,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
1042            calMaxX += xt;
1043            calMaxY += yt;
1044            break;
1045          case 3:
1046            tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff));
1047            tft.drawTextNoDma(0,100, "          Callibration done!", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
1048            tft.drawTextNoDma(0,116, "        (Click center to exit)", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);           
1049            callibrationStep++;
1050            calMinX += xt;
1051            calMaxY += yt;       
1052            break;                 
1053          case 4:
1054            //Serial.println(xt);
1055            //Serial.println(yt);
1056            if ( (xt > (TFT_REALWIDTH/4)) && (xt < (TFT_REALWIDTH*3)/4) 
1057              && (yt > (TFT_REALHEIGHT/4)) && (yt < (TFT_REALHEIGHT*3)/4) ) {
1058              calMinX /= 2;
1059              calMinY /= 2;
1060              calMaxX /= 2;
1061              calMaxY /= 2;
1062              writeCallibration();                       
1063              toggleMenu(true);
1064            }
1065            else {
1066              callibrationInit();              
1067            }
1068            break; 
1069                             
1070        }
1071        delay(100);
1072      }  
1073    }
1074    else {
1075      prev_zt = 0;
1076    }  
1077  }
1078  
1079  
1080  
1081  
1082  
1083  int emu_FileOpen(char * filename)
1084  {
1085    int retval = 0;
1086  
1087    char filepath[80];
1088    strcpy(filepath, romspath);
1089    strcat(filepath, "/");
1090    strcat(filepath, filename);
1091    emu_printf("FileOpen...");
1092    emu_printf(filepath);
1093  #ifdef USE_SDFS
1094    if( !(f_open(&file, filepath, FA_READ)) ) {
1095  #else    
1096    if ((file = SD.open(filepath, O_READ))) {
1097  #endif
1098      retval = 1;  
1099    }
1100    else {
1101      emu_printf("FileOpen failed");
1102    }
1103    return (retval);
1104  }
1105  
1106  int emu_FileRead(char * buf, int size)
1107  {
1108    unsigned char buffer[256];
1109    
1110    int remaining = size;
1111    int byteread = 0;
1112    int retval=0; 
1113    if (size < 256) {
1114  #ifdef USE_SDFS
1115      if( !(f_read (&file, buffer, size, &retval)) )
1116  #else
1117      retval = file.read(buffer, size);
1118  #endif
1119     if (retval>0) {
1120        memcpy(buf,buffer,retval);
1121        byteread += retval;   
1122     }   
1123    }
1124    else {
1125      while (remaining>0) {
1126  #ifdef USE_SDFS
1127        if( !(f_read (&file, buffer, 256, &retval)) )
1128        //f_read (&file, buffer, 256, &retval);
1129  #else
1130        retval = file.read(buffer, 256);
1131  #endif
1132        if (retval>0) {
1133          //emu_printi(retval);
1134          memcpy(buf,buffer,retval);
1135          buf += retval;
1136          byteread += retval;     
1137          remaining -= retval;
1138        }
1139        else {
1140          break;
1141        }
1142      }    
1143    }
1144  
1145    return byteread; 
1146  }
1147  
1148  unsigned char emu_FileGetc(void) {
1149    unsigned char c;
1150  #ifdef USE_SDFS
1151    int retval=0;
1152    if( !(f_read (&file, &c, 1, &retval)) )
1153  #else
1154    int retval = file.read(&c, 1);
1155  #endif  
1156    if (retval != 1) {
1157      emu_printf("emu_FileGetc failed");
1158    }  
1159    return c; 
1160  }
1161  
1162  
1163  void emu_FileClose(void)
1164  {
1165  #ifdef USE_SDFS
1166    f_close(&file); 
1167  #else
1168    file.close();  
1169  #endif  
1170  }
1171  
1172  int emu_FileSize(char * filename) 
1173  {
1174    int filesize=0;
1175    char filepath[80];
1176    strcpy(filepath, romspath);
1177    strcat(filepath, "/");
1178    strcat(filepath, filename);
1179    emu_printf("FileSize...");
1180    emu_printf(filepath);
1181  #ifdef USE_SDFS
1182    FILINFO entry;
1183    f_stat(filepath, &entry);
1184    filesize = entry.fsize; 
1185  #else
1186    if ((file = SD.open(filepath, O_READ))) 
1187    {
1188      emu_printf("filesize is...");
1189      filesize = file.size(); 
1190      emu_printf(filesize);
1191      file.close();    
1192    }
1193  #endif
1194   
1195    return(filesize);    
1196  }
1197  
1198  int emu_FileSeek(int seek) 
1199  {
1200  #ifdef USE_SDFS
1201    f_lseek(&file, seek);
1202  #else
1203    file.seek(seek);
1204  #endif
1205    return (seek);
1206  }
1207  
1208  int emu_FileTell(void) 
1209  {
1210  #ifdef USE_SDFS
1211    return (f_tell(&file));
1212  #else
1213    return (50);
1214  #endif
1215  }
1216  
1217  
1218  int emu_LoadFile(char * filename, char * buf, int size)
1219  {
1220    int filesize = 0;
1221      
1222    char filepath[80];
1223    strcpy(filepath, romspath);
1224    strcat(filepath, "/");
1225    strcat(filepath, filename);
1226    emu_printf("LoadFile...");
1227    emu_printf(filepath);
1228  #ifdef USE_SDFS
1229    if( !(f_open(&file, filepath, FA_READ)) ) {
1230      filesize = f_size(&file);
1231      emu_printf(filesize);
1232      if (size >= filesize)
1233      {
1234        int retval=0;
1235        if( (f_read (&file, buf, filesize, &retval)) ) {
1236          emu_printf("File read failed");        
1237        }
1238      }
1239      f_close(&file);
1240    }
1241  #else
1242    if ((file = SD.open(filepath, O_READ))) 
1243    {
1244      filesize = file.size(); 
1245      emu_printf(filesize);
1246      
1247      if (size >= filesize)
1248      {
1249        if (emu_FileRead(buf, filesize) != filesize) 
1250        {
1251          emu_printf("File read failed");
1252        }        
1253      }
1254      file.close();
1255    }
1256  #endif  
1257    
1258    return(filesize);
1259  }
1260  
1261  int emu_LoadFileSeek(char * filename, char * buf, int size, int seek)
1262  {
1263    int filesize = 0;
1264      
1265    char filepath[80];
1266    strcpy(filepath, romspath);
1267    strcat(filepath, "/");
1268    strcat(filepath, filename);
1269    emu_printf("LoadFileSeek...");
1270    emu_printf(filepath);
1271  #ifdef USE_SDFS
1272    if( !(f_open(&file, filepath, FA_READ)) ) {
1273      f_lseek(&file, seek);
1274      emu_printf(size);
1275      if (size >= filesize)
1276      {
1277        int retval=0;
1278        if( (!f_read (&file, buf, size, &retval)) ) 
1279        if (retval != size)
1280        {
1281          emu_printf("File read failed");      
1282        }
1283      }
1284      f_close(&file);
1285    }
1286  #else
1287    if ((file = SD.open(filepath, O_READ))) 
1288    {
1289      file.seek(seek);
1290      emu_printf(size);
1291      if (file.read(buf, size) != size) {
1292        emu_printf("File read failed");
1293      }        
1294      file.close();
1295    }
1296  #endif  
1297    
1298    return(filesize);
1299  }
1300  
1301  const uint32_t FILE_SIZE_MB = 8;
1302  const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB;
1303  #ifdef USE_SDFS
1304  static FIL tempfile; 
1305  #else
1306  static File tempfile;
1307  #endif
1308  
1309  void emu_FileTempInit(void) 
1310  {
1311  #ifdef USE_SDFS
1312   if( (f_open(&tempfile, SDFSDEV "/bench.dat", FA_READ| FA_WRITE )) ) {
1313  #else
1314  #ifdef USE_SDFAT
1315    if (!tempfile.open("/bench.dat", O_RDWR /*| O_CREAT | O_TRUNC*/)) {
1316  #else
1317    if ((tempfile = SD.open("/bench.dat", O_RDWR))) {
1318  #endif
1319  #endif
1320      Serial.println("psram open failed");
1321    }
1322  /*
1323    else {
1324      uint8_t buf[256];
1325      Serial.println("psram creating");    
1326      file = SD.open("/bench.dat", O_RDWR | O_CREAT | O_TRUNC);
1327      if (file) {
1328        Serial.println("psram opened");    
1329        file.truncate(0);
1330  
1331        if (!file.preAllocate(FILE_SIZE)) {
1332          Serial.println("allocate failed");  
1333        }      
1334        for(int i=0;i<FILE_SIZE/256;i++){
1335          file.write(buf, 256);
1336          Serial.println(i);
1337          
1338        }
1339        Serial.println("psram created");
1340      }
1341      
1342      //file.close();
1343    }
1344  */  
1345  #ifdef USE_SDFS
1346    FILINFO entry;
1347    f_stat(SDFSDEV "/bench.dat", &entry);
1348    int fs=entry.fsize;
1349  #else
1350    int fs=tempfile.size();
1351  #endif
1352    Serial.print("psram size is ");
1353    Serial.println(fs); 
1354  }
1355  
1356  void emu_FileTempRead(int addr, unsigned char * val, int n) 
1357  {
1358  #ifdef USE_SDFS
1359    f_lseek(&file, addr);
1360    int retval=0;
1361    f_read (&file, val, n, &retval);
1362  #else
1363    tempfile.seek(addr);
1364    tempfile.read(val, n);
1365  #endif    
1366  }
1367  
1368  void emu_FileTempWrite(int addr, unsigned char val) 
1369  {
1370    uint8_t v=val;
1371  #ifdef USE_SDFS
1372    f_lseek(&tempfile, addr);
1373    int retval=0;
1374    f_write (&tempfile, &v, 1, &retval);
1375  #else
1376    tempfile.seek(addr);
1377    tempfile.write(&v, 1);
1378  #endif   
1379  }
1380  
1381  
1382  void emu_init(void)
1383  {
1384    Serial.begin(115200);
1385  
1386  #ifdef USE_SDFS
1387    strcpy(romspath,SDFSDEV);
1388    strcat(romspath,ROMSDIR);    
1389    FRESULT rc;
1390    if((rc = f_mount (&fatfs, romspath, 1))) {
1391      emu_printf("Fail mounting SDFS");  
1392    }
1393    else { 
1394      rc = f_chdrive(ROMSDIR);
1395    }
1396  #else  
1397  #ifdef USE_SDFAT
1398    while (!SD.begin(SD_CONFIG))
1399  #else
1400    while (!SD.begin(SD_CS))
1401  #endif
1402    {
1403      Serial.println("SD begin failed, retrying...");
1404      delay(1000);    
1405    }
1406    strcpy(romspath,ROMSDIR);
1407  #endif
1408  
1409    nbFiles = readNbFiles(); 
1410  
1411    Serial.print("SD initialized, files found: ");
1412    Serial.println(nbFiles);
1413  
1414    
1415    emu_InitJoysticks();
1416  #ifdef SWAP_JOYSTICK
1417    joySwapped = true;   
1418  #else
1419    joySwapped = false;   
1420  #endif  
1421    readCallibration();
1422   
1423    if ((tft.isTouching()) || (emu_ReadKeys() & MASK_JOY2_BTN) ) {
1424      callibrationInit();
1425    } 
1426    else  
1427    {
1428      toggleMenu(true);
1429    }
1430  
1431  #ifdef HAS_I2CKBD
1432    byte msg[7]={0,0,0,0,0,0,0};
1433    Wire.begin(); // join i2c bus SDA2/SCL2
1434    Wire.requestFrom(8, 7);    // request 7 bytes from slave device #8 
1435    int i = 0;
1436    while (Wire.available() && (i<7) ) { // slave may send less than requested
1437      byte b = Wire.read(); // receive a byte
1438      msg[i++] = b;        
1439    }
1440    /*     
1441    Serial.println(msg[0], BIN);
1442    Serial.println(msg[1], BIN);
1443    Serial.println(msg[2], BIN);
1444    Serial.println(msg[3], BIN);
1445    Serial.println(msg[4], BIN);
1446    Serial.println(msg[5], BIN);
1447    Serial.println(msg[6], BIN);
1448    */  
1449    if ( (msg[0] == 0xff) && (msg[1] == 0xff) && 
1450         (msg[2] == 0xff) && (msg[3] == 0xff) && 
1451         (msg[4] == 0xff) && (msg[5] == 0xff) && (msg[6] == 0xff)) {
1452      i2cKeyboardPresent = true;
1453      Serial.println("i2C keyboard found");            
1454    }
1455  #endif
1456  
1457    keys = key_map1;
1458    keyMap = 0;
1459  }
1460  
1461