Dat is ongeveer het idee waar ik op doelde. Maar het zijn geen 4 instructies. Zo even uit mijn hoofd 'kost' een interrupt 2 cycles. Zo uit mijn hoofd is er een 'pin change' interrupt. Echter, dat is (wederom uit mijn hoofd) 1 interrupt voor alle pins waarbij je het 'aan' hebt staan. Of soms 2 of 3 (een beetje afhankelijk van de versie van de AVR). Dat betekent dat je je flags moet stacken (1 cycle), je werkregister moet stacken (1 cycle), op moet halen welke lijn de interrupt veroorzaakt (1 cycle), dat moet comparen (1 cycle) en dan wellicht jumpen (1 cycle).
Dan kun je de output setten (dat is voorbereid, maar moet je wel uit RAM halen), dat zijn zomaar 2 tot 4 cycles. Dan 2x wat van stack halen (2 cycles) en een return (2 cycles). Dat is zomaar een cycle of 15. Daarnaast komt die interrupt uiteraard op een moment dat je net een clock tick gehad hebt en een dual-cycle instructie loopt, dus dat worden er 17. Je kunt immers alleen maar interrupten tussen instructies. En dan zou het zomaar kunnen dat ik er nog eentje vergeten ben.
Welnu, op 20MHz ben je dan dus zomaar vrijwel 1μS onder water. Dus zelfs als die ALU op de ene clock tick de boel set en op de volgende uitleest, houdt het niet over. Als het ding op de rising edge address set en op de falling edge leest, dan ben je botweg te laat. Zelfs als je de tijd voor een 'unwrap' van je routine eraf haalt, is het erg tricky.
Je zou in je AVR nog wat met polling kunnen doen: kijken continu kijken naar het address (get, compare, jump-if-not-what-we-need, set output, jump to get). Dan ben je sneller. Dan moet je alleen wel ff nadenken hoe je de waarde die je wilt outputten gaat setten. Dat zou je nog met iets interrupt-drivens kunnen doen (en in de loop de interrupts uit zetten). Maar daar moet je goed over nadenken: mis je een scan, dan is er niks aan de hand. Maar als je halverwege een scan uit de ISR komt, dan zou je wel weer eens te laat kunnen zijn.
Ook dat is wel weer oplosbaar, maar het begint zo zachtjes aan wel op hogere wiskunde en diepere kennis van een controller te lijken.
Je zou een soort van moeten gaan tellen of je alle 8 lijntjes gehad hebt en dan heb je waarschijnlijk wel ff lucht voor wat anders. Maar daarvoor zou je moeten weten hoe die scanning in elkaar zit (een scope of LA vertelt je dat direct).
Het probleem is niet zo zeer dat je zoveel naar buiten moet brullen, maar meer dat je erg snel moet reageren als 'jouw' trigger voorbij komt. Met software naar hardware luisteren is doorgaans een verloren wedstrijd op deze manier. Het gaat misschien (net) goed omdat die 'oud' (en dus relatief traag) is.
Dat was voor mij de reden om te zeggen: frut het in een EPROM (mag ook parellel flash of EEPROM zijn). Simpel. Goedkoop. Beetje glue-logic. Alleen de inhoud maken vereist ff een klein beetje software om op basis van het address te berekenen wat de ULA moet 'zien'. Maar dat is geen rocket science.
Nog een andere insteek: een stel serieel-parallel shift registers. Je schuift vanuit een Arduino ofzo de waarde erin. Dan doe je een LATCH. De outputEnable hang je aan een address lijn, de outputs aan de ULA. Je hebt er wel 8 nodig (waar je dan helaas slechts 5 bits van gebruikt...). En wellicht een beetje glue-logic omdat er wellicht iets geïnverteerd moet worden.