Как работят прекъсванията на Intel 8080? Търсих в Google и в официалната документация на Intel (197X) и намерих само малко описание за това. Имам нужда от подробно обяснение за това, за да емулирам този процесор.
Как работят прекъсванията на Intel 8080?
Отговори (5)
8080 има линия за прекъсване (щифт 14). Всички периферни устройства са свързани към този щифт, обикновено в конфигурация "wire-OR" (което означава, че изходите за заявка за прекъсване са с отворен колектор и щифтът за прекъсване се изтегля високо с резистор). Вътрешно процесорът има бит за разрешаване на прекъсване. Две инструкции, EI и DI, задават и изчистват този бит. По този начин цялата система за прекъсване се включва или изключва, отделните прекъсвания не могат да бъдат маскирани на "голия" 8080. Когато дадено устройство издаде прекъсване, процесорът отговаря със сигнал "Потвърждение за прекъсване" (~INTA). Този сигнал има същото време като сигнала "Четене на паметта" (~MEMR) и е предназначен да задейства периферното устройство да постави инструкция "Рестартиране" на шината за данни. Сигналът за потвърждение на прекъсване е основно цикъл за извличане на инструкции, той се появява само в отговор на прекъсване.
Има осем инструкции за рестартиране, RST 0 - RST 7. RST 7 е код за операция "0xFF". Инструкциите за рестартиране карат процесора да натисне програмния брояч в стека и да започне изпълнението от местоположение на вектор за рестартиране. RST 0 вектори до 0x0000, RST 1 вектори до 0x0008, RST 2 вектори до 0x0010 и т.н. Рестартирайте 7 вектора до 0x0038. Тези векторни адреси са предназначени да съдържат изпълним код, обикновено инструкция за прескачане към рутинна услуга за прекъсване. Рутинната услуга за прекъсване ще подреди всички регистри, които използва, ще изпълни необходимите входно-изходни функции, ще деподреди всички регистри и ще се върне към основната програма чрез същата инструкция за връщане, която завършва подпрограмите (RET, код на операция 0xC9).
Инструкциите за рестартиране са действителни операционни кодове, което означава, че ще направят същото, ако бъдат извлечени от паметта по време на изпълнение на програмата. Беше удобно да се използва Restart 7 като "топло рестартиране" за монитор на клавиатурата/програма за отстраняване на грешки, тъй като ранните EPROM обикновено съдържаха 0xFF във всяко празно място. Ако изпълнявате празен EPROM, това означава, че нещо се е объркало и вероятно искате да се върнете към монитора така или иначе.
Обърнете внимание, че RST 0 векторира към същото място в паметта като RESET, като и двете започват да се изпълняват при 0x0000. Но RST 0 оставя адрес за връщане в стека. В известен смисъл RESET може да се разглежда като единственото немаскируемо прекъсване, което 8080 имаше.
Сигналът за прекъсване също ще изчисти бита за прекъсване, така че рутинната услуга за прекъсване ще трябва да изпълни EI инструкция, обикновено непосредствено преди RET. В противен случай системата ще реагира на едно и само едно прекъсване.
CP/M запази първите 256 байта памет за системна употреба -- и тази векторна карта на прекъсванията използва първите 64 байта (8 байта на инструкция за рестартиране). В CP/M системите RAM започва от 0x0000 и всеки ROM живее в горния край на паметта. Тези системи са използвали някаква форма на интелигентно превключване на банки, за да превключат EPROM или нещо подобно веднага след RESET, за да предоставят инструкция за JUMP към системния ROM, за да може да започне последователността на зареждане. Системи, които имат ROM в долния край на картата на паметта, програмираха инструкции за JUMP към вектори, разположени в RAM в първите 64 байта. Тези системи трябваше да инициализират тези RAM вектори при стартиране.
8080 беше зависим от външен хардуер, за да контролира обработката на прекъсвания, така че е невъзможно да се обобщи. Потърсете информация за контролерите за прекъсване Intel 8214 или 8259.
Най-накрая го намирам!
Създавам променлива, наречена bus, където отива кодът за прекъсване. След това извиках функция за обработка на прекъсването:
void i8080::interruption()
{
// only for RST
cycles -= cycles_table[bus];
instruction[bus]();
INT = false;
}
INT е вярно, когато има нужда от прекъсване. Инструкциите EI и DI обработват INTE.
Когато INT и INTE е true, се изпълнява прекъсване.
Функционалните указатели към манипулаторите на прекъсвания се съхраняват в ниската памет. Около 32 или повече от първите адреси са хардуерни прекъсвания: хардуерно задействани.
Следващите около 32 адреса се задействат от потребителя, те се наричат софтуерни прекъсвания. Те се задействат от INT
инструкция.
Параметърът за INT е номерът на вектор на софтуерното прекъсване, който ще бъде извиканото прекъсване.
Ще трябва да използвате инструкцията IRET
, за да се върнете от прекъсвания.
Вероятно трябва също така да забраните прекъсванията като първото нещо, което правите, когато въвеждате прекъсване.
За повече подробности трябва да се обърнете към документацията за вашия конкретен модел процесор, тя има тенденция да варира значително.
Прекъсването е начин за прекъсване на процесора с известие за обработка на нещо друго, не съм сигурен за чипа Intel 8080, но от моя опит най-добрият начин да се опише прекъсване е следният:
CS:IP
(Кодов сегмент: Указател на инструкция) е в тази инструкция на адрес на паметта 0x0000:0020, като пример за обяснение с помощта на инструкциите на Intel 8086, асемблерът е безсмислен и няма истинско значение... инструкциите са въображение
0x0000:001C MOV AH, 07 0x0000:001D CMP AH, 0 0x0000:001E JNZ 0x0020 0x0000:001F MOV BX, 20 0x0000:0020 MOV CH, 10 ; CS:IP is pointing here 0x0000:0021 INT 0x15
Когато CS:IP сочи към следващия ред и се издаде INT
errupt 15 шестнадесетичен, това се случва, процесорът избутва регистрите и флаговете в стека и след това изпълнява код на 0x1000:0100, който обслужва INT 15 като пример
0x1000:0100 PUSH AX 0x1000:0101 PUSH BX 0x1000:0102 PUSH CX 0x1000:0103 PUSH DX 0x1000:0104 PUSHF 0x1000:0105 MOV ES, CS 0x1000:0106 INC AX 0x1000:0107 .... 0x1000:014B IRET
След това, когато CS:IP достигне инструкцията 0x1000:014B, се издава IRET
(Interrupt RETurn), което изскача от ВСИЧКИ регистри и възстановява състоянието, и когато се изпълни, CS:IP на процесора сочи обратно тук, след инструкция на 0x0000:0021.
0x0000:0022 CMP AX, 0 0x0000:0023 ....
Как процесорът знае къде да премине към определено отместване се основава на таблицата на вектора на прекъсване, тази таблица на вектора на прекъсване се задава от BIOS на определено място в BIOS, ще изглежда така:
INT BIOS's LOCATION OF INSTRUCTION POINTER --- -------------------------------------- 0 0x3000 1 0x2000 .. .... 15 0x1000 <--- THIS IS HOW THE CPU KNOWS WHERE TO JUMP TO
Тази таблица се съхранява в BIOS и когато INT
15 се изпълни, BIOS ще пренасочи CS:IP към местоположението в BIOS, за да изпълни сервизния код, който обработва прекъсването.
Назад в старите времена, под Turbo C, имаше средство за замяна на рутинните процедури на векторната таблица на прекъсванията с вашите собствени функции за обработка на прекъсвания, използвайки функциите setvect
и getvect
, в които действителните манипулатори на прекъсвания бяха пренасочени към вашия собствен код.
Надявам се, че го обясних достатъчно добре, добре, това не е Intel 8080, но това е моето разбиране и бих бил сигурен, че концепцията е същата за този чип, тъй като фамилията чипове Intel x86 идва от него.