Interrupciones en procesadores 65xx - Interrupts in 65xx processors

La familia de microprocesadores 65xx , que consta de MOS Technology 6502 y sus derivados, WDC 65C02 , WDC 65C802 y WDC 65C816 y CSG 65CE02 , todos manejan las interrupciones de manera similar. Hay tres señales de interrupción de hardware comunes a todos los procesadores 65xx y una interrupción de software , la instrucción BRK . El WDC 65C816 agrega una cuarta interrupción de hardware , ABORT , útil para implementar arquitecturas de memoria virtual, y la instrucción de interrupción del software COP (también presente en el 65C802), diseñada para su uso en un sistema con un coprocesador de algún tipo (por ejemplo, un punto flotante procesador ).

Tipos de interrupción

65xx ubicaciones de vectores de interrupción
Interrumpir Vector (hexadecimal)
LSB MSB
ABORTAR FFF8 FFF9
POLICÍA FFF4 FFF5
IRQ / BRK FFFE FFFF
NMI FFFA FFFB
REINICIAR FFFC FFFD

Las señales de interrupción de hardware son todas activas bajas y son las siguientes:

REINICIAR
una señal de reinicio , activada por nivel
NMI
una interrupción no enmascarable , disparada por flanco
IRQ
una interrupción enmascarable , activada por nivel
ABORTAR
una interrupción de propósito especial, no enmascarable (solo 65C816, ver más abajo), activada por nivel

La detección de una señal RESET hace que el procesador entre en un período de inicialización del sistema de seis ciclos de reloj, después de lo cual establece la bandera de desactivación de solicitud de interrupción en el registro de estado y carga el contador del programa con los valores almacenados en el vector de inicialización del procesador ( $ 00FFFC - $ 00FFFD ) antes de comenzar la ejecución. Si funciona en modo nativo, los 65C816 / 65C802 vuelven al modo de emulación y permanecen allí hasta que regresan al modo nativo bajo el control del software.

Ubicaciones de vectores de interrupción en modo nativo 65C816 / 65C802
Interrumpir Vector (hexadecimal)
LSB MSB
ABORTAR 00FFE8 00FFE9
BRK 00FFE6 00FFE7
POLICÍA 00FFE4 00FFE5
IRQ 00FFEE 00FFEF
NMI 00FFEA 00FFEB
REINICIAR Ninguno

La detección de una señal NMI o IRQ , así como la ejecución de una instrucción BRK , provocarán la misma secuencia general de eventos, que son, en orden:

  1. El procesador completa la instrucción actual y actualiza los registros o la memoria según sea necesario antes de responder a la interrupción.
  2. 65C816 / 65C802 cuando se opera en modo nativo: El registro del banco de programas ( PB , la parte A16-A23 del bus de direcciones ) se inserta en la pila de hardware .
  3. El byte más significativo (MSB) del contador de programa ( PC ) se inserta en la pila.
  4. El byte menos significativo (LSB) del contador de programa se inserta en la pila.
  5. El registro de estado ( SR ) se inserta en la pila.
  6. La bandera de desactivación de interrupciones se establece en el registro de estado.
  7. 65C816 / 65C802: PB se carga con $ 00 .
  8. La PC se carga desde el vector correspondiente (ver tablas).

El comportamiento del 65C816 cuando se afirma ABORT difiere en algunos aspectos de la descripción anterior y se analiza por separado a continuación.

Tenga en cuenta que el procesador no empuja el acumulador y los registros de índice a la pila; el código en el manejador de interrupciones debe realizar esa tarea, así como restaurar los registros al finalizar el procesamiento de interrupciones, según sea necesario. También tenga en cuenta que el vector para IRQ es el mismo que para BRK en todos los procesadores 65xx de ocho bits, así como en el 65C802 / 65C816 cuando se opera en modo de emulación. Cuando funciona en modo nativo, el 65C802 / 65C816 proporciona vectores separados para IRQ y BRK .

