[WIP] Pokitto Emulator


#1

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

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):

To build source see this post, then simply run make. Original build script by @adekto.
Features in testing:

  • Multi-block SD card read support

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)
  • Must hardfault on bad memory access
  • 32-bit timers are incomplete
  • 16-bit timers are missing entirely
  • PWM + DAC + Sound
  • Joystick support
  • RTC / USART / I2C
  • ROM API (only has EEPROM and partial Flash API)

[Tool]Gameboy Emulator
Pokitto is on the way, what games should I make?
Error when compiling for simulator
#2

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.


#3

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.


#4

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.


#5

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)


#6

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?


#7

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?


#8

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)


#9

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


#10

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:


#11

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

#12

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.


#13

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?


#14

Works for me too :slight_smile: Good work!


#15

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.


#16

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.


#17

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


#18

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

Fixed it.


#19

Pulled it. :stuck_out_tongue:


#20

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