Homebrew arm9loaderhay - my own take on a A9LH file select

D

Deleted User

Guest
Uploaded a new version on first post. That's basically the test version above but without the 4 useless "-" at the beginning of the name. Not sure if they'll make a comeback but for now I don't see any reason to have a folder name with 16 characters if only 12 are used.

Old post in spoiler.
As you may be able to tell from the title, this is a fork from arm9select, so credits go to @FIX94 and whoever he credited. This also uses code from Decrypt9 for the password, so credits to @d0k3 and whoever I should credit too, but I have no idea who they are. You can PM me or post in the topic if you want to be credited.

Current boot managers (from what I've seen at least) either "only" allow you you to use one key per file or allow you to use two keys but one of them is fixed (like L+button with AuReiNand). This bothered me a bit, so I wanted to make a boot manager that allows you to use any button configuration for any payload, and that would also support password protection to avoid people booting GodMode9 and erasing all the things. Well here it is.

The magic folder is obviously the "arm9loaderhay" folder on your SD card (create it if needed). Here, you can put a default.bin payload and a default_bl file if the default payload needs backlight (same as arm9select so far).
Then, in that folder, you can have subfolders, containing a "arm9loaderhax.bin" payload (the name "arm9loaderhax.bin" allows to easily update the payload since probably all payloads are released with that name). Along with that payload, you can have a "backlight" file if the payload needs backlight, and a "password" file if the payload needs to be password protected. You can also add other files like a file named "AB_CtrBootManager" to specify that this folder is about CtrBootManager and is launched with AB.

The annoying part is the folder name. It is composed of 16 digits. From right to left, digits describe keys in that order : A, B, SELECT, START, RIGHT, LEFT, UP, DOWN, R, L, X, Y. Now you may say "it makes 12 digits and you said 16". Just put the remaining ones at 0.

So here's an example of what your SD card might look like.
Code:
SD
├── arm9loaderhax.bin
└── arm9loaderhay/
  ├── default.bin
  ├── default_bl
  ├── 0000000000000011/
  │  ├── arm9loaderhax.bin
  │  ├── backlight
  │  └── This_Is_CtrBootManager_On_A_B
  └── 0000000000100100/
  ├── arm9loaderhax.bin
  ├── backlight
  ├── password
  └── This_Is_GodMode9_On_LEFT_SELECT

The password file must actually be a text file containing your password. Yeah, that means you are able to set a different password for each payload. Or you can use the same one by copy-pasting the same password file in all your folders.
To describe your password, use this:
  • A,B,X,Y for the A,B,X,Y keys
  • E,T for SELECT and START (they both start with an S so they couldn't use their initials)
  • l,r,d,u for the arrow keys (in lowercase to avoid confusion with L and R)
  • L,R for the shoulders
So for example, if your password is A,B,X,Y, just write "ABXY" in your password file.
Notice that any password longer than 10 characters will be trimmed down to 10.
Also notice that any unrecognized character will mark the end or your password. "ABXYwatLR" for exemple is equivalent to "AXBY".
The last thing to notice is that you can't use the same key twice in a row, so ABA is valid but AAB isn't.
And since I did this during the night and uploaded it today in haste, it's not so heavily tested. I basically only tested it with "ABXY"...

Changes in code are as follow (plus get the hid.c, hid.h files from Decrypt9, and maybe some others I forgot).
In arm9select/payload_stage2/source/main.c
Code:
int main()
{
  FATFS fs;
  if(f_mount(&fs, "0:", 0) == FR_OK)
  {
  //Read pad state
  u16 padInput = (~(*(u16*)0x10146000)) & 0x0FFF;
  FIL f;

  //Deduce base filename
  u16 N = padInput;
  char base[] = "/arm9loaderhay/0000000000000000/arm9loaderhax.bin";
  char back[] = "/arm9loaderhay/0000000000000000/backlight";
  char pass[] = "/arm9loaderhay/0000000000000000/password";
  for (int i=0; i<16; i++) {
  base[30-i] = '0' + (N%2);
  back[30-i] = '0' + (N%2);
  pass[30-i] = '0' + (N%2);
  N = N/2;
  }

  //Password if needed
  if (f_open(&f, pass, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
  //u32 password[] = {BUTTON_LEFT, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A, 0};

  u32 password[11]; //password can't be longer than 10, because a max is reasonably needed and no one will go over 10...
  for (int i=0; i<11; i++) password[i] = 0;
  char read[10];
  UINT pass_length;
  f_read(&f, read, 10, &pass_length);
  f_close(&f);

  //convert char like 'A' or 'B' into u32 like 0001 or 0010...
  char ch[] = "ABETrludRLXY";
  for (int i=0; i<pass_length; i++) {
  char cur = read[i];
  int index = -1;
  for (int j=0; j<12; j++) if (cur == ch[j]) index = j;
  if (index != -1) password[i] = 1<<index;
  }

  int n = 0;
  int miss = 0;
  u32 pad = 0;
  u32 oldPad;
  while (password[n] != 0) {
  oldPad = pad;
  while (pad == 0 || pad == oldPad) pad = InputWait() & 0x0FFF;

  if (password[n] == pad) {
  n++;
  } else {
  miss++;
  n = 0;
  }
  }
  }

  if (tryLoadFile(base)) {
  jumpAndTryEnableBL(back);
  } else if (tryLoadFile("/arm9loaderhay/default.bin")) {
  if(*(vu8*)CFG_BOOTENV == COLDBOOT) {
  jumpAndTryEnableBL("/arm9loaderhay/default_bl");
  } else { //dont enable backlight again on soft reset
  jump();
  }
  }
  }
  i2cWriteRegister(I2C_DEV_MCU, 0x20, (u8)(1<<0));
  return 0;
}

I didn't test everything though, so I am not saying it works perfectly, and I warned you, so I can't be held responsible if your 3DS bricks from using this program (even though it shouldn't happen). For example, I can't test all existing passwords and all key combinations.

(And if you don't trust me because I never released anything, you can read this. Of course, it doesn't prove my program works (and maybe it doesn't, that's the first thing I compile for a 3DS) but at least I'm not a crook doing stuff that doesn't work on purpose).
Awesome! Can't wait to see if you ever find a way to make those have a comback! This version is pretty noob-friendly! Glad to see the progress!
 
D

Deleted User

Guest
Are you going to ever think about adding support for Non-Screen init forks? Currently, FIX94's and the rest of the forks are moth old code that don't have the newest features. Aurora Wright's fork is the newest and most updated so it seems that most attention is put towards no screen init forks rather than FIX94's fork. Aurora's no screen init is here: https://github.com/AuroraWright/arm9loaderhax/tree/noscreeninit you could possibly ask Aurora or Delebile on how to code screen init into arm9loaderhay
 

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
I don't know. That would be a useful feature of course, I'm not denying it, but I mean, that's not the job of a boot manager. I'm not sure other boot managers have screen init included.

I think that what should be done is a screen init payload that would only init the screen then execute another payload. This way, you can use whatever arm9loaderhax fork, if you need screen init you just add that payload to your boot chain.

Or add something in the lines of "if (screen_not_init'd) screen_init();" but yeah, I'd really need someone to help with that because these writes I see on every screen_init code don't make any sense so I'm not sure which one I need and when, and which one I don't need and when.
 
  • Like
Reactions: Deleted User
D

Deleted User

Guest
Some code to add Screen init within arm9loaderhay

You need to disable interrupts on arm11, or else you need weird delays XD You can see here: https://github.com/AuroraWright/AuR...d7a0bbf3c2424cf2808f48ca4/source/screeninit.c
Also, the "if(PDN_GPU_CNT == 1)" is a way to check if the screens have been inited or not, if that might be useful.
This was from Arm9Select but applies to your fork too!
@FIX94:

"Doing screen init but leaving backlight at 0x0 is a non-standard environment. The proper way for Fix94 would be to NOT do screen init in stage2 and doing it fully from inside Arm9Select. This way detection wouldn't be borked. This is not an issue with Aurei itself."

This is a quote from Aurora. Your version of A9L is causing issues with Aureinand now. (hangs if booted without config file). Perhaps moving screen init into Arm9Select would be better?
 
Last edited by ,

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
Oops, I saw your previous post at a moment when I couldn't answer then forgot about it. Sorry.
I'm actually working on other things and kind of left arm9loaderhay out.

But yeah if you want you can get the source and I'll give you thread access to edit the first post if you update it. The changes from arm9select are described in the first post but it's true that having everything in one place is better so here is a zip ;)
(And yeah, I could have made a github for that but first I'm a github noob, and second I didn't think it would be necessary for this little project).
 

Attachments

  • arm9loaderhay.zip
    499.8 KB · Views: 111
  • Like
Reactions: Deleted User
D

Deleted User

Guest
Oops, I saw your previous post at a moment when I couldn't answer then forgot about it. Sorry.
I'm actually working on other things and kind of left arm9loaderhay out.

But yeah if you want you can get the source and I'll give you thread access to edit the first post if you update it. The changes from arm9select are described in the first post but it's true that having everything in one place is better so here is a zip ;)
(And yeah, I could have made a github for that but first I'm a github noob, and second I didn't think it would be necessary for this little project).
Ok sounds good! I can't wait for your future projects!
 

MadMageKefka

Well-Known Member
Member
Joined
Apr 28, 2016
Messages
1,672
Trophies
0
Age
36
Location
World of ruin
XP
1,915
Country
United States
Any way the password file could be called something other than "password"? It would be harder for kids / people who don't know what they're doing to figure out they need to delete the password file if they THOUGHT it was something important.
 
D

Deleted User

Guest
Any way the password file could be called something other than "password"? It would be harder for kids / people who don't know what they're doing to figure out they need to delete the password file if they THOUGHT it was something important.
Go through a hex editor, open up the arm9loaderhax.bin, and then replace all instances of "password" with another EXACTLY 8 lettered word
 
  • Like
Reactions: MadMageKefka

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
Small update. Now works with Gateway on a9lh v2.
Tested on 2DS with a9lh v2, O3DS with a9lh v1, N3DS with a9lh v1 and N3DS with a9lh v2, all of them with the exact same setup (a9lhay into an old CtrBootManager9 into Gateway).
With the old a9lhay, only the a9lh v1 ones would boot.
With the new ones, all of them pass.
And they are obviously still able to boot to Luma too ;)

Also included in the zip a payload that turns the console off. Same source as a9lhay except that you only keep the last two lines in the main. Yeah, which means including fatfs and stuff for no reason, I was too lazy to remove that...
 
  • Like
Reactions: Temptress Cerise
D

Deleted User

Guest
Man!!! I still love this payload! Are you still thinking about porting it to init screen instead of enabling backlight? It's really hard to mod arm9loaderhax v2 to be like FIX94's old fork. Thank you for everything!
 

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
I really don't know. I actually never used any arm9loaderhax with screen init and backlight at 0. My a9lh v1 was a "regular" a9lh with screen init and not 0 backlight (which meant my screen turned on and off and on again), and now on v2 I have a no screen init a9lh and I can still use every payload I need. So I guess every payload who needs screen init does it itself or something. Or maybe Luma does it, CtrBootManager9 does it, and every other payload I need is only launched after CtrBootManager9 so that's why they don't have problems...

Anyway, I don't need it and I still don't know how to do it, so that's why I never made any progress there (not that I really tried hard either). Maybe I should just have forked BootCtr9 instead of arm9select, that one has screen init I think.
 
  • Like
Reactions: Deleted User

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
First build with screen init :D
I tested this on my N3DS on a9lh v2 no screen init and on my O3DS with the same setup.
I guess it works with screen init screen init setups too but if people could test this before I put that on the first post, it would be better I think :)