Cuando se establece, la bandera de deshabilitación de solicitud de interrupción (el bit I en el registro de estado) deshabilitará la detección de la señal IRQ , pero no tendrá ningún efecto en ninguna otra interrupción (sin embargo, consulte la sección a continuación sobre la instrucción WAI implementada en procesadores WDC CMOS) . Además, con el 65 (c) 02 o el 65C816 / 65C802 operando en modo de emulación, la copia del registro de estado que se empuja a la pila tendrá la bandera B activada si una BRK ( interrupción de software ) fue la causa de la falla. interrumpir, o borrar si una IRQ fue la causa. Por lo tanto, la rutina del servicio de interrupción debe recuperar una copia del registro de estado guardado desde donde fue empujado a la pila y verificar el estado de la bandera B para distinguir entre una IRQ y una BRK . Este requisito se elimina cuando se opera el 65C802 / 65C816 en modo nativo, debido a los vectores separados para los dos tipos de interrupciones.

ABORT interrupción

La entrada de interrupción ABORTB del 65C816 está destinada a proporcionar los medios para redirigir la ejecución del programa cuando se detecta una excepción de hardware, como una falla de página o una violación de acceso a la memoria . Por lo tanto, la respuesta del procesador cuando se afirma (niega) la entrada ABORTB es diferente de cuando se afirma IRQB y / o NMIB . Además, lograr un funcionamiento correcto en respuesta a ABORTB requiere que la interrupción ocurra en el momento adecuado durante el ciclo de la máquina , mientras que no existe tal requisito para IRQB o NMIB .

Cuando se afirma ABORTB durante un ciclo de memoria válido, es decir, cuando el procesador ha confirmado las salidas de estado de VDA y / o VPA , se producirá la siguiente secuencia de eventos:

  1. El procesador completa la instrucción actual pero no cambia los registros o la memoria de ninguna manera ; los resultados computacionales de la instrucción completa se descartan. Una interrupción de aborto no aborta literalmente una instrucción.
  2. El banco de programas ( PB , ver arriba) se empuja a la pila.
  3. El byte más significativo (MSB) de la dirección de la instrucción abortada se inserta en la pila.
  4. El byte menos significativo (LSB) de la dirección de la instrucción abortada se inserta en la pila.
  5. El registro de estado se inserta en la pila.
  6. La bandera de desactivación de interrupciones se establece en el registro de estado.
  7. PB está cargado con $ 00 .
  8. El contador del programa se carga desde el vector ABORT (ver tablas).

Como la dirección empujado a la pila es el de la instrucción abortado en lugar de los contenidos del contador de programa, la ejecución de una RTI ( R e T urna de I nterrupt) después de un ABORT interrupción hará que el procesador de retorno a la instrucción abortado, en vez que la siguiente instrucción, como sería el caso con las otras interrupciones.

Para que el procesador responda correctamente a un aborto, la lógica del sistema debe afirmar (negar) la entrada ABORTB tan pronto como se haya colocado una dirección válida en el bus y se haya determinado que la dirección constituye una falla de página, violación de acceso a la memoria u otra anomalía (por ejemplo, intento de ejecución de una instrucción privilegiada). Por lo tanto, la lógica no debe afirmar ABORTB hasta que el procesador haya confirmado las señales VDA o VPA . Además, ABORTB debe permanecer activo hasta la caída del reloj de la fase dos y luego ser liberado inmediatamente. Si no se observan estas limitaciones de tiempo, el propio manejador de interrupción de aborto puede abortarse, provocando que los registros y / o la memoria se modifiquen de una manera posiblemente indefinida.

Interrumpir anomalías

En el NMOS 6502 y derivados (por ejemplo, 6510), la afirmación simultánea de una línea de interrupción de hardware y la ejecución de BRK no se tuvieron en cuenta en el diseño; la instrucción BRK se ignorará en tal caso. Además, el estado del indicador de modo decimal en el registro de estado del procesador no cambia después de una interrupción de cualquier tipo. Este comportamiento puede resultar potencialmente en un error difícil de localizar en el controlador de interrupciones si el modo decimal está habilitado en el momento de una interrupción. Estas anomalías se corrigieron en todas las versiones CMOS del procesador.

Consideraciones sobre el controlador de interrupciones

