COURS 4.TXT

From Atari Wiki
Revision as of 13:53, 16 December 2023 by Olivier.jan (talk | contribs)
Jump to navigation Jump to search
******************************************************************
*                                                                *
*             ASSEMBLER COURSE 68000 ON ATARI ST                 *
*                                                                *
*                 by Le Féroce Lapin (from 44E)                  *
*                                                                *
*                          Course number 4                       *
*                                                                *
******************************************************************

We will now address address registers. Like
data registers, these registers are coded on 32 bits (a
long word). So a priori no difference, because the microprocessor 
knows only numbers, whether they represent data or addresses, it 
does not matter much to him. This is true in large part and indeed on some
microprocessors, there are only one or two registers, which can contain either
address or data.

Let's see, thanks to an example, the differences regarding the
68000 MOTOROLA.

So let's type in the following program, after making sure to
delete the old one, and assemble.

MOVE.L     #$12345678,D0
MOVE.B     #$AA,D0
MOVE.L     #$12345678,A0
MOVE.B     #$AA,A0 
MOVE.L     #$12345678,A1
MOVE.B     A1,D1

The assembler notes 2 errors and announces them as 'invalid size
at line 4' and the same for 'line 6'. Since it is the size
and not the operation itself that seems to be a problem, we conclude that
the MOVE to or from an address register,
is not possible on a byte. So let's correct line 4 and line 6 by replacing
the MOVE.B with MOVE.W and reassemble.

Note: When the assembler notes an error, it gives the line where
it is located. In this numbering, the blank lines are
counted.

So if you had entered a line after MOVE.L #$12345678,D0 the
errors would have been announced on lines 5 and 7.

This makes a difference already, since if you look at the
program, we wanted to perform an
operation with D0: Fill it to its maximum size, then check that the MOVE from the
line 2, would only affect the low byte, then perform
the same operation on A0.

Impossible a priori. Too bad, following our modification,
the operation will therefore take place on a word instead of a byte.

Debug our program. First observation: the assembler,
seeing that the operations take place with address registers and
not data registers, automatically modified the MOVE to A0 and A1, to transform them into MOVEA, which reads
MOVE ADDRESS

Run the program step by step. D0 takes the value $12345678,
then only its low byte is modified, so D0 then takes
the value $123456AA. Then A0 takes the value $12345678. After
the next line, the operation affecting the word, we should have $123400AA. But not at all! We get $000000AA.

So we have just seen that an address register is totally 
affected (so on a long word) when it is the destination of
the operation. So what about when it is the source?

So let's continue our program, filling A1 and D1. We
subsequently note that only the low word of A1 overwrites that of D1.

NOTE: $AA is indeed a number in hexadecimal. If you thought
they were just letters of the alphabet, sleep 1 or 2
days, and resume the course from the beginning!

From all this, we deduce 2 definitions:

DATA REGISTERS: Each data register has a length of
32 bits. The operands in byte form occupy the 8 bits of the
low byte, the operands in word form, the 16 bits of
the low byte and the long operands, the full 32 bits.

The least significant bit is addressed as bit 0, the most significant bit is addressed as bit
31.

When a data register is used either as a source operand
or as a destination operand, only the appropriate
low byte is changed. The remaining high byte is neither used nor modified.

ADDRESS REGISTERS: Each register has a length of 32 bits, and
contains an address on 32 bits. Address registers
do not accept an operand whose size is a byte. Consequently, when an address register is used as an operand
source, either the low word, or the entire long operand in its
entirety is used, depending on the size of the operation.

When an address register is used as the destination
operand, the entire register is affected, regardless of the
size of the operation. If the operation concerns a word, all
other operands undergo a sign extension to 32 bits before
the operation is performed.

Definitions taken from document ref EF68000 (integrated circuits
MOS THOMSON EFCIS), 45 avenue de l'Europe 78140 Velizy.

In these definitions, we notice a new term: operand.
This is the term that designates the value used in the operation.
So in MOVE.W D0,D1 the source operand is the low word of
D0 while the destination operand is the low word of D1.

We now know what the PC is, a data register, an address register, we have some idea of what is shown in
the MONST window, so let's continue to dissect this fabulous tool!

To observe the MONST window, if you have not assembled a
program, it is impossible to use Alternate+D. You will be told
that there is no program in memory. So type Alternate+M,
you will see MONST appear, but asking you which file
to load. Type ESC and here we are ready for an observation.

We can see in the top window our data registers
and on the right our address registers. Below the data registers
SR then PC. The PC (program counter), we know what it is,
but the SR?


THE STATUS REGISTER

The SR (pronounce Status Register), is a register coded as a word (16 bits) and
which, as its name indicates, informs us about the status of the
microprocessor.

It is a striking example of what we saw in the introduction
of course 3, namely that it is very dangerous to treat a set of bits
as a simple number, greater or lesser.
Let's see the breakdown of the Status Register.

bit number 15----------------------------------0
appellation       T . S . . . I2 I1 I0 . . . X N Z V C

First of all, it must be known that certain bits of the SR are not
used. They are symbolized here by a dot each.

Let's start with the description of the right bits, starting
with 0.

Bit C (C stands for Carry).
This bit is set to 1 when there is a carry in the most significant bit
(so in the highest weight) of the operand, in an arithmetic operation.

Bit V (V stands for oVerflow).
Imagine adding 2 positive numbers, when the result
will overflow the registers' limits, we will in fact obtain a
negative number in two's complement. Indeed, setting the most significant
bit to 1 indicates that the number is negative.
Since this is not, in the present case, the desired result, we are
warned of the overflow by the fact that the bit V is set to 1.
It also indicates, during divisions, that the quotient is longer
than a word or that we have a dividend that is too large.

