@@ -101,17 +101,28 @@ describe('timer', () => {
101101 expect ( tcnt ) . toEqual ( 0 ) ; // TCNT should stay 0
102102 } ) ;
103103
104- it ( 'should set TOV if timer overflows ' , ( ) => {
104+ it ( 'should set the TOV flag when timer reaches the TOP value ' , ( ) => {
105105 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
106106 new AVRTimer ( cpu , timer0Config ) ;
107107 cpu . writeData ( TCNT0 , 0xff ) ;
108108 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
109109 cpu . cycles = 1 ;
110110 cpu . tick ( ) ;
111- cpu . cycles = 2 ;
111+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0xff ) ;
112+ expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( TOV0 ) ;
113+ } ) ;
114+
115+ it ( 'should set the TOV if timer overflows past TOP without reaching TOP' , ( ) => {
116+ const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
117+ new AVRTimer ( cpu , timer0Config ) ;
118+ cpu . writeData ( TCNT0 , 0xfe ) ;
119+ cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
120+ cpu . cycles = 1 ;
112121 cpu . tick ( ) ;
113- const tcnt = cpu . readData ( TCNT0 ) ;
114- expect ( tcnt ) . toEqual ( 0 ) ;
122+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0xfe ) ;
123+ cpu . cycles += 4 ;
124+ cpu . tick ( ) ;
125+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0x2 ) ;
115126 expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( TOV0 ) ;
116127 } ) ;
117128
@@ -152,7 +163,7 @@ describe('timer', () => {
152163 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
153164 cpu . cycles = 1 ;
154165 cpu . tick ( ) ;
155- cpu . data [ TIMSK0 ] = TOIE0 ;
166+ cpu . writeData ( TIMSK0 , TOIE0 ) ;
156167 cpu . data [ SREG ] = 0x80 ; // SREG: I-------
157168 cpu . cycles = 2 ;
158169 cpu . tick ( ) ;
@@ -180,7 +191,7 @@ describe('timer', () => {
180191 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
181192 cpu . cycles = 1 ;
182193 cpu . tick ( ) ;
183- cpu . data [ TIMSK0 ] = 2 ;
194+ cpu . writeData ( TIMSK0 , 2 ) ;
184195 cpu . data [ SREG ] = 0x80 ; // SREG: I-------
185196 cpu . cycles = 2 ;
186197 cpu . tick ( ) ;
@@ -305,6 +316,29 @@ describe('timer', () => {
305316 expect ( cpu . data [ TIFR0 ] ) . toEqual ( OCF0A | TOV0 ) ;
306317 } ) ;
307318
319+ it ( 'should not set the TOV bit twice on overflow (issue #80)' , ( ) => {
320+ const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
321+ new AVRTimer ( cpu , timer0Config ) ;
322+ cpu . writeData ( TCNT0 , 0xfe ) ;
323+ cpu . writeData ( OCR0A , 0xff ) ;
324+ cpu . writeData ( TCCR0A , WGM01 ) ; // WGM: CTC
325+ cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
326+
327+ cpu . cycles = 1 ;
328+ cpu . tick ( ) ;
329+
330+ cpu . cycles = 2 ;
331+ cpu . tick ( ) ;
332+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0xff ) ;
333+ expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( TOV0 ) ;
334+ cpu . data [ TIFR0 ] &= ~ TOV0 ; // Clear the TOV0 bit
335+
336+ cpu . cycles = 3 ;
337+ cpu . tick ( ) ;
338+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0 ) ;
339+ expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( 0 ) ;
340+ } ) ;
341+
308342 it ( 'should set OCF0B flag when timer equals OCRB' , ( ) => {
309343 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
310344 new AVRTimer ( cpu , timer0Config ) ;
0 commit comments