@@ -42,6 +42,30 @@ describe('timer', () => {
4242 expect ( cpu . data [ 0x35 ] ) . toEqual ( 1 ) ; // TOV bit in TIFR
4343 } ) ;
4444
45+ it ( 'should set TOV if timer overflows in PWM Phase Correct mode' , ( ) => {
46+ const timer = new AVRTimer ( cpu , timer0Config ) ;
47+ cpu . data [ 0x46 ] = 0xff ; // TCNT0 <- 0xff
48+ cpu . writeData ( 0x47 , 0x7f ) ; // OCRA <- 0x7f
49+ cpu . writeData ( 0x44 , 0x1 ) ; // WGM0 <- 1 (PWM, Phase Correct)
50+ cpu . data [ 0x45 ] = 0x1 ; // TCCR0B.CS <- 1
51+ cpu . cycles = 1 ;
52+ timer . tick ( ) ;
53+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0 ) ; // TCNT should be 0
54+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 1 ) ; // TOV bit in TIFR
55+ } ) ;
56+
57+ it ( 'should set TOV if timer overflows in FAST PWM mode' , ( ) => {
58+ const timer = new AVRTimer ( cpu , timer0Config ) ;
59+ cpu . data [ 0x46 ] = 0xff ; // TCNT0 <- 0xff
60+ cpu . writeData ( 0x47 , 0x7f ) ; // OCRA <- 0x7f
61+ cpu . writeData ( 0x44 , 0x3 ) ; // WGM0 <- 3 (FAST PWM)
62+ cpu . data [ 0x45 ] = 0x1 ; // TCCR0B.CS <- 1
63+ cpu . cycles = 1 ;
64+ timer . tick ( ) ;
65+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0 ) ; // TCNT should be 0
66+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 1 ) ; // TOV bit in TIFR
67+ } ) ;
68+
4569 it ( 'should generate an overflow interrupt if timer overflows and interrupts enabled' , ( ) => {
4670 const timer = new AVRTimer ( cpu , timer0Config ) ;
4771 cpu . data [ 0x46 ] = 0xff ; // TCNT0 <- 0xff
@@ -81,4 +105,87 @@ describe('timer', () => {
81105 expect ( cpu . pc ) . toEqual ( 0 ) ;
82106 expect ( cpu . cycles ) . toEqual ( 1 ) ;
83107 } ) ;
108+
109+ it ( 'should set OCF0A flag when timer equals OCRA' , ( ) => {
110+ const timer = new AVRTimer ( cpu , timer0Config ) ;
111+ cpu . writeData ( 0x46 , 0x10 ) ; // TCNT0 <- 0x10
112+ cpu . writeData ( 0x47 , 0x11 ) ; // OCR0A <- 0x11
113+ cpu . writeData ( 0x44 , 0x0 ) ; // WGM0 <- 0 (Normal)
114+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
115+ cpu . cycles = 1 ;
116+ timer . tick ( ) ;
117+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 2 ) ; // TIFR0 should have OCF0A bit on
118+ expect ( cpu . pc ) . toEqual ( 0 ) ;
119+ expect ( cpu . cycles ) . toEqual ( 1 ) ;
120+ } ) ;
121+
122+ it ( 'should clear the timer in CTC mode if it equals to OCRA' , ( ) => {
123+ const timer = new AVRTimer ( cpu , timer0Config ) ;
124+ cpu . writeData ( 0x46 , 0x10 ) ; // TCNT0 <- 0x10
125+ cpu . writeData ( 0x47 , 0x11 ) ; // OCR0A <- 0x11
126+ cpu . writeData ( 0x44 , 0x2 ) ; // WGM0 <- 2 (CTC)
127+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
128+ cpu . cycles = 1 ;
129+ timer . tick ( ) ;
130+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0 ) ; // TCNT should be 0
131+ expect ( cpu . pc ) . toEqual ( 0 ) ;
132+ expect ( cpu . cycles ) . toEqual ( 1 ) ;
133+ } ) ;
134+
135+ it ( 'should set OCF0B flag when timer equals OCRB' , ( ) => {
136+ const timer = new AVRTimer ( cpu , timer0Config ) ;
137+ cpu . writeData ( 0x46 , 0x10 ) ; // TCNT0 <- 0x50
138+ cpu . writeData ( 0x48 , 0x11 ) ; // OCR0B <- 0x51
139+ cpu . writeData ( 0x44 , 0x0 ) ; // WGM0 <- 0 (Normal)
140+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
141+ cpu . cycles = 1 ;
142+ timer . tick ( ) ;
143+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 4 ) ; // TIFR0 should have OCF0B bit on
144+ expect ( cpu . pc ) . toEqual ( 0 ) ;
145+ expect ( cpu . cycles ) . toEqual ( 1 ) ;
146+ } ) ;
147+
148+ it ( 'should generate Timer Compare A interrupt when TCNT0 == TCNTA' , ( ) => {
149+ const timer = new AVRTimer ( cpu , timer0Config ) ;
150+ cpu . writeData ( 0x46 , 0x20 ) ; // TCNT0 <- 0x20
151+ cpu . writeData ( 0x47 , 0x21 ) ; // OCR0A <- 0x21
152+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
153+ cpu . writeData ( 0x6e , 0x2 ) ; // TIMSK0: OCIEA
154+ cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
155+ cpu . cycles = 1 ;
156+ timer . tick ( ) ;
157+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0x21 ) ; // TCNT should be 0x21
158+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 0 ) ; // OCFA bit in TIFR should be clear
159+ expect ( cpu . pc ) . toEqual ( 0x1c ) ;
160+ expect ( cpu . cycles ) . toEqual ( 3 ) ;
161+ } ) ;
162+
163+ it ( 'should not generate Timer Compare A interrupt when OCIEA is disabled' , ( ) => {
164+ const timer = new AVRTimer ( cpu , timer0Config ) ;
165+ cpu . writeData ( 0x46 , 0x20 ) ; // TCNT0 <- 0x20
166+ cpu . writeData ( 0x47 , 0x21 ) ; // OCR0A <- 0x21
167+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
168+ cpu . writeData ( 0x6e , 0 ) ; // TIMSK0
169+ cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
170+ cpu . cycles = 1 ;
171+ timer . tick ( ) ;
172+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0x21 ) ; // TCNT should be 0x21
173+ expect ( cpu . pc ) . toEqual ( 0 ) ;
174+ expect ( cpu . cycles ) . toEqual ( 1 ) ;
175+ } ) ;
176+
177+ it ( 'should generate Timer Compare B interrupt when TCNT0 == TCNTB' , ( ) => {
178+ const timer = new AVRTimer ( cpu , timer0Config ) ;
179+ cpu . writeData ( 0x46 , 0x20 ) ; // TCNT0 <- 0x20
180+ cpu . writeData ( 0x48 , 0x21 ) ; // OCR0B <- 0x21
181+ cpu . writeData ( 0x45 , 0x1 ) ; // TCCR0B.CS <- 1
182+ cpu . writeData ( 0x6e , 0x4 ) ; // TIMSK0: OCIEB
183+ cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
184+ cpu . cycles = 1 ;
185+ timer . tick ( ) ;
186+ expect ( cpu . data [ 0x46 ] ) . toEqual ( 0x21 ) ; // TCNT should be 0x21
187+ expect ( cpu . data [ 0x35 ] ) . toEqual ( 0 ) ; // OCFB bit in TIFR should be clear
188+ expect ( cpu . pc ) . toEqual ( 0x1e ) ;
189+ expect ( cpu . cycles ) . toEqual ( 3 ) ;
190+ } ) ;
84191} ) ;
0 commit comments