COURS 7.TXT: Difference between revisions

From Atari Wiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
 
(4 intermediate revisions by the same user not shown)
Line 271: Line 271:
 
After this comparison, we need to test it. Here we enter the possibilities of conditional branching, that is, conditional branches.
 
After this comparison, we need to test it. Here we enter the possibilities of conditional branching, that is, conditional branches.
   
  +
Each of these instructions begins with the letter B, signifying BRANCH. In simple terms, these instructions can be read as:
  +
  +
Go to a certain place if...
  +
  +
But if what???
  +
  +
Well, several conditions are available, which can be grouped into 3 categories:
  +
  +
First, a category that reacts to the state of one of the bits of the Status Register:
  +
  +
BCC Branch if carry clear (carry bit at 0)
  +
BCS Branch if carry set (carry bit at 1)
  +
BNE Branch if not equal (zero bit at 0)
  +
BEQ Branch if equal (zero bit at 1)
  +
BVC Branch if overflow clear (overflow bit at 0)
  +
BVS Branch if overflow set (overflow bit at 1)
  +
BPL Branch if plus (negative bit at 0)
  +
BMI Branch if minus (negative bit at 1)
  +
  +
  +
A second category, reacting to the comparison of unsigned numbers.
  +
  +
BHI Branch if higher (branch if greater than)
  +
BLS Branch if lower or same (lower or equal)
  +
(BEQ and BNE can also be included in this category)
  +
  +
  +
A third category, reacting to the comparison of signed numbers.
  +
  +
BGT Branch if greater than (if greater than)
  +
BGE Branch if greater or equal (if greater than or equal to)
  +
BLT Branch if lower than (if less than)
  +
BLE Branch if lower or equal (if less than or equal)
  +
(BEQ and BNE can be included here again!)
  +
  +
I am deeply sorry for the people at MICRO-APPLICATION (The Machine Language on ST, the Bible, the GEM Book, etc...) and for the journalist who writes the assembler courses in STMAG, but the BHS and BLO branches, despite being accepted by many assemblers, DO NOT EXIST!!!!
  +
  +
Therefore, it is impossible to find them in an assembled listing, the assembler either converts them or rejects them.
  +
  +
This set of conditional branching constitutes a set of commands of the type Bcc (branch conditionally)
  +
  +
Let's continue our slow progression through the listing...
  +
The comparison is made, let's test it:
  +
  +
CMP.W #"Q",D0 is it the letter 'Q'?
  +
BEQ EXIT branch if equal 'exit'
  +
  +
That is, if it's equal, jump to the label EXIT.
  +
If it's not equal, the program continues as if nothing happened and encounters a new test:
  +
  +
CMP.W #"q",D0 is it lowercase 'q'?
  +
BEQ EXIT branch if equal exit
  +
  +
We then compare it to 'V' uppercase and if equal, we jump to DISPLAY. Next comes the test with lowercase 'v'. Here, it's the opposite: If it's not equal, return to the start since all possibilities have been seen. However, if 'v' is pressed, the program will continue without going back to START, and will naturally fall onto DISPLAY.
  +
  +
The display is done classically with Gemdos 9. Once this display is finished, we need to go back to the beginning. Here, no need for a test because we must absolutely go back. We therefore use an unconditional branch command (unconditional) which is read as BRANCH ALWAYS (always branch) and is written as BRA.
  +
  +
In case of choice 'Q' or 'q', there is a jump to EXIT and therefore to the Gemdos 0 function which ends the program.
  +
  +
Do not hesitate to modify this program, to try other tests, to play with VT52, before moving on to the next one.
  +
  +
("A few hours pass..." In ('Le manoir de Mortevielle') act 2 scene III)
  +
  +
Now take listing number 3. We will study number 2 last due to its slightly longer length.
  +
  +
The goal of this listing is to create a display somewhat similar to that of schedules in train stations or airports: each letter is not displayed all at once but 'searched for' in the alphabet.
  +
  +
First, clear the screen by displaying Escape and 'E' with Gemdos 9: nothing but the usual for you now!
  +
  +
Then it gets more complicated. We place the address of TXT_FINAL in A6. Let's see what is at the label 'TXT_FINAL': we find the sentence to be displayed.
  +
  +
Now, let's VERY carefully observe what is at the address TXT. We see 27,"Y",42. Looking at our VT52 sheet, we find that this corresponds to a function placing the cursor at a specific place on the screen. We also notice 2 things:
  +
  +
1) The command is incomplete.
  +
2) A phrase displayed, for example with Gemdos 9, must end with 0, which is not the case here!
  +
Indeed, the phrase is incomplete if we only read this line. Let's take a look at the next line. We find 42, which might be the continuation of the command (thus we have escape+Y+42+42), and a line further down we find two zeros. We can also notice that although the phrase starts at the label TXT, the second line also has a label ('COLUMN') as does the third line ('LETTER').
  +
  +
Let's imagine now that we have a letter instead of the first zero in front of the label LETTER. If we display this phrase, we will see this letter appear on the 10th column of the 10th line (revise the Escape+Y command on the VT52 sheet).
  +
  +
Let's then imagine that we add 1 to the number at the label COLUMN and repeat the display. We would see our letter still on the 10th line, but now on the 11th column!
  +
This is what we are going to do, making it even more complicated. Place the ASCII code 255 (this is the maximum allowed code as ASCII codes are encoded on a byte) instead of the first zero of the label LETTER. We do this by MOVE.B #255,LETTER. Then we add 1 to the column number with ADD.B #1,COLUMN and then ask ourselves the following question: is the letter I am going to display (currently with ASCII code 255) the same as the one in the final sentence? To find out, we need to take this letter from that sentence. Since we have placed the address of this sentence in A6, we take it while advancing A6 to point to the second letter. MOVE.B (A6)+,D6
  +
  +