Source : take BootCtr9's source and replace the main.c with that one.
Code:
#include <stdio.h>
#include <stdlib.h>
#include "sdmmc.h"
#include "ff.h"
#include "config.h"
#include "hid.h"
#include "log.h"
#include "splash.h"
#include "helpers.h"
#include "constants.h"
#include "payload.h"

#define PAYLOAD_ADDRESS     0x23F00000
#define PAYLOAD_SIZE     0x00100000
#define A11_PAYLOAD_LOC  0x1FFF8000  //keep in mind this needs to be changed in the ld script for screen_init too

//used to detect if we are cold booting
#define CFG_BOOTENV       0x10010000
#define COLDBOOT       0

static inline void jump()
{
   ((void (*)())PAYLOAD_ADDRESS)();
}

void jumpAndTryEnableBL(char *file)
{
   FIL f;
   if(f_open(&f, file, FA_READ | FA_OPEN_EXISTING) == FR_OK)
   {
     setBrightness(0x44);
     f_close(&f);
   }
   jump();
}

int tryLoadFile(char *file)
{
   FIL f;
   UINT br;
   if(f_open(&f, file, FA_READ | FA_OPEN_EXISTING) == FR_OK)
   {
     f_read(&f, (void*)PAYLOAD_ADDRESS, PAYLOAD_SIZE, &br);
     f_close(&f);
     return 1;
   }
   return 0;
}

