/* * bank_io — HOME-resident helpers to read/write a "far" page that lives * in some physical RAM page outside the currently-mapped W3 bank. * * - We always run from HOME (window 1, always mapped), so we are free * to swap W3 (port 0xE2) between the caller's bank and the data * page, then restore it before returning. * - The caller must not rely on W3 contents during the call — the swap * is transparent to instruction-fetch (we execute from W1), and only * this function touches W3. * - DI/EI is NOT applied around the swap; ISRs in HOME are unaffected, * and banked-call ISRs are not expected in our current design. */ #include #include #include #include uint8_t bank_load_byte(uint8_t phys_page, uint16_t off_in_window) { uint8_t saved = _io_page_w3; sprinter_page_w3(phys_page); uint8_t v = *((volatile uint8_t *)(0xC000u + off_in_window)); sprinter_page_w3(saved); return v; } void bank_store_byte(uint8_t phys_page, uint16_t off_in_window, uint8_t v) { uint8_t saved = _io_page_w3; sprinter_page_w3(phys_page); *((volatile uint8_t *)(0xC000u + off_in_window)) = v; sprinter_page_w3(saved); } void bank_read(uint8_t phys_page, uint16_t off, void *dst, uint16_t n) { uint8_t saved = _io_page_w3; sprinter_page_w3(phys_page); memcpy(dst, (const void *)(0xC000u + off), n); sprinter_page_w3(saved); } void bank_write(uint8_t phys_page, uint16_t off, const void *src, uint16_t n) { uint8_t saved = _io_page_w3; sprinter_page_w3(phys_page); memcpy((void *)(0xC000u + off), src, n); sprinter_page_w3(saved); }