@@ -541,6 +541,37 @@ describe('timer', () => {
541541 expect ( gpioCallback ) . toHaveBeenCalledWith ( 6 , PinOverrideMode . Set , 0x2b ) ;
542542 } ) ;
543543
544+ it ( 'should not miss Compare Match when executing multi-cycle instruction (issue #79)' , ( ) => {
545+ const { program, instructionCount } = asmProgram ( `
546+ LDI r16, 0x10 ; OCR0A = 0x10; // <- TOP value
547+ OUT 0x27, r16
548+ ; Set waveform generation mode (WGM) to normal, enable OC0A (Set on match)
549+ LDI r16, 0xc0 ; TCCR0A = (1 << COM0A1) | (1 << COM0A0);
550+ OUT 0x24, r16
551+ LDI r16, 0x1 ; TCCR0B = (1 << CS00);
552+ OUT 0x25, r16
553+ LDI r16, 0xf ; TCNT0 = 0xf;
554+ OUT 0x26, r16
555+ RJMP 1 ; TCNT0 will be 0x11 (RJMP takes 2 cycles)
556+ ` ) ;
557+
558+ const cpu = new CPU ( program ) ;
559+ new AVRTimer ( cpu , timer0Config ) ;
560+
561+ // Listen to Port D's internal callback
562+ const gpioCallback = jest . fn ( ) ;
563+ cpu . gpioTimerHooks [ PORTD ] = gpioCallback ;
564+
565+ const runner = new TestProgramRunner ( cpu ) ;
566+ runner . runInstructions ( instructionCount ) ;
567+
568+ expect ( cpu . readData ( TCNT0 ) ) . toEqual ( 0x11 ) ;
569+ expect ( gpioCallback ) . toHaveBeenCalledWith ( 6 , PinOverrideMode . Enable , 0x2b ) ;
570+
571+ // Verify that Compare Match has occured and set the OC0A pin (PD6 on ATmega328p)
572+ expect ( gpioCallback ) . toHaveBeenCalledWith ( 6 , PinOverrideMode . Set , 0x2b ) ;
573+ } ) ;
574+
544575 it ( 'should only update OCR0A when TCNT0=TOP in PWM Phase Correct mode (issue #76)' , ( ) => {
545576 const { program, instructionCount } = asmProgram ( `
546577 LDI r16, 0x4 ; OCR0A = 0x4;
0 commit comments