11import { CPU } from '../cpu/cpu' ;
2+ import { asmProgram , TestProgramRunner } from '../utils/test-utils' ;
23import { AVRIOPort , portBConfig , PinState , portDConfig , PinOverrideMode } from './gpio' ;
34
45// CPU registers
@@ -8,6 +9,9 @@ const SREG = 95;
89const PINB = 0x23 ;
910const DDRB = 0x24 ;
1011const PORTB = 0x25 ;
12+ const PIND = 0x29 ;
13+ const DDRD = 0x2a ;
14+ const PORTD = 0x2b ;
1115const EIFR = 0x3c ;
1216const EIMSK = 0x3d ;
1317const PCICR = 0x68 ;
@@ -76,6 +80,42 @@ describe('GPIO', () => {
7680 expect ( cpu . data [ PINB ] ) . toEqual ( 0x4 ) ; // PINB should return port value
7781 } ) ;
7882
83+ it ( 'should only affect one pin when writing to PIN using SBI (issue #103)' , ( ) => {
84+ const { program } = asmProgram ( `
85+ ; register addresses
86+ _REPLACE DDRD, ${ DDRD - 0x20 }
87+ _REPLACE PIND, ${ PIND - 0x20 }
88+ _REPLACE PORTD, ${ PORTD - 0x20 }
89+
90+ ; Setup
91+ ldi r24, 0x48
92+ out DDRD, r24
93+ out PORTD, r24
94+
95+ ; Now toggle pin 6 with SBI
96+ sbi PIND, 6
97+
98+ break
99+ ` ) ;
100+ const cpu = new CPU ( program ) ;
101+ const portD = new AVRIOPort ( cpu , portDConfig ) ;
102+ const runner = new TestProgramRunner ( cpu ) ;
103+
104+ const listener = jest . fn ( ) ;
105+ portD . addListener ( listener ) ;
106+
107+ // Setup: pins 6, 3 are output, set to HIGH
108+ runner . runInstructions ( 3 ) ;
109+ expect ( listener ) . toHaveBeenCalledWith ( 0x48 , 0x0 ) ;
110+ expect ( cpu . data [ PORTD ] ) . toEqual ( 0x48 ) ;
111+ listener . mockReset ( ) ;
112+
113+ // Now we toggle pin 6
114+ runner . runInstructions ( 1 ) ;
115+ expect ( listener ) . toHaveBeenCalledWith ( 0x08 , 0x48 ) ;
116+ expect ( cpu . data [ PORTD ] ) . toEqual ( 0x8 ) ;
117+ } ) ;
118+
79119 it ( 'should update the PIN register on output compare (OCR) match (issue #102)' , ( ) => {
80120 const cpu = new CPU ( new Uint16Array ( 1024 ) ) ;
81121 const port = new AVRIOPort ( cpu , portBConfig ) ;
0 commit comments