[Tool]Pokitto Emulator

Downloads: Source | Builds

This is a fusion of ProjectABE and VisualBoyAdvance’s CPU core upgraded to Thumb2, resulting in a native C++ SDL2-based Pokitto emulator.

Being a WIP, there’s a whole lot of stuff that still needs to be done. If anybody wants to help: testing, bug reports (especially along with bin+elf files demonstrating the bug) and PRs are greatly appreciated.

Features

Keyboard Keys

  • A/S/D correspond to A/B/C.
  • Arrow keys
  • F2 take a PNG screenshot
  • F3 to start/stop recording a GIF.
  • F7 to Pause/Resume and F5 to Restart emulation

Joystick

  • Left analogue joystick corresponds to up/down/left right
  • Right analogue joystick corresponds to JoyHat direction

Sound

  • By default it plays sound at 8khz, but you can change by using the -A 16000 flag.

Debugger

Use it like this: PokittoEmu path/to/file.bin -g
Or like this: PokittoEmu path/to/file.bin -G port
If you don’t specify the port (-g), it defaults to 1234.
You can then connect to it using: arm-none-eabi-gdb path/to/file.elf.

Profiler

Use it like this: PokittoEmu path/to/file.bin -p
Then use this to get the source lines: addr2line -e path/to/file.elf < hotspots.log
While the emulator is running it will randomly sample the current instruction to detect hotspots. After shutdown it creates a hotspots.log file with the addresses of the top 10 hottest spots in the code, in descending order. These are probably the performance bottlenecks of your game.
addr2line is a tool that comes with gcc.

Gif recorder

Press F3 to start/stop recording a gif. It will be saved in the same path as the bin that is currently running. You can also use the -r flag to record automatically.

Bleeding edge (features in source, not in a build yet):

None, release is up-to-date with source.

To do (in no particular order):

  • Limit GIF frame rate (currently hardcoded speed is too fast)
  • Pixel art scaling algorithms
  • Backlight control (it’s always on)
  • 32-bit timers are incomplete
  • 16-bit timers are missing entirely
  • PWM + DAC
  • I2C

Mac

Emu compiled by @aus for Mac

I’ve attached my MAC compiled PokittoEmu which has been tested with TinyPool.

PokittoEmu (610.4 KB)

7 Likes

Never before have I seen a pointer used in a template parameter:

template <MemoryBank *mb, u32 shift, u32 mask> u32 readMap32( u32 addr ){
	return (*mb[ (addr >> shift) & mask ].read32)( addr );
}

That’s some serious voodoo from the VBA guys.

Since you posted that snippet: do you know if there’s any difference between fncptr() and (*fncptr)()? I’m under the impression the latter is more supported syntax.

Also: windows build is online.

Absolutely none:

#include <type_traits>
#include <iostream>

int func(void) { return 42; }

int main(void)
{
	auto fp0 = func;
	auto fp1 = *func;
	auto fp2 = *******func;

	static_assert(std::is_same<decltype(fp0), decltype(fp1)>::value, "func is not the same as *func");
	static_assert(std::is_same<decltype(fp0), decltype(fp2)>::value, "func is not the same as *******func");
	static_assert(std::is_same<decltype(fp1), decltype(fp2)>::value, "*func is not the same as *******func");

	std::cout << func() << '\n';
	std::cout << (*func)() << '\n';
	std::cout << (*******func)() << '\n';
	//getchar();

	return 0;
}

Most likely the reason for the dereferencing in this case is either that the original author wasn’t aware that the dereferencing is unnecessary, or it is done purely for the sake of consistency with non-function pointers.

Substituting the function pointers for pointer to objects that define the () operator would still be legal if a single level of dereferencing is used, but would not be legal otherwise.

I don’t seem to be able to get keyboard input working. Looking at the source it should be ASDBC is that correct? I can’t get past the volume screen. (windows version)

Does it detect if you press D in the loader screen? It might be crashing at/after the volume screen.
I’ll test it again as soon as I get home. Can you upload the bin?

