P9------------------------------------
P;      MANEJO DE INTERRUPCIONES
        POR ENCIMA  DE 68000
P:
      by  Terminator / Destiny
P9
-------------ooooOOOOoooo-----------
P8
Este artículo muestra como asegurar-
se  de  que nuestro sistema de inte-
rrupciones se establece correctamen-
te  con procesadores de toda la gama
680x0.

El problema  es que con procesadores
superiores al 68010 los primeros 100
bytes  de  memoria  pueden  estar en
cualquier parte y estos primeros by-
tes  son  muy  importantes  para  el
sistema. Asumiendo que siempre van a
estar en su sitio nuestras alusiones
a los primeros $200 bytes de memoria
funcionarán  siempre  con MC68000, y
quizá  siga funcionando muchas veces
con procesadores posteriores pero el
dia menos pensado PATAPLAF!

A Commodore  seguramente le gustaría
situar la tabla de vectores en memo-
ria  fast, pero  esto  supondría  un
sinfín de incompatibilidades, ya que
muchos  programadores  a  la hora de
instalar en el sistema una dirección
de  memoria para una interrupción de
nivel  3, por  ejemplo,  simplemente
escriben:

   P<     Move.l  #Mi_int3,$6c.w
P8
Pero  con  los  procesadores  de los
nuevos  Amigas podría fallar, ya que
la  forma  correcta  de acceder a la
"página  cero" es consultando su di-
rección  en  el registro VBR (Vector
Base Register).

La  siguiente  rutina explica una de
las  maneras en que puede hacerse un
acceso correcto a esta zona de memo-
ria  y presenta un ejemplo de insta-
lación de interrupción de nivel 3.


; Primero  tenemos que saber con que
; procesador estamos trabajando.
; para  eso  consultaremos attnflags
; de exec.
; 
; bit 0 - 68010
; bit 1 - 68020
; bit 2 - 68030  solo 2.0
; bit 3 - 68040  solo 2.0
; bit 4 - 68881
; bit 5 - 68882  solo 2.0
;
; Un 68020 también activará  el  bit
; del 68010,un 30 el del 20 y el 10,
; etc

P<Prep_int_Lev_3

  move.l  4.w,a6       P8; execbase
P<
  moveq.l #0,d0        P8; borrar  re-
                       P8; gistro
P<
  move.w  $128(a6),d0  P8;   attnflags
                       P8; de execbase
                       P8; en d0

P<  and.w   #$f,d0       P8; ¿es    algo
                       P8; más  que un
                       P8; 68000?

P<  beq.s   VBR_decidido P8; ¿No?pues no
                       P8; tiene VBR

P<  move.l  a5,-(a7)     P8; Salvar a5

P<  lea .coger_VBR(pc),a5  P8; apuntar a
                         P8; un  movec
                         P8; vbr,d0

P<  jsr     -30(a6)      P8; entrar   en
                       P8; modo    su-
                       P8; pervisor

P<  move.l  (a7)+,a5     P8;restaurar a5

P<  move.l  d0,VBR       P8; guarda  VBR
                       P8; obtenido

P<VBR_decidido

  move.l  VBR(pc),a0   P8; a0 = VBR
P<  move.l  $6c(a0),OldLev3 P8;  conser-
                          P8; var vie-
                          P8; ja inte-
                          P8; rrupción

P<  Lea     Mi_int3(PC),a1  P8;a1=interr
                          P8;nivel   3
                          P8;nueva

P<  Move.l  a1,$6c(a0)  P8; efectua   la
                      P8; instalación

P<  Rts                 P8; termina

P<.coger_VBR

P<  dc.l    $4e7a0801   P8; esta ins-
              P8;trucción precisa modo
              P8; supervisor,   es  un
              P8; movec vbr

P<  rte         P8; vuelve de excepción

P<VBR
  dc.l    0   P8;aqui se guarda el VBR

P<Reset_Int_Lev_3

  move.l  VBR(pc),a0   P8; a0 = VBR

P<  Move.l  Oldlev3(PC),$6c(a0)
         P8; devolver la int. original

P<  Rts                  P8; terminar


Otra  cosa que conviene saber es que
dentro de una interrupción solo pue-
den  usarse  algunas funciones exec.
Con seguridad puede llamarse a:
P?
     Alert           Findport
     Enable          Replymsg
     Disable         Findtask
     Findname        Signal
     Cause           Putmsg
P8
Además, si estás  usando tus propias
listas   durante  una  interrupción,
también   pueden   usarse  P? Addhead,
Adtail, Enqueue, Remhead y Remtail.
