Skip to content

gb_rom_read_16bit()

Mr-PauI edited this page Dec 21, 2025 · 5 revisions

This function isn't defined by walnut-cgb. Each implementation must provide this function to gb_init(). The precise name of the function doesn't matter of course, but for consistency in this example the same name as the internal function pointer is used. May require -fno-strict-aliasing on some platforms

uint8_t* rom_data; // for this example a pointer to rom_data in ram, flash or psram data
uint16_t gb_rom_read_16bit(struct gb_s *gb,const uint_fast32_t addr) {
      const uint8_t *src = &rom_data[addr];
      // Alignment check, not required for all platforms. ESP32 series mcu flash memory and psram sources *require* this
      if ((uintptr_t)src & 1) {
          // fallback to safe 8-bit reads when not aligned
          return ((uint16_t)src[0]) | ((uint16_t)src[1] << 8);          
      } 
      return *(uint16_t *)src;
}

An ISO C Version of this can also be written as follows:

uint8_t* rom_data; // for this example a pointer to rom_data in ram
uint16_t gb_rom_read_16bit(struct gb_s *gb,const uint_fast32_t addr) {
  /* ISO C version below */
      const uint8_t *src = &rom+data[addr];
      uint16_t val;
      memcpy(&val, src, sizeof(val));
      return val;
}

on platforms without any alignment performance or correctness concerns this could be simplified to something like.
This isn't ISO C and can be undefined behaviour on some platforms. Use with caution, and test for performance impact vs
aligned and ISO C versions if you are unsure of how your platform handles this.

uint8_t* rom_data; // for this example a pointer to rom_data in ram, flash or psram data
uint16_t gb_rom_read_16bit(struct gb_s *gb,const uint_fast32_t addr) {
      return *(uint16_t *)&rom_data[addr];
}

or whatever is appropriate for your platform.

Clone this wiki locally