Instrucoes de controlo

São seis as instruções que permitem controlar o microprocessador Z80. A instrução NOP tem o código 0000 0000(2) e em nada afecta o processamento da CPU. A instrução HALT suspende a operação da CPU até que um interrupt seja recebido. Tem o código 0111 0110(2) <=> 76 (16). As instruções DI e EI inibem e permitem, respectivamente, a realização de interrupções.

0 microprocessador Z80 tem disponível para o utilizador três modos de interrupção. Se o modo seleccionado for o 0, o dispositivo que gerou o sinal de interrupt tem a possibilidade de inserir no bus de dados o código de uma instrução que é executada pela CPU. 0 modo 1 é um modo simplificado em que a CPU, automaticamente, executa um «RESTART» (RST) para a posição 0038H (RST 56), não sendo necessário qualquer hardware exterior adicional (o antigo valor do PC é colocado na pilha).

As interrupções no modo 2 são as mais importantes e poderosas que fazem parte da CPU Z80. Este modo permite uma chamada indirecta para qualquer posição de memória. Neste modo, a CPU reconhece um endereço de 16 bits em que os oito bits de maior ordem estão armazenados no registo 1 (registo de interrupção, não confundir com os registos de índice) e os oito bits de menor ordem são fornecidos pelo dispositivo gerador da interrupção. Este endereço aponta para dois bytes, colocados sequencialmente numa tabela, onde se situa o endereço da rotina de serviço à interrupção (fig. 31). A CPU obtém automaticamente o endereço de começo da rotina e executa um salto (CALL) para este endereço.

Existe um outro tipo de interrupt (NMI) que não pode ser inibido pelo programador e que, portanto, será sempre aceite pelo microprocessador.

Seguidamente vamos analisar em pormenor os mecanismos de interrupção.

 

Resposta a Interrupções

 A finalidade de um interrupt é permitir que um dispositivo periférico interrompa, de uma forma ordenada, a operação da CPU forçando-a a executar uma rotina de serviço ao periférico. Normalmente esta rotina de serviço envolve a troca de dados, ou informação de controlo, entre a CPU e o periférico. Uma vez completa a rotina de serviço, a CPU retoma a execução do programa principal no ponto onde o processamento foi interrompido pelo pedido de interrupção.

 

1 - Permissão e inibição de interrupts.

 0 microprocessador Z80 possui dois pinos correspondentes a duas entradas de interrupção podendo uma delas ser inibida (mascarada) por programação (software maskable interrupt). Entende-se por máscara o estado de inibição de uma interrupção. 0 interrupt não «mascarável»,

NMI (non maskable interrupt), não pode ser inibido pelo programador, isto é, este interrupt será aceite pela CPU sempre que um periférico o requeira. Geralmente, reserva-se este tipo de interrupção para as funções mais importantes que devem ser executados logo que ocorram.

A interrupção que se pode «rriascarar,, (INT) pode ser, selectivamente, permitida (enabie) ou proibida (disabie) pelo programador. Este facto permite ao utilizador impedir os interrupts, durante os períodos em que o programa está sujeito a limitações de tempo, libertando a CPIJ de possíveis pedidos de interrupção.

0 microprocessador Z80 contém um flip-flop, designado por I FF, que é colocado no estado «1» (set) sempre que sejam possíveis interrupções e no estado «0» (reset) sempre que as interrupções não sejam permitidas. A instrução EI (enable interrupt) coloca a «1 » o flip-flop IFF, enquanto a instrução DI (disable interrupt) posiciona a «0» o mesmo flip-flop. Então, quando IFF está no estado «0» um pedido de interrupção não pode ser aceite pela CPU.

Na verdade, por razões que serão explicadas a seguir, a CPU contém dois flip-flops destinados à permissão (enable) e proibição (disable) das interrupções. Estes flip-flops são designados por IFF1 e IFF2:

 

 A instrução EI coloca ambos os flip-flops no estado de permissão de interrupções. Quando uma interrupção é aceite pela CPU, IFF1 e IFF2 são colocados automaticamente a «0» inibindo outros pedidos de interrupção. Com a execução de uma nova instrução EI o estado dos flip-flops passa da inibição para a permissão. Note-se que até este momento os estados de IM e IFF2 são sempre iguais.

