![]() |
![]() |
#1 |
Registered User
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
|
Beginning Amiga Assembly Programming
Been coding in assembly on the 64 for quite some time, would like to start learning it on the Amiga as well. Unfortunately almost everything I try to do results in a Guru, so as a really simple start I was wondering if someone could write a "Hello World" or something like that, with detailed comments so I can try and get to grip with the basics.
Thanks |
![]() |
![]() |
#2 |
Global Moderator
Join Date: Sep 2006
Location: Germany
Age: 46
Posts: 32,584
|
Maybe bippy's links are of any use : http://eab.abime.net/showthread.php?t=21516 ?
|
![]() |
![]() |
#3 |
Registered User
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
|
Thanks TCD, I did come across those links however I couldn't find anything in them that's along the lines of what I'm after. Plenty of source to look at which I'm sure will come in handy in the near future though.
When I started programming on the c64 someone explained to me how to print a message on to the screen, with a detailed explanation of what each instruction did. I found learning how to do more advanced things quite simple from there so I thought why not start off on the Amiga the same way ![]() |
![]() |
![]() |
#4 |
The Grim-Button
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 415
![]() |
Code stolen from Piru. hehe.
Comments by me. PC is the program Counter a0-a7 are the address registers d0-d7 are the data registers http://gega.homelinux.net/AmigaDevDo...#openlibrary() http://gega.homelinux.net/AmigaDevDo...closelibrary() http://gega.homelinux.net/AmigaDevDo....html#output() http://gega.homelinux.net/AmigaDevDocs/dos.html#write() <removed my rush job> If you want more details let me know. Last edited by Vairn; 11 March 2011 at 00:26. Reason: Fail |
![]() |
![]() |
#5 |
Registered User
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
|
That's exactly what I was after, thanks very much. The only thing I don't quite understand is the EQU's, eg:
_LVOOpenLibrary EQU -552 -552 from what? |
![]() |
![]() |
#6 | |
The Grim-Button
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 415
![]() |
heh, sorry.
See the first line, where it loads 4, into a6 move.l 4.w,a6 4 is the library base offset for the Exec library so to call functions from the exec library, you need to know there LVO (Library Vector offset) basically where they are in the library vector table. This link would explain it better then I, ever could. http://gega.homelinux.net/AmigaDevDo...17.html#17-5-1 Quote:
Last edited by Vairn; 10 March 2011 at 03:18. |
|
![]() |
![]() |
#7 |
Registered User
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
|
That makes sense, cheers.
With an instruction like "move.l 4.w,a6", I assume we're using a longword because if we used a word the 16 MSB's would not be altered? And please explain the function of the PC in the following instruction. lea dosname(pc),a1 Thanks very much. |
![]() |
![]() |
#8 |
The Grim-Button
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 415
![]() |
"lea" means "load effective address.
What "lea" does is load an effective address into an address register (I'll explain what an address register is later on). It's syntax is: lea effective address,an The address methods that "lea" can use are An, x(An), x(An,xr.s), x.w, x.l, x(PC), x(PC,xr.s). "An" means that it can use load the effective address into any of the eight address registers (a0-a7). Registers are kind of like the processor's scratch paper. All of the address registers are the same, except for a7, which is used the stack pointer. In the code, you can see that I did: dosname(PC),a1 This makes the a1 register a pointer to dosname (basically meaning that a1 refers to dosname). You must have the (PC) there, or else it won't work. "PC" is the Progam Counter, which keeps track of where the procesor is in the program. |
![]() |
![]() |
#9 | |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
Quote:
It would still work if you just did lea dosname,a1 ![]() Using pc relative addressing like this is shorter and faster but there are restrictions such as you can't use pc relative offsets across sections in code (without some trickery anyway) and there is a maximum displacement size although, again, with some extra manipulation, you can get around that too. |
|
![]() |
![]() |
#10 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
Hewitson I think you should look at a couple of books on 68kasm, I am currently reading through a couple, get an understanding for the chip, the addressing modes and opcodes is crucial.
Alongside this you will need to read through parts of the RKM's and also the HRM not to mention it may be worth looking at a couple of other books. |
![]() |
![]() |
#11 |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
bippym is definitely right in that it's worth doing some reading.
However, what I'd say from my experience is you don't need to do vast amounts and you don't need to read any of these book cover to cover, dip into what you need to know and what you find interesting. As a minimum you could try reading some or all of this: http://amiga-manuals.xiik.net/ebooks...0eBook-ENG.pdf and this: http://amiga-manuals.xiik.net/ebooks...0eBook-ENG.pdf and just start coding! In my opinion, anyone who does all theory and no practice will never learn to code - the real learning is in the doing... ![]() |
![]() |
![]() |
#12 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
Sorry but I don't think the comments here are really helpful (some of them are even wrong!). Commenting things like "moveq #-1,d3" with "moves -1 into d3" won't help in my opinion. It's clear what happens when you look at the instruction, there is no comment needed. Would have been much better to comment WHY d3 is set to -1. Looking at the comments I have the impression that you didn't really understand the code. Code:
tst.b (a0)+ ; tests if the address after a0, is null |
|
![]() |
![]() |
#13 |
Global Moderator
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
|
Hi
I have re-commented the code. Hopefully it makes more sense. Sorry Vairn but it is important this is done correctly otherwise there is no point. Code:
* First some library offsets. Read the RKM Libraries and the includes and autodocs for more information _LVOOpenLibrary EQU -552 ; Openlibrary allows your program to use the amiga libs, it opens them and returns the result (Success/failure) in d0 _LVOCloseLibrary EQU -414 ; Closelibrary does the opposite and closes opened libraries, freeing memory used _LVOOutput EQU -60 ; Allows us to specify the output source (file) and returns a BCPL pointer _LVOWrite EQU -48 ; Writes the source to the output (file) specified by LVOOutput start: move.l 4.w,a6 ; Loads the exec library base address into a6. This used with the _LVO offsets allows us to call exec libraries lea dosname(pc),a1 ; load the base address of dos.library into a1, this is the exec library we will be opening moveq #0,d0 ; Clear d0, this can be set to determine the minimum version of the library to open. Setting to 0 means any version jsr _LVOOpenLibrary(a6) ; Calls the Open Library function. tst.l d0 ; The base address of the library opened is returned in d0. If it is 0 then it is has failed to open. beq.s nodos ; If 0 is returned the library failed to open (the Z(ero) flag is set) and we branch to end the program. move.l d0,a6 ; move the base address of the dos.library into a6 so we can use it. A better way is to save the base address but for this program this is fine. lea msg(pc),a0 ; Loads the base address of the msg to be written to a0. The (pc) means it is within 32kb of the current location. moveq #-1,d3 ; moves -1 into d3 so we can set the length of data to be written using the strlen routine below. This is used by _LVOwrite to determine the length to be written move.l a0,d2 ; copy the base address of the data to be written to d2, this is used by _LVOWrite later strlen: addq.l #1,d3 ; increases d3 by 1. tst.b (a0)+ ; This tests if a0 is pointing to null (the terminating string for the hello world msg) and increments the address by 1 (the +) bne.s strlen ; if not, branches back to strlen jsr _LVOOutput(a6) ; Branch to the Output function and return the base address in d0 move.l d0,d1 ; Copies the base address of the output to d1 jsr _LVOWrite(a6) ; Writes the string Write(d1,d2,d3) (Base address of the output stream, d2 is the base address of the msg, d3 is the length of the msg) move.l a6,a1 ; Copy the base address of dos.library into a1 move.l 4.w,a6 ; Moves execbase into a6 jsr _LVOCloseLibrary(a6) ; Closes the dos.library (uses the base address in a1) nodos: moveq #0,d0 ; Clears d0 rts ; ends the program dosname: dc.b 'dos.library',0 ; It is important this is named properly msg: dc.b 'Hello, world!',10,0 ; Our message with a line feed and the terminating null at the end Last edited by BippyM; 10 March 2011 at 10:31. |
![]() |
![]() |
#14 | |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,970
|
Quote:
![]() |
|
![]() |
![]() |
#15 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
The syntax for the instructions can be looked up looked up in the 68k reference manual. |
|
![]() |
![]() |
#16 |
The Grim-Button
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 415
![]() |
*hangs his head in same*
Really I could of done that better, stingray is right. When someone is wanting to learn you shouldn't really rush through things. At least I have made myself look stupid :P I think I need to do a proper attempt at commenting some asm code ![]() Sorry guys. |
![]() |
![]() |
#17 |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,970
|
Perhaps you're right; it's just that such comments were helpful to me when I learned 68000 (doesn't mean much, eh
![]() Last edited by Thorham; 11 March 2011 at 18:41. |
![]() |
![]() |
#18 |
AMOS Extensions Developer
Join Date: Jun 2007
Location: near Cambridge, UK
Age: 44
Posts: 1,924
|
Well I agree with both Thorham and StingRay. If you were to look at the source of my current demo, you will find stupid comments like moves #1 -> d1 in the stuff I wrote when I started coding it (October last year), but now I write comments like sprite direction
![]() I think it is necessary to write stupid comments in the beginning, because if anything else it helps to build ones confidence in using the instruction. Atleast if you forgot what it does you have an easy lookup. I do think it's definately a good idea to write a "stupid comment" after instructions like move.l 4(a0,d0.w),d1 which are quite confusing for beginners - or atleast it was for me. Regards, Lonewolf10 |
![]() |
![]() |
#19 |
Registered User
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
|
I don't mean any disrespect to Vairn, I very much appreciate his efforts (as well as bippym's, thanks very much guys), however I completely agree with StingRay.
A comment like moves -1 into d3 is indeed useless. Anyone can see what it does, the explanation needed is why this is being done. I have got a couple of examples of "hello world" running and managed to add a wait for the LMB to be pressed. Any suggestions on another simple program I could try to knock up? Last edited by Hewitson; 14 March 2011 at 03:33. |
![]() |
![]() |
#20 |
Posts: n/a
|
Personally I think the code is bad...
Hi all... Sorry to throw my in my own comments here, but I have to agree that overly commented code, even for beginners isn't good. I spent years writing Amiga Demos/Cracktros for Skid Row/Fairlight etc and I remember the most important thing what not seeing each instruction, but understanding WHY it was done. I remember in my very early days another coder fixing my code, by changing an add.w to an add.l and not understanding WHY that fixed my code.
Also from the code I've seen above, although functional, it's not very nice at all. Firstly, I have a couple of issues with the code... 1. It's not entirely sensible to be calculating the length of the string at run time, when in reality it should be done at assembly time. 2. When you've called the _LVOOutput() function, you don't actually test if it returns a value CLI handle. If the code is run from an icon and not from the CLI, the code will actually crash. Here's how I would have written such code:- move.l (Execbase).w,a6 lea .dosname(pc),a1 moveq #0,d0 ; Use any library version. jsr _LVOOpenLibrary(a6) tst.l d0 beq.b .no_lib move.l d0,a6 jsr _LVOOutput(a6) move.l d0,d1 ; Make sure we have a CLI handle beq.b .no_cli lea .msg(pc),a0 move.l a0,d2 moveq #.length,d3 jsr Write(a6) .no_cli move.l a6,a1 move.l (Execbase).w,a6 jsr _LVOCloseLibrary(a6) .no_lib rts .msg dc.b "Hello World!",10 .length EQU *-.msg Now I'm writing this from memory and it's been like 15 years since I wrote Amiga assembly, but I'm pretty sure the above is okay. Last edited by The Welder; 09 August 2012 at 12:24. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Danish Amiga Assembly Programming Course | Controller | Coders. Tutorials | 62 | 26 December 2021 15:10 |
Beginning Programming | robheaton | Coders. General | 60 | 16 April 2011 11:49 |
New to forum Love AMIGA of old and beginning an emulation state | catwatch3 | New to Emulation or Amiga scene | 15 | 30 December 2010 12:38 |
Amiga Assembly sources - Please help! | W4r3DeV1L | Amiga scene | 21 | 16 July 2008 08:13 |
Beginning Amiga programming in C++ | zardoz | Coders. General | 3 | 17 May 2006 13:14 |
|
|