Skip to content

Commit ad45d47

Browse files
authored
Merge pull request #521 from gatk555/ioport_fix_merge
An alternative to PR #515 ...
2 parents f642e8f + 557cac2 commit ad45d47

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

simavr/sim/avr_ioport.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,34 @@ avr_ioport_irq_notify(
158158
uint8_t mask = irq->irq == IOPORT_IRQ_PIN_ALL_IN ?
159159
0xff : (1 << irq->irq);
160160
uint8_t ddr = avr->data[p->r_ddr];
161+
uint8_t new_pin;
161162

162163
value &= 0xff;
163164
value = (irq->irq == IOPORT_IRQ_PIN_ALL_IN) ?
164165
value : (!!value << irq->irq);
166+
new_pin = (avr->data[p->r_pin] & ~mask) | (value ? mask : 0);
165167
if (output) {
166-
if ((mask & ddr) == 0)
167-
return; // TODO: stop further processing of IRQ.
168+
uint8_t new_out;
169+
170+
new_out = (avr->data[p->r_port] & ~mask) | (value ? mask : 0);
171+
if (mask & ddr) {
172+
// If the IRQ was marked as Output, do the IO write.
173+
174+
avr_ioport_write(avr, p->r_port, new_out, p);
175+
avr_core_watch_write(avr, p->r_pin, new_pin);
176+
} else {
177+
/* Set the PORT register so the output will be visible
178+
* when the corresponding DDR bit is set.
179+
* Real hardware does not do this.
180+
*/
168181

169-
// If the IRQ was marked as Output, also do the IO write.
170-
avr_ioport_write(avr,
171-
p->r_port,
172-
(avr->data[p->r_port] & ~mask) | value,
173-
p);
182+
avr->data[p->r_port] = new_out;
183+
return; // TODO: stop further processing of IRQ.
184+
}
174185
} else {
175186
// Set the real PIN bit. Ignore DDR as it's masked when read.
176-
avr_core_watch_write(avr, p->r_pin,
177-
(avr->data[p->r_pin] & ~mask) | value);
187+
188+
avr_core_watch_write(avr, p->r_pin, new_pin);
178189

179190
/* BUG: If DDR bit is set here, there should be no
180191
* interrupt. But a spurious IRQ call by the user

0 commit comments

Comments
 (0)