a bit more speedup

This commit is contained in:
2025-10-12 00:33:48 +02:00
parent fc9e85aea0
commit a3b837f329
2 changed files with 38 additions and 19 deletions

View File

@@ -568,7 +568,6 @@ union cart_rtc
} reg;
uint8_t bytes[5];
};
extern "C" uint8_t gb_rom_read(struct gb_s*, const uint_fast32_t);
/**
* Emulator context.
@@ -730,9 +729,14 @@ struct gb_s
/* Implementation defined data. Set to NULL if not required. */
void *priv;
const uint8_t* rom;
} direct;
};
__attribute__((always_inline)) inline uint8_t gb_rom_read(struct gb_s* s, const uint_fast32_t addr) {
return s->direct.rom[addr];
}
#ifndef PEANUT_GB_HEADER_ONLY
#define IO_JOYP 0x00
@@ -3687,7 +3691,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
void *priv)
void *priv, const uint8_t* rom_data)
{
const uint16_t mbc_location = 0x0147;
const uint16_t bank_count_location = 0x0148;
@@ -3726,6 +3730,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
gb->gb_cart_ram_write = gb_cart_ram_write;
gb->gb_error = gb_error;
gb->direct.priv = priv;
gb->direct.rom = rom_data;
/* Initialise serial transfer function to NULL. If the front-end does
* not provide serial support, Peanut-GB will emulate no cable connected
@@ -3879,7 +3884,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
void *priv);
void *priv, const uint8_t* rom_data);
/**
* Executes the emulator and runs for the duration of time equal to one frame.

View File

@@ -76,6 +76,29 @@ static constexpr LUTFull buildNibbleLUT() {
inline constexpr LUTFull kNibbleLUT = buildNibbleLUT();
static constexpr LUTFull buildFullHeightWideByteLUT() {
LUTFull L{};
for (int yp = 0; yp < 2; ++yp)
for (int xp = 0; xp < 2; ++xp)
for (int p = 0; p < 256; ++p) {
const uint8_t p0 = static_cast<uint8_t>(p & 0x03);
const uint8_t p1 = static_cast<uint8_t>((p >> 2) & 0x03);
const uint8_t p2 = static_cast<uint8_t>((p >> 4) & 0x03);
const uint8_t p3 = static_cast<uint8_t>((p >> 6) & 0x03);
const uint8_t p4a = static_cast<uint8_t>(p0 | (p0 << 2) | (p1 << 4) | (p1 << 6));
const uint8_t p4b = static_cast<uint8_t>(p2 | (p2 << 2) | (p3 << 4) | (p3 << 6));
const uint8_t n0 = makeNibble(p4a, xp, yp);
const uint8_t n1 = makeNibble(p4b, xp, yp);
L[yp][xp][p] = static_cast<uint8_t>((n0 << 4) | (n1 & 0x0F));
}
return L;
}
inline constexpr LUTFull kFullHeightWideByteLUT = buildFullHeightWideByteLUT();
namespace apps {
namespace {
@@ -869,8 +892,8 @@ private:
}
std::memset(&gb, 0, sizeof(gb));
const auto initResult =
gb_init(&gb, &GameboyApp::cartRamRead, &GameboyApp::cartRamWrite, &GameboyApp::errorCallback, this);
const auto initResult = gb_init(&gb, &GameboyApp::cartRamRead, &GameboyApp::cartRamWrite,
&GameboyApp::errorCallback, this, romDataView);
if (initResult != GB_INIT_NO_ERROR) {
setStatus(initErrorToString(initResult));
romData.clear();
@@ -1276,23 +1299,17 @@ private:
CARDBOY_CHECK(yEnd > yStart);
CARDBOY_CHECK((kFullHeightWideOffsetX % 8) == 0);
const int xParityBase = kFullHeightWideOffsetX & 1;
for (int dstY = yStart; dstY < yEnd; ++dstY) {
const int yParity = dstY & 1;
int dstX = kFullHeightWideOffsetX;
for (int srcX = 0; srcX < LCD_WIDTH; srcX += 4) {
const uint8_t p0 = pixels[srcX + 0];
const uint8_t p1 = pixels[srcX + 1];
const uint8_t p2 = pixels[srcX + 2];
const uint8_t p3 = pixels[srcX + 3];
const uint8_t packIndex = static_cast<uint8_t>((pixels[srcX + 0]) | ((pixels[srcX + 1]) << 2) |
((pixels[srcX + 2]) << 4) | ((pixels[srcX + 3]) << 6));
const uint8_t p4a = static_cast<uint8_t>(p0 | (p0 << 2) | (p1 << 4) | (p1 << 6));
const uint8_t p4b = static_cast<uint8_t>(p2 | (p2 << 2) | (p3 << 4) | (p3 << 6));
const int xParity = dstX & 1;
const uint8_t n0 = kNibbleLUT[yParity][xParity][p4a];
const uint8_t n1 = kNibbleLUT[yParity][xParity][p4b];
const uint8_t pack = static_cast<uint8_t>((n0 << 4) | (n1 & 0x0F));
const uint8_t pack = kFullHeightWideByteLUT[yParity][xParityBase][packIndex];
fb.drawBits8(dstX, dstY, pack);
dstX += 8;
@@ -1403,9 +1420,6 @@ private:
}
};
extern "C" __attribute__((always_inline)) uint8_t gb_rom_read(struct gb_s* gb, const uint_fast32_t addr) {
return GameboyApp::romRead(gb, addr);
}
class GameboyAppFactory final : public cardboy::sdk::IAppFactory {
public:
const char* name() const override { return kGameboyAppName; }