--- /dev/null
+`define ADDR_IF 16'hFF0F
+`define ADDR_IE 16'hFFFF
+
+module Interrupt(
+ input clk,
+ input rd,
+ input wr,
+ input [15:0] addr,
+ inout [7:0] data,
+ input vblank,
+ input lcdc,
+ input tovf,
+ input serial,
+ input buttons,
+ output master,
+ output [7:0] jaddr);
+
+ wire [7:0] iflag = {3'b0,buttons,serial,tovf,lcdc,vblank};
+ reg [7:0] imask = 16'hFFFF;
+ reg [7:0] ihold = 0;
+ wire [7:0] imasked = ihold & imask;
+
+ assign data = rd ?
+ (addr == `ADDR_IF) ? ihold :
+ (addr == `ADDR_IE) ? imask :
+ 8'bzzzzzzzz :
+ 8'bzzzzzzzz;
+
+ assign master = (imasked) != 0;
+
+ assign jaddr = imasked[0] ? 8'h40 :
+ imasked[1] ? 8'h48 :
+ imasked[2] ? 8'h50 :
+ imasked[3] ? 8'h58 :
+ imasked[4] ? 8'h60 : 8'h00;
+
+ always @ (negedge clk)
+ begin
+ if (wr) begin
+ case(addr)
+ `ADDR_IF : ihold <= iflag | data;
+ `ADDR_IE : imask <= data;
+ endcase
+
+ end
+ else
+ ihold <= ihold | iflag;
+ end
+
+endmodule