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"
22 #include "ImplementationException.h"
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
[] = {
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 )
57 else if( strcmp(name
, "tifr") == 0 )
62 reg
->registerHW(this);
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);
84 void TimerInterrupts::checkForNewSetIrq(unsigned char tiac
) {
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
); }
98 void TimerInterrupts::checkForNewClearIrq(unsigned char tiac
) {
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
;
115 } else if( reg
== 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
);