Just checked the Windows build, input works OK.
I suspect the problem is in the sound initialization, all my tests so far had sound disabled.
Edit: Nope, that wasn’t it. No idea what’s wrong. @spinal: Can you send me a .bin and the .elf?

Sure. I got a chance to try again, the D key will get to the loader menu, but nothing would get pas the volume setting screen.

mixMode.bin (47.7 KB)
mixMode.elf (638.5 KB)

@FManga: FYI: volume screen reads and writes EEPROM and tries to talk to the digital volume potentiometer via I2C

1 Like

EEPROM works already, though it doesn’t get stored anywhere.
I haven’t implemented I2C yet, so I thought that could be the cause, but most of the builds in the PokittoLib repo work to some degree. :thinking:

I don’t know if anyone wants this, but I modified the copy.bat so that if you don’t have a pokitto connected, it will launch the emulator instead.

mode con: cols=80 lines=40
@echo off
:::          .--------------------------.
:::          |o                        o|
:::          | .----------------------. |
:::          | |                      | |
:::        __| |   __ __ /_ ,_/_/_ __ | |__
:::       (o_  |  /_//_//\ / / /  /_/ |  _o)
:::          | | /                    | |
:::          | |                      | |
:::          | '----------------------' |
:::          |      _              .-.  |
:::          |    _| |_       .-. ( A ) |
:::          |   [_ o _]     ( B ) '-'  |
:::          |     |_|        '-'       |
:::          |          ___             |
:::          |         (___)            |
:::          |o                        o|
:::          | .----------------------. |
:::          |o|                      |o|
:::          '-'                      '-'

for /f "delims=: tokens=*" %%A in ('findstr /b ::: "%~f0"') do @echo(%%A

IF [%1] EQU [] Goto:NoDrop


set VAR=Destination
for /f "skip=1" %%L in ('wmic logicaldisk where volumename^="CRP DISABLD" Get Caption') do @call :SetVar %%L

IF [%Destination%] == [] GOTO EMU

rem echo Copying data from "%~1" to %Destination%

del %Destination%\firmware.bin
rem copy "%~1" %Destination%\firmware.bin
esentutl /y "%~1" /d %Destination%\firmware.bin /o
goto :Finished

:SetVar
set Label=%1
if NOT [%Label%]==[] set %VAR%=%Label%
goto :EOF

:Finished
pause
cls
exit

:NoDrop
echo Drag and Drop your .bin file onto _copy.bat to send it to Pokitto.
pause
cls
exit

:EMU
start PokittoEmu %1
exit
1 Like

Fixed it, I think. I’ll do some more testing before I upload another build.

Edit: new build is ready.

There is still a bug in the arithmetic opcodes somewhere. Still trying to track it down.

Seems to work fine now :slight_smile:
Any chance of adding Esc key to close the emulator?

[edit]
Is the flashing pixel some sort of debug info?

1 Like

Works for me too :slight_smile: Good work!

I’m glad it’s working for both of you and hope its of use. Just remember to send bins+elfs when you find a bug, and at this point you’ll probably find a bunch!

Sounds good. I’ve been using Alt+F4, but Esc is easier.

Yes, it’s the current CPU time written directly to the screen. If it flashes slowly or stops then something is wrong and it probably crashed. I’ll remove this when things are a bit more stable.

A new build is up.

It now has GDB support, but I couldn’t get Code::Blocks to even try to debug (all the menu options are disabled).
Anybody want to try to get PlatformIO to debug?

I got Code::Blocks to run Pokitto games by putting the emulator in place of cb_console_runner.exe. It’s a dirty hack, but it’s nice to run code by simply pressing F9. Anybody know what the correct way to do this is? Looks like there’s little to no documentation on getting CB to work with a custom compiler.

4 Likes

@Pharap: I noticed you made a fork and you sent yourself a PR. Was that intentional?

2 Likes

Woops. That explains a lot.
I need to stop juggling things. :P

Fixed it.

2 Likes

Pulled it. :stuck_out_tongue:

1 Like

im willing to compile it for macOS but not sure what i need to setup sdl to make the Makefile work