@@ -6,6 +6,11 @@ import { AVRTimer, timer0Config, timer1Config, timer2Config } from './timer';
66// CPU registers
77const R1 = 1 ;
88const R17 = 17 ;
9+ const R18 = 18 ;
10+ const R19 = 19 ;
11+ const R20 = 20 ;
12+ const R21 = 21 ;
13+ const R22 = 22 ;
914const SREG = 95 ;
1015
1116// Port Registers
@@ -168,10 +173,10 @@ describe('timer', () => {
168173 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
169174 const timer = new AVRTimer ( cpu , timer0Config ) ;
170175 cpu . writeData ( TCNT0 , 0x10 ) ;
171- timer . tick ( ) ;
172176 cpu . writeData ( OCR0A , 0x11 ) ;
173177 cpu . writeData ( TCCR0A , 0x0 ) ; // WGM: Normal
174178 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
179+ timer . tick ( ) ;
175180 cpu . cycles = 1 ;
176181 timer . tick ( ) ;
177182 expect ( cpu . data [ TIFR0 ] ) . toEqual ( OCF0A ) ;
@@ -183,10 +188,10 @@ describe('timer', () => {
183188 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
184189 const timer = new AVRTimer ( cpu , timer0Config ) ;
185190 cpu . writeData ( TCNT0 , 0x10 ) ;
186- timer . tick ( ) ;
187191 cpu . writeData ( OCR0A , 0x11 ) ;
188192 cpu . writeData ( TCCR0A , WGM01 ) ; // WGM: CTC
189193 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
194+ timer . tick ( ) ;
190195 cpu . cycles = 1 ;
191196 timer . tick ( ) ;
192197 const tcnt = cpu . readData ( TCNT0 ) ;
@@ -199,10 +204,10 @@ describe('timer', () => {
199204 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
200205 const timer = new AVRTimer ( cpu , timer0Config ) ;
201206 cpu . writeData ( TCNT0 , 0x10 ) ;
202- timer . tick ( ) ;
203207 cpu . writeData ( OCR0B , 0x11 ) ;
204208 cpu . writeData ( TCCR0A , 0x0 ) ; // WGM: (Normal)
205209 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
210+ timer . tick ( ) ;
206211 cpu . cycles = 1 ;
207212 timer . tick ( ) ;
208213 expect ( cpu . data [ TIFR0 ] ) . toEqual ( OCF0B ) ;
@@ -214,11 +219,11 @@ describe('timer', () => {
214219 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
215220 const timer = new AVRTimer ( cpu , timer0Config ) ;
216221 cpu . writeData ( TCNT0 , 0x20 ) ;
217- timer . tick ( ) ;
218222 cpu . writeData ( OCR0A , 0x21 ) ;
219223 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
220224 cpu . writeData ( TIMSK0 , OCIE0A ) ;
221225 cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
226+ timer . tick ( ) ;
222227 cpu . cycles = 1 ;
223228 timer . tick ( ) ;
224229 const tcnt = cpu . readData ( TCNT0 ) ;
@@ -232,11 +237,11 @@ describe('timer', () => {
232237 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
233238 const timer = new AVRTimer ( cpu , timer0Config ) ;
234239 cpu . writeData ( TCNT0 , 0x20 ) ;
235- timer . tick ( ) ;
236240 cpu . writeData ( OCR0A , 0x21 ) ;
237241 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
238242 cpu . writeData ( TIMSK0 , 0 ) ;
239243 cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
244+ timer . tick ( ) ;
240245 cpu . cycles = 1 ;
241246 timer . tick ( ) ;
242247 const tcnt = cpu . readData ( TCNT0 ) ;
@@ -249,11 +254,11 @@ describe('timer', () => {
249254 const cpu = new CPU ( new Uint16Array ( 0x1000 ) ) ;
250255 const timer = new AVRTimer ( cpu , timer0Config ) ;
251256 cpu . writeData ( TCNT0 , 0x20 ) ;
252- timer . tick ( ) ;
253257 cpu . writeData ( OCR0B , 0x21 ) ;
254258 cpu . writeData ( TCCR0B , CS00 ) ; // Set prescaler to 1
255259 cpu . writeData ( TIMSK0 , OCIE0B ) ;
256260 cpu . writeData ( 95 , 0x80 ) ; // SREG: I-------
261+ timer . tick ( ) ;
257262 cpu . cycles = 1 ;
258263 timer . tick ( ) ;
259264 const tcnt = cpu . readData ( TCNT0 ) ;
@@ -311,9 +316,27 @@ describe('timer', () => {
311316 expect ( cpu . data [ R1 ] ) . toEqual ( 2 ) ;
312317 } ) ;
313318
319+ it ( 'should not start counting before the prescaler is first set (issue #41)' , ( ) => {
320+ const { program, instructionCount } = asmProgram ( `
321+ NOP
322+ NOP
323+ NOP
324+ NOP
325+ LDI r16, 0x1 ; TCCR2B = 1 << CS20;
326+ STS 0xb1, r16 ; Should start counting after this line
327+ NOP
328+ LDS r17, 0xb2 ; TCNT should equal 2 at this point
329+ ` ) ;
330+ const cpu = new CPU ( program ) ;
331+ const timer = new AVRTimer ( cpu , timer2Config ) ;
332+ const runner = new TestProgramRunner ( cpu , timer ) ;
333+ runner . runInstructions ( instructionCount ) ;
334+ expect ( cpu . readData ( R17 ) ) . toEqual ( 2 ) ;
335+ } ) ;
336+
314337 describe ( 'Phase-correct PWM mode' , ( ) => {
315338 it ( 'should count up to TOP, down to 0, and then set TOV flag' , ( ) => {
316- const { program, lines , instructionCount } = asmProgram ( `
339+ const { program, instructionCount } = asmProgram ( `
317340 ; Set waveform generation mode (WGM) to PWM, Phase Correct, top OCR0A
318341 LDI r16, 0x1 ; TCCR0A = 1 << WGM00;
319342 OUT 0x24, r16
@@ -323,36 +346,26 @@ describe('timer', () => {
323346 OUT 0x27, r16
324347 LDI r16, 0x2 ; TCNT0 = 0x2;
325348 OUT 0x26, r16
326-
327- NOP ; TCNT0 will be 3
328- NOP ; TCNT0 will be 2
329- NOP ; TCNT0 will be 1
330- NOP ; TCNT0 will be 0
331- NOP ; TCNT0 will be 1 (end of test)
349+
350+ IN r17, 0x26 ; TCNT0 will be 2
351+ IN r18, 0x26 ; TCNT0 will be 3
352+ IN r19, 0x26 ; TCNT0 will be 2
353+ IN r20, 0x26 ; TCNT0 will be 1
354+ IN r21, 0x26 ; TCNT0 will be 0
355+ IN r22, 0x26 ; TCNT0 will be 1 (end of test)
332356 ` ) ;
333- const nopCount = lines . filter ( ( line ) => line . bytes == nopOpCode ) . length ;
334357 const cpu = new CPU ( program ) ;
335358 const timer = new AVRTimer ( cpu , timer0Config ) ;
336359 const runner = new TestProgramRunner ( cpu , timer ) ;
337- runner . runInstructions ( instructionCount - nopCount ) ;
338- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 2 ) ;
339-
340- runner . runInstructions ( 1 ) ;
341- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 3 ) ;
342-
343- runner . runInstructions ( 1 ) ;
344- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 2 ) ;
345-
346- runner . runInstructions ( 1 ) ;
347- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 1 ) ;
348- expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( 0 ) ;
349-
350- runner . runInstructions ( 1 ) ;
351- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0 ) ;
360+ runner . runInstructions ( instructionCount ) ;
361+
362+ expect ( cpu . readData ( R17 ) ) . toEqual ( 2 ) ;
363+ expect ( cpu . readData ( R18 ) ) . toEqual ( 3 ) ;
364+ expect ( cpu . readData ( R19 ) ) . toEqual ( 2 ) ;
365+ expect ( cpu . readData ( R20 ) ) . toEqual ( 1 ) ;
366+ expect ( cpu . readData ( R21 ) ) . toEqual ( 0 ) ;
367+ expect ( cpu . readData ( R22 ) ) . toEqual ( 1 ) ;
352368 expect ( cpu . data [ TIFR0 ] & TOV0 ) . toEqual ( TOV0 ) ;
353-
354- runner . runInstructions ( 1 ) ;
355- expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 1 ) ;
356369 } ) ;
357370
358371 it ( 'should clear OC0A when TCNT0=OCR0A and counting up' , ( ) => {
@@ -408,12 +421,12 @@ describe('timer', () => {
408421 const timer = new AVRTimer ( cpu , timer1Config ) ;
409422 cpu . writeData ( TCNT1H , 0x22 ) ; // TCNT1 <- 0x2233
410423 cpu . writeData ( TCNT1 , 0x33 ) ; // ...
411- timer . tick ( ) ;
412424 const timerLow = cpu . readData ( TCNT1 ) ;
413425 const timerHigh = cpu . readData ( TCNT1H ) ;
414426 expect ( ( timerHigh << 8 ) | timerLow ) . toEqual ( 0x2233 ) ;
415427 cpu . writeData ( TCCR1A , 0x0 ) ; // WGM: Normal
416428 cpu . writeData ( TCCR1B , CS10 ) ; // Set prescaler to 1
429+ timer . tick ( ) ;
417430 cpu . cycles = 1 ;
418431 timer . tick ( ) ;
419432 cpu . readData ( TCNT1 ) ;
@@ -425,11 +438,11 @@ describe('timer', () => {
425438 const timer = new AVRTimer ( cpu , timer1Config ) ;
426439 cpu . writeData ( TCNT1H , 0x10 ) ; // TCNT1 <- 0x10ee
427440 cpu . writeData ( TCNT1 , 0xee ) ; // ...
428- timer . tick ( ) ;
429441 cpu . writeData ( OCR1AH , 0x10 ) ; // OCR1 <- 0x10ef
430442 cpu . writeData ( OCR1A , 0xef ) ; // ...
431443 cpu . writeData ( TCCR1A , 0x0 ) ; // WGM: Normal
432444 cpu . writeData ( TCCR1B , CS10 ) ; // Set prescaler to 1
445+ timer . tick ( ) ;
433446 cpu . cycles = 1 ;
434447 timer . tick ( ) ;
435448 expect ( cpu . data [ TIFR1 ] ) . toEqual ( OCF1A ) ; // TIFR1 should have OCF1A bit on
@@ -442,11 +455,11 @@ describe('timer', () => {
442455 const timer = new AVRTimer ( cpu , timer1Config ) ;
443456 cpu . writeData ( TCNT1H , 0x3 ) ; // TCNT1 <- 0x3ff
444457 cpu . writeData ( TCNT1 , 0xff ) ; // ...
445- timer . tick ( ) ;
446458 cpu . writeData ( TCCR1A , 0x3 ) ; // TCCR1A <- WGM10 | WGM11 (Fast PWM, 10-bit)
447459 cpu . writeData ( TCCR1B , 0x9 ) ; // TCCR1B <- WGM12 | CS10
448460 cpu . data [ 0x6f ] = 0x1 ; // TIMSK1: TOIE1
449461 cpu . data [ SREG ] = 0x80 ; // SREG: I-------
462+ timer . tick ( ) ;
450463 cpu . cycles = 1 ;
451464 timer . tick ( ) ;
452465 cpu . readData ( TCNT1 ) ; // Refresh TCNT1
@@ -461,10 +474,10 @@ describe('timer', () => {
461474 const timer = new AVRTimer ( cpu , timer1Config ) ;
462475 cpu . writeData ( TCNT1H , 0x50 ) ; // TCNT1 <- 0x500f
463476 cpu . writeData ( TCNT1 , 0x0f ) ; // ...
464- timer . tick ( ) ;
465477 cpu . writeData ( ICR1H , 0x50 ) ; // ICR1 <- 0x5010
466478 cpu . writeData ( ICR1 , 0x10 ) ; // ...
467479 cpu . writeData ( TCCR1B , WGM13 | WGM12 | CS10 ) ; // Set prescaler to 1, WGM: CTC
480+ timer . tick ( ) ;
468481 cpu . cycles = 2 ; // 2 cycles should increment timer twice, beyond ICR1
469482 timer . tick ( ) ;
470483 cpu . readData ( TCNT1 ) ; // Refresh TCNT1
0 commit comments