1 module gbaid.gba.interrupt; 2 3 import gbaid.util; 4 5 import gbaid.gba.io; 6 import gbaid.gba.cpu; 7 import gbaid.gba.halt; 8 9 public class InterruptHandler { 10 private ARM7TDMI processor; 11 private HaltHandler haltHandler; 12 private bool masterEnable = false; 13 private int enable = 0; 14 private int request = 0; 15 16 public this(IoRegisters* ioRegisters, ARM7TDMI processor, HaltHandler haltHandler) { 17 this.processor = processor; 18 this.haltHandler = haltHandler; 19 20 ioRegisters.mapAddress(0x208, &masterEnable, 0b1, 0).postWriteMonitor(&onMasterEnablePostWrite); 21 ioRegisters.mapAddress(0x200, &enable, 0x3FFF, 0); 22 ioRegisters.mapAddress(0x200, &request, 0x3FFF, 16) 23 .preWriteMonitor(&onInterruptAcknowledgePreWrite) 24 .postWriteMonitor(&onInterruptAcknowledgePostWrite); 25 } 26 27 public void requestInterrupt(int source) { 28 request.setBit(source, 1); 29 checkForIrq(); 30 } 31 32 private void onMasterEnablePostWrite(int mask, int oldMasterEnabled, int newMasterEnabled) { 33 // Trigger any IRQ requested when disabled 34 if (!oldMasterEnabled && newMasterEnabled) { 35 checkForIrq(); 36 } 37 } 38 39 private bool onInterruptAcknowledgePreWrite(int mask, ref int acknowledged) { 40 // Clear the acknowledged interrupts and replace the value by the updated request bits 41 acknowledged = request & ~acknowledged; 42 return true; 43 } 44 45 private void onInterruptAcknowledgePostWrite(int mask, int oldAcknowledged, int newAcknowledged) { 46 // Trigger another IRQ if any is still not acknowledged 47 checkForIrq(); 48 } 49 50 private void checkForIrq() { 51 auto irq = masterEnable && (request & enable); 52 processor.irq(irq); 53 if (irq) { 54 haltHandler.irqTriggered(); 55 } 56 } 57 } 58 59 public static enum InterruptSource { 60 LCD_VBLANK = 0, 61 LCD_HBLANK = 1, 62 LCD_VCOUNTER_MATCH = 2, 63 TIMER_0_OVERFLOW = 3, 64 TIMER_1_OVERFLOW = 4, 65 TIMER_2_OVERFLOW = 5, 66 TIMER_3_OVERFLOW = 6, 67 SERIAL_COMMUNICATION = 7, 68 DMA_0 = 8, 69 DMA_1 = 9, 70 DMA_2 = 10, 71 DMA_3 = 11, 72 KEYPAD = 12, 73 GAMEPAK = 13 74 }