#include <stdbool.h>
#include <stdint.h>
#define PEEK(address) (*(uint8_t *)(address))
#define POKE(address, value) *(uint8_t *)(address) = (value)
void called_every_frame();
typedef void (*function_type)(void);
function_type *const KERNAL_IRQ = (function_type *)0x0314;
function_type *const HARDWARE_IRQ = (function_type *)0xfffe;
void init_raster_irq(function_type irq_function, uint8_t triggering_raster_line,
function_type *const irq_address,
bool kill_kernal_and_basic) {
asm volatile(
"sei\n" "lda #$7f\n"
"sta $dc0d\n" "sta $dd0d\n" "lda $dc0d\n" "lda $dd0d\n" ::
: "a");
POKE(0xd01a, 0x01); POKE(0xd012, triggering_raster_line);
POKE(0xd011, 0x1b);
if (kill_kernal_and_basic) {
POKE(0x01, 0x35);
}
*irq_address = irq_function;
asm volatile("cli");
}
__attribute__((interrupt)) void irq_wrapper(void) {
called_every_frame();
asm volatile("lsr $d019");
}
void hardware_raster_irq_c(uint8_t triggering_raster_line) {
init_raster_irq(&irq_wrapper, triggering_raster_line, HARDWARE_IRQ, true);
}
inline void _indexed_memcopy() {
const uint16_t _src = 0x0541; const uint16_t _dst = 0x0540; const uint8_t _size = 39;
asm volatile(
"ldx #$00\n"
"loop: lda %[src],x\n"
"sta %[dst],x\n"
"inx\n"
"cpx #%[size]\n"
"bne loop\n"
:: [src] "i" (_src), [dst] "i" (_dst), [size] "i" (_size)
: "a", "x");
}