17 January 2007, 18:19 | #1 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
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. |
17 January 2007, 18:34 | #2 |
Registered User
Join Date: Feb 2005
Location: montreal / canada
Age: 47
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!
|
17 January 2007, 20:52 | #3 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
Hijacked my own post here
I am going to post any commands used and their syntax in this post Code:
move.<size> source,dest Code:
move.b #10,d0 Code:
move.l #RESULT,a1 (more to come!) Last edited by BippyM; 20 January 2007 at 15:50. |
17 January 2007, 21:14 | #4 |
Targ Explorer
|
I am! DDNI is getting tired of feeling like a retard whenever he happens to meet up with Girv!!!
|
17 January 2007, 21:39 | #5 |
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,149
|
Well I keep feeling like a skinflint. Let me buy the coffee one time!
|
17 January 2007, 23:56 | #6 |
Going nowhere
Join Date: Oct 2001
Location: United Kingdom
Age: 50
Posts: 9,016
|
Any help you need Bip, just ask.
|
18 January 2007, 08:41 | #7 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
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 |
18 January 2007, 09:40 | #8 | |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
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:
Any questions? Last edited by BippyM; 19 January 2007 at 09:55. |
|
18 January 2007, 17:09 | #9 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
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 |
18 January 2007, 17:14 | #10 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
oh I can also be seen idling on #asm on irc.abime.net
|
18 January 2007, 19:08 | #11 |
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,149
|
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. |
18 January 2007, 21:32 | #12 |
Registered User
Join Date: Feb 2005
Location: montreal / canada
Age: 47
Posts: 722
|
what about 10000000 ...is this -128 or 128 ? (because it's -127-1 and 127+1 at the same time)
|
18 January 2007, 21:44 | #13 | |
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,149
|
Quote:
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. |
|
19 January 2007, 10:20 | #14 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
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 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 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 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 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 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. |
19 January 2007, 10:47 | #15 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
Data Movement
Again I will be returning to these posts if needed
---- Code:
move.<size> source,destination example Code:
move.b #10,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 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 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 |
19 January 2007, 15:36 | #16 |
Registered User
Join Date: Feb 2005
Location: montreal / canada
Age: 47
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? |
19 January 2007, 15:42 | #17 |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
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. |
19 January 2007, 16:06 | #18 |
Registered User
Join Date: Feb 2005
Location: montreal / canada
Age: 47
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 ?
|
19 January 2007, 16:46 | #19 | |
move.w #$4489,$dff07e
Join Date: Sep 2005
Location: Norfolk, UK
Age: 43
Posts: 2,351
|
Quote:
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... |
|
19 January 2007, 17:12 | #20 |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
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 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. |
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 |
|
|