|
Lib: I/O
|
||||||||
|
||||||||
Deze Library is het binnenste schilletje om de I/O (= Input/Output) heen. Het zorgt ervoor dat het ArSid-programma rechtstreeks data kan schrijven in EN kan uitlezen uit de registers van de Latches-print. EN de Sids. Dit houdt in dat het een Adres op de Adresbus zet, de Control-signalen regelt en vervolgens de Data schrijft naar OF inlees van de Databus. De Decoder-print decodeert dan de Adres-bus naar signalen naar de juiste registers, c.q. Sid-IC. De Latches-print regelt de Data naar de registers voor het aansturen van de Lcd-display en de (kleuren-)Leds op het bovenpaneel. De I/O-Library doet dit met behulp van 4 functies, waarvan er twee hele bekende Basic namen hebben, namelijk POKE() en PEEK().
De Mega Pinnen.Allereerst een herhaling van welke I/O-pinnen van de Arduino Mega voor welke functies op de drie bussen zijn.
De Reset-puls.Reset(): De enige taak van deze functie is het geven van een puls op de Reset-lijn van de Control-bus. Deze puls is in alle 65xx-systemen nodig en zorgt ervoor dat alle (aangesloten) IC's hardware-matig gereset worden. Dit is inclusief de processor zelf. In een echt 65xx-systeem wordt de Reset-puls hardware matig opgewekt met meestal een RC-netwerk als basis. In de ArSid moet deze puls echter software-matig worden opgewekt. In de ArSid zit de Reset-lijn op PortD van de Arduino-Mega en wel (bij het begin ontwerpen) op bit 7. Er is een variabele RESET_MASK dit deze bit bevat. Software-matig wordt de Reset-lijn eerst als OUTPUT gedefini-eerd en wordt deze (weer) HOOG gemaakt (in het geval deze LAAG was), daarna LAAG en vervolgens weer HOOG gemaakt (en HOOG gehouden).
De Adres-bus klaarzetten.Set_Address_Out(): Deze functie defini-eert eerst ALLE adres-bus pinnen als uitgang. Dit betreft twee Arduino poorten, namelijk alle bits van PortC en PortL. De adres-bus is in het basis-ontwerp van de ArSid 9 bits breed, maar deze functie is voorbereidt op een bus van 15-bits breed. De 16de-bit is gereserveerd voor een adres-lijn met de naam AdresEnable en heeft als functie om aan te geven of een adres wel of niet geldig is. LAAG is geldig, HOOG is niet geldig of te wel Low-Active. Deze Adres-Enable-lijn is terug te vinden op de Latches-print en regelt daar de uiteindelijke activering van de Register-Clocks en de Sid CS-lijnen (van Chip Select). Daarna defini-eert deze functie de lijn Read/~Write als OUTPUT en de lijnen PHI2 en LCD_MASK als INPUT (dit gebeurt in twee losse regels) om als laatste de lijn Read/~Write hoog te maken, ten teke dat de Arduino op LEZEN staat. Op deze manier worden er geen gegevens in de diverse IC's veranderd.
Data schrijven naar een IC.Poke(aa, dd): Een bekende Basic-naam. En deze functie doet precies wat het Basic-commano zelf ook doet. Het schrijft een byte data DD naar een adres AA. Hierbij is Timing cruciaal. Na wat correctie AND-operaties schrijft deze functie eerst het adres AA naar de adres-bus (PortC en PortL). De Read/~Write wordt LAAG gemaakt, ten teke dat er geschreven gaat worden. De aangesloten IC's kunnen zich dan voorbereiden om hun databus INPUT te maken, om conflicten te voorkomen als er meerdere uitgangen op 1 lijn zijn. Pas daarna wordt de Data-bus (Port A) op uitgang gezet en wordt de Data zelf op de Data-bus geplaatst. Er wordt gewacht zolang de bus-clock Φ2 HOOG is. Dit wachten is om twee redenen nodig. De Arduino-Mega draait op een clokc-frequentie van 16MHz, terwijl de 65xx-bussen hier op 1MHz draaien. De Arduino moet dus wachten op de 65xx-bussen. Tevens mag een Read/~Write-signaal alleen worden veranderd, als de Φ2 niet meer HOOG is. Dan pas wordt de Adres-Enable-lijn LAAG gemaakt, ten teke dat de Adres en Data geldig is om over te nemen. Er wordt gewacht tot de Φ2 weer HOOG is en de Read/~Write-lijn wordt WEER op LAAG gezet. Deze tweede keer veroorzaakt echter een kleine tijdsvertraging, die kleiner is dan 1msec (en dus kleiner dan de functie DelayMicroSeconds(1) kan geven). Het blijkt dat deze kleine vertraging net genoeg is. Als laatste worden diverse handelingen weer in omgekeerde volgorde teruggezet. Dat is: de Read/~Write wordt hoog gemaakt (er wordt weer gelezen), de Adres-Enable wordt HOOG gemaakt (ten teke dat de Adressen niet meer geldig (kunnen) zijn) en de Databus worden allemaal weer op INPUT gezet. Alles staat weer op "lezen van de bus". That's It. Vrij recht-toe-recht-aan.
Data lezen van een IC.dd=Peek(aa): Een bekende Basic-naam. En deze functie doet precies wat het Basic-commano zelf ook doet. Het leest een byte data DD van een adres AA. Ook hier is Timing is essentieel. Allereerst wordt de Data-bus op INGANG gezet (tot zover dit nog niet gebeurd was). Na wat correctie AND-operaties schrijft deze functie het adres AA naar de adres-bus (PortC en PortL). De Read/~Write wordt HOOG gemaakt, ten teke dat er gelezen gaat worden. De Adres-Enable-lijn wordt LAAG gemaakt, ten teke dat het adres geldig is. Het betreffende IC kan zich dan voorbereiden om zijn databus OUTPUT te maken. Er mag slechts 1 IC zijn Databus op OUTPUT hebben, dit om conflicten te voorkomen als er meerdere uitgangen op 1 lijn zijn. De Adres-Enable-lijn wordt voor een tweede keer (achter elkaar) LAAG gemaakt, ook hier om een kleine tijdsvertraging te veroorzaken, kleiner dan 1msec (en dus kleiner dan de functie DelayMicroSeconds(1) kan geven). Ook hier blijkt dat deze kleine vertraging net genoeg is. Pas daarna wordt de Data-bus gelezen. Als laatste worden ook hier diverse handelingen weer in omgekeerde volgorde teruggezet. De Adres-Enable-lijn wordt HOOG gemaakt (ten teke dat de Adressen niet meer geldig (kunnen) zijn) en de Databus worden allemaal weer op INPUT gezet en de Read/~Write wordt (nog een keer) hoog gemaakt (er wordt nog steeds gelezen). En de ingelezen Data wordt aan de functie-naam teruggegeven (return dd). That's It. Ook hier is het vrij recht-toe-recht-aan. Er wordt niet gewacht op de Φ2. De status van de Φ2 doet niet ter zake bij het lezen van de register (om de schakelaars uit te lezen) en de Sid-IC's worden niet gelezen.
Interupts ...De hierboven 4 beschreven functies beginnen allemaal met de functie noInterrupts() en eingiden met de functie noInterrupts(). Timing in bovenstaande functies zijn soms zo cruciaal dat zij niet verstoort mogen worden door een Arduino interupt, zoals die opgewekt kunnen worden door de Interupt-Timer of de Seriele-Poort.
Basis-ontwerp functies - overbodige functies.Als laatste staan er nog drie functies onderaan deze Librarie. Zij werden het eerst geschreven met als doel om een beter begrip te krijgen van wat er moet gebeuren bij het schrijven naar het Adres-bus en bij het omschakelen van de Data-bus naar INPUT of OUTPUT. Zij worden hier niet gebruikt en zijn daarom als COMMENTAAR gemerkt.
Noot (jan-2019): Het negeren van de Φ2 bij het lezen (Peek()-functie) zou echter niet meer kunnen bij gebruik van FpgaSids. |
||||||||
|
||||||||
1: De broncode van I/O (.cpp)(Mon 01 January 2018) ArSid_IO.cpp: Het binnenste software schilletje om de I/O heen.
2: De broncode van I/O (.h)(Mon 01 January 2018) ArSid_IO.h: Het binnenste software schilletje om de I/O heen.
|
[Tekst] [Afbeeldingen] [Aansluitingen] [Broncodes] |