English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 14 July 2017, 16:31   #21
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
See, attached zip for the source code and exe.
Thanks a lot for the example, alkis, I've learned a lot from it. Unfortunately, it doesn't want to link:
Code:
execString: vlink -s -bamigahunk -o foo foo.o "E:\Amiga\Dev\NDK_3.9\Include\linker_libs\amiga.lib"
Error 32: Target amigahunk: Unsupported relocation type R_PC (offset=0, size=16, mask=ffffffffffffffff) at text+0x10.
I don't really know what this means, let alone how to solve this. I'm using the latest versions of vasm/vlink on win64. Btw, line 17 should probably read 'execbaseinit set -1', just like for printfused, but that's probably not the reason it doesn't link.


Alright, now let's try to take the next (logical, at least for me) step: turning this into a proper linkable library (.lib will do, for now). Is that just a question of defining some labels and throwing in some rts's when your function is done? Anyone have any stub code you could quickly post?

Also, your code seems to reference a function _printf in amiga.lib, which I assume is this function (but then prefixed with an underscore): http://amigadev.elowar.com/read/ADCD.../node0162.html Do those (auto-) docs contain an exhaustive list of everything in amiga.lib? Are these the reference/definitive docs? Btw, those kind of functions are exactly what I'm trying to make myself.

The mentioned _printf function takes its arguments from the stack, probably because there can be up to 9. But if you were to, say, write a function that adds 2 numbers together, you'd probably assume those numbers to be in some agreed upon registers, right?
guy lateur is offline  
Old 14 July 2017, 20:10   #22
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
First, linking problem.

Modify makefile to read

Code:
foo: foo.asm mymacros.i
	$(AS) -esc -Fhunk -o foo.o foo.asm
	$(LD) -s -sc -bamigahunk -o foo foo.o amiga.lib
Windows' build seem to need -esc added to vasm and -sc to vlink.

Line 17 is correct, printfused should be 1 instead of -1. Also the two first lines should be setting variables to -1.

