23 July 2020, 22:03 | #1 |
Registered User
Join Date: Jul 2020
Location: Zagreb / Croatia
Posts: 2
|
Organizing .asm projects
Hiya,
Trying to get into Amiga asm on a more serious level, and trying to figure out the best way to structure my projects. I just moved from the "big mess of included files" pattern to using a linker. I'm using vasm / vlink and the amiga assembly extension for VSCode. What would be the best way to use a piece of external asm code in my project? For example a mod replay routine. The amiga assebly extension just assembles / links every .s file in the project folder to build the .exe ... this would mean I'd have to copy the replayer source into my project... and update the file everytime there's a change / new version. I'd like to keep the replay routine (and other similar reusable code) in its own folder and just kind of "include" it in my project/workspace as a dependency without actually using an inline include directive. Is this possible, and what would be the best way to do it? |
23 July 2020, 22:17 | #2 |
Registered User
Join Date: Jul 2020
Location: Zagreb / Croatia
Posts: 2
|
Nevermind, just figured it out myself
You can add multiple folders to the VSCode workspace, and the Amiga Assembly extension will pick up source files from all the folders to asseble... |
24 July 2020, 11:20 | #3 |
Registered User
Join Date: Feb 2020
Location: Germany
Posts: 177
|
In my solutions i use includes. My routines i have stored in a file. With defines i decide which functions i want to use from the collection.
Here a small example from a project of mine main.s Code:
; set include folder as first INCDIR "../Share/Source" ; Define needed Functions FS_AAC: SET $1 ; AllocAndCopy ... ; Alloc memory: Sin data move.l #SinDataQuadrantSize,d1 ; Size sub.l a0,a0 ; Source a0=0 > do not copy lea (SinDataAdr,PC),a1 ; (new alloc) Target Address bsr AllocAndCopy tst d0 beq ExitProgramm ... ; include functions at last INCLUDE includes/functions.i Code:
; function is not needed as default IFND FS_AAC FS_AAC: SET $0 ENDC ... ; - - - - - - - - - - - - - - - - - - - - - - - ; AllocAndCopy: ; - allocate memory by given size on D1 and store the pointer to address of A1 ; - if source data A0 set, then copy the content to the allocate memory ; D1 < Size of needed memory in bytes ; A0 < Source Data ; A1 < Target Address to store new alloc memory adr ; D0 > $0 =Error ; - - - - - - - - - - - - - - - - - - - - - - - IF FS_AAC=1 AllocAndCopy: movem.l d1/a0-a1,-(SP) move.l d1,d0 ; Set size move.l ExecBase,a6 move.l #Clear,d1 ;Chip-RAM + clear up jsr AllocMem(a6) ;memory please movem.l (SP)+,d1/a0-a1 move.l d0,(a1) ; store addess into a1 beq .aacend cmp.l #$00,a0 ; Allocate ONLY! beq.s .aacend ; Copy source data to new allocated memory move.l (a1),a1 ; get address behind a1 subq #$01,d1 .aaccopy: move.b (a0)+,(a1)+ dbra d1,.aaccopy .aacend: rts ENDC On the old platforms space and computing time is precious. You can also use this method to assign a function name multiple times. The desired function is then determined via defines. So i have stored several music playback functions (a fast one only 8 grid lines long, one for NoiseTracker, one for FastTracker and a big one that beats all of them) and the call in the main program remains the same. Man könnte natürlich auch für jede Funktion eine Includefile erstellen, wenn man will. |
24 July 2020, 12:09 | #4 | |||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Quote:
Quote:
After that it's easy in the include to generate a call to some init function that will open all the necessary libraries, devices, etc (i also perform automatic cleanup but it's a little more tricky). Quote:
|
|||
25 July 2020, 12:25 | #5 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Quote:
When you save your routines as single object files and put those into a linker library, the linker would automatically pull only those objects into the final executable where you referenced a symbol from. No defines or includes needed. Just "xref externalfunction". |
|
25 July 2020, 13:06 | #6 | ||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Quote:
The one and only argument against this, is that the assembler will always have to reassemble everything, using unnecessary time. But considering (in my case) the performance of Phxass under Winuae Jit, this argument is moot. Quote:
In any case, i would go from 2 files to 200+ (100+ functions, with sources and objects). THAT would be complicated and messy (and, in fact, simply impossible because my startup/cleanup code wouldn't know what to do). And as said, included code can be adaptative. My screen opener for example needs to know what is used, otherwise it will support ST screens, C2P and 24-bit (HAM8) even where it's of no use. |
||
25 July 2020, 16:01 | #7 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Because you have to construct something with includes, conditional assembly and macros in your source texts which the linker can do automatically. It would also improve readability.
Quote:
Quote:
|
||
25 July 2020, 16:35 | #8 | ||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Quote:
There is nothing complicated in here. Of course one might want to do something more complex. My startup/cleanup code for example is automatic, depending on what functions are used (yes i have full resource tracking ). This makes the code not very readable indeed, but guess what : the linker just can't do this. I can also optimize some parts if a feature isn't used, f.e. my copymem is a true memmove, but it can be configured as mere memcpy to make code shorter. Remember that the linker can only remove whole functions (actually whole sources !), it can not alter code in a function to remove or rewrite a small part of it. Furthermore, an include can provide lots of useful macros to circumvent missing features of 68k. I can't live without mine. Quote:
Let's admit it can remove everything that's not really used, the project still has to include all these object files. And if some function is called but the coder forgot to add it to his project, the linker won't fetch it for him. Of course he could just add all functions in the project but adding a hundred files to all projects does not look like a good idea. |
||
25 July 2020, 22:25 | #9 | |||||||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Quote:
Quote:
Linkers support automatic constructor/destructor handling. For example vlink recognises vbcc-style constructors starting with __INIT.. and destructors starting with __EXIT... (SAS/C-style and gcc-style are also supported). It even builds a list of constructor and destructor pointers for you, to call all these function on program startup and exit. These lists can be referenced by __CTOR_LIST__ and __DTOR_LIST__. So when you have an object file with a function which needs some initialisation on startup you would just add an __INIT_myfunc function to this same object. Quote:
Quote:
But some linkers (including vlink) can also do section garbage collection. Which works by tracing all symbol references from the starting point to find out which sections are referenced by the program flow. All other sections will be removed. FreePascal uses this vlink-feature. Quote:
Quote:
Quote:
Quote:
I think we reached the core of your problem here. You think you have to specify all single object files manually on the command line and also remove those manually which you don't need? No, you won't do that. You will put all these object files in a linker library(!). For Amiga hunk-format a linker library is as simple as join #?.o as my.lib Then link your current project with "-lmy" and the linker will automatically pick only those objects you need. Quote:
|
|||||||||
27 July 2020, 10:27 | #10 | |||||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Not really ! Single include, many xref.
I don't want to have bunches of xref in source code. It has to be automatic, so the xref would have to be... in an include. Quote:
This is for individual functions. Usually some library will be used by several of them, but needs to be opened only once. Are these CTORs allowed to FAIL btw ? I mean, can they prevent other CTORs to be called and trigger a program exit (that will call all relevant DTORs but not the ones related to unitialized things) ? With single init routine full of ifd/endc it's very easy. How do you do that with local-to-function init code ? Anyway, having many small routines instead of a single big one isn't very optimal - and not so easy to call in the right order. Quote:
Anyway, that means there will be different versions to maintain. There can be a feature disabled, some 68k vs 020 small change, etc. If several unrelated differences occcur in same function there can be many versions of it. Several versions mean either copy-paste of same function in different places (yuck !) or includes with macros and if/endc (i.e. the exact thing you wanted to avoid). Quote:
It also needs to be able to tell the coder the source line at which an unresolved reference occurs (in case a nonexisting function is called). Last time i used a linker (Phxlnk) it didn't, but things might have changed. Quote:
In addition, the main problem here is that it forces the coder to use a linker, leading to several commands to type instead of one (or use scripts, etc). That for zero benefit from the library user's point of view. This is missing the point of easy-to-use library code, which is to make coder's life easier. Yes but - now that an include is there, why not just use it at its fullest ? Quote:
But a change to a function is for me altering a single source. With your method i would in addition have to reassemble the function (multiple times if there are different versions of it like you suggested above), then rebuild the linker library. Not very convenient for debugging. Ok, ok But we still end up with a gazillion files on the HD. |
|||||
27 July 2020, 11:34 | #11 |
Semi-Retired
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 1,993
|
|
27 July 2020, 13:56 | #12 |
Registered User
Join Date: Feb 2020
Location: Germany
Posts: 177
|
So the method with the defines works very well on real Amiga
|
28 July 2020, 17:48 | #13 | |||||||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Quote:
Quote:
Quote:
Quote:
What I am doing is to make a single source with conditional assembly for different CPUs or features and assemble the same source with different defines into different object files using a Makefile. So when I change something, a simple "make" rebuilds all objects and also the linker library with them. Quote:
Quote:
Quote:
Quote:
Quote:
I just wanted to mention that there are alternatives to a huge include-block, because the original post asked for it. |
|||||||||
28 July 2020, 20:11 | #14 | ||||||||||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
|
Quote:
One init routine for one library function, so that the init routine is somehow local to that function. You didn't say how i can use this method to open dos.library only once, btw. Quote:
Quote:
Quote:
Be honest : is a pair of ifd/endc added to every routine that much to handle ? Quote:
Quote:
Yours on the other hand doesn't work without a linker. Btw. My "giant blob" is probably smaller than what the equivalent linker library would be and is just 170kb, wow so big. Oh, and of course it can perfectly use sub-includes not there unless used, so it's not fully included every time. Quote:
You also forget the command to assemble the source. All that together is single, small command for me. Am I starting to pick on your nerves ? Quote:
Quote:
You're saying there is benefit ? But where is it ? I only see shortcomings : - more steps to build the project - lots and lots of files - requires a linker (and a good one) - imprecise error messages (you know, that missing line number) - init/exit code not very manageable (because order isn't obvious) - suboptimal code (in comparison) Do you have such a list ? If so I want to see it. Quote:
It was probably not the intent, but it is equivalent to jumping in here saying : hey your solution is just BS, i've something better. You see ? |
||||||||||
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
ASM: Asm-ONE or AsmPro - how to set a Hello amiga coders, I hope it is ok to hijack ? | Fireball | Coders. Asm / Hardware | 2 | 24 April 2020 21:16 |
Organizing Amiga collection | amiga_Forever | Retrogaming General Discussion | 0 | 14 February 2017 01:05 |
Proposal: Split Amiga projects and PC projects? | andreas | project.Amiga Game Factory | 4 | 12 February 2008 12:00 |
Organizing adf/rom collection | mtb | Retrogaming General Discussion | 3 | 17 July 2007 19:14 |
|
|