#define FCRAM_TWL_FIRM_LOC (FCRAM_FIRM_LOC + FCRAM_SPACING) // Double size
#define FCRAM_AGB_FIRM_LOC (FCRAM_TWL_FIRM_LOC + FCRAM_SPACING * 2)
-// Location patches get loaded to.
-#define FCRAM_PATCH_LOC (FCRAM_AGB_FIRM_LOC + FCRAM_SPACING * 2)
-
// Throwaway temporary space. Don't expect it to stay sane.
-#define FCRAM_JUNK_LOC (FCRAM_PATCH_LOC + FCRAM_SPACING)
-
-// Path that the patch menu is created at.
-#define FCRAM_MENU_LOC (FCRAM_JUNK_LOC + FCRAM_SPACING)
-
-// Path that the patch enable list is located at.
-#define FCRAM_PATCHLIST_LOC (FCRAM_MENU_LOC + (FCRAM_SPACING / 2))
+#define FCRAM_JUNK_LOC FCRAM_START
-// Path that the font will be loaded at.
-#define FCRAM_FONT_LOC (FCRAM_PATCHLIST_LOC + (FCRAM_SPACING / 2))
+// Location to perform static allocations at.
+#define FCRAM_STATIC_ALLOC_LOC (FCRAM_START + FCRAM_SPACING)
-// Path that the menu for chains will be at
-#define FCRAM_CHAIN_LOC (FCRAM_FONT_LOC + FCRAM_SPACING)
+// Grow memory segment.
+void *fake_sbrk(size_t bytes);
-// Location to perform static allocations at.
-#define FCRAM_STATIC_ALLOC_LOC (0x25000000)
+// Allocate memory for use.
+void *malloc (size_t size);
-// Allocate static memory.
-void *static_allocate(size_t bytes);
+// Free in-use memory.
+void free (void* ptr);
#endif
uint32_t current_chain_index = 0;
-struct options_s *chains = (struct options_s*)FCRAM_CHAIN_LOC;
+struct options_s *chains = NULL;
int show_menu(struct options_s *options, uint8_t *toggles);
}
void chainload_menu() {
- list_chain_build(PATH_CHAINS);
+ if (chains == NULL) {
+ chains = malloc(sizeof(struct options_s) * 100);
+ list_chain_build(PATH_CHAINS);
+ }
show_menu(chains, NULL);
}
#include <common.h>
+// 16 <- AES block size.
+#define SALLOC_ALIGN 16
+
void *fcram_temp = (void *)0x23000000;
void *fcram_static_mem = (void*)FCRAM_STATIC_ALLOC_LOC;
-void *static_allocate(size_t bytes) {
- size_t aligned_bytes = bytes + (4 - (bytes % 4)); // Align to integer size (for ARM processor)
+
+struct alloc_info* first_mem = NULL;
+
+// Low level static allocator / sbrk-like function.
+void *fake_sbrk(size_t bytes) {
void *ret = fcram_static_mem;
- fcram_static_mem = (uint8_t*)fcram_static_mem + aligned_bytes;
+
+ fcram_static_mem = (uint8_t*)fcram_static_mem + bytes;
+
return ret;
}
+
+// This is an incredibly crappy and inefficient implementation of malloc/free nicked from stackoverflow.
+
+typedef struct free_block {
+ size_t size;
+ struct free_block* next;
+} free_block;
+
+static free_block free_block_list_head = { 0, 0 };
+
+// static const size_t overhead = sizeof(size_t);
+
+static const size_t align_to = 16;
+
+void* malloc(size_t size) {
+ size = (size + sizeof(free_block) + (align_to - 1)) & ~ (align_to - 1);
+ free_block* block = free_block_list_head.next;
+ free_block** head = &(free_block_list_head.next);
+ while (block != 0) {
+ if (block->size >= size) {
+ *head = block->next;
+ return ((char*)block) + sizeof(free_block);
+ }
+ head = &(block->next);
+ block = block->next;
+ }
+
+ block = (free_block*)fake_sbrk(size);
+ block->size = size;
+
+ return ((char*)block) + sizeof(free_block);
+}
+
+void free(void* ptr) {
+ if (ptr == NULL) return;
+
+ free_block* block = (free_block*)(((char*)ptr) - sizeof(free_block ));
+ block->next = free_block_list_head.next;
+ free_block_list_head.next = block;
+}
#include <ctr9/sha.h>
#include <common.h>
-firm_h *firm_loc = (firm_h *)FCRAM_FIRM_LOC;
+firm_h *firm_loc = NULL;
uint32_t firm_size = FCRAM_SPACING;
firm_section_h firm_proc9;
exefs_h *firm_p9_exefs;
-firm_h *twl_firm_loc = (firm_h *)FCRAM_TWL_FIRM_LOC;
+firm_h *twl_firm_loc = NULL;
uint32_t twl_firm_size = FCRAM_SPACING * 2;
firm_section_h twl_firm_proc9;
exefs_h *twl_firm_p9_exefs;
-firm_h *agb_firm_loc = (firm_h *)FCRAM_AGB_FIRM_LOC;
+firm_h *agb_firm_loc = NULL;
uint32_t agb_firm_size = FCRAM_SPACING * 2;
firm_section_h agb_firm_proc9;
exefs_h *agb_firm_p9_exefs;
uint32_t firm_offset = 0x0B130000 + (index % 2) * 0x400000,
firm_size = 0x00100000; // 1MB, because
- buffer[0] = static_allocate(firm_size);
+ buffer[0] = malloc(firm_size);
uint8_t ctr[0x10],
cid[0x10],
fprintf(stderr, "FIRM load triggered.\n");
+ firm_loc = malloc(firm_size);
+
fprintf(stderr, "Loading NATIVE_FIRM\n");
if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, PATH_NATIVE_CETK, &firm_size, NATIVE_FIRM_TITLEID) != 0) {
abort("\n Failed to load NATIVE_FIRM.\n");
find_proc9(firm_loc, &firm_proc9, &firm_p9_exefs);
fprintf(stderr, " Ver: %x, %u\n", get_firm_info(firm_loc)->version, get_firm_info(firm_loc)->console );
+ twl_firm_loc = malloc(twl_firm_size);
+
fprintf(stderr, "TWL_FIRM\n");
if (load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, PATH_TWL_CETK, &twl_firm_size, TWL_FIRM_TITLEID) != 0) {
fprintf(stderr, "\n TWL_FIRM failed to load.\n");
fprintf(stderr, " Ver: %x, %u\n", get_firm_info(twl_firm_loc)->version, get_firm_info(twl_firm_loc)->console );
}
+ agb_firm_loc = malloc(agb_firm_size);
+
fprintf(stderr, "AGB_FIRM\n");
if (load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, PATH_AGB_CETK, &agb_firm_size, AGB_FIRM_TITLEID) != 0) {
fprintf(stderr, "\n AGB_FIRM failed to load.\n");
// File wasn't found. The user didn't enable anything.
return 0;
}
+
uint32_t len = fsize(f);
- fread((uint8_t *)FCRAM_PATCH_LOC, 1, len, f);
+
+ uint8_t* patch_loc = malloc(len);
+
+ fread(patch_loc, 1, len, f);
fclose(f);
if (build_cache == 1) {
- patch = (struct system_patch *)FCRAM_PATCH_LOC;
+ patch = (struct system_patch*)patch_loc;
// Make sure various bits are correct.
if (memcmp(patch->magic, "AIDA", 4)) {
return 0;
} else {
- patch_mem = (uint8_t *)FCRAM_PATCH_LOC;
+ patch_mem = patch_loc;
patch_len = len;
}
#endif
#ifndef LOADER
if (stack_glob == NULL) {
- stack_glob = static_allocate(STACK_SIZE);
+ stack_glob = malloc(STACK_SIZE);
}
#endif
#include <common.h>
#include <ctr9/ctr_system.h>
-#define MAX_PATCHES ((FCRAM_SPACING / 2) / sizeof(struct options_s))
-struct options_s *patches = (struct options_s *)FCRAM_MENU_LOC;
-uint8_t *enable_list = (uint8_t *)FCRAM_PATCHLIST_LOC;
+// FIXME - Remove limit
+#define MAX_PATCHES 256
+struct options_s *patches = NULL;
+uint8_t *enable_list = NULL;
static struct options_s options[] = {
// Patches.
{
current_menu_index_patches = 0;
+ if (!enable_list)
+ enable_list = malloc(FCRAM_SPACING / 2); // FIXME - the PATCHENABLE file has to go. Badly.
+
+ if (!patches)
+ patches = malloc(sizeof(struct options_s) * 258); // FIXME - hard limit. Implement realloc.
+
memset(enable_list, 0, FCRAM_SPACING / 2);
if (!desc_is_fname) {
extern uint8_t *enable_list;
+extern struct options_s* patches;
+
void
wait()
{
list_patches_build(PATH_PATCHES, 1);
- struct options_s *patches = (struct options_s *)FCRAM_MENU_LOC;
-
for (int i = 0; patches[i].index != -1; i++) {
if (enable_list[patches[i].index]) {
// Patch is enabled. Cache it.
unsigned char color_bottom = 0xf0;
int kill_output = 0;
+uint8_t* font_data = NULL;
+
#define TRANSP_THRESH 178
static uint8_t alphamap[256] = {0};
alphamap[i] = i - 0x7F;
}
- top_bg = static_allocate(TOP_SIZE);
- bottom_bg = static_allocate(BOTTOM_SIZE);
- log_buffer = static_allocate(LOG_BUFFER_SIZE);
+ top_bg = malloc(TOP_SIZE);
+ bottom_bg = malloc(BOTTOM_SIZE);
+ log_buffer = malloc(LOG_BUFFER_SIZE);
}
static uint32_t colors[16] = {
unsigned int c_font_w = (new_w / 8) + (new_w % 8 ? 1 : 0);
- fread((void*)FCRAM_FONT_LOC, 1, c_font_w * new_h * (256 - ' '), f); // Skip non-printing chars.
+ font_data = malloc(c_font_w * new_h * (256 - ' '));
+
+ fread(font_data, 1, c_font_w * new_h * (256 - ' '), f); // Skip non-printing chars.
fclose(f);
int yDisplacementBg = ((height - (y + yy) - 1) * 3);
unsigned int pos_b = xDisplacementBg + yDisplacementBg;
- unsigned char char_dat = ((char*)FCRAM_FONT_LOC)[(character - ' ') * (c_font_w * font_h) + yy];
+ unsigned char char_dat = font_data[(character - ' ') * (c_font_w * font_h) + yy];
for(unsigned int i=0; i < font_w + font_kern; i++) {
screen[pos] = 0xFF;