What if the letter we just retrieved was ASCII code 0?
  +
This would mean that we are at the end of the sentence and
  +
thus it's time to exit!!! We therefore compare D6, which contains
  +
the ASCII code of the letter, with 0.
  +
  +
CMP.B #0,D6
  +
BEQ END if it's equal, bye bye!
  +
  +
Phew! It's not the last letter; we can therefore display
  +
our phrase. This is done with Gemdos 9, by passing the address
  +
of the beginning of the phrase in the stack. This address is TXT, and
  +
Gemdos will display until it encounters 0. It will therefore
  +
display 27,"Y",42,43,255,0. Having done this, let's compare the letter we
  +
just displayed, which is at the label LETTER,
  +
with the one in D6, which was taken from the model sentence.
  +
  +
If it's the same, we go back up to the label NEXT,
  +
we change the column, we take the next letter in
  +
the model sentence and we start over. But what if it's not the
  +
same letter?
  +
  +
Well, we decrease the ASCII code of 'LETTER' by 1 (SUB.B
  +
#1,LETTER) and we re-display our phrase which is now
  +
27,"Y",42,43,254,0
  +
  +
Got it?
  +
  +
This is also a good study that will help you get by.
  +
  +
Don't abandon this listing saying "oh, I've more or less
  +
understood"
  +
you must PERFECTLY UNDERSTAND. Don't hesitate to use
  +
MONST to go and see what's happening at the address of LETTER. To
  +
get the addresses of the labels, type L when you are under
  +
MONST. It is entirely possible to ask that the memory window
  +
(the 3rd one) points to a part showing you LETTER and
  +
COLUMN, then go back to window 2 to step through the program. This will allow you to see the memory content changing while watching the instructions execute.
  +
  +
There remains a small point to clarify, concerning the word EVEN which
  +
is located in the data section. We have already understood (or at least
  +
I hope) that the assembler only translates instructions into numbers so
  +
that they are understood by the machine.
  +
We have also seen that the 68000 doesn't like odd addresses
  +
(we haven't seen it yet, and it's just as well...). When the assembler translates
  +
mnemonics into numbers, there's no worry, as they are always
  +
translated into an even number of bytes.
  +
  +
Unfortunately, this is not necessarily the case with data. In
  +
this case, the label CLS starts at an even address (because
  +
before it, there are only mnemonics) but at the address CLS, there are
  +
only 3 bytes. We deduce that the label TXT will be
  +
at an odd address. To avoid this, the assembler provides
  +
an instruction that imposes an even address
  +
for the following label, EVEN meaning even in
  +
English.
  +
  +
Note: Just like SECTION DATA, DC.B, DC.W or DC.L, EVEN is not
  +
a 68000 instruction. It's an order that will be understood by
  +
the assembler.
  +
  +
Generally, these orders are understood by many assemblers
  +
but sometimes there are variants. Thus some assemblers
  +
require .DATA or DATA and not SECTION DATA. Similarly,
  +
for some assemblers, labels (tags) must
  +
be followed by two points. You have to check in the documentation of your assembler and work with it, it's the only solution!
  +
Note, however, that this does not change the mnemonics!
  +
  +
Let's now move to the last listing of this course, number 2.
  +
  +
This listing displays a Degas image whose name is written in the
  +
data section, at the label FILE_NAME. It is evident that this
  +
name must not contain a cedilla but rather a backslash, which my printer refused to print!
  +
  +
Only 2 or 3 small things are unknown to you. First of all
  +
the instruction TST.W (just after opening the image file)
  +
This instruction is read as Test, and so here we read:
  +
Test word D0.
  +
  +
This simply means doing CMP.W #0,D0.
  +
  +
The second thing still unknown to you is the SECTION BSS.
  +
  +
We saw in the previous lessons that initialized variables
  +
were placed in a SECTION DATA. Well, uninitialized variables are placed in a section named SECTION BSS. This
  +
section has an interesting feature: the data in it
  +
doesn't take up any space on the disk!
  +
  +
So if you have a 3 kilobyte program but in this
  +
program, you want to reserve 30 kilo to be able to load
  +
different things later, if you reserve by doing THING
  +
DC.B 30000 your program, once on a floppy disk, will be 33000 bytes. However, if you reserve by THING DS.B 30000, your program will only occupy 3 Ko on the disk.
  +
  +
These directives placed in the BSS section are quite different from
  +
those placed in the data section.
  +
  +
THING DC.W 16 reserves space for 1 word which is
  +
initialized with the value 16.
  +
THING DS.W 16 reserves space for 16 words.
  +
  +
It is important to be careful with this, as it's a rare but possible mistake!
  +
If we note in the BSS section
  +
  +
THING DS.W 0
  +
MACHINE DS.W 3
  +
  +
When we look for the label THING and write data
  +
into it, this data cannot go INTO thing since
  +
this label corresponds to nothing (0 words reserved) and therefore
  +
we will write into MACHINE, perhaps overwriting what we had previously placed there.
  +
  +
  +
Well, normally you should know enough to use the
  +
Gemdos, the Bios, and the Xbios (I remind you that the Bios is called by Trap #13, exactly in the same way as Gemdos
  +
or Xbios).
  +
  +
You should therefore be able to create the following programs:
  +
  +
Requesting the name of an image. Type the name on the keyboard, then the
  +
program reads the image from the floppy disk and displays it. Warns and
  +
asks for another name if the image is not found. If X is typed,
  +
it's the end and the program exits.
  +
  +
Reading the first sector of the first track of the floppy disk.
  +
If the first byte of this sector is equal to $61 (it's the code
  +
of the BRA instruction), ring ring ring by displaying the
  +
ASCII code 7 (bell), display "infected floppy", wait
  +
for a key press and bye bye. If the floppy is not infected, display
  +
"I thank the Fierce Rabbit for his excellent assembler courses,
  +
super well done that it's him the best" and exit.
  +
  +
You can also try vaccination, by erasing the first byte (put to 0, for example).
  +
  +
Another interesting example to program. You have seen in the
  +
listing 3 how to take data located one after the other
  +
in a string: D6 indeed contains first F then E then R
  +
etc... Imagine that you have 3 strings: the first contains numbers
  +
corresponding to the display column, the second numbers
  +
corresponding to the line and the third numbers
  +
corresponding to colors, all these data in VT52 format.
  +
(look at Escape+'Y' and Escape+'b' or Escape+'c'). Place an address
  +
register for each of these lists, read a number from
  +
each, place this number in a sentence:
  +
  +
(27,"Y",X1,X2,27,"b",X3,"*",0)
  +
  +
X1 being the number taken from list 1
  +
X2 being the number taken from list 2
  +
X3 being the number taken from list 3
  +
  +
Thus, you display at different positions a star, in different
  +
colors according to the displays.
  +
  +
Advice: Try to make as many small programs as possible, to
  +
well understand the use of VT52, Gemdos, Bios, and
  +
Xbios. This will also help you get used to commenting
  +
your programs, organizing them, hunting for sneaky errors.
  +
  +
Carefully scrutinize your programs using MONST. For the
  +
moment, errors will still be very easy to find, so it is
  +
imperative to train very, very well!!!
  +
  +
If one of your programs doesn't work, take your time and think.
  +
It's often a HUGE error that is right in front of
  +
you: note the values of the registers on paper, step through
  +
the program under MONST, think well about the principle of the
  +
stack with its advantages but also its disadvantages. Use the
  +
principle of subroutines by passing parameters to them in order to master this principle very well.
  +
  +
You will receive the second series of courses in about a month. This
  +
gives you time to work. Especially deepen your understanding, and resist
  +
the temptation to disassemble programs to try to
  +
understand something, or the temptation to take large
  +
sources thinking you'll find fantastic things. This is not
  +
the right solution, on the contrary!!!
  +
  +
If you really want to do something big right away, then
  +
make a word processor. With VT52, Gemdos, and Bios,
  +
it's entirely possible. Of course, there won't be a mouse and
  +
you'll need to type the file name instead of clicking in the se-
  +
lector, but imagine the look on your neighbor's face who brags about his
  +
scrolling by understanding 1 instruction out of 50 when you tell him
  +
"Scrolling is for kids... I'm making a word processor!!"
  +
  +
From the bottom of my heart, good luck The Fierce Rabbit (from 44E)
  +
  +
Provisional summary of series 2
  +
Reprogramming Traps,
  +
Disassembling and commenting on a program of which we are not the authors,
  +
Screen memory
  +
Animations (vertical, horizontal scrolling, sprites, ...),
  +
Music (with and without digits,
  +
Sound trackers...),
  +
Creation of routines not using the operating system,
  +
GEM and resources etc....
   
 
</pre>
 
</pre>
 
Back to [[ASM_Tutorial]]
 
Back to [[ASM_Tutorial]]
[[Category: ASSEMBLER 68000 on ATARI ST Part 1 ]]
+
[[Category: 68000 ASSEMBLY ON ATARI ST Part 1 ]]

Latest revision as of 00:01, 17 December 2023

   ******************************************************************
   *                                                                *
   *              68000 ASSEMBLER COURSE ON ATARI ST                *
   *                                                                *
   *                    by The Fierce Rabbit (from 44E)             *
   *                                                                *
   *                            Lesson number 7                     *
   *                                                                *
   ******************************************************************

   We now approach the seventh lesson in the series. The entire 
   course is in 2 series (well, at the time I'm typing these lines, 
   that's what is planned!), this one is the last of the first!

   At the end of this one and if you have very carefully and very 
   scrupulously followed the previous 6 lessons, you should be 
   able to display images, save files etc...

   But first let's go back to our stack and the question from the 
   previous lesson. Did you find the error?

   Well look at the value of A7 before stacking $12345678 and
   $23456, and compare it to the value at the end of the program. Alas!
   it is not the same! Normal, if we count the stackings and 
   the unstackings, we realize that we have stacked 8 
   bytes more than we have unstacked. Indeed, since we have
   retrieved our 2 numbers by first saving A7 in A0,
   we did not touch A7 at the time of recovery.
   Fortunately, though, because the routine return would have been modified!

   Based on the principle of unstacking in reverse order, we must
   therefore correct the stack once back from the subroutine. As we
   have stacked by doing -(SP) we must add so that the stack becomes
   as before. Having stacked 2 numbers of 4 bytes each, 
   we must add 8 bytes to the stack address to correct it
   as it should be. We have already seen how to increase an 
   address, with ADDA.

   It is therefore appropriate to add right after the line BSR AJOUTE an
   addition on SP, by doing ADDA.L #8,SP (which reads ADD ADDRESS 
   LONG 8 STACK POINTER)

   A call to a subroutine by passing parameters on the
   stack will therefore typically be of the kind:

          MOVE.W     #$1452,-(SP)
          MOVE.L     #$54854,-(SP)
          MOVE.L     #THING,-(SP)
          BSR        TINKERING
          ADDA.L     #10,SP

   We pass the word of value $1452 in the stack (modified thus
   of 2 bytes), the long word of value $54854 in the stack (modified
   of 4 bytes), the address spotted by the label THING in the stack
   (modified of 4 bytes) then we go towards our subroutine. Upon 
   return correction of 2+4+4=10 bytes of the stack pointer to return
   to the original state.

The stack has a small peculiarity. We saw in the previous lessons that the 68000 is a 16/32-bit microprocessor. It has a hard time accessing odd addresses. However, if we start stacking bytes instead of just words or long words, the Stack Pointer can very easily point to an odd address, which could crash our machine.

Type the following program:

         MOVE.L     #$12345678,D0
         MOVE.L     D0,-(SP)
         MOVE.B     D0,-(SP)
         MOVE.L     #$AAAAAAAA,D1

Assemble and then step through in MOnst, carefully observing the address of the SP (the one visible in A7).

We notice that the stack pointer changes by 4 when we do MOVE.L D0,-(SP) but changes by 2 when we do MOVE.B D0,-(SP), even though we might expect a change of 1! Therefore, errors caused by odd addresses are avoided with the stack. Thank you, Mr. MOTOROLA!

(Note: this is a peculiarity of the A7 and A7' registers. If we had worked with A3 instead of SP, it would have had an odd address. It's the type of usage made of the stack that led the people at MOTOROLA to create this difference.)

Now let's approach the final chapter of this first series:

                              THE 'TRAP'

A TRAP instruction is comparable to a BSR instruction. It acts as a branch to a routine. However, unlike the BSR instruction, which requires a label to find the routine, the TRAP instruction is satisfied with a number. This number can vary from 0 to 15. When the 68000 encounters a TRAP instruction, it looks at its number and acts accordingly. Remember the very first lessons, where we talked about the principle used by the 68000 when it found the T bit (trace mode) of the SR (status register) at 1? Jump to the first kilobyte of memory (exception vector table), search for address $24, look in the tube at this address, find a long word, this long word is the address of the routine, and go to this address to execute the routine.

Look at the sheet that lists the exception vectors, and take a look at vectors 32 to 47. There are our TRAP vectors!!! When the 68000 encounters, for example, the instruction TRAP #8, it rushes to address $0A0 to find the address of the routine it must execute.

At first glance, this seems quite complicated for not much! Indeed, you have to plan your routine, put it in memory, and then place its address in the vector. More complicated than a BSR, especially since BSR KEYBOARD_ADJUSTMENT is more telling than a TRAP #5 or a TRAP #12!!!

Here, we go back again (I told you that EVERYTHING was important in these courses!!!!!) to remember the concept of User mode and Supervisor mode. The Supervisor has access to all memory and all instructions, not the User.

If it's about forbidding the User assembler instructions such as RESET, our User will not be too bothered. On the other hand, it's concerning memory that everything will get seriously complicated. Do you want to know the resolution in which your machine is? It's easy, it's noted at address $FF8260.

You want to change the color palette? Nothing simpler, it is noted at $FF8240. Print a small text? Easy, just use the communication registers to the outside of the sound chip (surprising, isn't it!). It's located at $FF8800 and $FF8802.

Sorry??? What??? You are a User??? Ah well.... Because it's embarrassing... All these addresses are located in the memory area only accessible to the Supervisor.....

The User is quite stuck and the possibilities are greatly reduced. Fortunately, the TRAPs are there!!! Thanks to this system, the user will have access to areas that are normally forbidden to him. Not directly, of course, but thanks to the supervisor. The supervisor has indeed created routines that he placed in memory and whose addresses are in the TRAP vectors. These routines are executed in supervisor mode and attack the protected memory areas at will. When the User wants to use them, he calls them through the TRAPs. The protection is therefore well assured because the User only triggers a routine of which he generally only knows the parameters to pass and the type of message he will receive in response. This is how we can access the operating system of our Atari!!!

xA quick reminder: what is an operating system?

The first one who says it's GEM gets a slap. GEM is the user interface, not the operating system.

The operating system (or Operating System) in our case is TOS. The confusion between User Interface and Operating System comes from the fact that some operating systems also integrate a user interface: for example, this is the case with MS DOS on PC.

The operating system is a set of routines that allow the machine to be exploited. These multiple routines allow, for example, to display a character on the screen, open a file, format a floppy disk track, send a byte to the MIDI port, etc... In fact, all the basic 'stuff', but never complicated things. An operating system routine will not, for example, allow you to read the content of a file on the floppy disk. Indeed, this requires several operations with tests each time:

File opening: does it exist, is the floppy disk not damaged, etc...
Positioning the pointer in the file: did the positioning go well?

Reading: Haven't we tried to read too many bytes, etc, etc....

So, we often need several calls to different routines to achieve what we want.

It is always possible to do without the operating system, especially when programming in assembler. Indeed, all the routines of the OS (abbreviation of Operating System) are intended for common use, just like the routines of the User Interface.

This often explains the rewriting of very small parts of the system to use only what is strictly necessary. For example, GEM's mouse management routine must take care of the mouse, but also the keyboard, MIDI, and joystick. For a game, it might be interesting to rewrite this routine to manage only the joystick and thus have a routine that 'sticks' more to the need.

We will see much later how to look into the operating system in order to be able to create our own routines. Before that, let's simply use this system!

We will therefore call it using TRAPs.
4 TRAPs are 'normally' accessible in the ST:

TRAP #1      GEMDOS routines
TRAP #2      GEM routines
TRAP #13     BIOS routines
TRAP #14     Extended BIOS routines (eXtended Bios, so XBIOS)

GEMDOS   = Graphic Environment Manager Disk Operating System
GEM      = Graphic Environment Manager (subsequently divided into AES, VDI, etc.. A chapter of the second series will be dedicated to this)
BIOS     = Basic Input Output System
XBIOS    = Extended Basic Input Output System

The other TRAP vectors (0, 3 to 12, and 15) are, of course, active but have no routines assigned to them. We can use them as long as we put our routines in them before, which will be the subject of the first course of the second series.

We notice that TRAP #1 allows us to call GEMDOS. However, there is not just one GEMDOS routine but a good quantity. Moreover, these routines sometimes require parameters. How to pass them? Simply through the stack!!!

Type the following program:

         MOVE.W     #65,-(SP)
         MOVE.W     #2,-(SP)
         TRAP       #1
         ADDQ.L     #4,SP

         MOVE.W     #7,-(SP)
         TRAP       #1
         ADDQ.L     #2,SP
         MOVE.W     #0,-(SP)
         TRAP       #1
         ADDQ.L     #2,SP

Assemble this program but don't debug it, launch it by Alternate+X. You will see an A appear on your ST screen. Press a key and voila, you return to GENST! Let's analyze what we did because a lot of things happened and let's admit it, we didn't see anything!!!!

First of all, we called the Cconout() function of Gemdos. We called Gemdos with TRAP #1, but this instruction sent us to a set of routines, all belonging to Gemdos. To indicate to this main routine which Gemdos subroutine we want to go to, we passed the number of this subroutine in the stack. Always starting from the principle of the last entered first out, it is evident that this number must be stacked last so that it can be unstacked first by the main Gemdos routine, so that it can orient itself towards the subroutine that interests us. The Cconout function having the number 2, we therefore did MOVE.W #2,-(SP). (see above to remember that 2 can very well be coded on a byte but, as we work towards the stack, it will be taken as a word anyway).

Now, having found 2 as a parameter, Gemdos heads towards this barbarically named routine, whose function is to display a character on the screen. Once reaching this routine, Gemdos will seek to know which character to display. That's why we placed the ASCII code of this character on the stack with MOVE.W #65,-(SP).

Note: For the assembler, the ASCII code can be replaced by the letter itself. We could have written MOVE.W #"A",-(SP) without forgetting the quotes!

Returning from the TRAP, we need to correct the stack to avoid the problem that was the subject of the beginning of this course. We had stacked a word, so 2 bytes, and then another word, making a total of 4 bytes. We are therefore going to add 4 to the SP. We take advantage here of an operation faster than ADDA, ADDQ which reads add quick. This addition is allowed up to 8 inclusive. For example, it is not possible to do ADDQ.L #12,D1

Then we do the same kind of thing again, with function 7 of GEMDOS (named Crawcin) which expects no parameter, that's why we just pass its number on the stack. This function waits for a key press. Having passed a parameter on a word, we correct the stack by 2 after returning from the TRAP.

The program ends with function 0 of GEMDOS (Ptermo) which frees the memory occupied by our program and ends it for good. This routine does not expect a parameter, we only pass its number in the stack, so a correction of 2. Note: the stack correction for the Ptermo function is there only for educational purposes. This function ending the program, our last instruction ADDQ.L #2,SP will never be reached!

Several things now. First, don't be surprised by the strange names of the GEMDOS, BIOS, or XBIOS functions. These are the real names of these functions. In assembler, we will not use them directly since the call is made by a number, but in C, for example, this is how these functions are called. In the ST MAG assembler courses (whose educational virtues are more than questionable), we can read that the names of these functions were chosen randomly and that the Malloc() function, for example, could have been called Mstroumph(). This is ridiculous! Each of the names is, as always in computing, the abbreviation of an Anglo-Saxon expression that concretely indicates the purpose or function. Thus Malloc means Memory Allocation, this GEMDOS function is therefore for reserving a part of memory!!! Unfortunately, many books pass over this 'detail' and only provide the abbreviation.

This does not prevent you from needing a list of all the functions of GEMDOS, BIOS, and XBIOS. These functions are described in the Developer's Book, in the Bible, but also in the last pages of the GFA 3 documentation.

Note: in the GFA documentation, the GEMDOS 32 function is missing, which allows switching to Supervisor mode. This mode is of limited interest to you for now, so don't panic, we will describe all this in the second series.

Let's continue for now with small examples.
Let's display a sentence on the screen instead of a letter.
This will be done with the following program:

         MOVE.L     #MESSAGE,-(SP)        address of the text
         MOVE.W     #9,-(SP)   number of the function
         TRAP       #1         call gemdos
         ADDQ.L     #6,SP      stack correction

* waiting for a key press

         MOVE.W     #7,-(SP)   number of the function
         TRAP       #1         call GEMDOS
         ADDQ.L     #2,SP      stack correction

* end of the program

         MOVE.W     #0,-(SP)
         TRAP       #1

         SECTION DATA

MESSAGE   DC.B       "SALUT",0

Introducing a new feature: passing an address. Indeed, function 9 of the GEMDOS requires the address of the string of characters to be displayed as a parameter. So, we have given MESSAGE, which is the label, the tag used to locate the place in the memory where our sentence is located, just as we used a label AJOUTE to locate our subroutine in the previous lesson.

This message is a sequence of letters, each encoded on one byte. For this reason, we say that this string is a constant composed of bytes. We thus define a byte constant: Define Constant Byte, abbreviated as DC.B. Be aware that this is not a 68000 instruction! It's simply a notation for the assembler to say: 

"Don't try to assemble this as normal code, it's just a constant." Similarly, we define a zone.

Function 9 of GEMDOS requires that the sentence ends with 0, which explains its presence at the end.

Now, let's create a program following this schema:

- Display of an introduction text in reverse video;
- This text asks whether to exit or see a message;
- If the choice is to exit, then bye bye;
- Otherwise, display 'coucou' and ask again, etc...

Let's detail a bit more, translating this program into pseudo-code. This is how we call the way of presenting a sequence of operations in clear language, but whose organization already resembles programming.

   DISPLAY        "EXIT (Q) OR SEE THE MESSAGE (V)?"
   IF ANSWER=Q
        GO TO EXIT
   IF ANSWER=V
        DISPLAY "COUCOU"
        RETURN TO DISPLAY "EXIT...."
   IF ANSWER IS DIFFERENT RETURN TO DISPLAY "EXIT..."

For convenience, this listing is on a separate sheet (listing number 1 / Course number 7).

First, display the phrase that will serve as a menu, with the Gemdos function 9. This phrase is located at the label MENU, let's go see it to detail it. We first notice that it starts with 27. After looking at an ASCII code table, we note that this is the ASCII code for the Escape key. So, we are first trying to display Escape. But, as you surely know, this character is not printable!

   Impossible to display it on the screen!

This is quite normal! In fact, the goal here is not to actually display a character, but rather to call a set of routines, known as VT52. To call these routines, you need to display Escape. Seeing this, the system thinks:
   "Hmm, someone is trying to display Escape, so it's actually a call to VT52."

The VT52 emulator thus reacts, but what should it do? To find out, it will look at the letter following Escape. In this case, it is a capital E. Look at the annexes to this course series, there is one dedicated to VT52. We see that Escape followed by E clears the screen, so that's what will happen here.

Next, it was said in the 'specifications' of our program that the MENU should be displayed in reverse video.

So, let's consult the sheet on VT52. We find: Escape and lowercase 'p' = switches to reverse video writing. Just what we need! We therefore put 27,"p" in our phrase.

Three remarks:

   First, you must put Escape each time. Doing 27,"E","p" would have cleared the screen and then displayed p.

   Second, it's important to distinguish between uppercase and lowercase letters. Escape+E clears the screen but Escape+e activates the cursor!!!

   Third, in the listing, a letter can be represented by its 'character' or by its ASCII code.

So, if you want to display Salut, you can write the listing like this:
TXT       DC.B       "Salut",0
or like this:
   TXT    DC.B    83,97,108,117,116,0
It's also possible to mix data in decimal, binary, hexadecimal, and ASCII codes. For example, this:

TXT       DC.B       65,$42,%1000011,"D",0

   will display ABCD if this "phrase" is used with Gemdos 9.

This will be very useful when you need to display letters that are difficult to find on the keyboard. For the 'o' with umlaut, it's possible to do:

TXT       DC.B       "A bient",147,"t les amis.",0

Note: I hope that since the beginning, no one has read DC.B as "decebe"!!!! I remind you that it is read Define Constant Byte.

Let's continue exploring our program. So, our phrase clears the screen and then switches to reverse video. Then comes the text itself:

   EXIT (Q) OR SEE THE MESSAGE (V) ?

Next, a new VT52 command to switch back to normal video, then 2 ASCII codes that are also not printable. They are the carriage return codes. So, the cursor will be at the left of the screen, one line down. Finally, the 0 indicating the end of the phrase.

Once the 'menu' is displayed, we wait for a key press with Gemdos function number 7. This function returns a result in D0. This result is encoded in a long word, like this:

   Bits 0 to 7  ASCII code of the key
   Bits 8 to 15 set to zero
   Bits 16 to 23 keyboard code
   Bits 24 to 31 Indication of the keyboard toggle keys (shifts..)

In our case, we are only interested in the ASCII code of the pressed key. We will therefore compare the word of D0 with each of the ASCII codes we expect, namely Q, q, V, and v. This comparison will be made with a new instruction: Compare (CMP). As we are comparing a word, we note CMP.W, which we read as COMPARE WORD. We compare Q with D0 (we could have written CMP.W #81,D0 since 81 is the ASCII code of Q).

After this comparison, we need to test it. Here we enter the possibilities of conditional branching, that is, conditional branches.

Each of these instructions begins with the letter B, signifying BRANCH. In simple terms, these instructions can be read as:

   Go to a certain place if...

   But if what???

   Well, several conditions are available, which can be grouped into 3 categories:

   First, a category that reacts to the state of one of the bits of the Status Register:

     BCC  Branch if carry clear (carry bit at 0)
     BCS  Branch if carry set   (carry bit at 1)
     BNE  Branch if not equal   (zero bit at 0)
     BEQ  Branch if equal       (zero bit at 1)
     BVC  Branch if overflow clear (overflow bit at 0)
     BVS  Branch if overflow set   (overflow bit at 1)
     BPL  Branch if plus  (negative bit at 0)
     BMI  Branch if minus (negative bit at 1)


   A second category, reacting to the comparison of unsigned numbers.

     BHI  Branch if higher  (branch if greater than)
     BLS  Branch if lower or same (lower or equal)
   (BEQ and BNE can also be included in this category)


   A third category, reacting to the comparison of signed numbers.

     BGT Branch if greater than (if greater than)
     BGE Branch if greater or equal (if greater than or equal to)
     BLT Branch if lower than  (if less than)
     BLE Branch if lower or equal (if less than or equal)
    (BEQ and BNE can be included here again!)

   I am deeply sorry for the people at MICRO-APPLICATION (The Machine Language on ST, the Bible, the GEM Book, etc...) and for the journalist who writes the assembler courses in STMAG, but the BHS and BLO branches, despite being accepted by many assemblers, DO NOT EXIST!!!!

   Therefore, it is impossible to find them in an assembled listing, the assembler either converts them or rejects them.

   This set of conditional branching constitutes a set of commands of the type Bcc (branch conditionally)

   Let's continue our slow progression through the listing...
   The comparison is made, let's test it:

          CMP.W      #"Q",D0    is it the letter 'Q'?
          BEQ        EXIT       branch if equal 'exit'

   That is, if it's equal, jump to the label EXIT.
   If it's not equal, the program continues as if nothing happened and encounters a new test:

          CMP.W      #"q",D0    is it lowercase 'q'?
          BEQ        EXIT       branch if equal exit

   We then compare it to 'V' uppercase and if equal, we jump to DISPLAY. Next comes the test with lowercase 'v'. Here, it's the opposite: If it's not equal, return to the start since all possibilities have been seen. However, if 'v' is pressed, the program will continue without going back to START, and will naturally fall onto DISPLAY.

   The display is done classically with Gemdos 9. Once this display is finished, we need to go back to the beginning. Here, no need for a test because we must absolutely go back. We therefore use an unconditional branch command (unconditional) which is read as BRANCH ALWAYS (always branch) and is written as BRA.

   In case of choice 'Q' or 'q', there is a jump to EXIT and therefore to the Gemdos 0 function which ends the program.

   Do not hesitate to modify this program, to try other tests, to play with VT52, before moving on to the next one.

   ("A few hours pass..." In ('Le manoir de Mortevielle') act 2 scene III)

   Now take listing number 3. We will study number 2 last due to its slightly longer length.

   The goal of this listing is to create a display somewhat similar to that of schedules in train stations or airports: each letter is not displayed all at once but 'searched for' in the alphabet.

   First, clear the screen by displaying Escape and 'E' with Gemdos 9: nothing but the usual for you now!

   Then it gets more complicated. We place the address of TXT_FINAL in A6. Let's see what is at the label 'TXT_FINAL': we find the sentence to be displayed.

   Now, let's VERY carefully observe what is at the address TXT. We see 27,"Y",42. Looking at our VT52 sheet, we find that this corresponds to a function placing the cursor at a specific place on the screen. We also notice 2 things:

   1) The command is incomplete.
   2) A phrase displayed, for example with Gemdos 9, must end with 0, which is not the case here!
      Indeed, the phrase is incomplete if we only read this line. Let's take a look at the next line. We find 42, which might be the continuation of the command (thus we have escape+Y+42+42), and a line further down we find two zeros. We can also notice that although the phrase starts at the label TXT, the second line also has a label ('COLUMN') as does the third line ('LETTER').

   Let's imagine now that we have a letter instead of the first zero in front of the label LETTER. If we display this phrase, we will see this letter appear on the 10th column of the 10th line (revise the Escape+Y command on the VT52 sheet).

   Let's then imagine that we add 1 to the number at the label COLUMN and repeat the display. We would see our letter still on the 10th line, but now on the 11th column!
   This is what we are going to do, making it even more complicated. Place the ASCII code 255 (this is the maximum allowed code as ASCII codes are encoded on a byte) instead of the first zero of the label LETTER. We do this by MOVE.B #255,LETTER. Then we add 1 to the column number with ADD.B #1,COLUMN and then ask ourselves the following question: is the letter I am going to display (currently with ASCII code 255) the same as the one in the final sentence? To find out, we need to take this letter from that sentence. Since we have placed the address of this sentence in A6, we take it while advancing A6 to point to the second letter. MOVE.B (A6)+,D6

What if the letter we just retrieved was ASCII code 0?
   This would mean that we are at the end of the sentence and
   thus it's time to exit!!! We therefore compare D6, which contains
   the ASCII code of the letter, with 0.

          CMP.B      #0,D6
          BEQ        END        if it's equal, bye bye!

   Phew! It's not the last letter; we can therefore display
   our phrase. This is done with Gemdos 9, by passing the address
   of the beginning of the phrase in the stack. This address is TXT, and
   Gemdos will display until it encounters 0. It will therefore
   display 27,"Y",42,43,255,0. Having done this, let's compare the letter we
   just displayed, which is at the label LETTER,
   with the one in D6, which was taken from the model sentence.

   If it's the same, we go back up to the label NEXT,
   we change the column, we take the next letter in
   the model sentence and we start over. But what if it's not the
   same letter?

   Well, we decrease the ASCII code of 'LETTER' by 1 (SUB.B
   #1,LETTER) and we re-display our phrase which is now
   27,"Y",42,43,254,0

   Got it?

   This is also a good study that will help you get by.

   Don't abandon this listing saying "oh, I've more or less
   understood"
   you must PERFECTLY UNDERSTAND. Don't hesitate to use
   MONST to go and see what's happening at the address of LETTER. To
   get the addresses of the labels, type L when you are under
   MONST. It is entirely possible to ask that the memory window
   (the 3rd one) points to a part showing you LETTER and
   COLUMN, then go back to window 2 to step through the program. This will allow you to see the memory content changing while watching the instructions execute.

   There remains a small point to clarify, concerning the word EVEN which
   is located in the data section. We have already understood (or at least
   I hope) that the assembler only translates instructions into numbers so
   that they are understood by the machine.
   We have also seen that the 68000 doesn't like odd addresses
   (we haven't seen it yet, and it's just as well...). When the assembler translates
   mnemonics into numbers, there's no worry, as they are always
   translated into an even number of bytes.

   Unfortunately, this is not necessarily the case with data. In
   this case, the label CLS starts at an even address (because
   before it, there are only mnemonics) but at the address CLS, there are
   only 3 bytes. We deduce that the label TXT will be
   at an odd address. To avoid this, the assembler provides
   an instruction that imposes an even address
   for the following label, EVEN meaning even in
   English.

   Note: Just like SECTION DATA, DC.B, DC.W or DC.L, EVEN is not
   a 68000 instruction. It's an order that will be understood by
   the assembler.

   Generally, these orders are understood by many assemblers
   but sometimes there are variants. Thus some assemblers
   require .DATA or DATA and not SECTION DATA. Similarly,
   for some assemblers, labels (tags) must
   be followed by two points. You have to check in the documentation of your assembler and work with it, it's the only solution!
   Note, however, that this does not change the mnemonics!

   Let's now move to the last listing of this course, number 2.

   This listing displays a Degas image whose name is written in the
   data section, at the label FILE_NAME. It is evident that this
   name must not contain a cedilla but rather a backslash, which my printer refused to print!

   Only 2 or 3 small things are unknown to you. First of all
   the instruction TST.W (just after opening the image file)
   This instruction is read as Test, and so here we read:
   Test word D0. 

   This simply means doing CMP.W #0,D0.

   The second thing still unknown to you is the SECTION BSS.

   We saw in the previous lessons that initialized variables
   were placed in a SECTION DATA. Well, uninitialized variables are placed in a section named SECTION BSS. This
   section has an interesting feature: the data in it
   doesn't take up any space on the disk!

   So if you have a 3 kilobyte program but in this
   program, you want to reserve 30 kilo to be able to load
   different things later, if you reserve by doing THING
   DC.B 30000 your program, once on a floppy disk, will be 33000 bytes. However, if you reserve by THING DS.B 30000, your program will only occupy 3 Ko on the disk.

   These directives placed in the BSS section are quite different from
   those placed in the data section.

THING   DC.W     16   reserves space for 1 word which is
                        initialized with the value 16.
THING   DS.W     16   reserves space for 16 words.

   It is important to be careful with this, as it's a rare but possible mistake!
   If we note in the BSS section

THING      DS.W       0
MACHINE    DS.W       3

   When we look for the label THING and write data
   into it, this data cannot go INTO thing since
   this label corresponds to nothing (0 words reserved) and therefore
   we will write into MACHINE, perhaps overwriting what we had previously placed there.


   Well, normally you should know enough to use the
   Gemdos, the Bios, and the Xbios (I remind you that the Bios is called by Trap #13, exactly in the same way as Gemdos
   or Xbios).

   You should therefore be able to create the following programs:

   Requesting the name of an image. Type the name on the keyboard, then the
   program reads the image from the floppy disk and displays it. Warns and
   asks for another name if the image is not found. If X is typed,
   it's the end and the program exits.

   Reading the first sector of the first track of the floppy disk.
   If the first byte of this sector is equal to $61 (it's the code
   of the BRA instruction), ring ring ring by displaying the
   ASCII code 7 (bell), display "infected floppy", wait
   for a key press and bye bye. If the floppy is not infected, display
   "I thank the Fierce Rabbit for his excellent assembler courses,
   super well done that it's him the best" and exit.

   You can also try vaccination, by erasing the first byte (put to 0, for example).

   Another interesting example to program. You have seen in the
   listing 3 how to take data located one after the other
   in a string: D6 indeed contains first F then E then R
   etc... Imagine that you have 3 strings: the first contains numbers
   corresponding to the display column, the second numbers
   corresponding to the line and the third numbers
   corresponding to colors, all these data in VT52 format.
   (look at Escape+'Y' and Escape+'b' or Escape+'c'). Place an address
   register for each of these lists, read a number from
   each, place this number in a sentence:

    (27,"Y",X1,X2,27,"b",X3,"*",0)

   X1 being the number taken from list 1
   X2 being the number taken from list 2
   X3 being the number taken from list 3

   Thus, you display at different positions a star, in different
   colors according to the displays.

   Advice: Try to make as many small programs as possible, to
   well understand the use of VT52, Gemdos, Bios, and
   Xbios. This will also help you get used to commenting
   your programs, organizing them, hunting for sneaky errors.

   Carefully scrutinize your programs using MONST. For the
   moment, errors will still be very easy to find, so it is
   imperative to train very, very well!!!

   If one of your programs doesn't work, take your time and think.
   It's often a HUGE error that is right in front of
   you: note the values of the registers on paper, step through
   the program under MONST, think well about the principle of the
   stack with its advantages but also its disadvantages. Use the
   principle of subroutines by passing parameters to them in order to master this principle very well.

   You will receive the second series of courses in about a month. This
   gives you time to work. Especially deepen your understanding, and resist
   the temptation to disassemble programs to try to
   understand something, or the temptation to take large
   sources thinking you'll find fantastic things. This is not
   the right solution, on the contrary!!!

  If you really want to do something big right away, then
   make a word processor. With VT52, Gemdos, and Bios,
   it's entirely possible. Of course, there won't be a mouse and
   you'll need to type the file name instead of clicking in the se-
   lector, but imagine the look on your neighbor's face who brags about his
   scrolling by understanding 1 instruction out of 50 when you tell him
   "Scrolling is for kids... I'm making a word processor!!"

     From the bottom of my heart, good luck The Fierce Rabbit (from 44E)

                   Provisional summary of series 2
   Reprogramming Traps,
   Disassembling and commenting on a program of which we are not the authors,
   Screen memory 
   Animations (vertical, horizontal scrolling, sprites, ...),
   Music (with and without digits,
   Sound trackers...),
   Creation of routines not using the operating system,
   GEM and resources etc....

Back to ASM_Tutorial