Bit Z (Z stands for Zero). It does not indicate that the result is
equal to 0, but rather that the result has passed to the other side
of 0. Indeed, this bit is set to 1 when after an operation the most significant
bit of the result is set to 1, which indicates that
we are in the presence of a negative number in two's complement. The
bit N (N stands for Negate) means that we are in the presence
of a negative number.

Bit X (X stands for eXtend). This is a very special bit which behaves a little like a carry. The instructions
that use this bit specify it in their name. For example ADDX
which is read add with extend is an addition operation taking into
account this bit X. This bit X is generally the reflection of bit C,
but, unlike the latter, certain instructions do not modify it.

When we study the 68000 instructions more closely, the
fact that the instruction affects or not such or such bit will sometimes
be very important.

Bit T (T stands for Trace).
When this bit is 1, the 68000 is in Trace mode.

So be very attentive, what follows is essential for the following courses!!!

The Trace mode is a mode of debugging for programs. And
yes, this command is inserted directly into the microprocessor. Each time the 68000
executes an instruction, it will check in which state the bit T is. If it finds this bit at
0, it moves on to the next instruction. On the other hand, if this bit is
at 1, the 68000 temporarily puts the main program aside
to turn to a routine (a 'bit' of program) which will display for example the value of all the registers
(D0 to D7 and A0 to A7). Let's imagine that we have to press a key to exit this routine: We therefore have all the time
to consult these values. We press a key: end of our routine, the 68000 therefore returns
to the main program, executes the next instruction, tests the bit T, and finds it again at 1, so
it switches to our routine, etc... We therefore have a step-by-step mode. However, you have already used this feature by observing
the sequence of instructions with MONST!

Type the following program:
MOVE.W     #$23,D0
MOVE.W     #$15,D1

Assemble and press Alternate+D to go under MONST. Press
once on Control+Z and observe the Status Register. MONST has displayed
T, indicating that this bit is at 1. So we are
indeed in Trace mode. Exit the program with Control+C.

We are now able to ask ourselves a question: The 68000 has
found the bit T at 1. Okay, it knows where its Status register is
and it knows that bit T is the 15th. But after that? The 68000
has turned to a routine which in this case is a part of MONST.

But how did it find this routine? MONST is indeed a
completely ordinary program, which
has been loaded into memory from the floppy disk, and which can be placed anywhere in that
memory.

A first solution would be to always place this program
at the same place. MOTOROLA
could have designed the 68000 by specifying: The debugging programs that will be called
thanks to the setting of bit T to 1, must start at address $5000.
Simple, but very annoying because it becomes practically impossible
to have several programs residing in memory simultaneously, without
running the risk that they will interfere with each other!!!

There is however another solution, a little more twisted but on the other hand much
more flexible, which consists of loading the debugging program anywhere in memory, taking note of the address
at which it is located, and noting this address at a specific location.
When the 68000 finds bit T at 1, it will rush to this predefined location
in advance by MOTOROLA, it will not find the routine there but a long word, the address of this routine, to which it
will then only have to go.

This specific location, where the address of the routine will be stored when the bit T is found at 1, is an
area located in the first kilobyte of memory (so in the first 1024
bytes). In the case of the trace mode, it is the address $24.

Let us summarize: MONST is loaded into memory. It is a complete program
with some routines that allow showing the registers.
MONST looks at the address at which these routines start, notes
this address and then sets it at address $24. This long word is
placed at address $24, $25, $26 and $27 since we know that the
'diameter' of the 'memory tube' is only one byte.
When the microprocessor finds bit T at 1, it goes to address $24, it
extracts a long word from it which happens to be the address of MONST's routines, and it goes straight to this address. Ok?

We will now make a little program and we are going to
'crash' your ATARI!
Type the following:

MOVE.W     #$1234,D1
MOVE.W     #$6789,D2
MOVE.W     #$1122,D3

Assemble and then type Alternate+D to go under MONST. Press
Control+Z once. The bit T of the Status register is set to 1, indicating
that we are indeed in Trace mode. Since we executed an
instruction, D1 is now filled with $1234. Let's now press
Alternate + 3.

We have just activated the right window (number 3).
Press Alternate+A. A request appears: we have to indicate
what address will be the first one visible in the window.
We must type this address in hexadecimal. So we type...24.
(no $ before, MONST knows on its own that we are talking in hexa)
We see the address 24 displayed at the top of the window and opposite a number which is the address of our MONST routine!

For me it is 00027086 but as I said previously this
depends on the machines. In my case when the 68000 finds bit T
at 1, it will therefore rush to execute the routine located
at $00027086. So I will modify this address! Press Alternate+E to
enter edit mode. The cursor is placed on the first nibble
of the address. Type for example 11112222 or any other number. 
Now switch back to window 1 by pressing Alternate+1.

Now let's think: We are going to do Control+Z again. The 68000
will dash to $24, will now find $11112222, and will dash
to this address to execute whatever it finds, in other words it will
be totally random! There is very little chance that it will succeed in
reading something coherent and will indicate an error to you.

Go ahead, do not be afraid, you
will not risk breaking your machine!

Hop Control+Z and, depending on the cases, you will get various
messages (Illegal exception, Bus Error etc...).

Exit by doing Control+C or as a last resort do a
RESET.

I hope that this principle is VERY VERY WELL UNDERSTOOD. If that seems
more or less clear to you, read it all over again because the following will
very often refer to this principle of address in the first kilobyte,
containing the address of a routine.

Next time, we will finish studying the Status Register, in the meantime
I will have a little vodka. To your health!

Back to ASM_Tutorial