Um reset da CPU força tanto IFF1 como IFF2 a conterem o valor «0» sendo proibidas as interrupções. Para as permitir de novo, o programador pode introduzir, em qualquer momento, uma instrução EI. Quando uma instrução EI é executada, qualquer pedido de interrupção que esteja pendente não será aceite antes de a instrução que se segue a EI também ter sido executada. Este atraso introduzido é necessário para os casos em que a instrução seguinte representa uma operação (RETURN). Neste caso, as interrupções não devem ser aceites sem antes ter sido executada a instrução de retorno. Na figura 30 ilustra-se esta situação, em que um pedido de interrupt é gerado durante a execução de uma sub-rotina.

 

 0 propósito do flip-flop IFF2 é ressalvar o estado de IFF1 quando ocorre um interrupt não «mascarável» (NMI). Quando um interrupt NMI é aceite, o flip-flop IFF1 é colocado no estado «0» para inibir outros pedidos de interrupção que possam surgir. Assim, depois de um interrupt NMI ter sido aceite as interrupções «mascaráveis» são proibidas mas o estado primitivo de IFF1 é salvaguardado (IFF2), pelo que o estado da CPU, anterior à interrupção NMI, pode ser restaurado em qualquer momento.

Quando a instrução LD A, I (ou LD A, R) é executada, o estado do flip-flop IFF2 é copiado para a flag de paridade. Então, o conteúdo da flag pode ser testado e uma opção pode ser tomada quanto à execução de uma instrução EI (executanto-se EI se o valor de P/V for «1»).

Um segundo método para restaurar o estado de IFF1 é através da execução da instrução de retorno de um interrupt NMI (instrução RETN). Uma vez que esta instrução indica que a rotina de serviço a uma interrupção NMI terminou, o conteúdo de IFF2 é copiado para IFF1, restaurando-se automaticamente o estado deste flip-flop com o valor que continha anteriormente à aceitação do interrupt.

Resumindo, o efeito nos dois flip-flops das diferentes instruções é o seguinte:

      

● o indica que não há alteração

 2 - Reposta da CPU

 

a) Interrupções não «mascaráveis» (NMI)

 Uma interrupção não «mascarável», será aceite depois de terminada a operação que está a ser executada pela CPU. Quando ocorre, a CPU ignora a próxima instrução a executar e efectua um restart para a posição 0066H. Tudo se passa como se a CPU executasse uma instrução RST. A diferença reside unicamente no facto de nenhuma das oito posições da instrução RST servir de endereço de salto (o salto é para a posição 66H). Um restart é simplesmente uma chamada (ca11) para uma posição na página 0 da memória (0000 - OFFF). 0 flip-flop 1 inibe as interrupções INT (IFF1 a 0). 0 retorno da sub-rotina de interrupção que serve o NMI é feito com a instrução RETN porque esta instrução repõe o flip-flop 1 no estado em que se encontrava antes da interrupção NMI. Durante a sub-rotina de interrupção NMI não são aceites interrupções INT porque IFF11 =0. 0 flip-flop 2 IFF2 memoriza temporariamente o estado do flip-flop durante a sub-rotina de interrupção NMI.

 

b) Interrupções «mascaráveis» (INT)

 A CPU pode ser programada de três modos diferentes para responder a este tipo de interrupções.

 

Modo 0

 Neste modo o dispositivo gerador do sinal de interrupção tem a possibilidade de colocar o código de qualquer instrução no barramento de dados, para depois a CPU a executar. Assim, é o dispositivo que interrompe o processamento do programa que fornece a próxima instrução a ser executada, em vez de esta ser extraída da memória como normalmente sucede. Frequentemente esta instrução representa um restart (RSI), uma vez que o dispositivo exterior só necessita de fornecer um código formado por um único byte.

 Alternativamente, qualquer outra instrução, tal como um CALL formado por três bytes, pode ser executada, pois a CPU gera os sinais necessários de modo a prolongar o cicio de resposta ao interrupt e obter tempo suficiente para a recepção dos três bytes da instrução.

Depois da aplicação de RESET a CPU fica de imediato no modo 0.

 

Modo 1

 Quando este modo é seleccionado pelo utilizador a CPU responde a um interrupt executando um restart para a posição 0038 H da memória (RST 56). Assim, esta resposta é idêntica à de um interrupt NMI, com a diferença de que a posição para onde salta o processamento é a 38 H em lugar de 66 H.

 