The logic is this (idea totally stollen from Thorham's macros)
The first time you use printf, the system needs _stdout to have a proper value, so you initialise _stdout by the return value of DOS/Output()
But what happens on your second or third printf?

You keep initialising it again and again.

So you put a guard against it. You define a variable printfused and initially set it to 0.
And then you have conditional assembly inside the macro asking "is printfused >= 0" (ifge printfused), if so it includes the code but also at the end of that code that you only need to run once, you set the guard variable 'printfused' to -1. So now, the second time you call mprintf the code between 'ifge printfused' and 'endc' won't run.

Anyways, I re-attached the corrected code.

Yes, the autodocs contain exchausted documentation and should be your _first_ reference when coding for amigaos. (and yes you got the function printf right

All variadic functions (functions with variable number of arguments) take their args from stack.
I don't quite understand the gist of your last question. Yes, you can have functions accepting arguments on registers. But that's not what you are asking, is it?

PS: I messed up the 0,-1 logic far too many times..sorry...regrab source if you have dl'ed already
Attached Files
File Type: zip asm.zip (1.2 KB, 63 views)

Last edited by alkis; 14 July 2017 at 20:18. Reason: typo
alkis is offline  
Old 14 July 2017, 21:20   #23
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
First, linking problem.
Solved! Fantastic, thanks a lot!

Quote:
Originally Posted by alkis View Post
Line 17 is correct, printfused should be 1 instead of -1. Also the two first lines should be setting variables to -1.
I'm still not following you there, I'm afraid. Your last attached code has the right solution, ie initializing to zero and setting them to -1 once, on the first call. Unless I'm very much mistaking, your original code had this, except execbaseinit (and not printfused) was set to 1 instead of -1 after having been initialised -- which would have meant the ifge code would be called everytime. And yes, I do understand the reasoning behind doing these kind of things only once, if ever. I tend to use the singleton pattern a lot in my 'modern' development efforts..

Quote:
Originally Posted by alkis View Post
Yes, the autodocs contain exchausted documentation and should be your _first_ reference when coding for amigaos. (and yes you got the function printf right
Ok, cool. Surely I can write autodoc-compatible libs myself? Btw, they seem to conveniently have 'forgotten' to include a %f (floating point) type in this printf function, there..

Quote:
Originally Posted by alkis View Post
All variadic functions (functions with variable number of arguments) take their args from stack.
I don't quite understand the gist of your last question. Yes, you can have functions accepting arguments on registers. But that's not what you are asking, is it?
Not really, no. I guess I'm asking for some kind of coding 'etiquette', or standard/best practices. Eg, I've noticed that a (simple) result is often returned in d0. I've seen arguments being passed through all kinds of data (usually d0, d1, and up) and adress (usually a6 and down) registers. Also, it appears to be ok to modify d0 and d1 and.. in your subroutine?

I could also default to always using the stack (as a lot of .lib functions seem to do), and/or saving all registers upon entering and restoring them back -- but that might generate a lot of unneccesary overhead for simple subroutines.

Also, I was asking about putting this functionality in a more reusable kind of form (.lib), but I think I'm almost there right now.. Hang on..
guy lateur is offline  
Old 14 July 2017, 21:47   #24
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
I'm still not following you there, I'm afraid. Your last attached code has the right solution, ie initializing to zero and setting them to -1 once, on the first call. Unless I'm very much mistaking, your original code had this, except execbaseinit (and not printfused) was set to 1 instead of -1 after having been initialised -- which would have meant the ifge code would be called everytime. And yes, I do understand the reasoning behind doing these kind of things only once, if ever. I tend to use the singleton pattern a lot in my 'modern' development efforts..
Yes, I messed up too many times on that post when replying. Your catch was right in the first place

Quote:
Originally Posted by guy lateur View Post
Ok, cool. Surely I can write autodoc-compatible libs myself?
There is no such a thing. Yes, you can write libraries (*.library). Yes, you can write libs. (*.lib) Yes, you can use autodoc style docementation on anything

Quote:
Originally Posted by guy lateur View Post
Btw, they seem to conveniently have 'forgotten' to include a %f (floating point) type in this printf function, there..
You don't need floats in assembly *evil grin*

Quote:
Originally Posted by guy lateur View Post
Not really, no. I guess I'm asking for some kind of coding 'etiquette', or standard/best practices. Eg, I've noticed that a (simple) result is often returned in d0. I've seen arguments being passed through all kinds of data (usually d0, d1, and up) and adress (usually a6 and down) registers. Also, it appears to be ok to modify d0 and d1 and.. in your subroutine?
Amigaos, uses the following convention. a0/a1/d0/d1 are scratch registers. This means when you call an OS-function, the function is gonna trash those registers. All other registers are preserved.
(UNLESS otherwise specified in the autodoc of the function, there are a couple of functions that preserve all registers by design)

Everything (byte,word,long, char *, void *, whatever *) is returned at d0, as you have noticed. If something bigger than d0 is returned, like long long, I think it's on d0/d1. When you are not sure, just do a quick sketch in C and see how the compiler does it. (gcc -S is your friend or your compiler's equivalent)

Quote:
Originally Posted by guy lateur View Post
I could also default to always using the stack (as a lot of .lib functions seem to do), and/or saving all registers upon entering and restoring them back -- but that might generate a lot of unneccesary overhead for simple subroutines.
Depends on how many times it gets called. If something is called once or twice (like opening a library) you don't really care for 100-200 cycles or whatever. If it's in a loop, that's another story.

Quote:
Originally Posted by guy lateur View Post
Also, I was asking about putting this functionality in a more reusable kind of form (.lib), but I think I'm almost there right now.. Hang on..
Good
alkis is offline  
Old 14 July 2017, 22:01   #25
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Ok, I finally succeeded in using a .lib file for a reusable subroutine. The printing code is still done through macros, but at least the UByteRep routine is linkable as desired.

I've attached 2 zip files: the stringUtil source (and make-script.py), which you'll have to assemble first to generate stringUtil.lib, which you'll need in a path you'll be including in the second step:

PrintDecimal2.zip, containing the exec source, the printing macros include file and also a make script.

Works great over here, making me very happy, indeed!
Attached Files
File Type: zip stringUtil.zip (982 Bytes, 63 views)
File Type: zip PrintDecimal2.zip (1.8 KB, 61 views)
guy lateur is offline  
Old 14 July 2017, 22:17   #26
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
ok try to present UByteRep's C prototype.

(hint: who's defining the value of a5?)
alkis is offline  
Old 14 July 2017, 22:27   #27
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
I'm very interested in your use of macros.
They sure make maths library functions easier to use.

Quote:
Originally Posted by guy lateur View Post
I've often wondered what \1 & \2 were all about..
Yeah, they're parameters. There's also \0 for sizes, so you can do things like this:
Code:
foo macro
    move.\0     \1,\2
 endm
 
    foo.l       #123,d0
Quote:
Originally Posted by guy lateur View Post
I'm looking to print things (strings, decimal, floats, ..) to screen/stdout, so I started from a basic hello world example, and I'm trying to separate the printing functionality, using macros. Here's what I have ATM
Be careful with overusing macros. It can become messy quickly. For example, this macro would be more useful if it had a parameter for the library base, because it would work with any library.

Code:
dosUtilRelease macro
	;	close	dos.library
	movea.l	_DOSBase,a1
	movea.l	_SysBase,a6
	jsr		_LVOCloseLibrary(a6)
	clr.l	_DOSBase
endm
Quote:
Originally Posted by guy lateur View Post
Still, I'm beginning to think including these macros isn't really the way to go if I want to make this functionality reusable.
Yes. Macros are definitely not always the best way to make things reusable. Those maths macros are a good example of when they are, but for many other things subroutines are better.

Quote:
Originally Posted by guy lateur View Post
I'll probably need to put this in a separate .o/.lib file, and link to that.
If you're using a standalone assembler and just starting out, you could start by simply including the source directly. You don't really have to link anything anyway. VASM can probably do that automatically (that's what you're using, right?).

You also don't really need amiga.lib. Certainly not for OS calls. Just include this file: LVOs.zip

With that you don't need those annoying XREFs for OS calls. You will have to allocate your own storage for things like library bases (I find that cleaner anyway).

Quote:
Originally Posted by guy lateur View Post
Btw, they seem to conveniently have 'forgotten' to include a %f (floating point) type in this printf function, there..
That's because it probably just calls the OS VPrintf function in the dos.library: http://amigadev.elowar.com/read/ADCD.../node01CE.html

VPrintf calls RawDoFmt (this performs the actual string formatting) and this doesn't handle floating point :http://amigadev.elowar.com/read/ADCD.../node0227.html
Thorham is offline  
Old 14 July 2017, 22:27   #28
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
ok try to present UByteRep's C prototype.
What? Why? You want me to program in C, now, do you?

Quote:
Originally Posted by alkis View Post
(hint: who's defining the value of a5?)
Uhm, the caller is responsible for declaring enough storage, is this what you mean? Or are you asking why a5 and not a6?
guy lateur is offline  
Old 14 July 2017, 22:38   #29
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Using a Python script instead of a Makefile is... interesting.

Your library test will become a real test as soon as you have more than one object module in it. Currently it links everything from the library to your executable, as only a single object is present.

Try to make a library with two objects and do only reference symbols from one of them. Then verify that only a part of the library code is included in your executable.

To answer some of your questions:
Code:
        XDEF    _main           ; ?? is this relevant/special ??
As long as you don't reference _main from a different object module there is no need for it. XDEF declares a symbol with global scope for the linker, so it can be referenced from other object modules using XREF.

Code:
; ?? can't move this to dosUtil.i ??
.fail:
A local label is only visible between two global labels. So when you move it to dosUtil.i, behind global symbols like _DOSBase and _StdOut, nobody can see it. You should define this function with a global label, so your macro can reach it in any situation.

Code:
; should probably put this in a data section or something..     
Hello:
        dc.b    'Hello World!!'
Not really. It can make sense to keep read-only data in the code section, so you can access it with PC-relative addressing mode.

Read-write data, especially when it is larger, should go into its own data section to keep your code clean and small, and allow PC-relative 16-bit branches as long as possible.
phx is offline  
Old 14 July 2017, 22:51   #30
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
If you're using a standalone assembler and just starting out, you could start by simply including the source directly. You don't really have to link anything anyway. VASM can probably do that automatically (that's what you're using, right?).
Well I was trying to include everything I needed earlier, as you suggest. But I want to build up some basic reusable code, and I'm not sure including everything in source will satisfy all my needs. I'll probably want to link to functionality other people have written, and which I don't neccesarily have the source of. And even for the things I write myself, the idea of being able to link to my other (precompiled/indepently developed) libs is very appealing. After all, it's how I'm used to developing, nowadays, and it would make things a lot clearer in my head.

Also, I was using AsmPro earlier, and I felt the need for a separately usable linker, for reasons mentioned above, which is how I ended up with vasm/vlink. That and the fact I can now code on Windows, of course..
Quote:
Originally Posted by Thorham View Post
You also don't really need amiga.lib. Certainly not for OS calls. Just include this file: Attachment 53743
With that you don't need those annoying XREFs for OS calls. You will have to allocate your own storage for things like library bases (I find that cleaner anyway).
I don't mind linking to some libs. I don't like including files 90% of which I won't usually be using. When linking to a proper .lib, only what you're actually using is added to your .exe -- or so I've heard..
guy lateur is offline  
Old 14 July 2017, 23:19   #31
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
When linking to a proper .lib, only what you're actually using is added to your .exe -- or so I've heard..
Dude. You don't link with amiga.lib to grab the vectors. You include them.

You gonna need the system includes for other things. Use them. Use the LVOs.

Ok, let me see you print VBlankFrequency which is part of SysBase structure without using system includes and linking with amiga.lib.
alkis is offline  
Old 14 July 2017, 23:20   #32
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
What? Why? You want me to program in C, now, do you?


Uhm, the caller is responsible for declaring enough storage, is this what you mean? Or are you asking why a5 and not a6?
Your documentation is wrong.

Said something like "d0 is input, output is a5"
alkis is offline  
Old 14 July 2017, 23:22   #33
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by phx View Post
Using a Python script instead of a Makefile is... interesting.
Just being pragmatic, here, using what I know. Using makefiles is on my todo list, so please let me know if you happen to know a good make.exe on win..

Quote:
Originally Posted by phx View Post
Your library test will become a real test as soon as you have more than one object module in it. Currently it links everything from the library to your executable, as only a single object is present. Try to make a library with two objects and do only reference symbols from one of them. Then verify that only a part of the library code is included in your executable.
Yeah, I hear you, I'll check that out. Just out of interest: do you think it will work as we would like it to?

Quote:
Originally Posted by phx View Post
To answer some of your questions:
<snip>
Thanks for that, but I'll need some time to get head around all of this. I might get back to you on this
guy lateur is offline  
Old 14 July 2017, 23:38   #34
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
Dude. You don't link with amiga.lib to grab the vectors. You include them.

You gonna need the system includes for other things. Use them. Use the LVOs.
Alright already, I will. LVOs.i, you mean, right?

Quote:
Originally Posted by alkis View Post
Ok, let me see you print VBlankFrequency which is part of SysBase structure without using system includes and linking with amiga.lib.
That's gone way above my head, yet again, I'm afraid. I'll probably get there eventually, hopefully..
guy lateur is offline  
Old 14 July 2017, 23:39   #35
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
Your documentation is wrong.

Said something like "d0 is input, output is a5"
Yeah, it's not that clear, I know. So how would you go about this function signature/autodocs?
guy lateur is offline  
Old 15 July 2017, 00:52   #36
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
Alright already, I will. LVOs.i, you mean, right?
Riiiiiight.

And here is some modified source. amiga.lib eliminated I rolled my own printf
Attached Files
File Type: zip foo.zip (2.0 KB, 56 views)
alkis is offline  
Old 15 July 2017, 01:02   #37
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
Yeah, it's not that clear, I know. So how would you go about this function signature/autodocs?
Well, lets see Write
Code:
dos.library/Write                                           dos.library/Write

    NAME
	Write -- Write bytes of data to a file

    SYNOPSIS
	returnedLength =  Write( file, buffer, length )
	D0			 D1    D2      D3

	LONG Write (BPTR, void *, LONG)

So you could go like

Code:
    NAME
	UByteRep -- Writes ascii decimal value of ubyte at buffer

    SYNOPSIS
	UByteRep( byte, buffer)
	 	  D0.b    a5      

	void UByteRep (UBYTE, void *)
alkis is offline  
Old 15 July 2017, 18:17   #38
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
And here is some modified source. amiga.lib eliminated I rolled my own printf
Nice one, thanks for sharing this!
guy lateur is offline  
Old 16 July 2017, 11:55   #39
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by guy lateur View Post
please let me know if you happen to know a good make.exe on win..
I don't use Windows for development, so I can only do what you also could do (ask Google). For example, a standalone GNU-make seems available here:
http://www.equation.com/servlet/equation.cmd?fa=make


Quote:
Just out of interest: do you think it will work as we would like it to?
Chances are good, as long as you manage to create a correct hunk-format library (join several objects).
phx is offline  
Old 16 July 2017, 12:34   #40
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
@phx would it be possible to embed lvo definitions in vasm? That would eliminate even the need for include
alkis 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
AmiDevCpp and Floats AmigaEd Coders. General 0 18 January 2006 03:16

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 03:59.

Top

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