+CyranoJ Posted February 8, 2019 Share Posted February 8, 2019 Take the address you get from end and make sure it is phrase aligned move.l #end,d0 add.l #8, d0 and.l #$fffffff8, d0 Will leave you with a phrase aligned address in d0 Ugh: addq.l #8,d0 and.b #$f8,d0 Will nobody think of the wasted cycles? 1 Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted February 8, 2019 Share Posted February 8, 2019 Will nobody think of the wasted cycles? It's sample code written for clarity not performance and I'm still half asleep Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 8, 2019 Share Posted February 8, 2019 This funny thing is that I don't have the misaligned data from the heap, I got it into "static" data. .phrase _bmp1: incbin "bmp1.bin" .phrase _bmp2: incbin "bmp2.bin" .phrase _bmp4: incbin "bmp4.bin" ... Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted February 8, 2019 Share Posted February 8, 2019 Weird, I have done similar in my stuff and it has to my knowledge worked fine. Are you using RMAC for the pure ASM side of things? Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 8, 2019 Share Posted February 8, 2019 Weird, I have done similar in my stuff and it has to my knowledge worked fine. Are you using RMAC for the pure ASM side of things? Yes, and If I look at the labels in the ELF file the are ok, but after executing brownout to generate a TOS executable they are misaligned. Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted February 8, 2019 Share Posted February 8, 2019 Yes, and If I look at the labels in the ELF file the are ok, but after executing brownout to generate a TOS executable they are misaligned. So this isn't a Jaguar project? I'm confused by "TOS executable". I have had a quick google for brownout but obviously most of what I found was related to power and the one link I found for Atari related stuff was dead. What does it (or is supposed to) do? Sounds like the issue lies within Brownout? Maybe if it's targetted for TOS machines it's not understanding the alignment and attempting to reclaim lost bytes by moving stuff around? making it long aligned? Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 8, 2019 Share Posted February 8, 2019 It's a Jaguar project but I'm using the gcc-atari-st-toolchain, then I relocate the TOS executable to address $4000. I'm going to try with rln, the last time about two months ago it didn't work. Quote Link to comment Share on other sites More sharing options...
SCPCD Posted February 8, 2019 Share Posted February 8, 2019 It's seems that it's phrase aligned in compile time, but your start data section address in link time is not aligned making the final thing misaligned. Exemple : .text .loop bra .loop .data .phrase toto: dc.b 0 .phrase titi: dc.b 1 will be assembled to : LTEXT+0 : bra.s LTEXT+0 LDATA+0 : toto : dc.b 0 LDATA+1 : dc.b 0 LDATA+2 : dc.w 0 LDATA+4 : dc.l 0 LDATA+8 : titi : dc.b 1 so if DATA is not properly aligned, toto & titi will be misaligned. Another point to take account is to pay attention about multiple file linking as if no proper alignment size is specified between each file, it can result on misalignement. Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 8, 2019 Share Posted February 8, 2019 Another point to take account is to pay attention about multiple file linking as if no proper alignment size is specified between each file, it can result on misalignement. This is the problem. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 9, 2019 Share Posted February 9, 2019 Most linkers do not respect "internal" alignment. You have to align the section, than (sometimes) linkers (GNU LD for example) align the section while placing. But I learned (the hard way), it is better to force certain alignment in the linker script. Quote Link to comment Share on other sites More sharing options...
ggn Posted February 9, 2019 Share Posted February 9, 2019 Another option would be to perform a so called "unity build", in which you compile a single file that includes every other files your project contains. Then the only thing the linker has to do is plug in the absolute addresses and won't bother with any alignment at all since everything will be resolved at compile time. Of course if you also link in assembly object files which aren't gas compatible format this will turn hairy very quick. (And I assume you do). Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 11, 2019 Share Posted February 11, 2019 I've wasted a lot of time trying to make brownout output sections aligned to 8 bytes, but then I've realised that I can just align the sections of the TOS file, it has only three and the format it's much easier. For now it works with a simple test program. tos2jag.zip Quote Link to comment Share on other sites More sharing options...
42bs Posted February 11, 2019 Share Posted February 11, 2019 What do you take for linking? I did not have any problems with rln, nor GNU ld?! Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 11, 2019 Share Posted February 11, 2019 (edited) g++, I tried rln but I had some problems with some files (format not recognised by rln) and didn't bother and tried again with g++. I'm using the files from here, with a few changes to make it work on the Jaguar. It compiles all the files into an ELF, then brownout convert it to a TOS and then I relocate it to $4000 with tos2jag. https://bitbucket.org/ggnkua/bigbrownbuild/src Edited February 11, 2019 by swapd0 Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 Ok, g++ is just the driver. So you use GNU ld. So why bother with a Atari ST GCC? And TOS output? GNU ld is very powerful, so you can nearly anything you want. Output an absolute ELF, then use objcopy to generate the binary. Not need to hassle with tos2jag, relocation etc. Do you need C++14 features? If not, you can just use any m68k-elf-gcc around. BTW: "brownout" is a strange word used here. Coming from embedded, "brownout" defines the moment just before "blackout" 1 Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 12, 2019 Share Posted February 12, 2019 I took the files for the Atari ST GCC from Atari-forum and from ggn, it looks that some versions ago (about 4.3?) they removed the support for 68000 processors but some users have added it again, now I'm using version 8.1. I don't what to use C++14 features but I've seen the code generated by gcc (version 7 & and it's much better than vbcc, I haven't tested with older versions. The main problem with vbcc it's that it generates code for the 68000 as it was a 32bit processor, this means that if you have an int16_t var, the compiler will read it from memory, expand to 32 bits, and operate with 32 bits opcodes, and any multiplication it's translated as 4 muls. If I use any m68k-elf-gcc around what file format it's used for the output? Can it generates a header-less absolute address executable? Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 ld generates in general ELF, but you can choose absolute or relocatable. objcopy will then generate a plain binary or srec or .... I tried building bigbrownbuild.sh, but install fails But the compiler works. Anyway, you should skip brownout. It converts ELF to TOS, and then you convert TOS to BIN. You can go directly from ELF to bin. But you need to provide a cstartup to initialize the different sections. Do you have experience writing linker scripts for GNU ld? Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 Simple command line: m68k-elf-atarist-gcc -nostdlib -Wl,-Ttext=0x4000 -Wl,--oformat,binary -o main.bin main.c Links to 0x4000 and outputs a plain binary. Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 12, 2019 Share Posted February 12, 2019 If it works don't touch it XDXDXD Maybe I'll try that later, but anyway although my method has more steps, it works and with todays computers it doesn't matter because it's fast. Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 12, 2019 Share Posted February 12, 2019 I've used GCC for many years but always with an IDE. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 If it works don't touch it XDXDXD Maybe I'll try that later, but anyway although my method has more steps, it works and with todays computers it doesn't matter because it's fast. more steps == more possible bugs 1 Quote Link to comment Share on other sites More sharing options...
ggn Posted February 12, 2019 Share Posted February 12, 2019 BTW: "brownout" is a strange word used here. Coming from embedded, "brownout" defines the moment just before "blackout" I can assure you it's nothing like that Simple command line: m68k-elf-atarist-gcc -nostdlib -Wl,-Ttext=0x4000 -Wl,--oformat,binary -o main.bin main.c Links to 0x4000 and outputs a plain binary. If you skim back a bit, the problem with that approach was that the entry point is not known (ld can place _start at whatever address it suits itself). So while we were developing brownout we added a step in which we hunted for the _start symbol and placed a "jmp XXXXXXXX" instruction at the start of the binary. Since this is TOS .prg and we are in charge of outputting the final relocation info, it doesn't matter much since we can shift the start of the actual program by a few bytes downwards. Perhaps swapd0 could have done this by altering brownout source himself but it's not the way he chose to go. 1 Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 (edited) I can assure you it's nothing like that If you skim back a bit, the problem with that approach was that the entry point is not known (ld can place _start at whatever address it suits itself). So while we were developing brownout we added a step in which we hunted for the _start symbol and placed a "jmp XXXXXXXX" instruction at the start of the binary. Since this is TOS .prg and we are in charge of outputting the final relocation info, it doesn't matter much since we can shift the start of the actual program by a few bytes downwards. Perhaps swapd0 could have done this by altering brownout source himself but it's not the way he chose to go. Sure, ld looks for _start, this is normaly the entry point of an executable. But you do not need to start patching. Just add "_start". But you can set the entry to any other label. Either per linker script (ENTRY) or via command line (--entry). So a "simple" program is: void _start(void) { main(); } void main(void) { for(;; } But mostly, _start has to initialize the sections, that's at minimum the .bss (set to zero), but can be as complicated as you want depending on your linker script. extern char __bss_start[]; extern char _end[]; void _start() { char *p = __bss_start; while( p < _end ){ *p++ = 0; } (void)main(); } Esp. for the Jaguar, I recommend to use a linker script to keep control over alignment of sections. Edited February 12, 2019 by 42bs Quote Link to comment Share on other sites More sharing options...
ggn Posted February 12, 2019 Share Posted February 12, 2019 Sure, ld looks for _start, this is normaly the entry point of an executable. But you do not need to start patching. Just add "_start". But you can set the entry to any other label. Either per linker script (ENTRY) or via command line (--entry). So a "simple" program is: void _start(void) { main(); } void main(void) { for(;; } But mostly, _start has to initialize the sections, that's at minimum the .bss (set to zero), but can be as complicated as you want depending on your linker script. extern char __bss_start[]; extern char _end[]; void _start() { char *p = __bss_start; while( p < _end ){ *p++ = 0; } (void)main(); } Esp. for the Jaguar, I recommend to use a linker script to keep control over alignment of sections. I think I get what you mean - we do that in our tiny startup .s file here and link it as early as possible. But still ld at its convenience chose to not place _start at the entry point. (and that's why we added code to check for that in brownout). I agree what you say about having a dedicated linker script since on Jaguar you want to produce an absolute binary, although I'm not sure if that would help with _start placement. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 12, 2019 Share Posted February 12, 2019 (edited) I think I get what you mean - we do that in our tiny startup .s file here and link it as early as possible. But still ld at its convenience chose to not place _start at the entry point. (and that's why we added code to check for that in brownout). I agree what you say about having a dedicated linker script since on Jaguar you want to produce an absolute binary, although I'm not sure if that would help with _start placement. Ah, now I think I get your problem. Yes, "_start" does not have to be at the beginning of the code. _start can be anywhere in the executable. If you want _start at the first address, you need a linker script. So you can do this: __attribute((__section(".init"))) void _start() { /*...*/ (void) main() } And compile with: m68k-elf-atarist-gcc -nostdlib -Wl,-Ttext-segment=0x4000,--oformat,binary,-Map,x.map -o x.bin x.c The default linker script places .init section first. Then .text. This all refers to the Jaguar, not ST, as there you need relocation information, and not absolute linking. Edited February 12, 2019 by 42bs Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.