Modo 2

 Como já foi referido anteriormente, o modo 2 é o mais importante e poderoso. Através de oito bits (um byte) fornecidos pelo utilizador, uma chamada indirecta pode ser executada para qualquer posição de memória.

Neste modo o programador constrói uma tabela de endereços, de 16 bits, representando cada um deles o início de uma rotina de serviço. Esta tabela pode estar localizada em qualquer local da memória.

Quando uma interrupção é aceite, é formado um ponteiro de 16 bits que aponta a posição de memória onde se encontra o endereço da sub-rotina de serviço a essa interrupção, isto é, uma posição de tabela de endereços é seleccionada.

Os oito bits mais significativos deste ponteiro são constituídos pelo conteúdo do registo 1. Este registo teve de ser carregado previamente pelo utilizador com o valor desejado, ou seja, a CPU executa anteriormente a instrução LD I, A. De notar que um reset da CPU coloca a zero o conteúdo do registo 1, pelo que este registo é inicializado com zeros.

Os oito bits menos significativos do ponteiro são fornecidos pelo dispositivo que requereu a interrupção. Na verdade, só sete bits são obtidos do dispositivo que gerou o sinal de interrupt, pois o bit menos significativo deve ser sempre «0». Este facto verifica-se porque o ponteiro é utilizado na obtenção de dois bytes adjacentes, de modo a formar-se o endereço de 16 bits do início da rotina de serviço, devendo o primeiro destes bytes situar-se numa posição par (fig. 31).

 0 primeiro byte da tabela representa o byte menos significativo do endereço da sub-rotina. Obviamente o programador deve preencher a tabela com os endereços desejados antes de qualquer interrupção ser aceite.

De notar que esta tabela pode ser modificada em qualquer momento pelo utilizador (desde que se encontre numa zona de memória RAM), permitindo que periféricos diferentes sejam servidos por sub-rotinas diferentes.

Em qualquer dos modos de interrupção apresentados o conteúdo inicial do contador de programa é sempre guardado na pilha, para ser reposto no final da sub-rotina de serviço ao interrupt (instrução de retorno). Convém salientar também que um interrupt gerado durante a execução de uma instrução só será atendido depois de essa instrução ter sido completamente executada.

Na figura 32 está ilustrado o processo de execução de um pedido de interrupção no modo 2. A tabela de endereços de sub-rotinas de serviço começa na posição OAOO H. 0 endereço da sub-rotina que o periférico pretende que a CPU execute encontra-se nas posições 0A10 H e 0A11 H. Então, o registo 1 deve conter o valor OA H e o dispositivo gerador da interrupção deve colocar no barramento de dados o vector 10 H (vector interrupt). Deste modo, é obtido o endereço 1800 H para início da sub-rotina de serviço.

 

0 microprocessador Z80 permite a execução de vários níveis de interrupts (fig. 33), isto é, durante a execução de uma sub-rotina de serviço a uma interrupção podem surgir e ser aceites outros pedidos de interrupção desde que seja executada a instrução EI dentro destas sub-rotinas. Cada uma destas sub-rotinas termina por uma instrução de retorno que conduz sistematicamente o processamento para a sub-rotina mais exterior (primeiro pedido de interrupção), atingindo-se por fim o programa principal. Note-se que o nível das sub-rotinas está condicionado pela existência da instrução EI em cada uma das sub-rotinas, visto que quando o sinal de interrupção é aceite a CPU automaticamente proíbe novas interrupções.

  Códigos das Instruções de Interrupção

 As instruções EI e DI são formadas por um único byte e, tal como tem sido referido repetidas vezes, desinibem e inibem, respectivamente, a ocorrência de interrupções:

 As instruções SET INTERRUPT MODE seleccionam um dos três modos de utilização da entrada de interrupt que se pode mascarar. São instruções de dois bytes com o seguinte formato:

 Por último, resta-nos apresentar os códigos das instruções de RETURN das sub-rotinas de serviço de interrupções (RETN e RETI):

 A instrução RETN é utilizada no fim das sub-rotinas de resposta a um interrupt NMl (que não pode ser inibido). Esta interrupção carrega o flip-flop IFF1 com o valor de IFF2, como foi referido anteriormente.

A instrução RETI é utilizada para terminar as sub-rotinas de resposta às interrupções que se podem mascarar (INT).

Na tabela 29 apresenta-se um resumo dos códigos hexadecimais das instruções de controlo da CPU.

 

<-- Voltar

Hosted by www.Geocities.ws

1