/* interrupts_demo1 ARM9 Code Chris Double (chris.double@double.co.nz) http://www.double.co.nz/nintendo_ds */ #include #include "nds/arm9/console.h" #include #include static int old_x = 0; static int old_y = 0; static int shape_x = 0; static int shape_y = 0; static int shape_width = 10; static int shape_height = 10; static int interrupt_count = 0; static int swi_return_count = 0; void draw_shape(int x, int y, uint16* buffer, uint16 color) { buffer += y * SCREEN_WIDTH + x; for(int i = 0; i < shape_height; ++i) { uint16* line = buffer + (SCREEN_WIDTH * i); for(int j = 0; j < shape_width; ++j) { *line++ = color; } } } void on_irq_vblank() { old_x = shape_x; old_y = shape_y; shape_x++; if(shape_x + shape_width >= SCREEN_WIDTH) { shape_x = 0; shape_y += shape_height; if(shape_y + shape_height >= SCREEN_HEIGHT) { shape_y = 0; } } draw_shape(old_x, old_y, VRAM_A, RGB15(0, 0, 0)); draw_shape(shape_x, shape_y, VRAM_A, RGB15(31, 0, 0)); printf("\x1b[2J"); printf("Interrupt Count: %d\n", interrupt_count); printf("SWI Count : %d\n", swi_return_count); } void on_irq_keys() { // Key interrupt occurred. interrupt_count++; } void on_irq() { if(REG_IF & IRQ_VBLANK) { on_irq_vblank(); VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK; REG_IF |= IRQ_VBLANK; } if(REG_IF & IRQ_KEYS) { on_irq_keys(); VBLANK_INTR_WAIT_FLAGS |= IRQ_KEYS; REG_IF |= IRQ_KEYS; } } void swiWaitForKeys() { asm("mov r0, #1"); asm("mov r1, #4096"); asm("swi #262144"); } int main(void) { powerON(POWER_ALL); videoSetMode(MODE_FB0); vramSetBankA(VRAM_A_LCD); // Set up second screen details videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); vramSetBankC(VRAM_C_SUB_BG); SUB_BG0_CR = BG_MAP_BASE(31); BG_PALETTE_SUB[255] = RGB15(31,31,31); consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16); // Set up the interrupt handler REG_IME = 0; IRQ_HANDLER = on_irq; REG_IE = IRQ_VBLANK | IRQ_KEYS; REG_IF = ~0; DISP_SR = DISP_VBLANK_IRQ; REG_IME = 1; // The interrupt will fire when both the A and B key are // pressed. Bit 15 being set is what makes the requirement that both // keys must be pressed. REG_KEYCNT = KEY_A | KEY_B | (1<<14) | (1<<15); while(1) { swiWaitForKeys(); ++swi_return_count; } return 0; }