GBARunner2

Discussion in 'NDS - Emulation and Homebrew' started by Gericom, Dec 4, 2016.

Dec 4, 2016

GBARunner2 by Gericom at 9:46 PM (30,271 Views / 50 Likes) 482 replies

  1. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    Hi guys,

    I am presenting you a new way to play gba games on your ds from your slot 1 card (r4, dstwo etc.).

    It works a bit like gbaemu4ds, but it's made from scratch, almost completely in assembly and much cleaner. (And I didn't know gbaemu4ds used the same idea I had until I had a working base tbh) I am still optimizing everything, and mainly the abort handler, by using self-modifying code and large jump tables.
    Compared to gbaemu4ds, gbarunner2 has almost no sprite glitches and better sound. SD access speed is currently lower, but I am working on that.

    Only SRAM is supported, so patching is required if your rom uses EEPROM or FLASH. The save is not written to your sd card, I'll be implementing that later on (just like a gui and stuff)

    Github: https://github.com/Gericom/GBARunner2

    If you want to try it out:
    1. Make sure you have devkitpro installed
    2. Download the git repo
    3. Run make in the root
    4. Make sure your sd card is fat32 formatted
    5. Put a gba bios as bios.bin in the root of your sd card
    6. Put Gbarunner2.nds on your sd card
    7. SRAM patch your gba rom with gbata if needed
    8. Put the rom as runner.gba in the root of your sd
    9. Run gbarunner2.nds

    I would like to know which games work and which don't (and on which version of gbarunner2, aka commit)

    Put your findings here: https://wiki.gbatemp.net/wiki/GBARunner2
     
    Last edited by Gericom, Jan 3, 2017
    SLiV3R, elBenyo, Sinon and 47 others like this.


  2. Mikemk

    Member Mikemk GBAtemp Maniac

    Joined:
    Mar 26, 2015
    Messages:
    1,339
    Country:
    United States
    Use mkdir in the Makefile to create a folder.
     
  3. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    I am simply going to remove the need for that folder.
     
  4. windwakr

    Member windwakr GBAtemp Fan

    Joined:
    Sep 13, 2009
    Messages:
    470
    Country:
    United States
    Very impressive. Can't wait to see the compatibility improve.

    Commit 6c1dc96:
    Advance Wars - Seems to run fast with good audio, but a lot of graphical bugs. Will freeze if you don't skip the intro.
    Zelda Minish Cap - Extremely slow, graphical bugs, garbage audio. Too slow to bother trying to get in game.
    Castlevania Circle of the Moon - Very slow, a few graphical bugs, good audio.
    Final Fantasy Tactics Advance - Extreme graphical bugs, title screen seems to have some sort of palette issue then freezes.


    Tested on a launch day phat(wow, it's 12 years old now) with an Acekard 2i.
     
    Last edited by windwakr, Dec 5, 2016
  5. VinLark

    Member VinLark Check this 5

    Joined:
    Jun 11, 2016
    Messages:
    3,525
    Location:
    4chan and other wonders of the internet
    Country:
    United States
    Wew lad, new NDS homebrew is always a site to see.

    I'll try this out when I can, I do want to see how this holds up to the other gba emulator. Nice!
     
    DarkRioru likes this.
  6. nxwing

    Member nxwing GBAtemp Advanced Maniac

    Joined:
    Jul 22, 2013
    Messages:
    1,889
    Country:
    Philippines
    This is pretty nice! I'll test it out with a few games and I'll try and make an entry on the wiki for this.
     
  7. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    Thanks, that would be nice. Make sure to include a field for the commit number, as things might change from commit to commit.
     
  8. Coto

    Member Coto GBAtemp Addict

    Joined:
    Jun 4, 2010
    Messages:
    2,312
    Country:
    Chile
    very nice work Gericom.!

    I might give some feedback as I get used to this codebase.
     
  9. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    I've commited some bugfixes, Super Mario Advance 3: Yoshi's Island now works and Mario and Luigi gets a little further. Some other games now boot aswell.
     
  10. raystriker

    Member raystriker Alpha PC Builder

    Joined:
    Dec 28, 2011
    Messages:
    1,205
    Location:
    Bloomington
    Country:
    India
    OT: There was a time when people used to get banned for asking whether the nds could emulate the gba.
    Thanks for reviving the gba hypervisor for nds, we've waited long enough :bow:
     
  11. Coto

    Member Coto GBAtemp Addict

    Joined:
    Jun 4, 2010
    Messages:
    2,312
    Country:
    Chile
    arm7 touchscreen
    I got RTC working in gbaemu4ds long ago so i'll share how it was done:

    (I just literally mapped them)

    first I used IPC to transfer stuff between ARM7->ARM9

    //ipc header definition
    Code:
    ipc.h
    
    //---------------------------------------------------------------------------------
    typedef struct sMyIPC {
    //---------------------------------------------------------------------------------
      int16 touchX,  touchY;  // raw x/y
       int16 touchXpx, touchYpx; // TFT x/y pixel
    
       int16 touchZ1,  touchZ2;  // TSC x-panel measurements
       uint16 tdiode1,  tdiode2;  // TSC temperature diodes
       uint32 temperature;  // TSC computed temperature
    
       uint16 buttons;  // keypad buttons
      uint16 buttons_xy_folding;  // X, Y, /PENIRQ buttons
    
       u8 touched;          //TSC touched?
      u8 touch_pendown;  //TSC already held before?
    
       uint16 battery;  // battery life status
       uint16 aux;  // SPI AUX port status
    
    
      //IPC Clock
      //[0]; //yy
      //[1]; //mth
      //[2]; //dd
      //[3]; //wat - day of week?
      //[4]; //hh
      //[5]; //mm
      //[6]; //ss
      u8 clockdata[0x20];
    
    
    } tMyIPC;
    
    //Shared Work  027FF000h 4KB  -  -  -  R/W
    //IPC Struct
    #define SHARED_ADDR_REGION ((tMyIPC volatile *)(0x027FF000))
    
    

    //ipc definition opcodes (i dont really care about BCD conversion....)
    Code:
    
    //gbaemu4ds clock opcodes
    u8 gba_get_yearbytertc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[0];
    }
    
    u8 gba_get_monthrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[1];
    }
    
    u8 gba_get_dayrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[2];
    }
    
    u8 gba_get_dayofweekrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[3];
    }
    
    
    u8 gba_get_hourrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[4];
    }
    
    u8 gba_get_minrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[5];
    }
    
    u8 gba_get_secrtc(){
       return (u8)(u32)SHARED_ADDR_REGION->clockdata[6];
    }
    
    


    //ARM7

    Code:
    touch_ipc.h
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    extern void updateMyIPC();
    
    #ifdef __cplusplus
    }
    #endif
    
    
    
    Code:
    touch_ipc.c
    
    #include "touch_ipc.h"
    #include "../../common/gba_ipc.h"
    
    #include <nds/ndstypes.h>
    #include <nds/system.h>
    #include <nds/arm7/touch.h>
    #include <nds/input.h>
    #include <nds/interrupts.h>
    
    #include <nds/bios.h>
    #include <nds/arm7/clock.h>
    #include <nds/ipc.h>
    #include <stdlib.h>
    
    //coto: use it at vcount interrupts so you save battery (or vblank but vcount works just fine)
    void updateMyIPC()
    {
       uint16 but=0, batt=0;
       int t1=0, t2=0;
       uint32 temp=0;
       u32 i=0;
       u8 clock_buf[sizeof(SHARED_ADDR_REGION->clockdata)];
    
      touchPosition tempPos;
      touchReadXY(&tempPos);
    
       // Read the touch screen
       but = REG_KEYXY;
       batt = touchRead(TSC_MEASURE_BATTERY);
       // Read the time
       rtcGetTimeAndDate(clock_buf);
    
       // Read the temperature
       temp = touchReadTemperature(&t1, &t2);
    
      // Update the IPC struct
       SHARED_ADDR_REGION->buttons     = but;
       SHARED_ADDR_REGION->touched  = ((tempPos.px > 0) || (tempPos.py > 0)) ? 1 : 0;
    
      //raw x/y
      SHARED_ADDR_REGION->touchX  = tempPos.rawx;
      SHARED_ADDR_REGION->touchY  = tempPos.rawy;
    
      //TFT x/y pixel
      SHARED_ADDR_REGION->touchXpx = tempPos.px;
      SHARED_ADDR_REGION->touchYpx = tempPos.py;
    
       SHARED_ADDR_REGION->touchZ1 = tempPos.z1;
       SHARED_ADDR_REGION->touchZ2 = tempPos.z2;
       SHARED_ADDR_REGION->battery     = batt;
    
      //Get time
      for(i=0; i< sizeof(clock_buf); i++){
      SHARED_ADDR_REGION->clockdata[i] = clock_buf[i];
      }
    
       SHARED_ADDR_REGION->temperature = temp;
       SHARED_ADDR_REGION->tdiode1 = t1;
       SHARED_ADDR_REGION->tdiode2 = t2;
    
    }
    
    


    //ARM9

    arm9 touchscreen handler (only if you want touchscreen on custom handlers)
    Code:
    touch_ipc.h
    
    
    #ifndef GBAEMU4DS_ARM9TOUCH
    #define GBAEMU4DS_ARM9TOUCH
    
    #include <nds.h>
    #include <nds/touch.h>
    
    #endif
    
    
    #ifdef __cplusplus
    extern "C"{
    #endif
    
    extern void touchReadXY_gbaemu4ds(touchPosition * touchpos_inst);
    
    #ifdef __cplusplus
    }
    #endif
    
    
    Code:
    touch_ipc.c
    
    #include "touch_ipc.h"
    #include <nds.h>
    #include <nds/touch.h>
    #include "../../../common/gba_ipc.h"
    
    //usage: struct touchPosition touchposition;
    //touchReadXY_gbaemu4ds(&touchposition);
    
    void touchReadXY_gbaemu4ds(touchPosition * touchpos_inst){
    
      touchpos_inst->rawx =  SHARED_ADDR_REGION->touchX;
      touchpos_inst->rawy =  SHARED_ADDR_REGION->touchY;
    
      //TFT x/y pixel
      touchpos_inst->px  =  SHARED_ADDR_REGION->touchXpx;
      touchpos_inst->py  =  SHARED_ADDR_REGION->touchYpx;
    
      touchpos_inst->z1  =  SHARED_ADDR_REGION->touchZ1;
      touchpos_inst->z2  =  SHARED_ADDR_REGION->touchZ2;
    }
    


    and then VBA libs:
    Code:
    RTC.H
    
    // -*- C++ -*-
    // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
    // Copyright (C) 1999-2003 Forgotten
    // Copyright (C) 2004 Forgotten and the VBA development team
    
    // This program is free software; you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation; either version 2, or(at your option)
    // any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    //
    // You should have received a copy of the GNU General Public License
    // along with this program; if not, write to the Free Software Foundation,
    // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    
    #ifndef VBA_RTC_H
    #define VBA_RTC_H
    extern u16 rtcRead(u32 address);
    extern bool rtcWrite(u32 address, u16 value);
    extern void rtcEnable(bool);
    extern bool rtcIsEnabled();
    extern void rtcReset();
    
    extern void rtcReadGame(gzFile file);
    extern void rtcSaveGame(gzFile file);
    
    #endif
    
    
    Code:
    RTC.C
    
    // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
    // Copyright (C) 1999-2003 Forgotten
    // Copyright (C) 2005 Forgotten and the VBA development team
    
    // This program is free software; you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation; either version 2, or(at your option)
    // any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    //
    // You should have received a copy of the GNU General Public License
    // along with this program; if not, write to the Free Software Foundation,
    // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    
    #include "ipc.h"
    
    #include "System.h"
    #include "GBA.h"
    #include "Globals.h"
    #include "Port.h"
    #include "Util.h"
    #include "NLS.h"
    
    #include <time.h>
    #include <nds/memory.h>//#include <memory.h> ichfly
    #include <nds/ndstypes.h>
    #include <nds/memory.h>
    #include <nds/bios.h>
    #include <nds/system.h>
    #include <nds/arm9/math.h>
    #include <nds/arm9/video.h>
    #include <nds/arm9/videoGL.h>
    #include <nds/arm9/trig_lut.h>
    #include <nds/arm9/sassert.h>
    
    enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
    
    typedef struct {
      u8 byte0;
      u8 byte1;
      u8 byte2;
      u8 command;
      int dataLen;
      int bits;
      RTCSTATE state;
      u8 data[12];
      // reserved variables for future
      u8 reserved[12];
      bool reserved2;
      u32 reserved3;
    } RTCCLOCKDATA;
    
    static RTCCLOCKDATA rtcClockData;
    static bool rtcEnabled = false;
    
    void rtcEnable(bool e)
    {
      rtcEnabled = e;
    }
    
    bool rtcIsEnabled()
    {
      return rtcEnabled;
    }
    
    u16 rtcRead(u32 address)
    {
      if(rtcEnabled) {
      if(address == 0x80000c8)
      return rtcClockData.byte2;
      else if(address == 0x80000c6)
      return rtcClockData.byte1;
      else if(address == 0x80000c4) {
      return rtcClockData.byte0;
      }
      }
    
      return READ16LE((&rom[address & 0x1FFFFFE])); //your little endian u16 read from gba map gets replaced here
    }
    
    static u8 toBCD(u8 value)
    {
      value = value % 100;
      int l = value % 10;
      int h = value / 10;
      return h * 16 + l;
    }
    
    bool rtcWrite(u32 address, u16 value)
    {
      if(!rtcEnabled)
      return false;
    
      if(address == 0x80000c8) {
      rtcClockData.byte2 = (u8)value; // enable ?
      } else if(address == 0x80000c6) {
      rtcClockData.byte1 = (u8)value; // read/write
      } else if(address == 0x80000c4) {
      if(rtcClockData.byte2 & 1) {
      if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
      rtcClockData.state = COMMAND;
      rtcClockData.bits = 0;
      rtcClockData.command = 0;
      } else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
      rtcClockData.byte0 = (u8)value;
      switch(rtcClockData.state) {
      case COMMAND:
      rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
      rtcClockData.bits++;
      if(rtcClockData.bits == 8) {
      rtcClockData.bits = 0;
      switch(rtcClockData.command) {
      case 0x60:
      // not sure what this command does but it doesn't take parameters
      // maybe it is a reset or stop
      rtcClockData.state = IDLE;
      rtcClockData.bits = 0;
      break;
      case 0x62:
      // this sets the control state but not sure what those values are
      rtcClockData.state = READDATA;
      rtcClockData.dataLen = 1;
      break;
      case 0x63:
      rtcClockData.dataLen = 1;
      rtcClockData.data[0] = 0x40;
      rtcClockData.state = DATA;
      break;
      case 0x64:
      break;
      case 0x65:
      {
    
      /*
      struct tm *newtime;
      time_t long_time;
    
      time( &long_time );  // Get time as long integer.
      newtime = localtime( &long_time );// Convert to local time.
    
      rtcClockData.dataLen = 7;
      rtcClockData.data[0] = toBCD(newtime->tm_year);
      rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
      rtcClockData.data[2] = toBCD(newtime->tm_mday);
      rtcClockData.data[3] = toBCD(newtime->tm_wday);
      rtcClockData.data[4] = toBCD(newtime->tm_hour);
      rtcClockData.data[5] = toBCD(newtime->tm_min);
      rtcClockData.data[6] = toBCD(newtime->tm_sec);
      rtcClockData.state = DATA;
      */
    
      //coto: own IPC.
      rtcClockData.dataLen = 7;
      rtcClockData.data[0] = toBCD(gba_get_yearbytertc());
      rtcClockData.data[1] = toBCD(gba_get_monthrtc());
      rtcClockData.data[2] = toBCD(gba_get_dayrtc());
      rtcClockData.data[3] = toBCD(gba_get_dayofweekrtc());
      rtcClockData.data[4] = toBCD(gba_get_hourrtc());
      rtcClockData.data[5] = toBCD(gba_get_minrtc());
      rtcClockData.data[6] = toBCD(gba_get_secrtc());
      rtcClockData.state = DATA;
    
      }
      break;
      case 0x67:
      {
      /*
      struct tm *newtime;
      time_t long_time;
    
      time( &long_time );  // Get time as long integer.
      newtime = localtime( &long_time ); // Convert to local time.
    
      rtcClockData.dataLen = 3;
      rtcClockData.data[0] = toBCD(newtime->tm_hour);
      rtcClockData.data[1] = toBCD(newtime->tm_min);
      rtcClockData.data[2] = toBCD(newtime->tm_sec);
      rtcClockData.state = DATA;
      */
    
      //coto: own IPC.
      rtcClockData.dataLen = 3;
      rtcClockData.data[0] = toBCD(gba_get_hourrtc());
      rtcClockData.data[1] = toBCD(gba_get_minrtc());
      rtcClockData.data[2] = toBCD(gba_get_secrtc());
      rtcClockData.state = DATA;
    
      }
      break;
      default:
      systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
      rtcClockData.state = IDLE;
      break;
      }
      }
      break;
      case DATA:
      if(rtcClockData.byte1 & 2) {
      } else {
      rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
      ((rtcClockData.data[rtcClockData.bits >> 3] >>
      (rtcClockData.bits & 7)) & 1)*2;
      rtcClockData.bits++;
      if(rtcClockData.bits == 8*rtcClockData.dataLen) {
      rtcClockData.bits = 0;
      rtcClockData.state = IDLE;
      }
      }
      break;
      case READDATA:
      if(!(rtcClockData.byte1 & 2)) {
      } else {
      rtcClockData.data[rtcClockData.bits >> 3] =
      (rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
      ((value << 6) & 128);
      rtcClockData.bits++;
      if(rtcClockData.bits == 8*rtcClockData.dataLen) {
      rtcClockData.bits = 0;
      rtcClockData.state = IDLE;
      }
      }
      break;
         default:
      break;
      }
      } else
      rtcClockData.byte0 = (u8)value;
      }
      }
      return true;
    }
    
    void rtcReset()
    {
      memset(&rtcClockData, 0, sizeof(rtcClockData));
    
      rtcClockData.byte0 = 0;
      rtcClockData.byte1 = 0;
      rtcClockData.byte2 = 0;
      rtcClockData.command = 0;
      rtcClockData.dataLen = 0;
      rtcClockData.bits = 0;
      rtcClockData.state = IDLE;
    }
    
    
    Then

    Code:
    //your little endian u16 write handler to gba map gets replaced here
    CPUWriteHalfWord(u32 address, u16 value){
      switch(address >> 24) {
      case 8:
      case 9:
      if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
      if(!rtcWrite(address, value))
      goto unwritable;
      } else if(!agbPrintWrite(address, value)) goto unwritable;
      break;
      }
    
    }
    
    
    //your little endian u16 read handler from gba map gets replaced here
    u16 CPUReadHalfWord(u32 address){
    switch(address >> 24) {
      case 8:
      case 9:
      case 10:
      case 11:
      case 12:
      if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
      value = rtcRead(address);
      else
       {
         value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
       }
      break;
    
    }
    }
    
    

    so before gba execution begins you:
    Code:
    rtcReset();
    
    then
    
    rtcEnable(true); //nds7 RTC support.
    
    You could print the RTC values and see if they read the clock. Libnds does this but since we are in broken defaulttemplateland stuff like this must be done.

    edit: 06/12/2016 fixed SHARED_ADDR_REGION declaration usage across source files.
     
    Last edited by Coto, Dec 18, 2016
  12. DarkRioru

    Member DarkRioru YamiRioru

    Joined:
    Aug 29, 2015
    Messages:
    1,761
    Location:
    In azuril's nightmare
    Country:
    United States
    awesome! can it play games from a folder or is the runner.gba the only game I can run??
     
  13. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    This sounds like it should be quite straightforward to implement. I think I'll have a look at it.
    Currently it can only start runner.gba, but later on I want to implement a gui.
     
    SLiV3R and Lunedi like this.
  14. DaRk_ViVi

    Member DaRk_ViVi ...is everywhere!

    Joined:
    Apr 13, 2004
    Messages:
    1,033
    Location:
    Asti, Italy
    Country:
    Italy
    Great, I will test it ASAP!
    With the GUI coming in the future, would it be possible to provide precompiled .nds files that loads the bios.bin directly from the SD?
     
  15. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    Yes, I will be implementing that indeed later on. I was now mainly focusing on getting the games to run as good as possible.
     
  16. Coto

    Member Coto GBAtemp Addict

    Joined:
    Jun 4, 2010
    Messages:
    2,312
    Country:
    Chile
    Also remember that NIFI requires stable arm7 interrupts (if you ever want multiplayer working). Which is why I was asking to have a separate branch for ARM7 / ARM9 - libfat, C code (interrupts, timer cycles, IPC like the RTC example shown above). It will truly save you a lot of headaches once you start implementing more things that must be synced(which would be better to maintain to remove any race attack condition events).

    Also,if you run DSWIFI libs to sync at vblank nds clock cycle, its pretty stable.

    If you dont at least handle vblank properly in ARM9 NIFI will work but unstable (and socket-like services devkitpro, will cause lockups).

    edit: also I have flash/eeprom/sram handling like the RTC example working. If you are interested to see those examples (should be C code in my opinion) since it is not a timing dependant operation, unless you want to emulate the clockchip cycles (definitely not required)
     
    Last edited by Coto, Dec 6, 2016
    zfreeman likes this.
  17. xtheman

    Member xtheman GBAtemp's Official Ghost

    Joined:
    Jan 28, 2016
    Messages:
    5,592
    Country:
    Antarctica
    This is great! I just ran this on my 3ds and it works perfectly
     
  18. Flame

    Member Flame Me > You

    Joined:
    Jul 15, 2008
    Messages:
    3,612
    Country:
    great work. hope to see more of this project :yay:
     
  19. AtlasFontaine

    Member AtlasFontaine GBAtemp Maniac

    Joined:
    Jul 18, 2015
    Messages:
    1,025
    Location:
    Venezuela-Zulia.
    Country:
    Venezuela
    Tested Zelda minish cap (after SRAM patching it), it runs until the intro video, after ending the intro it crashes on black screen (graphics are messed up on title screen also).

    Tried Advanced Wars 2 Black Hole Rising but the game crashed right after the bios intro and showed this on the bottom screen:
    Pic

    Castlevania Aria of Sorrow ran pretty good (60fps), I played it for 15 minutes.

    Completed the first level of Wario Land 4 and it worked perfectly.

    played Fire Emblem to the 2nd mission and it worked perfectly.
     
    Last edited by AtlasFontaine, Dec 6, 2016
    Subtle Demise and elBenyo like this.
  20. Gericom
    OP

    Member Gericom GBAtemp Advanced Fan

    Joined:
    Jun 30, 2011
    Messages:
    726
    Country:
    Netherlands
    Thanks for your feedback, we really need a compatibility list like the one gbaemu4ds has. Would be interesting to compare compatibility too.
     

Share This Page