#include #include #include #include #include #include static dma_context ctx; void dma_start(u8 start) { ctx.start_delay = 1; ctx.value_buffer = start; ctx.dma_waiting = true; } void dma_begin() { ctx.active = true; ctx.byte = 0; ctx.value = ctx.value_buffer; ctx.dma_waiting = false; } void dma_tick() { ctx.transferring = false; if (ctx.start_delay) { ctx.start_delay--; } else if(ctx.dma_waiting) { dma_begin(); } if (!ctx.active) { return; } ctx.transferring = true; u8 data = 0; u16 addr = (ctx.value << 8) | ctx.byte; if(ctx.value < 0x80) { data = cart_read(addr); } else if (ctx.value < 0xA0) { data = ppu_vram_read(addr); } else if (ctx.value < 0xC0) { data = cart_read(addr); } else { data = wram_read((addr & 0x1FFF) | 0xC000); } ppu_oam_write(ctx.byte, data); ctx.byte++; ctx.active = ctx.byte < 0xA0; } bool dma_transferring() { return ctx.transferring;// && ctx.active; } void dma_save_state(dma_state* state) { state->ctx = ctx; } void dma_load_state(const dma_state* state) { ctx = state->ctx; }