Bug fix: check if vm exists
[avr-sim.git] / TimerInterrupts.cpp
blobf067d061cd0e609d2bbf79dc51f77cde94d96bf3
1 #include "TimerInterrupts.h"
2 #include "Registers.h"
3 #include "Bus.h"
4 #include "ImplementationException.h"
6 namespace avr {
8 bool TimerInterrupts::attachReg(const char *name, IORegister *reg) {
9 if( strcmp(name, "timsk") == 0 )
10 timsk = reg;
11 else if( strcmp(name, "tifr") == 0 )
12 tifr = reg;
13 else
14 return false;
16 reg->registerHW(this);
17 return true;
20 void TimerInterrupts::checkForNewSetIrq(unsigned char tiac) {
21 tiac &= mask;
22 if( tiac & (1<<0) ) { bus.raiseInterrupt( bit0Vec ); }
23 if( tiac & (1<<1) ) { bus.raiseInterrupt( bit1Vec ); }
24 if( tiac & (1<<2) ) { bus.raiseInterrupt( bit2Vec ); }
25 if( tiac & (1<<3) ) { bus.raiseInterrupt( bit3Vec ); }
26 if( tiac & (1<<4) ) { bus.raiseInterrupt( bit4Vec ); }
27 if( tiac & (1<<5) ) { bus.raiseInterrupt( bit5Vec ); }
28 if( tiac & (1<<6) ) { bus.raiseInterrupt( bit6Vec ); }
29 if( tiac & (1<<7) ) { bus.raiseInterrupt( bit7Vec ); }
32 * TODO: Once an irq has been raised, the flag should be cleared,
33 * _BUT_ should it be done here? Might be a problem if there are
34 * many interrupts pending and then the user wants to clear one.
36 tifrOld = tifr->get() & ~tiac;
37 tifr->set( tifrOld );
40 void TimerInterrupts::checkForNewClearIrq(unsigned char tiac) {
41 tiac &= mask;
42 if( tiac & (1<<0) ) { bus.clearInterrupt( bit0Vec ); }
43 if( tiac & (1<<1) ) { bus.clearInterrupt( bit1Vec ); }
44 if( tiac & (1<<2) ) { bus.clearInterrupt( bit2Vec ); }
45 if( tiac & (1<<3) ) { bus.clearInterrupt( bit3Vec ); }
46 if( tiac & (1<<4) ) { bus.clearInterrupt( bit4Vec ); }
47 if( tiac & (1<<5) ) { bus.clearInterrupt( bit5Vec ); }
48 if( tiac & (1<<6) ) { bus.clearInterrupt( bit6Vec ); }
49 if( tiac & (1<<7) ) { bus.clearInterrupt( bit7Vec ); }
52 void TimerInterrupts::regChanged( IORegister *reg ) {
53 unsigned char tiacOld = timskOld & tifrOld;
55 if( reg == timsk ) {
56 timskOld = *timsk;
57 } else if( reg == tifr ) {
58 tifrOld = *tifr;
61 unsigned char tiacNew= timskOld & tifrOld;
63 unsigned char changed = tiacNew ^ tiacOld;
64 unsigned char setnew = changed & tiacNew;
65 unsigned char clearnew = changed & (~tiacNew);
67 checkForNewSetIrq(setnew);
68 checkForNewClearIrq(clearnew);