1 #ifndef M0_IRQ_H
2 #define M0_IRQ_H
3 
4 #include "lcddef.h"
5 #include "../savestate.h"
6 
7 namespace gambatte {
8 
9 class M0Irq {
10 public:
M0Irq()11 	M0Irq()
12 	: statReg_(0)
13 	, lycReg_(0)
14 	{
15 	}
16 
lcdReset(unsigned statReg,unsigned lycReg)17 	void lcdReset(unsigned statReg, unsigned lycReg) {
18 		statReg_ = statReg;
19 		 lycReg_ =  lycReg;
20 	}
21 
statRegChange(unsigned statReg,unsigned long nextM0IrqTime,unsigned long cc,bool cgb)22 	void statRegChange(unsigned statReg,
23 	                   unsigned long nextM0IrqTime, unsigned long cc, bool cgb) {
24 		if (nextM0IrqTime - cc > cgb * 2U)
25 			statReg_ = statReg;
26 	}
27 
lycRegChange(unsigned lycReg,unsigned long nextM0IrqTime,unsigned long cc,bool ds,bool cgb)28 	void lycRegChange(unsigned lycReg,
29 	                  unsigned long nextM0IrqTime, unsigned long cc,
30 	                  bool ds, bool cgb) {
31 		if (nextM0IrqTime - cc > cgb * 5 + 1U - ds)
32 			lycReg_ = lycReg;
33 	}
34 
doEvent(unsigned char * ifreg,unsigned ly,unsigned statReg,unsigned lycReg)35 	void doEvent(unsigned char *ifreg, unsigned ly, unsigned statReg, unsigned lycReg) {
36 		if (((statReg_ | statReg) & lcdstat_m0irqen)
37 				&& (!(statReg_ & lcdstat_lycirqen) || ly != lycReg_)) {
38 			*ifreg |= 2;
39 		}
40 
41 		statReg_ = statReg;
42 		 lycReg_ =  lycReg;
43 	}
44 
saveState(SaveState & state)45 	void saveState(SaveState &state) const {
46 		state.ppu.m0lyc = lycReg_;
47 	}
48 
loadState(SaveState const & state)49 	void loadState(SaveState const &state) {
50 		 lycReg_ = state.ppu.m0lyc;
51 		statReg_ = state.mem.ioamhram.get()[0x141];
52 	}
53 
statReg()54 	unsigned statReg() const { return statReg_; }
55 
56 private:
57 	unsigned char statReg_;
58 	unsigned char lycReg_;
59 };
60 
61 }
62 
63 #endif
64