English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Tutorials

 
 
Thread Tools
Old 17 January 2007, 18:19   #1
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Part Diary of an ASM Learner

I've started to learn ASM again from the start, i'm going to try and keep notes and maybe even a diary and my thoughts in this thread.

Everything I am reading I am taking notes (Thanks Steve) and i'm going to copy them into this thread.

Alot of the notes initially will be from the Mastering Amiga Assembler by Paul Overaa which is the book I am going to start (again) with!

Seasoned ASM coders can feel free to post examples code or test code to estgablish how well I am doing and newbies can feel free to try and follow what I am doing and ask questions!

I hope thisa will turn into an online asm lesson where questions and answers can be asked that relate to where I am and what I have learnt up until that point.

Please post your initial thoughts on this

Thanks

The following members have expressed an interest in learning from this thread

Code:
pbareges
haakon
superbuster

Last edited by BippyM; 26 January 2007 at 09:34.
BippyM is offline  
Old 17 January 2007, 18:34   #2
pbareges
Registered User
pbareges's Avatar
 
Join Date: Feb 2005
Location: montreal / canada
Age: 42
Posts: 722
plugged in . i learnt most of the programming languages i know through existing code..but this method failed for asm each time i tried...it's way too confusing! i hope you'll find the right path to make it interesting from the beginning (all binary and hex plus basic operators are quite boring). i guess a good old hello world should be fine given we find the right rom lib to display characters..also is the book you're reading dedicated to 68000 or 68020 and does it make a lot of differences?...also do chipset and rom differences between amiga models involve a lot of differences ? we should also all sync to one asm interpreter/compiler...mastering the asm editor has also been really difficult for me each time i tried....hope this will help you format this experience!
pbareges is offline  
Old 17 January 2007, 20:52   #3
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Hijacked my own post here

I am going to post any commands used and their syntax in this post

Code:
move.<size> source,dest
move allows the programmer to move data from source to destination. The source can be either a register, address or other data supplied and destination can be either a register or an address.

Code:
move.b    #10,d0
moves 10 into do

Code:
move.l    #RESULT,a1
Put the address that is referenced by RESULT into a1

(more to come!)

Last edited by BippyM; 20 January 2007 at 15:50.
BippyM is offline  
Old 17 January 2007, 21:14   #4
DDNI
Targ Explorer

DDNI's Avatar
 
Join Date: Mar 2006
Location: Northern Ireland
Age: 44
Posts: 5,183
Send a message via ICQ to DDNI Send a message via MSN to DDNI
I am! DDNI is getting tired of feeling like a retard whenever he happens to meet up with Girv!!!
DDNI is offline  
Old 17 January 2007, 21:39   #5
girv
Reticulator of Splines
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 920
Send a message via ICQ to girv Send a message via AIM to girv Send a message via MSN to girv Send a message via Yahoo to girv
Well I keep feeling like a skinflint. Let me buy the coffee one time!
girv is offline  
Old 17 January 2007, 23:56   #6
Galahad/FLT
Going nowhere

Galahad/FLT's Avatar
 
Join Date: Oct 2001
Location: United Kingdom
Age: 45
Posts: 6,988
Any help you need Bip, just ask.
Galahad/FLT is offline  
Old 18 January 2007, 08:41   #7
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Number formats & logic operators

Here are some links for number formats

Binary
Hexadecimal
Octal

For Amiga asm we will mainly be using binary, hex and decimal so knowing how to convert between the different formats is essential. Get practising.

Boolean Logic
BippyM is offline  
Old 18 January 2007, 09:40   #8
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Registers

Here we go. Please remember these are MY notes and NOT a tutorial. If there are any issues or inaccuraicies then please post and i'll correct the posts. The same can be said for additional info

Also don't be critical unless it is constructive, if you don't want to help or learn then stay out this thread. I will delete any irrelevant posts!

Registers

The 680x0 processors have 16 registers, they are split into 2 groups. d0-d7 are data registers and a0-a7 address registers

The Stack
Register a7 has a special purpose and serves as the 680x0's stack. The stack is used as a last in, first out (LIFO) basis and the stack must always be stored in an even memory address.

The stack is used to preserve the contents of registers so they can be restored later. The stack is also a space of memory that is reserved for this function and can be set to be anywhere in chip or fastram - galahad

All the registers can hold a 4byte (32 bit) number which can be moved between memory and registers.

Program Counter
The PC (Program Counter) stores the address of the next command that the cpu is going to execute. By simply changing the address on the PC one can make jumps and branches. The condition of the jumps are dependant on certain processor flags.


Status Register

The status register (SR) is divided into two eight bit registers known as the system byte and user byte. The system byte is only accessed in Supervisor Mode and wont be discussed here until we venture into hardware.