Un manejador de interrupciones bien diseñado y conciso o una rutina de servicio de interrupciones (ISR) no solo atenderá rápidamente cualquier evento que cause una interrupción, lo hará sin interferir de ninguna manera con la tarea de primer plano interrumpida; el ISR debe ser "transparente" para la tarea interrumpida (aunque pueden aplicarse excepciones en casos especializados). Esto significa que el ISR debe preservar el estado del microprocesador (MPU) y no alterar nada en la memoria que se supone que no debería alterar. Además, el ISR debe ser completamente reentrante , lo que significa que si dos interrupciones llegan en sucesión cercana, el ISR podrá reanudar el procesamiento de la primera interrupción después de que se haya reparado la segunda. La reentrada generalmente se logra utilizando solo la pila de hardware MPU para el almacenamiento (aunque existen otros métodos posibles).

Preservar el estado de la MPU significa que el ISR debe asegurarse de que los valores que estaban en los registros de la MPU en el momento de la interrupción estén allí cuando termine el ISR. Una parte del proceso de preservación es manejada automáticamente por la MPU cuando reconoce la interrupción, ya que empujará el contador de programa (y el banco de programa en el 65C816 / 65C802) y el registro de estado a la pila antes de ejecutar el ISR. Al finalizar el ISR, cuando se ejecuta la instrucción RTI , la MPU invertirá el proceso. Ningún miembro de la familia 65xx empuja ningún otro registro a la pila.

En la mayoría de los ISR, el acumulador y / o los registros de índice deben conservarse para asegurar la transparencia y luego restaurarse como los pasos finales antes de ejecutar RTI . En el caso del 65C816 / 65C802, debe tenerse en cuenta si está funcionando en modo emulación o nativo en el momento de la interrupción. En este último caso, también puede ser necesario preservar los registros del banco de datos ( DB ) y de la página directa (cero) ( DP ) para garantizar la transparencia. Además, un sistema operativo en modo nativo 65C816 puede usar una ubicación de pila diferente a la del software de la aplicación, lo que significa que el ISR tendría que conservar y restaurar posteriormente el puntero de pila ( SP ). Para complicar aún más las cosas con el 65C816 / 65C802 es que los tamaños del acumulador y los registros de índice pueden ser de 8 o 16 bits cuando operan en modo nativo, lo que requiere que se conserven sus tamaños para una restauración posterior.

Los métodos mediante los cuales se conserva y restaura el estado de la MPU dentro de un ISR variarán con las diferentes versiones de la familia 65xx. Para los procesadores NMOS (por ejemplo, 6502, 6510, 8502, etc.), solo puede haber un método por el cual se conservan el acumulador y los registros de índice, ya que solo el acumulador puede empujarse y extraerse de la pila. Por lo tanto, el siguiente código de entrada ISR es típico:

        PHA                     ; save accumulator
        TXA
        PHA                     ; save X-register
        TYA
        PHA                     ; save Y-register
        CLD                     ; ensure binary mode by clearing decimal flag

La instrucción CLD es necesaria porque, como se señaló anteriormente, las versiones NMOS del 6502 no borran el indicador D (modo decimal) en el registro de estado cuando ocurre una interrupción.

Una vez que se han conservado los registros de índice y acumulador, el ISR puede utilizarlos según sea necesario. Cuando el ISR haya concluido su trabajo, restauraría los registros y luego reanudaría la tarea de primer plano interrumpida. Nuevamente, el siguiente código NMOS es típico:

        PLA
        TAY                     ; restore Y-register
        PLA
        TAX                     ; restore X-register
        PLA                     ; restore accumulator
        RTI                     ; resume interrupted task

Una consecuencia de la instrucción RTI es que la MPU volverá al modo decimal si ese era su estado en el momento de la interrupción.

El 65C02 y el 65C816 / 65C802 cuando operan en modo de emulación, requieren menos código, ya que pueden presionar y tirar de los registros de índice sin usar el acumulador como intermediario. También borran automáticamente el modo decimal antes de ejecutar el ISR. Lo siguiente es típico:

        PHA                     ; save accumulator
        PHX                     ; save X-register
        PHY                     ; save Y-register

Al terminar, el ISR revertiría el proceso:

        PLY                     ; restore Y-register
        PLX                     ; restore X-register
        PLA                     ; restore accumulator
        RTI                     ; resume interrupted task

