English Amiga Board


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

 
 
Thread Tools
Old 10 March 2011, 00:37   #1
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,772
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
Hewitson is offline  
Old 10 March 2011, 00:50   #2
TCD
HOL/FTP busy bee
 
TCD's Avatar
 
Join Date: Sep 2006
Location: Germany
Age: 46
Posts: 31,522
Maybe bippy's links are of any use : http://eab.abime.net/showthread.php?t=21516 ?
TCD is offline  
Old 10 March 2011, 01:43   #3
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,772
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
Hewitson is offline  
Old 10 March 2011, 02:16   #4
Vairn
The Grim-Button
 
Vairn's Avatar
 
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 414
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
Vairn is offline  
Old 10 March 2011, 03:00   #5
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,772
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?
Hewitson is offline  
Old 10 March 2011, 03:12   #6
Vairn
The Grim-Button
 
Vairn's Avatar
 
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 414
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:
Libraries and devices
The main modularisation technique in AmigaOS is based on dynamically-loaded shared libraries, either stored as a file on disk with a ".library" filename extension, or stored in the Kickstart ROM. All library functions are accessed via an indirect jump table, which is a negative offset to the library base pointer. That way, every library function can be patched or hooked at run-time, even if the library is stored in ROM.
The most important library in AmigaOS is exec.library (Exec), which can be considered a microkernel, as well as a library. It acts as a scheduler for tasks running on the system, providing pre-emptive multitasking with prioritised round-robin scheduling. Exec also provides access to other libraries and high-level inter-process communication via message passing. (Other microkernels have had performance problems because of the need to copy messages between address spaces. Since the Amiga has only one address space, Exec message passing is quite efficient.) The only fixed memory address in the Amiga software (address 4) is a pointer to exec.library, which can then be used to access other libraries. Exec was designed and implemented by Carl Sassenrath.
Unlike traditional operating systems, the exec kernel does not run "privileged". Contemporary operating systems for the 68000 such as Atari TOS and SunOS used trap instructions for invoking kernel functions. This made the kernel functions run in the 68000's supervisor mode, while user software ran in the unprivileged user mode. Mac OS on the 68000 even used supervisor mode for everything, kernel and application code alike. By contrast, exec function calls are made with the library jump table, and the kernel code normally executes in user mode. Whenever supervisor mode is needed, either by the kernel or user programs, the library functions Supervisor() or SuperState() are used.
Device drivers are also libraries, but they implement a standardised interface. Applications do not usually call devices directly as libraries, but use the exec.library I/O functions to indirectly access them. Like libraries, devices are either files on disk (with the ".device" extension), or stored in the Kickstart ROM.

Last edited by Vairn; 10 March 2011 at 03:18.
Vairn is offline  
Old 10 March 2011, 04:14   #7
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,772
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.
Hewitson is offline  
Old 10 March 2011, 05:37   #8
Vairn
The Grim-Button
 
Vairn's Avatar
 
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 414
"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.
Vairn is offline  
Old 10 March 2011, 08:07   #9
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Quote:
Originally Posted by Vairn
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.
What you're doing here is loading a1 with the effective address of the pointer to the dos.library name in memory as a relative offset from the current position of the program counter - that's what the (pc) in this means.

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.
pmc is offline  
Old 10 March 2011, 08:53   #10
BippyM
Global Moderator
 
BippyM's Avatar
 
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.
BippyM is offline  
Old 10 March 2011, 09:06   #11
pmc
gone
 
pmc's Avatar
 
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...
pmc is offline  
Old 10 March 2011, 09:37   #12
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Vairn View Post
Code:
_LVOOpenLibrary EQU -552
_LVOCloseLibrary EQU -414
_LVOOutput EQU -60
_LVOWrite EQU -48

start:
  move.l  4.w,a6
  lea     dosname(pc),a1               ;  load the address of dosname. into a1
  moveq   #0,d0                  ; sets d0, to be null, or 0
  jsr     _LVOOpenLibrary(a6)        ; Calls the Open Library function  since d0, is set to 0, it doesn't care what version.
  tst.l   d0                        ; d0 should of been set, if the open lib succeeded. This is testing if d0, is set to 0
  beq.s   nodos                    ; if the test was true, it branches to nodos
  move.l  d0,a6                    ; move the value from d0, into a6
  lea     msg(pc),a0                ; loads address of  msg into a0
  moveq   #-1,d3                ; moves -1 into d3
  move.l  a0,d2                    ; moves in value of a0, into d2.
strlen:
  addq.l  #1,d3                    ; increases d3 by 1.
  tst.b   (a0)+                    ; tests if the address after a0, is null
  bne.s   strlen                    ; if not, branches back to strlen
  jsr     _LVOOutput(a6)            ;  Gets stout, and puts it in d0
  move.l  d0,d1                    ; move d0, to d1
  jsr     _LVOWrite(a6)            ; Writes the string Write(stdout,buff,size)
  move.l  a6,a1                    ; moves the value of a6, into a1
  move.l  4.w,a6                    ; moves 4 into a1
  jsr     _LVOCloseLibrary(a6)        ; closes the dos library
nodos:
  moveq   #0,d0                    ; sets d0 to null
  rts                            ; ends the program
dosname:
  dc.b 'dos.library',0
msg:
  dc.b 'Hello, world!',10,0
If you want more details let me know.

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
This comment f.e. is totally wrong. This instruction tests if the byte a0 is pointing to is null and increases a0 by 1 afterwards.
StingRay is offline  
Old 10 March 2011, 10:03   #13
BippyM
Global Moderator
 
BippyM's Avatar
 
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.
BippyM is offline  
Old 10 March 2011, 19:29   #14
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by StingRay View Post
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.
For more experienced coders this is true, but for beginners, comments like this can be very helpful. Especially in combination with comments that descibe the function of a piece of code
Thorham is online now  
Old 10 March 2011, 22:16   #15
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Thorham View Post
For more experienced coders this is true, but for beginners, comments like this can be very helpful. Especially in combination with comments that descibe the function of a piece of code
I disagree wholeheartedly. What does a comment like "moves -1 into d3" teach you? It isn't helpful, even for a beginner it should be no problem to understand what moveq #-1,d3 does. It is much more important to comment why something is done because then you will learn something.
The syntax for the instructions can be looked up looked up in the 68k reference manual.
StingRay is offline  
Old 11 March 2011, 00:25   #16
Vairn
The Grim-Button
 
Vairn's Avatar
 
Join Date: Jan 2008
Location: Melbourne Australia
Age: 43
Posts: 414
*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.
Vairn is offline  
Old 11 March 2011, 18:36   #17
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by StingRay View Post
I disagree wholeheartedly.
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.
Thorham is online now  
Old 14 March 2011, 00:29   #18
Lonewolf10
AMOS Extensions Developer
 
Lonewolf10's Avatar
 
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
Lonewolf10 is offline  
Old 14 March 2011, 00:43   #19
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,772
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.
Hewitson is offline  
Old 09 August 2012, 12:18   #20
The Welder
 
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

Similar Threads
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

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 23:30.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10417 seconds with 15 queries