continuation on INTERRUPTS ...
14) TBCR: Identical to TACR, except this register controls TIMER B
($FFFA1B)
15) TCDCR: Bit vector serving the same role as TACR and TBCR for
TIMER C and TIMER D, but here only the DELAY MODE is
available.
($FFFA1D)
Bits 0 to 2 are reserved for TIMER C
Bits 4 to 6 are reserved for TIMER D
Refer to the TACR table for the meaning of the bits...
I remind you that we will not use these TIMERS because
they are already used by the system originally.
16) to 19) TADR, TBDR, TCDR, TDDR (starting from $FFFA1F):
Here are the DATA registers of the 4 TIMERS ...
20) to 24) SRC,CR,RSR,TSR,DR (starting from $AFFF27):
Registers that are not used by the TIMERS, and they
simply control the transmission of characters...
Now that you are familiar with the various registers
of the MFP 68901, you will be able to start creating your first
programs with interrupts.
To modify a register of the MFP, it is enough to know the address
of the register and to deposit the necessary data there.
- Here's how to proceed to put a routine under
interrupt:
* We switch to SUPERVISOR MODE to be able to access the MFP registers.
* We set to 0 the bit corresponding to the TIMER used in the IMR register.
(With an AND #BBB, destination or a BCLR #BBB, destination)
* We set to 0 the bit corresponding to the TIMER used in the ISR register.
* We set to 0 the bit corresponding to the TIMER used in the IPR register.
* We set to 0 the bit corresponding to the TIMER used in the IER register.
* We install our routine:
.Either by depositing the address of our routine directly in the
EXCEPTION VECTOR corresponding to the used TIMER:
$134 for TIMER A, $120 for TIMER B, $114 for TIMER C,
$110 for TIMER D (with MOVE.L #ADDRESS,$vector)
(See the Table of exception vectors)
Then by modifying directly the CONTROL and DATA REGISTERS
of the TIMER by depositing the new values at their addresses.
(With MOVE.B #VALUE,$address)
(Refer to the addresses of the CONTROL REGISTERS TACR,TBCR,TCDCR and the
addresses of the DATA REGISTERS TADR,TBDR,TCDR,TDDR)
.Or by calling an XBIOS function that does it for us:
This is the XBTIMER function of the XBIOS.
The parameters to pass are:
L-M: Address of the routine
WORD: Value of the DATA register
WORD: Value of the CONTROL register
WORD: The code of the TIMER (0=TIMER A,1=TIMER B,2=TIMER C,3=TIMER D)
WORD: Code of the function = $1F
We will still need to:
.Set to 1 the bit of the IER register corresponding to our TIMER (To
enable our interrupt routine)
.Set to 1 the bit of the IMR register corresponding to our TIMER
And there, my routine is installed !!!
The routine itself:
---------------------
The routine to be placed under interrupt must be able to execute
fully before the next TIMER call because otherwise beware
of crashes!!
It should therefore not be too long:
For example, you cannot put a routine that takes 0.5
seconds to execute fully under interrupt and set
its call frequency at 0.007 seconds...
Your interrupt routine should always end with:
.A reset to 0 of the bit corresponding to the TIMER used in the ISR register
,to indicate to the MFP that the routine is finished.
--------------------------------
With BCLR #5,$FFFA07 for TIMER A (On ISRA)
or BCLR #0,$FFFA11 for TIMER B (On ISRB)
--------------------------------
.An RTE (Return From Exception)
---
Furthermore, since your routine executes at regular intervals, I strongly
advise against using DN or AN registers (even SP) because
this can cause sudden changes at the level of the registers
concerned in the main program. (The interrupt subroutine
executes without interrupting the main program, we will see
a very good illustration of this in a future exercise)
However, the interrupt subroutine can call addresses of the DATA or BSS segment to read or deposit values...
That's it for the theory, I strongly advise you to reread the whole
chapter thoroughly because now come the EXERCISES ...
-----------------
Laurent PIECHOCKI
8, Impasse Bellevue Continuation in the file: EXOS_4.DOC
57980 TENTELING ----------
Back to ASM_Tutorial