Como se indicó anteriormente, hay un poco más de complejidad con el 65C816 / 65C802 cuando se opera en modo nativo debido a los tamaños de registro variables y la necesidad de contabilizar los registros DB y DP . En el caso de los registros de índice, se pueden insertar sin tener en cuenta sus tamaños, ya que el cambio de tamaño establece automáticamente el byte más significativo (MSB) en estos registros en cero y no se perderán datos cuando se restaure el valor insertado, siempre que el los registros de índice tienen el mismo tamaño que cuando se presionaron.

El acumulador, sin embargo, es realmente dos registros: designados .A y .B . Empujar el acumulador cuando está configurado en 8 bits no preservará .B , lo que podría resultar en una pérdida de transparencia si el ISR cambiara .B de alguna manera. Por lo tanto, el acumulador siempre debe establecerse en 16 bits antes de empujarlo o jalarlo si el ISR va a utilizar .B . También es más eficiente establecer los registros de índice en 16 bits antes de presionarlos. De lo contrario, el ISR debe enviar una copia adicional del registro de estado para poder restaurar los tamaños de los registros antes de extraerlos de la pila.

Para la mayoría de los ISR, el siguiente código de entrada logrará el objetivo de transparencia:

        PHB                     ; save current data bank
        PHD                     ; save direct page pointer
        REP #%00110000          ; select 16 bit registers
        PHA                     ; save accumulator
        PHX                     ; save X-register
        PHY                     ; save Y-register

En el fragmento de código anterior, el símbolo % es tecnología MOS y sintaxis de lenguaje ensamblador estándar WDC para un operando bit a bit .

Si el ISR tiene su propia ubicación de pila asignada, la preservación del puntero de pila ( SP ) debe ocurrir en la memoria después de que se hayan producido los empujes anteriores; debería ser evidente por qué esto es así. El siguiente código, agregado a la secuencia anterior, manejaría este requisito:

        TSC                     ; copy stack pointer to accumulator
        STA stkptr              ; save somewhere in safe RAM
        LDA isrptr              ; get ISR's stack pointer &...
        TCS                     ; set new stack location

Al finalizar el ISR, los procesos anteriores se revertirían de la siguiente manera:

        REP #%00110000          ; select 16 bit registers
        TSC                     ; save ISR's SP...
        STA isrptr              ; for subsequent use
        LDA isstkptr            ; get foreground task's SP &...
        TCS                     ; set it
        PLY                     ; restore Y-register
        PLX                     ; restore X-register
        PLA                     ; restore accumulator
        PLD                     ; restore direct page pointer
        PLB                     ; restore current data bank
        RTI                     ; resume interrupted task

Tenga en cuenta que al ejecutar RTI , el 65C816 / 65C802 restaurará automáticamente los tamaños de registro a los que tenían cuando ocurrió la interrupción, ya que al extraer el registro de estado previamente guardado se configuran o borran ambos bits de tamaño de registro a lo que eran en el momento de la interrupción. .

Si bien es posible cambiar el 65C816 / 65C802 del modo nativo al modo de emulación dentro de un ISR, esto conlleva muchos peligros. Además de forzar el acumulador y los registros de índice a 8 bits (causando una pérdida del byte más significativo en los registros de índice), ingresar al modo de emulación truncará el puntero de la pila a 8 bits y reubicará la pila en la página 1 RAM . El resultado es que la pila que existía en el momento de la interrupción será inaccesible a menos que también estuviera en la RAM de la página 1 y no supere los 256 bytes. En general, el cambio de modo mientras se da servicio a una interrupción no es un procedimiento recomendado, pero puede ser necesario en entornos operativos específicos.

Usando BRK y COP

Como se señaló anteriormente, BRK y COP son interrupciones de software y, como tales, pueden usarse de diversas formas para implementar funciones del sistema.

Un uso histórico de BRK ha sido ayudar a parchear PROM cuando se descubrieron errores en el firmware de un sistema . Una técnica típica que se utiliza a menudo durante el desarrollo de firmware era disponer que el vector BRK apunte a un "área de parche" no programada en la PROM. En el caso de que se descubriera un error, el parche se lograría "fundiendo" todos los fusibles en la dirección donde se encontraba la instrucción defectuosa, cambiando así el código de operación de la instrucción a $ 00 . Al ejecutar el BRK resultante , la MPU se redirigiría al área de parche, en la que se escribiría el código de parche adecuado. A menudo, el código de área del parche comenzaba "rastreando la pila" para determinar la dirección en la que se encontró el error, permitiendo potencialmente la presencia de más de un parche en la PROM. El uso de BRK para el parcheo de PROM disminuyó una vez que las EPROM y EEPROM se volvieron comúnmente disponibles.

