
First Steps
===========

Contents
--------
1/ Assumptions
2/ Discussion ( monalog ??? )
3/ Fundementals
   3.1/ The Assembler
   3.2/ Labels
   3.3/ Program Layout
   3.4/ Operation Size
   3.5/ Pseudo Op's
   3.6/ Number Base
4/ Instructions
   4.1/ RTS
   4.2/ MOVE
5/ Apendicies
   a1/ Assembling Notes
   a2/ Exersises
   a3/ ASCII Set

1 Assumptions
-------------

 I am assuming you are using Devpac for this tutorial, with all the include
files. I doubt if the include files of other assemblers are the same. If you
are using another assembler dont panic, I will try to get help in converting
the code somehow so it will work with any assembler I am informed of ( except
A68K which I've given up with totaly even though it is a good assembler ).
DevpacII realy is a good buy for the beginner, the working enviroment is ideal
and you can assemble to ram and run a program from within it. I dont believe
Argasm lets you do this.

 Also I expect you to know how to use Devpac to assemble a source file to
memory, ram: disk and floppy disk. It will also help if you have 2 drives.

2 Discussion
------------

 Well here is the first installment for all you beginners out there. I am
going to progress at a fairly slow pace I'm afraid so dont expect to be
writing spreadsheets or mega demos just yet.

 For the purpose of this discussion I would like you to think of your Amiga
as a brain ( the 68000 ) that's connected to some memory ( 512k+). The brain
cannot think for itself but it can follow a set of instructions stored in its
memory. The instructions let you test memory, move data around in memory and
preform simple and boolean arithmetic operations on data.
 
 Before we consider the brain any further lets examine its memory. The memory
is made up of loads ( and loads and loads ... ) of pidgeon holes each of which
can contain a value between 0 and 255 ( 1 byte of information ). So the brain
can distinguish between each pidgeon hole each has its own unique address.
What the brain spends most of its time doing is fetching data from a pidgeon 
hole, doing something to it and then putting it back into a pidgeon hole.

 The brain has two sets of internal pidgeon holes ( called registers ). One
set is used to store data ( the data registers d0->d7 ) and the other to 
store the address of a pidgeon hole in memory ( the address registers a0->a7 ).
There are 8 of each type of register. 

 The brain works with its internal registers much faster than it works with
pidgeon holes in memory and to speed things up further a register can hold
the contents of four memory pidgeon holes, so in one foul swoop the contents
of four consecutive memory locations can be moved into an internal register.

3 Fundementals
==============

 Before looking at the instruction set we have to cover some of the basics
of using an assembler and assembly language programming.

3.1 The Assembler
-----------------

 The language we are programming in is called Assembly Language. The 68000
does not understand this language in the form we write it, so we use an
assembler to convert it to true Machine Code which the 68000 can understand.
True machine code is a long string of 0's and 1's and as such would not make 
much sense to a mere mortal ( de-bugging would be a nightmare ). Assembly
Language instructions convert to machine instructions on a one to one basis
and for this reason assembly language is often called machine code. High 
Level languages such as BASIC, Pascal, Fortran and C differ in that their
instructions convert to machine instructions on a one to many basis ie one
instruction in BASIC would produce loads of machine instructions.

3.2 Labels
----------

 A label is a convinient name of our choosing that we assign to an address in
memory. Why ? well its far easier to remember a label such as scroll_up than
it is to remember the address of the scroll up routine which may look like
$00CD4A0C, dont you agree ! The 68000 does not recognise labels, infact the
labels we use are not even passed to the 68000. The assembler converts them
into the correct address for us. There are some restrictions on the names you
can use for labels, see the Devpac manual for more details. A label must 
always start in the left most coloum of the display, more on this later.
As you will soon discover labels are a very useful tool.
 
3.3 Program Layout
------------------

 The way your program is set out on the page is important as the assembler 
expects you to follow certain rules. The diagram below shows the diffirent 
fields of the display.

|  LABEL   |  INSTRUCTION  |      OPERAND        |  COMMENT  |
|          |               | source,destination  |           |
|          |               |                     |           |
|          |               |                     |           |
|          |               |                     |           |
|          |               |                     |           |

 The rules you must follow are:
 
1/ As already stated labels must start in the left most coloum of the display
2/ At least one space ( or TAB ) must seperate each field
3/ The LABEL and COMMENT fields may be left blank
4/ Blank lines are allowed ( the assembler ignores them  )
5/ Any line starting with a ; is ignored and may be used to start a comment
   line. The ; must be in the left most coloum as for a label
   
3.4 Operation Size
------------------

 Since the 68000 can handle up to four bytes at a time we have to specify the
size of data we wish to operate on. We can choose to operate on a byte, a 
word ( 2 bytes ) or a long word ( 4 bytes ). We specify which size is required
by following the instruction immidiately by either .b .w or .l for byte, word
and long word respectively. A word of warning: to acess data as a word or long
word the address in memory must be an even number. If you are defining a list
of variables in memory you can use the assembler instruction EVEN to ensure
the next data starts at an even address. You will pick this up in time.

 If you do not specify the size with .b .w or .l then Devpac will assume you
are operating on word length data ( .w ).

3.5 Pseudo Op's
---------------

 What ???
 
 Dont panic you've already met one, the EVEN command. Pseudo ops are instruc-
tions to the assembler. EVEN tells the assembler to make sure that whatever
follows starts on an even address in memory. The others we are interested in
at the moment are EQU and DC ( Pseudo ops do not have to be enterd in upper
case, I'm only doing this for clarity ).

EQU  This instruction tells the assembler to assign a value to the label that
    preceeds it. This is useful for defining constants in your programs and
    it also makes your code more readable and easier to modify.
    
    eg   length   equ   20
    
    this instructs the assembler to replace all future occurences of length
    with 20. Note you can use = instead of equ if you prefer, so the example
    above could be written:
    
         length    =    20
         
    Devpac even allows you to use simple arithmetic in equ's
    
    eg   length   equ   20
         width     =    15+2*3
         area      =    length*width
         
    Once a value has been assigned to a label however your program cannot 
    change it.
    
DC   This instruction instructs the assembler to set asside either a byte,
    word or long word of memory at the point in the program that it appears.
    You can then use this memory to store your programs variables in, and to
    make it easier to locate this memory it is usual to preced the instruction
    with a label. A value should also be enterd in the operand field, this 
    is the memory set asside. An example or two should clarify:
    
    age     dc.b  25        this sets by 1 byte initialised as 25
    height  dc.w  237       this sets by 1 word initialised as 237
    
     If you have assigned values to labels using equ's you can use these to
    initialise the memory, for example:
    
    length      equ      20+15
    
    
    room_len	dc.w     length
    
     You can even use the same simple arithmetic as with equ's:
     
    length      equ      20+15
    width        =       length-5*2
    
    
    room_area   dc.w     length*width
    
    Translating this into English ( or almost ), length is assigned the value
    35, width is assigned the value 25 and then the memory at the address
    labeled room_area is initialised with the value 875 ( I used me calculator
    for that one).
    
     The dc statement realy comes into its own for storing text in your 
    since Devpac will convert any characters enclosed in single or double
    quotes into a string of bytes containing the characters ASCII codes ( if
    you dont know what an ASCII code is see the apendix at the end of this
    tutorial ). Let's look at an example:
    
    my_name      dc.b     'Mark Meany'
    
     this will set asside 10 bytes initialised with the ASCII code of each
    character ( including the space ) in my name.
    
     You can also initialise consecutive memory locations with just one dc
    instruction, just seperate the values with a comma eg
    
    xy_pair      dc.w      10,20
     
     This will initialise two words starting at the address labeld xy_pair.
     
3.6 Number Base
---------------
    
  So far you will notice that all examples I've given use decimal ( base 10 )
numbers. Well Devpac is not restricted to just decimal and you may at some
time wish to enter numbers as hex ( base 16 ) or binary ( base 2 ). Well this
is simplicity itself, to tell Devpac a number is a hex number preceed it with
a $ and to indicate a binary number preceed it with a %. The following three
lines are all equivalent:

length     dc.w     $14

length     dc.w     20

length     dc.w     %10100

 Devpac does all the necessary conversions for us. It still pays to be 
conversant with all three yourself, so get practasing.

4 The Instructions
==================

 Before we look at individual instructions ( we will get there in the end,
promise ) lets look at the three general instruction formats:

  1/   INSTRUCTION
  
  2/   INSTRUCTION     SOURCE
  
  3/   INSTRUCTION     SOURCE,DESTINATION
  
 In the above SOURCE and DESTINATION instruct the 68000 where to find the
data to manipulate, and where to put the result respectively. Both can be
either a register or a location in memory ( pidgeon hole ). If either
SOURCE or DESTINATION are in memory then the address of the location is
required. Rather than just specifying an address ( which is allowed ) the
68000 has a number of ways at arriving at the address, some are very weird
and tend to confuse the beginner ( well they confused the hell out of me at
first anyway ). The diffirent ways of arriving at the address are called the
68000's addressing modes ( see chapter 2 of Abicus MC book ). I will introduce
you to the various addressing modes when we get on to the MOVE instruction
shortly.

4.1 RTS
-------

 SYNTAX:     RTS

 Well this is the first instruction we will look at. This is the return command
and it tells the 68000 to jump back to wherever it came from. For example if
this was the only command in your program and you ran it from the CLI, when 
the 68000 executed this instruction it would jump back to the CLI, so ending 
the program. The correct definition is return from subroutine and this command
should be used to end all subroutines you write. At present programs you write
can be considered as subroutines of the CLI or Workbench and as such the RTS
command will return control to the enviroment that called it.

 To convince yourself load eg_1.s to Devpac, assemble it to ram: and then
run it .

4.2 MOVE
--------

 SYNTAX:     MOVE.s     SOURCE,DESTINATION
 
 This is the most frequently used instruction in the 68000's vocabulary. Data
is copied from the source to the destination. We are going to look at numerous
examples of this instruction to demonstrate the various forms of addressing.

 Firstly lets see how to get an immediate value into a data register. Lets 
move the value 20 into data register d0.

main	move.w	#20,d0	move value 20 into data register d0
	rts		return to calling routine ( in this case Devpac )
	
 The first thing to note about the above program is the four fields as 
explained earlier. You will also notice that the label at the start of the
program is called main, get used to this since I have included some files
to assist you which expect all your programs to begin with the label main.

 The # infront of the 20 tells the assembler that this value is immediate
data, if we omitted it the assembler would think the 20 was an address in
memory. This is another identifier similar to $ and % in that it tells the
assembler something about the number that follows it.

 So what does the program do ? well the first line instructs the 68000 to
move 20 into the lowest word of register d0. I use the expression lowest 
word since as you will recall the internal register can hold 4 bytes or two
words and this instruction only effects the lowest word since we used the .w
size after the instruction. If we had used the .b size then only the lowest
byte would be effected. Once the 68000 has done this it steps to the next
instruction rts which tells it to return to the routine that called it.

 If you were to type this program into DEVPAC, assemble it to memory and then
run it you would probably be dissapointed. Why ? well the program does not
appear to do anything. It has done what we asked it to and moved the value 20
into register d0, but this does not have any mind boggling effect on the Amiga
sound or graphics department. Enter the routines I have included for you.
These dont have any more dramatic effect but they will let you see that your
programs are doing something. Load the file startup.s into Devpac and you will
see the following :
------------------------------------------------------------------------------
	opt	o+,ow-	tell Devpac to optomise

; The next four lines bring in the startup code which handles the CLI
;or Workbench correctly and then opens a console window for I/O.
;macros.i includes the macro routines explained in the text.
;subroutines.i includes the routines required for the macros.

	incdir	'df1:abicus/'	change to Club3:Abicus
	include	'startup.i'
	include	'macros.i'
	include	'subroutines.i'
	
; Your program should start at the label main and should end with an
;rts instruction.  M.Meany  June 1990 
	
main	
-----------------------------------------------------------------------------

 Notice that the label main is here for you. To use this as it stands the
Club3 disk must be in drive 1 and your Devpac disk should be in drive 0. The
program will load include files from the Devpac disk so make sure they are all
there.

 Now type the example in again starting at the label main. When you assemble 
it this time it takes a lot longer but not much more happens when you run it.
To get a visual result you will have to use one of the commands ( macros ) I
have written for you, display_d0. This macro displays the content of the
lowest word of register d0 in a CON: window in binary, decimal and hex. To
use the macro is simplicity itself, just type it in as if it were a 68000
command. The following example should demonstrate:

------------------------------------------------------------------------------
	opt	o+,ow-	tell Devpac to optomise

; The next four lines bring in the startup code which handles the CLI
;or Workbench correctly and then opens a console window for I/O.
;macros.i includes the macro routines explained in the text.
;subroutines.i includes the routines required for the macros.

	incdir	'df1:abicus/'	change to Club3:Abicus
	include	'startup.i'
	include	'macros.i'
	include	'subroutines.i'
	
; Your program should start at the label main and should end with an
;rts instruction.  M.Meany  June 1990 
	
main	move.w	#20,d0	d0=20
	display_d0	display contents of d0
	rts	

-----------------------------------------------------------------------------
 This is eg_2.s in the Abicus directory so you dont have to type it in, just
load and assemble.

 As there are eight data registers so there are eight macros to display their
contents:
	REGISTER	TO DISPLAY ITS CONTENTS
	  d0			display_d0
	  d1			display_d1
	  d2			display_d2
	  d3			display_d3
	  d4			display_d4
	  d5			display_d5
	  d6			display_d6
	  d7			display_d7
 
 Chapter 2, page 24 of the Book ( as I am going to refer to it from now on ) 
lists the 68000's addressing modes. Looking at the first line of our program
you should see that we have used Direct Addressing for the source and Data
Register Direct Addressing for the destination.

 To move data from one data register to another we would need to use Data
Register Direct Addressing for both source and destination as follows:

main	move.w	#20,d0
	move.w	d0,d2
	rts
	
 The first line we are already familiar with, the second line copies the data
from the lowest word of register d0 into the lowest word of register d2 using
Data Register Direct Addressing for both source and destination. To convince
yourself of this enter the following example at the label main ( from now on
assume that for all examples you have to load start.s and enter them from the
label main ). This displays the contents of d2 before we copy the contents of
d0 into it, and again after the move instruction has taken place.

main	move.w	#20,d0
	display_d2
	move.w	d0,d2
	display_d2
	rts
	
*****************************************************************************	
 I recommend you type in all examples, assemble them to ram and run them. This
will get you more familiar to using Devpac and also some practise at entering
source. If you have any problems send the offending source to me.
*****************************************************************************

 Try altering the above examples so they copy byte data size and then long
word data size just to be sure you are understanding what you have read.

 Time to introduce another macro. This one will display the word contents of
a memory location in binary, decimal and hex. You need to supply the label
attatched to the memory location as the following example should demonstrate:

main	display_mem	my_age
	rts
	
my_age	dc.w	25

 As you will see the macro is called display_mem and the label I am using in 
this example is my_age. This example also demonstrates that the dc.w command
initialises the memory at the address my_age to 25.

 Now we can store values in memory we want to be able to move them about. It's
time to look at Absolute Addressing. There are two forms of absolute 
addressing, long and short, but you dont need to concern yourself with the
diffirences as Devpac will decide which is most appropriate for you.

 Absolute addressing involves using the address of the memory location you 
want to access as either the source or destination depending on whether you
are copying data out of or into this location. It's simpler than it soudls (in
practise. For example suppose in the previous example we wished to change the
value stored at my_age to 18 we could use immediate data as the source and the
address my_age as the destination. The following example is eg_3.s:

main	display_mem	my_age
	move.w		#18,my_age
	display_mem	my_age
	rts
	
my_age	dc.w		25

 The second line moves the immediate vilue 18 into memory at address my_age.
Using the address in the source field is just as easy:

main	display_d0
	move.w		my_age,d0
	display_d0
	rts
	
my_age	dc.w		25
 
 The second line moves the word value 25 from memory location my_age into
register d0.

 To copy from one memory location to another you could use the following
example which has absolute addresses in both source and destination:

main	move.w		my_age,temp
	display_mem	temp
	move.w		wifes,temp
	display_mem	temp
	rts
	
temp	dc.w		0
my_age	dc.w		25
wifes	dc.w		22

 Lets analyse this. The first line moves the value 25 from location my_age
to location temp. The second line displays the value stored in location temp
. The third line moves the value 22 from location wifes to location temp. The
fourth line displays the value stored in temp and the fifth line finishes the
program.

 As explained earlier there is a set of address registers for storing the
address of locations. The addressing modes available using these are very
powerful as you will soon find out. The first thing we need to do is learn
how to get an address into an address register. Putting the label in the 
source field would not work as this would cause the contents of this location
to be copied ( absolute addressing ) so we must instruct the assembler to
treat the label as immediate data. You remember how to do that dont you ? you
preceed it with a #. I have not written any macros to display the contents of
the address registers ( though it would be very simple ) because as I stated
earlier the 68000 does not know anything of the labels we have used, all that
would be displayed is a rather large number that would mean very little to us
at this stage. Anyway on to an example. Lets use immediate addressing for the
source and address register direct for the destination to get the address of
the value at my_age into register a0.

main	move.l		#my_age,a0
	rts
	
my_age	dc.w		25
	
 Well that was jolly painless wasn't it ! a0 now holds the address my_age.

 Note that the move instruction uses the .l size identifier. This is because
all addresses on the Amiga are long words.
 
 Time to explain some jargon ( as I understand it ). When a memory location
is used to store a value which we can recall and alter it is known as a 
variable. I will now refer to the memory at location my_age for example as
the variable my_age or just my_age. a0 holds the address of the variable 
my_age in the above example, so we say a0 points to my_age.

 We know how to get an address register to point to an address in ram 
( and you will learn another way later ) but how do we use this address
register to move data in and out of this location ? I wont leave you guessing,
we use address register indirect addressing ( ohh no, sounds complicated ).
Address register indirect addressing tells the 68000 to acess the data in the
location that the address register is pointing at. To use this mode you must
enclose the register in brackets ie (a0). An example is called for:

main	move.l		#my_age,a0	a0 points to my_age
	move.w		#18,(a0)	my_age=18
	display_mem	my_age
	rts
	
my_age	dc.w		25		init my_age=25

 The second line is all thats new here, it instructs the 68000 to move the 
immediate word value 18 into the memory location pointed to by a0 ( which
in this case is my_age ).

 Can you figure out what the following example will do before assembling it?
 
main	move.l		#my_age,a0
	move.l		#temp,a1
	move.w		(a0),(a1)
	display_mem	temp
	move.w		wifes,d4
	move.w		d4,(a1)
	display_mem	temp
	move.w		(a1),d2
	display_d2
	rts
	
temp	dc.w		0
my_age	dc.w		25
wifes	dc.w		22
	
 This source is eg_4.s on the disk so you dont even have to type it in.
	
 You have met all the addressing modes before, only now they are being used
together in source and destination fields. This example was put in to 
demonstrate what you can already achieve. A little posotive thinking and
experementing at this point would be most beneficial to you.

 Incase you are floundering here's the breakdown ( not the nervous type ).
 
 line 1:  point a0 to my_age.
 line 2:  point a1 to temp.
 line 3:  move the word value at memory location pointed to by a0 (my_age)
          to the memory location pointed to by a1 (temp). temp now holds
          the value 25.
 line 4:  display the contents of temp ( 25 ).
 line 5:  move the word value at memory location wifes ( 18 ) into register d4
 line 6:  move the word value in d4 ( 18 ) into the location pointed at by
          by a1 ( temp )
 line 7:  display the contents of temp ( 18 )
 line 8:  move the word value at memory location pointed to by a1 ( temp ) 
          into register d2.
 line 9:  display contents of register d2 ( 18 ).
 
 Well I haven't finished with move yet, but I have finished for this month.
Please let me know if this type of tutorial is beneficial or if I am wasting
my time. Also let me know if I have made any mistakes.

Apendicies
==========

a1 Assembling Notes
-------------------

 The start.s file in the Abicus directory on this disk should always be loaded
first, start typing your own code at the label main.

 The start.s file allows all programs to be run from either the CLI or the
Workbench. You will need to give the assembled file an icon to run it from
the workbench, the easiest way of doing this is to select the DRIVE option
in the assembly preference window, give the file a name like ram:eg_1 in the
string gadget and once assembly is complete use iconiser to give the program
an icon ( iconiser is a PD utility and was on Club2 ). You can then use the
icon to put the program onto whatever disk you please.

a2 Exersises
------------

1. When a program that is started from the CLI finishes the long word value in
  register d0 is the error code. If this is zero then no error is reported, 
  any other value will cause an error report in the CLI window. Write two
  programs that test the validity of this statement.

2. Write a program which moves the word values of all 7 data registers into 7
  variables called d_reg0,d_reg1,d_reg2,...,d_reg7 then alter the contents
  of all seven data registers and finaly restore the registers to their 
  initial values.

3. Write a program to display the ASCII code of your initials.

  
 I look forward to receiving your solutions, some of which will be on the next
disk.

 M.Meany July 1990.
 
a3 The ASCII Set
----------------

 The ASCII character set is an international standard for encoding characters
as one byte data. Here is a hex conversion table:

	           second nibble
       
             0  1 2 3 4 5 6 7 8 9 A B C D E F
	  ------------------------------------
	2 | spc ! " # $ % & ' ( ) * + , - . /
1st	3 |  0  1 2 3 4 5 6 7 8 9 : ; < = > ?
nibble	4 |  @  A B C D E F G H I J K L M N O
	5 |  P  Q R S T U V W X Y Z [ \ ] ^ _
	6 |  `  a b c d e f g h i j k l m n o
	7 |  p  q r s t u v w x y z { | } ~
