/* * bank_local_data — demonstrates that a banked function can own its own * static (BSS) array and a const lookup table without burning HOME * memory. When the function executes, BANK1 is mapped into window 3 * and both code and data are directly addressable. * * No bank_read / bank_write needed — the trampoline maps the bank for * us and the C code touches the arrays normally. */ #include #include extern void bank1_fill (int seed) __banked; extern uint16_t bank1_sumtab (void) __banked; extern uint8_t bank1_peek (int idx) __banked; extern void bank1_map_print(void) __banked; extern uint8_t *bank1_alloc_and_fill(int n, uint8_t pattern) __banked; extern void bank1_free (void *p) __banked; /* MUST be `const`: crt0_banked reads _n_banks BEFORE gsinit, so * non-const initialized variables haven't been copied yet and would * read 0 → bank loading is skipped → garbage in window 3. */ const uint8_t n_banks = 1; uint8_t local0_buf[16]; int main(int argc, char **argv) { puts("bank_local_data: testing static data in BANK1"); bank1_map_print(); /* Verify crt0_banked parsed argv correctly. */ printf("argc=%d, argv[0]=\"%s\"\n", argc, argv[0]); printf("local0_buf = %p\n", local0_buf); for (int i = 1; i < argc; i++) printf(" argv[%d]=\"%s\"\n", i, argv[i]); /* Seed the BSS array in BANK1. */ bank1_fill(0x10); /* Read it back through another banked function — verifies the data * survived after the trampoline returned to HOME and re-entered. */ int ok = 1; for (int i = 0; i < 8; i++) { uint8_t v = bank1_peek(i); uint8_t expected = (uint8_t)(0x10 + i); if (v != expected) { printf(" bank1_buf[%d] = 0x%02X, expected 0x%02X\n", i, v, expected); ok = 0; } } if (ok) puts(" buf[0..7] OK"); /* Use the const lookup table that lives in BANK1. */ uint16_t sum = bank1_sumtab(); printf(" bank1_sumtab() = %u (expected 1500)\n", sum); /* malloc from a banked function — the heap lives in W2 (HOME), * which stays mapped across W3 page swaps. Returned pointer * should be usable both inside the bank AND from HOME afterwards. */ uint8_t *heap_p = bank1_alloc_and_fill(32, 0xA0); if (heap_p == NULL) { puts(" malloc from bank FAILED"); } else { printf(" caller sees pointer = %p\n", heap_p); int ok = 1; for (int i = 0; i < 32; i++) { uint8_t expected = (uint8_t)(0xA0 + i); if (heap_p[i] != expected) { printf(" heap_p[%d] = 0x%02X, expected 0x%02X\n", i, heap_p[i], expected); ok = 0; } } if (ok) puts(" bank-allocated heap [0..31] OK from HOME"); bank1_free(heap_p); } puts("done"); return 0; }