Fixed problem in DeviceSettings::strParam, returned wrong string
[avr-sim.git] / src / TimerInterrupts.cpp
blob38dcdf8109d6fd30d15190543721ee25cb0dc49c
1 /*
2 * avr-sim: An atmel AVR simulator
3 * Copyright (C) 2008 Tom Haber
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "TimerInterrupts.h"
20 #include "Registers.h"
21 #include "Bus.h"
22 #include "ImplementationException.h"
24 #include <cstring>
26 namespace avr {
28 TimerInterrupts::TimerInterrupts(Bus & bus, unsigned char mask,
29 unsigned int bit0Vec, unsigned int bit1Vec,
30 unsigned int bit2Vec, unsigned int bit3Vec,
31 unsigned int bit4Vec, unsigned int bit5Vec,
32 unsigned int bit6Vec, unsigned int bit7Vec)
33 : Hardware(bus), mask(mask),
34 bit0Vec(bit0Vec), bit1Vec(bit1Vec), bit2Vec(bit2Vec), bit3Vec(bit3Vec),
35 bit4Vec(bit4Vec), bit5Vec(bit5Vec), bit6Vec(bit6Vec), bit7Vec(bit7Vec) {
37 unsigned int vec[] = {
38 bit0Vec,
39 bit1Vec,
40 bit2Vec,
41 bit3Vec,
42 bit4Vec,
43 bit5Vec,
44 bit6Vec,
45 bit7Vec
48 for(int i = 0; i < 8; ++i) {
49 if( (mask & (1<<i)) != 0 )
50 bus.claimInterrupt(vec[i], this);
54 bool TimerInterrupts::attachReg(const char *name, IORegister *reg) {
55 if( strcmp(name, "timsk") == 0 )
56 timsk = reg;
57 else if( strcmp(name, "tifr") == 0 )
58 tifr = reg;
59 else
60 return false;
62 reg->registerHW(this);
63 return true;
66 bool TimerInterrupts::finishBuild() {
67 return (timsk != 0) && (tifr != 0);
70 void TimerInterrupts::beforeInvokeInterrupt(unsigned int vector) {
71 if( vector == bit0Vec ) tifrOld &= ~(1<<0);
72 else if( vector == bit0Vec ) tifrOld &= ~(1<<0);
73 else if( vector == bit1Vec ) tifrOld &= ~(1<<1);
74 else if( vector == bit2Vec ) tifrOld &= ~(1<<2);
75 else if( vector == bit3Vec ) tifrOld &= ~(1<<3);
76 else if( vector == bit4Vec ) tifrOld &= ~(1<<4);
77 else if( vector == bit4Vec ) tifrOld &= ~(1<<5);
78 else if( vector == bit6Vec ) tifrOld &= ~(1<<6);
79 else if( vector == bit7Vec ) tifrOld &= ~(1<<7);
81 tifr->set( tifrOld );
84 void TimerInterrupts::checkForNewSetIrq(unsigned char tiac) {
85 tiac &= mask;
86 if( tiac & (1<<0) ) { bus.raiseInterrupt( bit0Vec ); }
87 if( tiac & (1<<1) ) { bus.raiseInterrupt( bit1Vec ); }
88 if( tiac & (1<<2) ) { bus.raiseInterrupt( bit2Vec ); }
89 if( tiac & (1<<3) ) { bus.raiseInterrupt( bit3Vec ); }
90 if( tiac & (1<<4) ) { bus.raiseInterrupt( bit4Vec ); }
91 if( tiac & (1<<5) ) { bus.raiseInterrupt( bit5Vec ); }
92 if( tiac & (1<<6) ) { bus.raiseInterrupt( bit6Vec ); }
93 if( tiac & (1<<7) ) { bus.raiseInterrupt( bit7Vec ); }
95 tifr->set( tifrOld );
98 void TimerInterrupts::checkForNewClearIrq(unsigned char tiac) {
99 tiac &= mask;
100 if( tiac & (1<<0) ) { bus.clearInterrupt( bit0Vec ); }
101 if( tiac & (1<<1) ) { bus.clearInterrupt( bit1Vec ); }
102 if( tiac & (1<<2) ) { bus.clearInterrupt( bit2Vec ); }
103 if( tiac & (1<<3) ) { bus.clearInterrupt( bit3Vec ); }
104 if( tiac & (1<<4) ) { bus.clearInterrupt( bit4Vec ); }
105 if( tiac & (1<<5) ) { bus.clearInterrupt( bit5Vec ); }
106 if( tiac & (1<<6) ) { bus.clearInterrupt( bit6Vec ); }
107 if( tiac & (1<<7) ) { bus.clearInterrupt( bit7Vec ); }
110 void TimerInterrupts::regChanged( IORegister *reg ) {
111 unsigned char tiacOld = timskOld & tifrOld;
113 if( reg == timsk ) {
114 timskOld = *timsk;
115 } else if( reg == tifr ) {
116 tifrOld = *tifr;
119 unsigned char tiacNew= timskOld & tifrOld;
121 unsigned char changed = tiacNew ^ tiacOld;
122 unsigned char setnew = changed & tiacNew;
123 unsigned char clearnew = changed & (~tiacNew);
125 checkForNewSetIrq(setnew);
126 checkForNewClearIrq(clearnew);