The user byte contains flags that are set or cleared according to the results of certain instructions. Five flags providde single bitwise TRUE|FALSE type detection of processor conditions

The flags are

Carry - Thgis flag holds the carry from the most significant bit. The 680x0 inverts the subtraction so it becomes a borrow flag (COULD A SEASONED PROGRAMMER EXPLAIN THIS BETTER PLEASE)
Zero - this is set to -1 when a result returned is 0
Negative - Always takes the value of the most significant bit (How a negative number is done (thanks girv)
OVerflow - not covered yet
EXtend - not covered yet

Flags in lay-mans terms, thanks to steve for this

Quote:
Originally Posted by steve
Ok, try and imagine five guys on an aircraft carrier holding flags. lol. Stay with me here. Ok the aircraft carrier is the Amiga hardware with planes taking off and landing (data and addresses being copied in memory).

Now the five guys holding flags are part of the user byte and raise (Turn On) or lower (Turn Off) their flags when they see things happening. Imagine a simple calculation occured aboard deck like 23-23. This equals zero so the guy holding the zero flag would raise it (turn it on). The flag would be 1 (ON). This was the result of the calculation. Not any specific instruction!

As for negative, well the guy holding the negative flag would raise this when a calculation creates a number with a negative value, for example 5-10 = -5. The most significant bit is the bit in a binary number with the largest value. It is usually the value furthest to the left as binary numbers increase in size from right to left. For example:

128 64 32 16 8 4 2 1

This is an 8bit binary number with a total value of 255 (add them all together). The largest (most significant bit) is obviously 128. If the 8bit value held is a negative then the most significant bit is turned on to indicate that the number is negative. That means it no longer counts as a value of 128 and therefore the binary number is limited to a range of +127 to -127.

http://en.wikipedia.org/wiki/Most_significant_bit

Similarly the carry flag is used during division calculations to indicate that there is a remainder from the division calculation.

So to sum up, the guys with flags aboard ss assembler are there as observers and observe and declare what is going on above deck!
Well that is it so-far for registers, i'll add and change anything as I progress

Any questions?

Last edited by BippyM; 19 January 2007 at 09:55.
BippyM is offline  
Old 18 January 2007, 17:09   #9
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Guys i'm going to delete posts in this thread that don't serve much purpose, I might also copy and past explanations into my posts and then delete the post to keep things together and in a logical order.

I will naturally give credit where it is due

Later I hope to post the next bits i have done, though I might add some regarding assemblers and also make my unfinished asm hdf available
BippyM is offline  
Old 18 January 2007, 17:14   #10
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
oh I can also be seen idling on #asm on irc.abime.net
BippyM is offline  
Old 18 January 2007, 19:08   #11
girv
Reticulator of Splines
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 920
Send a message via ICQ to girv Send a message via AIM to girv Send a message via MSN to girv Send a message via Yahoo to girv
A note on the binary representation of negative numbers: on 68k (and most systems) integers, including negatives, are held in Two's Complement form [wikipedia] so it's not as simple as just turning on the most significant bit to indicate negativity.

eg: 1 is 00000001
but: -1 is 11111111 not 10000001

This form makes binary arithmetic with negatives simpler: consider the above example and add 1 to -1.

To determine the two's complement form of the negative of an integer, invert the bits in the positive form and add 1 to the result.
girv is offline  
Old 18 January 2007, 21:32   #12
pbareges
Registered User
pbareges's Avatar
 
Join Date: Feb 2005
Location: montreal / canada
Age: 42
Posts: 722
what about 10000000 ...is this -128 or 128 ? (because it's -127-1 and 127+1 at the same time)
pbareges is offline  
Old 18 January 2007, 21:44   #13
girv
Reticulator of Splines
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 920
Send a message via ICQ to girv Send a message via AIM to girv Send a message via MSN to girv Send a message via Yahoo to girv
Quote:
Originally Posted by pbareges
what about 10000000 ...is this -128 or 128 ? (because it's -127-1 and 127+1 at the same time)
-128; you can't store +128 in 8 bit 2's complement (127 is the max)

Think of bit 7 has having the decimal value -128.
10000000 = -128
10000001 = -128+1 = -127
10000010 = -128+2 = -126
10000011 = -128+1+2 = -125
...

Going to the end of the positive scale:
01111111 = 64+32+16+8+4+2+1 = 127

Adding 1 to 01111111 does give 10000000, but that's an overflow condition.
girv is offline  
Old 19 January 2007, 10:20   #14
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Addressing Modes

This post willbe a work in progress as the book hasn't covered all modes yet.

As I learn an addressing mode i'll update this post and provide examples

----

Register addressing

This form basically means that the operands reside in the cpu registers so no memory address is required

Code:
	move.b	d0,d1
Immediate Addressing


The operand itself is placed directly after the op-code in memory. In simple terms instead of the address of the operand being placed onto the pc for recovery it is directly after the op-code in memory so there is no jump to the actual location in memory

Code:
	move.l	#0,d0
the 32bit #0 will be placed directly after the move.l instruction in memory

Address Register Indirect Addressing

The address of the operand is held in an address register and so this method is not the same as indirect addressing where the address is held in memory. It os a very powerful addressing mode and is indicated by placing parenthesis around the register name.

Code:
	move.b	(a2),d0
This will copy the the contents of the byte whose address is located in register a2 into register d0

Inherent
Absolute
Address Register Indirect with displacement

Address Register Indirect with postincrement


This addressing mode allows the automatic increment of an address after it has been used. Byte, Word and Long-Word sizes can be used and increments by 1, 2 and 4 accordingly. The mode is specified by placing a + sign after the normal indirect addressing scheme.

Code:
move.b (a0)+, d0
This will copy the contents of the memory location pointed to by a0 into d0 and then automatically increase the address pointed to by a0 by 1 byte.

Address Register Indirect with postdecrement

This mode is similar to the above addressing mode but it provides for automatic decrementing of the address before it has been used. byte, word and long-word can be used. The mode is specified by placing a - before the normal indirect addressing mode.

Code:
move.b -(a0), d0
This will decrease the address pointed to by a0 by 1 and then copy the contents of the address now pointed to by a0 into d0

Address Register Indirect with index and displacement
Program Counter with displacement
Program Counter with index and displacement


I will cover these once I come across them with examples

Last edited by BippyM; 26 January 2007 at 10:09.
BippyM is offline  
Old 19 January 2007, 10:47   #15
BippyM
Registered User

BippyM's Avatar
 
Join Date: Nov 2001
Location: Nottingham, UK
Age: 43
Posts: 8,649
Data Movement

Again I will be returning to these posts if needed

----

Code:
    move.<size>    source,destination
The move command simply moves data from source to destination

example
Code:
    move.b    #10,d0
Moves 10 into the lower 8 bits of register d0

the following flags are affected by the move command N, Z, V, C

the Z & N flags are set while the C and V flags are cleared.

Here is a simple asm program using the move command to copy the contents of a memory location to another. Not all commands have been discussed yet but they will be later so stick with it

Code:
    move.b    X,d0    Copy contents of X into d0
    move.b    d0,Y    Copy contents of d0 to Y
    rts       end

X    dc.b    10    set X to 10
Y    ds.b    1    Allocate 1 byte of memory
This program basically sets a memory location to 10 (X) and reserves memory for it to be copied to (Y). It then uses register d0 as a temporary storage. It then copies the contents of X to d0 and then from d0 to Y.

A simpler way would be

Code:
    move.b    X,Y    Copy contents of X directly to Y
    rts       end

X    dc.b    10    set X to 10
Y    ds.b    1    Allocate 1 byte of memory
Memory could be initialised and then the value copied directly. When taking this approach the data requires a # symbol placing in front of it

Code:
    move.l    #10,X    Copy 10 into X
    move.l    X,Y    Copy contents of X to Y
    rts        end

X    dc.l    1    Allocate 1 long of memory
Y    ds.l    1    Allocate 1 long of memory
Address registers can be used instead of data registers but the move command cannot be used. A special form must be used which is the movea command. To copy data from an address register the normal move command can be used. Moving data into an address register wont affect the SR
BippyM is offline  
Old 19 January 2007, 15:36   #16
pbareges
Registered User
pbareges's Avatar
 
Join Date: Feb 2005
Location: montreal / canada
Age: 42
Posts: 722
i don't get it! what's the difference between .b and .l instructions ? also what's the difference betwen dc and ds..sometimes it's allocate, sometimes it's set....thx again!

sorry understood...b for byte (8-bit) and l for long (16-bit?)...but still what about dc and ds?
pbareges is offline  
Old 19 January 2007, 15:42   #17
Steve
Truth seeker...
Steve's Avatar
 
Join Date: Jul 2001
Location: UK
Age: 40
Posts: 2,200
A couple of notes...

Some jargon stuff incase anyone is confused:

8 bits = byte
16 bits = word (2 bytes)
32 bits = long word (4 bytes)


Also commands such as move, add, mul and div all have a . extension which indicates how many 'bits' of the particular register are to be copied, added, multiplied etc. I think you can leave out the extension and it defaults to byte size calculations. I think.


move.b (this copies the lower 8 bits of the source to the lower 8 bits of the destination)
move.w (this copies the lower 16 bits of the source to the lower 16 bits of the destination)
move.l (this copies all 32 bits of the source to all 32 bits of the destination)


Also...

rts = return from subroutine
dc = define constant variable (a bit of memory you can name and give a value)
ds = define storage variable (a bit of memory you can name and reserve for future use)


Variables in 68000 can also be declared as byte, word or long word size. If you know a variable will never exceed a specific value then limit the size of your variable. For example don't create a dc.l 32-bit variable when the value it holds will never be larger than 100. It won't cause any problems by setting it as 32-bit but it is wasteful of memory which is quite precious on an Amiga.

Another instruction I think is worth mentioning at this stage is the equate directive: EQU. This is very similar to the define constant instruction which is described above except that the value it holds is set in stone and can never change. These constant values can contain decimal, hexadecimal or even binary values! These constant values are very useful and are used a lot in assembly programming! Note that the equate command does not accept a size extension like the dc and ds instructions.

Here is a quick example taken from the GameBoy Mr Do source code:
Code:
MRDOSPEED	EQU	128+64+32
EATSPEED	EQU	128+32
BALLSPEED	EQU	2
BRDLEN		EQU	9		;SCORE BOARD LENGTH

STACK		EQU	$CFFF
OBJSET		EQU	$8000		;$1000
BGSET		EQU	OBJSET+$1000	;$800
DISPSCREEN	EQU	$9800		;$400
STATSCREEN	EQU	$9C00		;$400
BACKSCREEN	EQU	$C800		;$400
BYTESCREEN	EQU	$CC00		;$100
WORKRAM	EQU	$C000
OAMRAM		EQU	$FE00
INTRAM		EQU	$FF80
BLITS		EQU	INTRAM
OBJDATA		EQU	OAMRAM

Last edited by Steve; 19 January 2007 at 17:01.
Steve is offline  
Old 19 January 2007, 16:06   #18
pbareges
Registered User
pbareges's Avatar
 
Join Date: Feb 2005
Location: montreal / canada
Age: 42
Posts: 722
but in the above code, it says dc.l 1 reserves 1 long variable...it is not consistent with your explanation right? or to be more precise what is the difference between constant and static vars ?
pbareges is offline  
Old 19 January 2007, 16:46   #19
musashi5150
move.w #$4489,$dff07e
musashi5150's Avatar
 
Join Date: Sep 2005
Location: Norfolk, UK
Age: 37
Posts: 2,296
Quote:
Originally Posted by pbareges
but in the above code, it says dc.l 1 reserves 1 long variable...it is not consistent with your explanation right? or to be more precise what is the difference between constant and static vars ?
EQU is used for contants that never change
DS.x is used to Define Storage (uninitialised) - you can change this when running
DC.x is used for Define Constant (initialised) - you can change this when running

Example:
Code:
        ds.b    4    ;Reserves 4 bytes storage (contains random trash data)
        dc.b    4    ;Reserves 1 byte storage and puts the value '4' into it
beefy   equ     4    ;Reserves NO storage, but you can use the word 'beefy' to mean 4 in your program code...
musashi5150 is offline  
Old 19 January 2007, 17:12   #20
Steve
Truth seeker...
Steve's Avatar
 
Join Date: Jul 2001
Location: UK
Age: 40
Posts: 2,200
Stick out tongue

Yes, well explained musashi. Doh! I said static instead of storage! I've been hanging around c++ too much! lol.

Yes the EQU directive is actually nothing like ds and dc, you're right. lol. As you say, it is used to give a numeric value to a name (usually in upper case letters) and can never change its value while the program is running.

One thing I didn't mention is why EQU is so useful. Imagine in your code you wanted the speed of your player to be 2 pixels per frame so you would write:

Code:
PLYRSPEED	EQU	2
You can now place PLYRSPEED in your code and the assembler will replace it with the value 2.

Now imagine that later on you decide to make the player a bit quicker for playability reasons. Ok, now imagine you hadn't used EQU and had lots of 2s all over your program for the players speed. You would have to replace that 2 value in every part of your program! Ack! What a pain in the arse!

Using the equate directive allows great versatility in your program. To change the speed of your player you would only need to replace the EQU from 2 to whatever value you liked. Wherever there was a PLYRSPEED in your program code, this would be replaced with the new value when the program is compiled. Magic!

Last edited by Steve; 19 January 2007 at 17:22.
Steve is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Downfall - diary of a game... Graham Humphrey Amiga scene 505 15 March 2015 19:26
Uridium 2 : Diary of a Game silkworm Amiga scene 15 09 August 2011 09:00
19 Part One - Boot Camp Retro-Nerd project.aGTW 2 19 February 2008 22:11
Help....what is this part 2? Dizzy Retrogaming General Discussion 7 05 June 2007 15:27

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 15:26.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.
Page generated in 0.12231 seconds with 14 queries