Otro uso de BRK en el desarrollo de software es como ayuda de depuración junto con un monitor de lenguaje de máquina . Al sobrescribir un código de operación con BRK ( $ 00 ) y dirigir el vector de hardware BRK al punto de entrada del monitor, se puede hacer que un programa se detenga en cualquier punto deseado, permitiendo que el monitor tome el control. En ese momento, uno puede examinar la memoria, ver los valores de registro del procesador, el código de parche, etc. La depuración, como lo recomiendan Kuckes y Thompson, puede facilitarse esparciendo generosamente el código de uno con instrucciones NOP (código de operación $ EA ) que pueden ser reemplazadas por Instrucciones BRK sin alterar el comportamiento real del programa que se está depurando.

Una característica de las instrucciones BRK y COP es que el procesador trata como una instrucción de dos bytes: el código de operación en sí y el siguiente byte, que se conoce como la "firma". Tras la ejecución de BRK o COP , el procesador agregará dos al contador del programa antes de empujarlo a la pila. Por lo tanto, cuando se ejecuta RTI ( R e T urn from I nterrupt), el programa interrumpido continuará en la dirección inmediatamente siguiente a la firma. Si se utiliza BRK como dispositivo de depuración, es posible que el contador del programa deba ajustarse para que apunte a la firma para que la ejecución se reanude donde se esperaba. Alternativamente, se puede insertar un NOP como un "marcador de posición" de firma, en cuyo caso no se requerirá ningún ajuste del contador del programa.

El hecho de que BRK y COP incrementen dos veces el contador del programa antes de enviarlo a la pila facilita la técnica de tratarlos como instrucciones de llamada de supervisor , como se encuentra en algunas computadoras centrales . El procedimiento habitual es tratar la firma como un índice de servicio del sistema operativo. El controlador BRK o COP del sistema operativo recuperaría el valor del contador de programa enviado a la pila, lo reduciría y leería desde la ubicación de memoria resultante para obtener la firma. Después de convertir la firma en un índice de base cero, se puede consultar una tabla de búsqueda simple para cargar el contador del programa con la dirección de la rutina de servicio adecuada. Una vez completada la rutina de servicio, la instrucción RTI se utilizaría para devolver el control al programa que realizó la llamada al sistema operativo. Tenga en cuenta que la firma para BRK puede tener cualquier valor, mientras que la firma para COP debe limitarse al rango de $ 00 - $ 7F .

El uso de BRK y / o COP para solicitar un servicio del sistema operativo significa que las aplicaciones de usuario no tienen que conocer la dirección de entrada de cada función del sistema operativo, solo el byte de firma correcto para invocar la operación deseada. Por lo tanto, la reubicación del sistema operativo en la memoria no romperá la compatibilidad con las aplicaciones de usuario existentes. Además, como la ejecución de BRK o COP siempre lleva al procesador a la misma dirección, se puede usar un código simple para preservar los registros en la pila antes de transferir el control al servicio solicitado. Sin embargo, este modelo de programación resultará en una ejecución algo más lenta en comparación con llamar a un servicio como una subrutina , principalmente como resultado de la actividad de la pila que ocurre con cualquier interrupción. Además, las solicitudes de interrupción se habrán deshabilitado ejecutando BRK o COP , requiriendo que el sistema operativo las vuelva a habilitar.

Instrucciones WAI y STP

WAI ( WA it for I nterrupt, opcode $ CB ) es una instrucción disponible en la versión WDC de los microprocesadores 65C02 y 65C816 / 65C802 (MPU) que detiene la MPU y la coloca en un estado semi-catatónico hasta que seproduceuna interrupción del hardware. ocurre cualquier tipo. El uso principal de WAI es en sistemas integrados de baja potencia donde la MPU no tiene nada que hacer hasta que ocurre un evento esperado y se desea un consumo mínimo de energía mientras el sistema está esperando y / o se requiere una respuesta rápida. Un ejemplo típico de código que utilizaría WAI es el siguiente:

        SEI                     ; disable IRQs
        WAI                     ; wait for hardware interrupt
        ; ... execution resumes here

