Ahoj, pokracuji ve zkoumani obvodu. Nyni se metodou hazeni bomb do rybnika snazim zjistit co nastane, kdyz se deji veci, ktere se bezne nepredpokladaji. Napr. kdyz procesor v IM2 dostane interrupt, nicmene PIO v danou chvili zadny cekajici interrupt v zasobe nema, nebo jej sice ma, ale je zrovna potlacen. BTW k potlaceni interruptu muze zrejme dojit alespon dvema zpusoby: 1) klasicky nastavenim disable interrupt (0x03) - tohle ovsem neni ani tak zakazani interruptu, ale spise jeho zneviditelneni. Pokud se v dobe, kdy je nastaveno "disable" odehraje nejaka udalost, ktera je schopna vyvolat interrupt, tak jej PIO ve sve interni logice normalne zpracuje a port prejde do specialniho stavu "interrupt pending" ze ktereho uz jej nedostane nic jineho, nez to, ze dojde ke zviditelneni cekajiciho interruptu (0x83) a pak musi nasledovat jeho prevzeti procesorem, ktery to na sbernici oznami aktivaci signalu /M1 + /IORQ. Dalsi moznosti jak se v PIO zbavit cekajiciho interruptu je 4. bit v ICRW viz bod 2, nebo HW reset procesoru, ktery si PIO umi identifikovat. 2) zapsanim Interrupt Control Word ( xxxx 0111 ) ve kterem je 4. bit nastaven "1" - tim dojde k okamzitemu smazani pripadneho cekajiciho interruptu. Nasledne se ceka na zapis masky, dokud ji nezapiseme, tak se PIO ke vsem udalostem chova jako mrtvy brouk a interrupt nikdy nezaeviduje. Ve chvili kdy zapiseme masku (treba i stejnou jaka byla predtim), tak se provede inicializace stavu - nazveme to treba interrupt state scan. Tento scan se provadi rovnez pri inicializaci MODE3 ve chvili, kdy vlozime bajt s I/O maskou a take ve chvili, kdy CPU prevezme interrupt, uz neni aktivni /INT, ale je aktivni /IEO, tzn., ze CPU prave zacalo vykonavat rutinu interruptu a jeste se na sbernici neobjevilo RETI. Zadnym jinym zpusobem se jiz cekajiciho interruptu nezbavite. Nepomuze ani zmena stavu na sledovanych bitech/pinech. Ani zmena mode. Ani zmena interrupt function, ci urovne LOW/HIGH. Dalsi zajimavost: pokud je interrupt function "OR" a maska je nastavena sledovani stavu vice nez jednoho bitu/pinu, tak PIO musi vzdy na vsech techto pinech nejprve zaregistrovat uplny klidovy stav. Do te doby, nez k nemu dojde, tak zadna zmenova udalost na pinech nevyvola interrupt. Napr.: 1) nastavime ICRW: IENABLE, OR, HIGH, MASK => 10110111 => 0xb7 2) ocekava se maska - nastavme citlivost na dolni 4 bity: 0xf0 Dejme tomu, ze ve chvili, kdy byla vlozena maska, tak na stupnich pinech nebylo nic "0000" - klidovy stav. 1) Dojde k nejake zmene "0001" a ta vyvola interrupt - PIO je ve stavu interrupt pending a zadne dalsi zmeny na pinech jej nezajimaji. 2) CPU prevezme interrupt - provede se scan stavu "0001" 3) V dobe kdy jeste neprislo RETI nastane dalsi zmena "0000" a za ni bude nasledovat treba "0010" - PIO prejde do stavu, ktery je podobny tomu "interrupt pending" s potlacenym int. 4) Ve chvili, kdy prijde RETI, tak PIO prejde do viditelneho "interrupt pending"... pomerne castou praktikou je zakoncovat rutinu sequenci EI, RETI a tak vlastne okamzite po RETI nasleduje opetovny skok na zacatek prerusovaci rutiny - pokud se to opakuje, tak se vlastne vubec nevykonava program, ale jen interrupti rutina (par takto fungujicich programu jsem na Sharpu videl) Ovsem muze byt i takovyto vyvoj: 1) Dojde k nejake zmene z "0000" na "0001" a ta vyvola interrupt, ktery je procesorem prijat 2) V dobe kdy jeste neprislo RETI nastane dalsi zmena "0011" a treba "1010" 3) Ve chvili, kdy prijde RETI, tak PIO prejde do rezimu, kdy stale ceka na klidovy stav a urovne na sledovanych pinech mohou divocit jak chteji, dokud nenastane "0000", tak tohle radeni zadny dalsi interrupt nevyvola Jak uz jsem na zacatku psal, tak se nyni snazim vyzkoumat neco ohledne zpracovani IM2 callbacku, ktery nema z pohledu PIO opodstatneni. V priloze je testovaci zdrojak, kterym si nejprve nastavim CTC, i8255 a PIOZ80. Nasledne jsem schopen zavolat interrupt iniciovany od CTC2, nebo kteroukoliv z bran A/B v PIOZ80. Pokud je procesor v IM2 a vygeneruju interrupt z CTC2, tak se na sbernici ocekava LSB cast interrupt vektoru na kterem je ulozena adresa prerusovaci rutiny. Pole s vektory jsem si ulozil od adresy 0x3000. Jeho rozptyl jde od 0x00 - 0x100. Kdyz mam popsano cele pole vektoru hodnotou 0x00, tak musi IM2 interrupt vykonat vzdy CALL 0x0000. Na teto adrese mam kod pro nastaveni modreho borderu a zastaveni programu. Postupnym repisovanim obsahu v poli vektoru jsem zjistil, ze takto ziskany LSB je sice nejake hausnumero, NICMENE jak se zda, tak pro danou konfiguraci je toto ziskane cislo vzdy konstantni, coz mi prijde zajimave. V kodu, ktery je v priloze je to hodnota 0x20, coz zpusobi, ze propgram konci s cervenym borderem. Prozatim jeste nevim jaky hazard tuto magickou hodnotu zpusobuje - vzpomente treba na magickou hodnotu posledniho bajtu, kterou prectete z datovky, kdyz se pokusite cist z nepripojeneho portu. Cislo v ziskane LSB se zmeni, kdyz realokuju cely program, ci zmenim nastaveni PIO. Parkrat se mi stalo, ze jsem obdrzel hodnotu, ktera odpovidala vectoru z brany A - mohlo se jednat i o nahodu, nicmene ted mne napada, ze tohle budu umet lehce proverit. Pri experimentovani s polem vektoru a s takto nahodne ziskanym LSB se muze stat samozrejme i to, ze se strefi jen jeden bajt z vektoru, program se nekam vykoleji, nicmene nejakym zazrakem se dostane k rutine se zmenou barvy borderu. K odhaleni takoveho stavu mam na zacatku programu cca 10s wait s cernymi pruhy v borderu. V tech 10s si zapnu analyzer, ktery mi pak ukaze co se delo, kdyz prisel interrupt. Pokud se vykonalo jen par instukci a pak prislo /IORQ (border: 0x06cf) a HALT, ktery je lehce identifikovatelny, tak sel program spravnou cestou. Pokud vsak vidim, ze po prijeti INT se na sbernici vykonavalo more ruznych instrukci, tak to znamena, ze se vektor strefil jen do jednoho bajtu a program se vykolejil. Pokud se vam bude chtit, tak vyzkousejte na Sharpu prilozeny MZF, pripadne si s pasmo nakompilujte vlastni. Pokud vam program skonci s cervernym borderem, tak je pravdepodobne, ze se u vas choval stejne jako u mne (pripadne ze se jen sikovnym zpusobem vykolejil :) Michal