int main()
{
   setBrightness(0);
   setScreenState(true);

   FATFS fs;
   if(f_mount(&fs, "0:", 0) == FR_OK)
   {
     char ch[] = "ABETrludRLXY";

     //Read pad state
     u16 padInput = (~(*(u16*)0x10146000)) & 0x0FFF;
     FIL f;

     //Deduce base filename
     u16 N = padInput;
     char base[] = "/arm9loaderhay/------------/arm9loaderhax.bin";
     char back[] = "/arm9loaderhay/------------/backlight";
     char pass[] = "/arm9loaderhay/------------/password";
     for (int i=0; i<12; i++) {
       if (N%2) {
         base[26-i] = ch[i];
         back[26-i] = ch[i];
         pass[26-i] = ch[i];
       }
       N = N/2;
     }

     //Password if needed
     if (f_open(&f, pass, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
       //u32 password[] = {BUTTON_LEFT, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A, 0};

       u32 password[11]; //password can't be longer than 10, because a max is reasonably needed and no one will go over 10...
       for (int i=0; i<11; i++) password[i] = 0;
       char read[10];
       UINT pass_length;
       f_read(&f, read, 10, &pass_length);
       f_close(&f);

       //convert char like 'A' or 'B' into u32 like 0001 or 0010...
       for (int i=0; i<pass_length; i++) {
         char cur = read[i];
         int index = -1;
         for (int j=0; j<12; j++) if (cur == ch[j]) index = j;
         if (index != -1) password[i] = 1<<index;
       }

       int n = 0;
       int miss = 0;
       u32 pad = 0;
       u32 oldPad;
       while (password[n] != 0) {
         oldPad = pad;
         while (pad == 0 || pad == oldPad) pad = InputWait() & 0x0FFF;

         if (password[n] == pad) {
           n++;
         } else {
           miss++;
           n = 0;
         }
       }
     }

     if (tryLoadFile(base)) {
       jumpAndTryEnableBL(back);
     } else if (tryLoadFile("/arm9loaderhay/default.bin")) {
       if(*(vu8*)CFG_BOOTENV == COLDBOOT) {
         jumpAndTryEnableBL("/arm9loaderhay/default_bl");
       } else { //dont enable backlight again on soft reset
         jump();
       }
     }
   }
   return 0;
}
Also lol, you can tell I used BootCtr9 as a based for that from the size. It used to be 10KB, it is now 100KB :P
But yeah, you can guess there is a lot of stuff I don't need in these 100KB... No idea if I'll clean things or not but at least I agree it's stupid.
 

Attachments

  • arm9loaderhax.zip
    54.7 KB · Views: 97
  • Like
Reactions: Deleted User

Hayleia

Well-Known Member
OP
Member
Joined
Feb 26, 2015
Messages
1,485
Trophies
0
XP
1,294
Country
France
New release on the github https://github.com/Hayleia/arm9loaderhay/releases
Adds basic splash screens.

They are not meant for cosmetics actually (though obviously, you put the splash screen you want), that's why only the top screen is supported (though I can most likely add the bottom screen too if people insist). They're mostly useful if you have a payload with no backlight and you don't know when you're supposed to type your password for example. Well, you type it when you see the first splash. As soon as that splash goes away (either replaced with the second one or disappeared due to backlight being gone), you know your password was taken into account and you don't have to type it again.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • Julie_Pilgrim @ Julie_Pilgrim:
    the internet
  • Julie_Pilgrim @ Julie_Pilgrim:
    @Psionic Roshambo i have 16 gb in my pc and i run into issues with ram more than i'd like to admit
  • HiradeGirl @ HiradeGirl:
    I got only 8GB of RAM. But I want 32GB.
  • Sonic Angel Knight @ Sonic Angel Knight:
    Time to just download more ram
  • K3Nv2 @ K3Nv2:
    Yeah search Google
  • Sonic Angel Knight @ Sonic Angel Knight:
    Or, I also heard that if you use flash memory, it can act as more "RAM" at least windows tell me when I stick a flash drive into it.
  • Veho @ Veho:
    It can act as a swap drive but that isn't more RAM, it's slooow.
  • K3Nv2 @ K3Nv2:
    I wish we could have 1Gbps external storage by now
  • K3Nv2 @ K3Nv2:
    Like for micro
  • Veho @ Veho:
    New Myoo.
  • SylverReZ @ SylverReZ:
    @Veho, Yooo noice
  • SylverReZ @ SylverReZ:
    Looks like a Famicom handheld
  • Veho @ Veho:
    Yeah, they were going for that.
  • Veho @ Veho:
    It's not very good though.
  • Veho @ Veho:
    I'm watching the review, the emulators it uses suck bawls.
  • Veho @ Veho:
    Software update might improve it.
  • Psionic Roshambo @ Psionic Roshambo:
    Or maybe someone will make like Emulation Station for it or something?
  • Veho @ Veho:
    That counts as a software update :tpi:
    +1
  • OctoAori20 @ OctoAori20:
    Ello
  • K3Nv2 @ K3Nv2:
    I can think of the design teams process another joystick and no audio or a joystick and mono audio
  • Veho @ Veho:
    "You think we can just put the speakers at the top
    ?" "NO!"
    +1
  • K3Nv2 @ K3Nv2:
    Pft stereo speakers you're fired
    +1
    K3Nv2 @ K3Nv2: Pft stereo speakers you're fired +1