NES Classic Mini.
In USA it's called NES Classic Edition.
A very controversial thing.
On the one side it's just a Linux emulator which
has only a collection value,
and it would be much better to buy something like Raspberry-Pi.
Even the official site tells us, that primarily
this is just a good gift for collectors
and gamers, nothing more.
On the other side, it's still a complete solution with
the familiar design, original controllers
which works on modern TVs out of the box.
What else does a common user need?
There is a lot of dispute on this subject, but everyone agrees to one thing
- those thirty games that are built in are clearly not enough.
The most popular games are included, but it's surely lacking some
opportunities for adding or, which is only logical,
buying additional games.
Especially it goes for Russians, since piracy was common here in 90s
and other games were popular.
Pirates did not give us many popular in USA games, but
they gave us Battle city, which wasn't officially released
outside of Japan while in Russia it became even more
recognizable than Mario franchise.
Hello everyone, here's Cluster and today I'm going to tell you about
how I modified NES Mini. But first - some dull
backstory.
I didn't buy this console for myself, because I didn't see much point in it
for me, so Viktor Karasyef from the Cozy Cellar channel
gave it to me to hack and shoot the new episode of
"While everyone plays". The hype would be stratospheric.
Also I'd love to say my traditional "Let's get down to work!",
but... I did not have the brains for it.
Yes, I soldered to UART-outs to get the console access to the console.
Hmm. The console access to the console. Sounds a bit...
Strange
But I didn't see anything there except "starting Linux".
I used my own Linux build on the system following
the guide I got from the Internet, but that's where I got majorly stuck.
My Linux knowledge wasn't enough even to
get the access to NAND memory.
Vitya tried to persuade me to unsolder the flash memory, remove it
and make a programmer but that's absolutely barbaric.
I knew there had to be an easier way, but I just couldn't do it.
So I had this console sitting around, until
one fine day one guy named madmonkey from the GBX.ru forum
hacked NES Mini.
This guy is definitely a brainiac.
There is a lot of people much smarter than me,
they just don't show off on YouTube.
But let's get back to business.
I will say it one more time: "I didn't hack NES Mini,
madmonkey did it, don't believe rumour and press".
But I decided to write a program to do everything
with just a couple of clicks, which would be understandable for everyone.
I like being in a situation when I can do something
very cool that is very highly sought by people.
This brings a huge amount of positive feedback from satisfied users.
Let's do this!
[geekdays.log] #8 - Pumping Up NES Classic Mini
The most curious thing is that I won't need to solder
or disassemble anything for this hack.
Everything is made by using a micro USB plug which
is used for power supply.
It can be done using a usual micro USB cable which is included
in the set.
NES Mini is built on the Allwinner CPU,
and they have a so-called FEL mode,
which is intended for debugging and flashing purposes using USB.
On different devices you can switch to this mode differently,
and in case of NES Mini you just need to hold down
the RESET button when turning it on.
After doing this and using a special program
you can read RAM, write RAM it and
execute code.
Not to put too fine a point on it - there is no protection.
That being said, on Nintendo's official site you can find
a U-Boot source code. Yeah, you heard it right.
According to the GPL license Nintendo is obliged to share
the source code of their developments.
This allowed madmonkey to compile a U-Boot, upload it to
NES Mini's RAM, execute it, read
the Linux kernel together with the RAM-disc image and using the same
method re-write it back.
The rest is a piece of cake.
Madmonkey wrote a program named "hakchi" which
allows to read Linux kernel, patch it and
re-write back. After that it becomes possible
to add other games.
I immediately became interested in the way it works,
because I needed to sort it out to learn something new and maybe
make a few improvements.
But it wasn't quite easy as I thought.
I must have spent all the day looking at his scripts while
snapping and snarling at my family members if they even
tried to somehow disctract me
But in the end I sorted it out.
It was something like a discovery for me that you can mount one directory
over the other one in Linux.
I mean mounting, not creating symbolic links.
Games are on the read-only
partition.
That being said NES Mini has a huge 300 MB partition
which is available for recording. The console keeps the save states
and settings in there.
Madmonkey's scripts create a directory inside this partition
to use as a storage for games, copy the original game directory's content there
and mount a new (our) directory over the original one
on the early stage of system loading.
Eventually the folder with games becomes available for recording and the original
files are kept intact, which also matters,
as well as the programme shell not noticing that the directory has been changed.
The same method can be used for switching the system files by opening
the console access via UART, which lets you take a look
at the whole file system and makes debugging much easier.
Shortly after that I wrote an easy program which uses hexdump via UART cord
and downloads the whole file system.
It's an extremely slow process, but I wanted
to look at the contents.
As I already said the games are being kept in a special directory,
each game has a sub-directory with a cover,
config file and the game's ROM per se.
The funniest thing is that those ROMs are the regular .nes format files
and are identical to those ROMS that can easily be found
in the Internet.
You can say: "What of it?
The games are identical, so why should the ROMs be different?"
The point is that iNES format itself was developed by pirates,
one of them being the administrator of GBX.ru forum.
These titles use a mapper numeration which was also developed
by pirates.
This was when I freaked out.
How?.. Why?.. No, don't get me wrong, I understand that
it's easier for Nintendo to download their own games from the Internet
instead of trying to find some 30-year old cartridge firmware in their
archives
But I never expected them to actually go and do it!
So what is it?.. Nintendo sells us pirated copies
of their own games, right?
Someone in twitter told me that something similar happened with Nintendo Wii.
In the matter of fact there was a bif of a feeding frenzy about this
in the news.
Oh well, it only plays into our hands.
If NES Mini uses a pirate format for game storage, it means
it can be used to play pirate games from the Internet
without any special modifications.
Well, madmonkey did this too.
I was puzzled - how does NES Mini detect the mapper
of the game?
I never even imagined that they did it using
pirate headers.
But let's get back to the simple and convenient program to download
games into NES Mini that I decided to write.
It was planned as an analog of madmonkey did, but should have been something that,
if you'll excuse the joke, even a monkey would be able to understand.
As you already know, I have some problems with thinking of names,
so if his program is called hakchi, mine should be called
hakchi2… as odd as it can be.
I'm not good with interface features too.
If you only knew how much I hate making them.
Usually I focus on the functionality, not on the way it looks.
This is why usually I make console programs or
even services/daemons.
I saw a perfect inteface like this: a list of games on the left
with checkboxes and a set of options for the chosen game
on the right.
On the lower side of the screen - "add a game" and "flash" buttons.
This way pressing the wrong button or getting confused would be
close to impossible.
As for the contents of the program -
It performs three basic actions.
1. Dumps the NES Mini Linux kernel.
To do that a u-boot is booted into the console using FEL-mode,
and then it executes the command for reading data
from the NAND-memory again into RAM, and then using the same
method to transfer data from RAM to the PC.
2. Then the modified kernel is put into NES Mini.
We need only one kind of modification - to make our script, if it exists,
execute on start up.
So this action should be done
only once.
The process of recording the kernel into NAND-memory goes according to
the same principle as reading, but in the opposite direction.
3. It assembles a modified kernel with scripts and games,
doesn't flash it but loads it into RAM and
executes.
Those scripts mount the required partitions, write new games
and turn the console off afterwards.
To assemble and disassemble the kernel, like madmonkey did, I also used
ready-made programs from the Android Kitchen set.
So I just use other executable files
with the required parameters in the right order.
As for the process of reading and recording memory -
it's more complicated and it's best to use a direct approach.
There are pre-made libraries, but they are for C and I use C#.
Of course I could have written a wrapper, but I googled the FEL
protocol description and decided to write my own library
from scratch.
It wasn't hard and it worked pretty soon,
to my amazement.
I used my own libraries to work with ROMs.
By trial and error I understood which mappers were suitable for
the NES Mini built-in emulator to make the program sort out
those games that won't work.
The hardest problem on this stage for me was the
the installation of the driver.
Well, if I decided to make this program easy for use, the driver's
installation should be as simple as possible.
I didn't want to give users any complicated instructions or
send them to some other site to download
a separate utility.
I'm talking about Zadig - it is a great solution for fast
and simple installation of popular basic USB drivers.
Fortunately it has an open source code, even with the
console version in the examples.
I quite fast made a simple program out of it which allows to
install the driver right at startup.
After that I made it possible to change the different game
parameters, added an option of choosing box art images and automatically
resize them, added a button for automatic search of box art images in Google
and at the last moment also decided
to add Russian language.
After I put it all together I uploaded it in the net and
named it version 2.0.
Because it's hakchi2.
I guess I really managed to make
this problem highly usable without any
kind of a guide. It remembers if the user dumped the kernel,
flashed the modified kernel, on its own, and also
lets the user know what to do and when.
Hakchi2 really became popular quite fast, neverminding the fact
that many antiviruses considered it to be dangerous
because of utilities and drivers in the same archive.
Many people were afraid of becoming a part of russian botnet.
But do I really have to say how many bugs appeared after the first release...
The hardest was the "pipe read error" which appeared if it wasnt' possible
to initiate the device after
running the code for execution in the memory.
For some reason it didn't appear
randomly, which was why several times I mistakenly thought that at last
I found some consistent pattern.
By the way such cognitive bias is called "clustering illusion".
But no, this error was completely random.
The thing that really got to me was this: if the original
hakchi from madmonkey was used after NES Mini stopped working with my program
the console stopped freezing
and continued working.
So, madmonkey somehow did a right initialization in his program
and I apparently did something wrong.
But no matter how thorough I was in studying his source code, I never
saw any peculiarities.
In the end I found a program which picked up and showed
the USB traffic and started to compare everything byte by byte.
This is a example of how initialization should be made.
I had a problem specifically during the second stage while
getting the response.
The data I kept receiving were completely different from what I expected.
It turned out that my mystake this time was in trying to
start the initialization anew from the very beginning.
Madmonkey's program in this case repeats the sequence starting
from the second phase. After that the device proceeded
to work normally.
It's some kind of magic, but this error never bothered me again.
But apart from that I encountered a much more stranger
bug.
It must have been the strangest and nontrivial bug of all
my life.
Scripts for copying games after the end of the process turn
the console off, so the user has to wait until the
LED turns off.
But a lot of people told me that the LED was still active
even half an hour after.
Forum users were sharing their experience.
In some cases it worked perfectly, some people had this eternally
glowing LED problem.
Some thought that there were different console versions,
others had it working on other PCs.
Dozens of people tried to find any kind of repeating pattern.
There was a lot of illusions, but in the end one person
a 100% correct consistent pattern.
My program didn't work if it was unpacked with WinRAR,
but was fully functional if 7zip was used for this purpose.
It turns out that some WinRar builds under certain conditions
didn't keep the file attributes after unpacking.
But when we compile a RAM-disc for Linux kernel to be used on Windows,
the sym-links should always have a "system" attribute.
I never even imagined that the problem was
in the archivator, especially minding the fact
that I myself don't use WinRAR.
Shortly after discovering this I added a file attribute check in the program,
and the problem disappeared for good.
Sometimes though it's not possible to change the attributes on Windows 10,
but at least this time an error message
pops up.
On this stage the program was already quite useful,
but also there was a whole set of problems connected with the
console itself and its environment: the fonts included only the required
symbols and the names of many added games were displayed incorrectly,
each time you had to use the RESET button to get back
to the menu, moreover, the NES Mini's shell was simply
not designed for this amount of games, which lead for different
kinds of glitches.
I decided to start with fonts.
At least this task seemed to be real from the first
glance, since right in the folder with the games there were
title.fnt and copyright.fnt, so all I had to do was edit or
replace them.
However, not even one fonts editor did not agree to open them,
so I needed to understand the format of this files.
If you swapped these files around the text in the game titles became
small.
So, the font was bit-mapped and not vectored and the symbols
were included in it as images.
If you open the file in hexadecimal editor, you can see, that
every font had a "BMF" signature
not long from the beginning.
Googling "BMF font" led me to a site where
I found both a utility for font generation and a detailed description of
the font binary format which I rushed to start reading.
Yes, every file really had to contain a BMF signature,
but right in the beginning of the file.
In NES Mini case there were some 9 bytes before it,
they were different in different files (except the first byte).
I hoped they were not needed, but when I tried to change any of them
the console simply didn't start up, showing black screen.
It meant that I had to understand the sense of these nine bytes.
The first was always a 01.
Other two bytes - some values, then there were two zeroes.
Then there were two bytes with values, and then again - two zeroes.
After that sequence there were the font data.
I already thought that these coupled data looked like two 32-bit
numbers.
I looked at the first one, compared it to the file size, and I didn't see any
consistensies.
The same happened with the second one, but then I decided to put them together
and...got the precise size of this file without the header.
So, these numbers meant sizes of some file
sections.
I rewinded the file to the value that was included in the first
four bytes and saw... The PNG file header.
I took it out from it and yes, it was a image with all the symbols.
It was only logical since the program has a several files output
to generate the fonts.
NES Mini just had them combined in one.
Analogically I put together the header and the files of the generated
font, uploaded the result on the NES Mini and... presto!
The missing symbols appeared!
I thought that everyone had to be happy at that point, but shortly
after that I started getting messages from Japanese Famicom Mini owners,
who told me that all the kanji symbols were missing.
I politely explained that I was as good in Japanese as
nothing, didn't understand a word.
But I wasn't lazy and explained them what I found out and how to generate
the font.
Soon after that I got sent a Japanese font, so I included it
in the distributive. The scripts are able to easily identify
the region of the console.
Special thanks to the japanese guy named xsnake.
Now people have understood the principle and started uploading many different
fonts, even Comic Sans, of course they had
to include it.
But people started asking for some unreal features.
As I already said, many people needed the possibility of pressing the reset
button, meaning that they needed to quit to the menu without putting
the controller down.
I was saying from the beginning that this was impossible.
Well... I actually say this rather often... I didn't have the source code
of the emulator, so I couldn't change the button functions,
but soon after that I realized that if you used Wii's Classic
Controller with more buttons the HOME
button could serve exactly this purpose.
So the emulator code included this possibility.
With all that the emulator used the SDL2 library, which
had an open source code, but reassembling and changing
such a huge library for such a trifle function didn't
seem like a wise choice.
I started looking through Nintendo's source code again
and I saw a controller driver source code in there.
That was precisely what I needed!
The internal code name of the controller, by the way, is "clovercon".
It was derived from the word "clover"
NES Mini has the same name of the programme shell - Clover,
and the name of the console's model is CLV-001. I guess now everybody
understands what this "CLV" means.
So, the driver's code was quite easy, so I was quick in finding
the place to insert just one code line.
I compiled the driver without any special problems, which was amusing since
I'm not really good with Linux and here suddenly
I was easily able to compile a kernel module. However, it was too early to be happy.
Insmode utility refused to load this module.
After a short period of googling I understood that it happened because of
vermagic mismatch.
This is a string inside the module which describes the Linux kernel
version and the parameters that were used while assembling it.
It's used for one simple purpose -
to ensure the binary compatibility.
To make long story short, the driver needs to be assembled with the same
kernel config as the NES Mini's kernel config that were used during its assembly.
But where could I get these config?
Yes, Nintendo has the kernel's source code on their site too,
but there isn't any configuration data.
It's like it was made on purpose... I was chasing my tail about this problem
for a long time, changing many different parameters of the kernel.
From the vermagic code line I had a vague idea of what was missing,
or what was in the way.
However, when I had a vermagic match and the model finally loaded,
the system refused to react on button press.
Also debugging wasn't possible since
kprint in the kernel of NES Mini was missing.
As well as dmesg.
In the end I almost gave up and this music got stuck in my head,
so I started hearing it everywhere!
I'm going slightly mad...
Do you hear it too?
But no, I'm still quite sane.
Well, I am able to make a few more episodes.
So after I lost all hope I got into the "Kernel hacking"
partition and started to clearing all tick box consequently.
Suddenly the driver started working!
The most important thing here is to make a backup.
I did what I wanted, the down+select combination now opened
the menu.
However, people had a new demand soon - they asked to make a possibility
of changing the combination of buttons.
How could I do that?
These data were put inside the driver's binary code, but I simply added
a string into the code. The driver used this string to get a combination
and my program, before uploading to the console, takes this string
and changes the values.
It would have been so useful if Nintendo didn't make the controller's
cord so short!
Now I really need an extension cable.
After that I had some people asking for
an autofire.
I always considered it cheating which we were used to from
our childhood, since we almost never saw originall controllers
in Russia then.
So I ignored these demands after I started getting the same
messages even from foreigners.
I guess there's nothing much to talk about here,
just another driver modification.
Now it's possible to hold select+A or select+B for a second
to turn on the autofire on a corresponding button.
In case of Classic Controller X and Y buttons are used as
autofire A and autofire B buttons from the very start.
As for the limit on the number of games... Well,
it's not entirely clear.
The thing is that you can upload something like 97 games to NES Mini,
but if you do that the save states stop working.
The less games are in the menu - the more save states you can
possibly have, but it doesn't depend on the flash memory limitations,
there is a lot of free space in the partition.
It looks as though the programme shell just can't
get enough RAM to load all the images,
since every saved game has a screenshot
and if you count all the games, the sizes
of their covers, the size of those screenshots, keeping in mind that
it isn't kept in the memory in some compressed format, you get a really
huge value.
At first I thought I had to put up with this.
Especially minding the fact that I have no idea which games could possibly
be uploaded there in such a quantity - I hardly found 30 games for myself,
and the half of these is already pre-installed in the console.
But people seemed to be really into it and made a lot of requests.
Then I remembered that the config file had a full path to the emulator and 468 00:21:11,450 --> 00:21:14,150' the command line's arguments for every game.
So it's possible to not only execute the emulator, but any script
which is not in the way when
mounting the other game directory,
which would look as folders for the user.
I tried it - and it worked!
As a result I was able to upload as many as 600 games in one go.
My program automatically puts them into different folders, sorting them
alphabetically.
With this approach save states continue being completely functional,
and the system works with no glitches.
I would like to also have a possibility of choosing the algorhytm of the folder
tree generation and to change the pictures of these folders, but
after this thought it came to my mind that it would be a good place to stop
and make a video about all this.
I added several other features over the last month,
but it's difficult remember them all now.
I also found a lot of bugs and curious peculiarities.
For instance, the console refuses to turn on if at least one game's title
has an apostrophe and any
number in succession.
I had to make a check for that too.
Unusual game effects are in fact
the protection from epileptic seizures that turns on by using
a command line's argument.
By the way, the built-in emulator has a lot of other
command line arguments, it eagerly displays them.
For some reason though not all of them work.
For example, I couldn't turn the PAL emulation on no matter
how hard I tried.
And yes, the european version of the console includes the
american versions of games.
Famicom Disk System's BIOS is also present, neverminding the fact that the games for it
were released only in Japan.
So they can be used too.
As for the cartridge games - the console doesn't support many mappers,
but all the popular ones are in place, so about 90%
of games are up and running.
However I still get a lot of requests to add another mapper
or two in the program from those people who don't know that
it's not something that depends on me.
Theoretically it may be possible to compile another emulator for
NES Mini, but I'll leave this idea for someone smarter.
The list of original games has one hidden game.
It's not the game though, it looks more like some production tests,
something like a service menu.
Maybe it's possible to use some sophisticated combination to
have an access to it without workaround.
Cah4e3 here has already started disassembling the emulator file.
Fun fact - it has a hidden message from the developers.
More precisely - from some "Hanafuda Captain".
In reality "Hanafuda" means playing cards which Nintendo used to make
in the century before last.
Cah4e3 told me there were pointers for this text, so some code actually
uses it.
Quite possibly it's a working easter egg of some sort.
Other fun facts: if you create a folder named "pixelart" in any of your game folders
and put any PNG picture in that folder,
you will see this image during
the console's wait mode.
And generally the console's memory has a lot of different pics,
sounds and scripts which can be edited.
This way, if you really want to, you can really enhance
your console.
Thanks for the donats for this program I was able to finally buy
my own NES Mini.
I also soldered to the UART, but I made a small
connector pin outside.
My NES Mini was bought only for experiments, I don't even think
about playing games on it though I regularly scroll through the menu,
turn the games on, check stuff... What else can I do
with it?
I guess I should finally get rid of this annoying music
in the menu!
♫ What is Dendy... What is Dendy... ♫ (*Dendy is Russian NES clone popular in 90th)
Yes, that's much better!
You know, this might be the first console hack that benefits the
issuers instead of inflicting losses.
They do not sell games separately, but the console is being
gobbled up from shelves.
It almost seems like Nintendo staff were sitting there and
patiently waiting for someone to hack it already.
So I hope they won't give me a copyright strike
or sue me, especially keeping in mind that I don't do anything illegal
as long as I don't distribute games.
Well, I guess it's all for today.
This was Cluster.
Bye!
Không có nhận xét nào:
Đăng nhận xét