En el fragmento de código anterior, la MPU se detendrá tras la ejecución de WAI y entrará en un estado de muy bajo consumo de energía. A pesar de que las solicitudes de interrupción (IRQ) se han desactivado antes de la instrucción WAI , la MPU responderá a cualquier interrupción de hardware mientras espera. Al recibir una interrupción, la MPU se "despertará" en un ciclo de reloj y reanudará la ejecución en la instrucción inmediatamente posterior a WAI . Por lo tanto, la latencia de interrupción será muy corta (70 nanosegundos a 14 megahercios), lo que dará como resultado la respuesta más rápida posible a un evento externo.

Similar en algunos aspectos a WAI es la instrucción STP ( ST o P , código de operación $ DB ), que apaga completamente la MPU mientras espera una única entrada de interrupción. Cuando se ejecuta STP , la MPU detiene su reloj interno (pero retiene todos los datos en sus registros) y entra en un estado de bajo consumo. La MPU se saca de este estado bajando su pin de entrada de reinicio ( RESB , que se clasifica como una entrada de interrupción). Luego, la ejecución se reanudará en la dirección almacenada en las ubicaciones $ 00FFFC- $ 00FFFD , el vector de reinicio del hardware. Al igual que con WAI , STP está diseñado para su uso en aplicaciones integradas de baja potencia donde pueden transcurrir largos períodos de tiempo entre eventos que requieren la atención de MPU y no se requiere ningún otro procesamiento. STP no se utilizaría en la programación normal, ya que daría lugar al cese total del procesamiento.

Notas al pie

  1. ^ Un b El ABORT entrada está disponible sólo con los W65C816S.
  2. ^ a b La instrucción COP está disponible en ambos modos de funcionamiento.
  3. ^ El 65C816 / 65C802 no tiene un vector de interrupción de modo nativo para laseñal RESET , ya que un reset siempre revierte el procesador al modo de emulación.
  4. ^ El valor de labandera B en el registro de estado es siempre 1 , independientemente del tipo de interrupción.  B es significativo solo en la copia del registro de estado que se inserta en la pila en respuesta a una interrupción, y no existe realmente en el registro de banderas.

Referencias

  1. a b c d e J. S. Anderson (1994). Tecnología de microprocesador . Butterworth-Heinemann. págs. 143-144. ISBN 9780750618397.
  2. ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa David Eyes y Ron Lichty (28 de abril de 1992). "Programación del 65816" (PDF) . The Western Design Center, Inc. Archivado desde el original (PDF) el 23 de julio de 2012 . Consultado el 29 de noviembre de 2012 . Cite journal requiere |journal=( ayuda )
  3. ^ a b "Arquitectura básica" . 6502 . 2002-01-02.
  4. a b Leo J. Scanlon (1980). 6502 Diseño de software . HW Sams. págs.  172-173 . ISBN 9780672216565.
  5. a b c Lance A. Leventhal (1986). 6502 Programación en lenguaje ensamblador . Osborne / McGraw-Hill. ISBN 9780078812163.
  6. ^ Ronald J. Tocci y Lester P. Laskowski (1979). Microprocesadores y microcomputadoras: hardware y software . Prentice Hall. pag. 379 . ISBN 9780135813225.
  7. ^ Arthur F. Kuckes y BG Thompson (1987). Apple II en el laboratorio . ARRIBA Archivo. pag. 93. ISBN 9780521321983.
  8. ^ Harrod, Dennette A. (octubre de 1980). "6502 obtiene instrucciones microprogramables" . BYTE . Vol. 5 no. 10. McGraw Hill . págs. 282-285. Archivado desde el original el 25 de mayo de 2006 . Consultado el 31 de mayo de 2009 .
  9. ^ Richard R. Smardzewski (1984). Programación y aplicaciones de microprocesadores para científicos e ingenieros . Elsevier. pag. 125 . ISBN 9780444424075.

Otras lecturas