ggn Posted February 12, 2019 Share Posted February 12, 2019 Now, I won't pretend I remember all the things we tried when we were working on browncc/brownout, but I'm sure we tried a few things with linker scripts. The results we got was that ld would crash or ignore our scripts with the back then current binutils. So instead of trying to report our issues or hope they magically fix them we just went ahead with-Ttext-segment=0 and then wrote brownout to do the rest of the work. But hey, if that linker script above works, then it's good news! Quote Link to comment Share on other sites More sharing options...
ggn Posted February 12, 2019 Share Posted February 12, 2019 Also, small reminder/updater: http://brownbot.mooo.comis based on Compiler Explorer and lets you see the assembly output as you type your C code immediately! Also, under the "C" section there is now the option to use a couple of ST compilers using a thin emulation layer. It's fun to sometimes see gcc producing worse code than a 90s compiler . Quote Link to comment Share on other sites More sharing options...
42bs Posted February 13, 2019 Share Posted February 13, 2019 (edited) Also, small reminder/updater: http://brownbot.mooo.comis based on Compiler Explorer and lets you see the assembly output as you type your C code immediately! Also, under the "C" section there is now the option to use a couple of ST compilers using a thin emulation layer. It's fun to sometimes see gcc producing worse code than a 90s compiler . It is shocking, what horrible code gcc produces sometimes. Esp. Duff's device is a good example where C compilers reach their limit Or where careful chosen types (unsigned instead of signed) produce much better code. Edited February 13, 2019 by 42bs Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 13, 2019 Share Posted February 13, 2019 F*******CK!!!!! I've done more testing and it doesn't work. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 13, 2019 Share Posted February 13, 2019 F*******CK!!!!! I've done more testing and it doesn't work. Don't get mad. When it comes to gcc/ld I might help. I am fighting with those for the last 25 years, so ... Quote Link to comment Share on other sites More sharing options...
ggn Posted February 13, 2019 Share Posted February 13, 2019 Personally I'd advise to start clean and try out Bastian's tips and nothing else. Those should lead to an absolute binary without much fuss. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 13, 2019 Share Posted February 13, 2019 (edited) Here a small framework (Note: only tested for compilation, not run!): # Makefile (make sure to replace SPACES with TABs!!) ALL: jaggy.bin CC=m68k-atarist-elf-gcc -mcpu=68000 LD=m68k-atarist-elf-gcc -mcpu=68000 AS=m68k-atarist-elf-gcc -mcpu=68000 OBJCOPY=m68k-atarist-elf-objcopy CFLAGS=-g ASFLAGS=-g -Wa,--bitwise-or,--register-prefix-optional,--gdwarf2 LDFLAGS=-nostartfiles -nostdlib -Wl,-T,jaggy.ld,-Map,jaggy.map OBJECTS=jaggy.o cstartup.o _start.o jaggy.bin: jaggy.elf $(OBJCOPY) -Obinary $< $@ jaggy.elf: $(OBJECTS) $(LD) $(LDFLAGS) -o $@ $(OBJECTS) .ONESHELL: %.o : %.c @echo "CC $<" $(CC) -c $(CFLAGS) $< .ONESHELL: %.o : %.S @echo "AS $<" $(AS) -c $(ASFLAGS) $< Linker script: /* jaggy.ld */ /* mimimal linker script */ ENTRY(_start) MEMORY { rom (rx) : org = 0x802000, len = 2M-0x2000 ram (rx) : org = 0x4000, len = 2M-0x4000 } stack_top = ORIGIN(ram)-4; SECTIONS { .text : { KEEP(*(.init)) *.o(.text) . = ALIGN(4); /* needed for cstartup */ __section_init = .; LONG(0); LONG(0); LONG(0); /* dummy, needed for later ROM => RAM copy of code */ LONG(0); LONG(0); LONG(0); /* dummy, needed for later ROM => RAM copy of data */ LONG(ADDR(.bss)); LONG(SIZEOF(.bss)) } > ram .data ALIGN( : { *(.data) . = ALIGN(; } > ram .bss ALIGN( : { *(.bss) . = ALIGN(; } > ram } Entry point: /* _start.S */ .section ".init","ax" .extern stack_top .globl _start .type _start,@function _start: lea stack_top,sp /* add jaguar setup here */ jmp cstartup cstartup: /* cstartup.S */ .extern main .extern __section_init .text .globl cstartup .type cstartup,@function cstartup: lea __section_init,a0 move.l (a0)+,a1 // text_romstart move.l (a0)+,a2 // text_start move.l (a0)+,d1 // text_size beq.s crt2 cmp.l a1,a2 // src == dst => no copy beq.s crt2 crt1: move.l (a1)+,(a2)+ subq.l #4,d1 bne.s crt1 crt2: move.l (a0)+,a1 // data_romstart move.l (a0)+,a2 // data_start move.l (a0)+,d1 // data_size beq.s crt4 cmp.l a1,a2 beq.s crt4 crt3: move.l (a1)+,(a2)+ subq.l #4,d1 bne.s crt3 crt4: move.l (a0)+,a1 // bss_start move.l (a0)+,d1 // bss_size beq.s crt6 crt5: clr.l (a1)+ subq.l #4,d1 bne.s crt5 crt6: jmp main And last but not least the main function: /* jaggy.c */ char test1[12]; __attribute((aligned()) short fb[320*240]; const char hello[] = "jaggy rulez"; void main(void) { for(;; } When you check jaggy.map, you'll see, that the fb array is really aligned on 8 bytes. The linker script now places everything in RAM. It can be expanded to link for ROM and have code linked for RAM. HTH Edit: Fix stack_top. Edited February 13, 2019 by 42bs 2 Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 13, 2019 Share Posted February 13, 2019 It works with my sprite test, I've changed my makefile and used the linker script, etc and looks ok, even I've changed a few things into my code and still runs. Now I'm gonna try with the st-niccc demo... Thanks a lot. 1 Quote Link to comment Share on other sites More sharing options...
42bs Posted February 13, 2019 Share Posted February 13, 2019 It works with my sprite test, I've changed my makefile and used the linker script, etc and looks ok, even I've changed a few things into my code and still runs. Now I'm gonna try with the st-niccc demo... Thanks a lot. Great. The next step are overlays => Different code in ROM linked to the same address in RAM ...... Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 13, 2019 Share Posted February 13, 2019 I've st-niccc running and it's faster... Quote Link to comment Share on other sites More sharing options...
42bs Posted February 14, 2019 Share Posted February 14, 2019 I've st-niccc running and it's faster... Nice. Because? Now gcc before vbcc? Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 14, 2019 Share Posted February 14, 2019 (edited) Nice. Because? Now gcc before vbcc? vbcc generates code as a 32bits processor, it doesn't matter if you use int16_t types, it will read the value, expand to 32bits and do the operation. The speed up it's quite huge, much better than I thought. Edit: https://twitter.com/swapd0/status/1095996493603979264 Edited February 14, 2019 by swapd0 3 Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 15, 2019 Share Posted February 15, 2019 It's weird. I've in classic kong an assembly file with some incbin, I forgot to use .data directive in the file and the makefile puts that data file at the start, it doesn't use the ENTRY(_start). Quote Link to comment Share on other sites More sharing options...
42bs Posted February 15, 2019 Share Posted February 15, 2019 It's weird. I've in classic kong an assembly file with some incbin, I forgot to use .data directive in the file and the makefile puts that data file at the start, it doesn't use the ENTRY(_start). You mean the linker not the Makefile, I guess. Did you check the map file, if _start.o was included? BTW: If you use sub-directories, you have to add a "*" in front of the files. LD is kinda stupid. If you write "_start.o(.init)" _start.o must be in the same place as the linker script. If you write "*_start.o(.init)", it can be anywhere. Maybe PM your linker-script and map-file. 2 Quote Link to comment Share on other sites More sharing options...
ggn Posted February 15, 2019 Share Posted February 15, 2019 LD is kinda stupid. Can confirm - I made it explode in so many weird and wonderful ways while adding elf support to rmac 1 Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 21, 2019 Share Posted February 21, 2019 There's a way to avoid to put __attribute__((aligned (4))) at the C data that I've to access from the GPU to avoid alignment issues? Quote Link to comment Share on other sites More sharing options...
42bs Posted February 21, 2019 Share Posted February 21, 2019 It should align data on the natural boundary, that is char on byte, short on two and int on four bytes. From gnu.org: -malign-int -mstrict-align 1 Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted February 21, 2019 Share Posted February 21, 2019 There's a way to avoid to put __attribute__((aligned (4))) at the C data that I've to access from the GPU to avoid alignment issues? Not sure if it would work but define your own types with that included? Or a way that should certainly work, create your own macro's for types you wish to be 4 byte aligned? I know a lot of people view macro's as dirty, but that should work if you can stop yourself from using the actual real types by mistake. There is probably a cleaner way, just my 2p 1 Quote Link to comment Share on other sites More sharing options...
42bs Posted February 21, 2019 Share Posted February 21, 2019 The C++ adicts thing macros are bad and prefer templates. But you can do so much fun stuff with macros .... :-) Defining own types is a valid option. stdint.h has already something like int_fast_t etc. So why not int_aligned_t or phrase_aligned_t.Nice idea. Quote Link to comment Share on other sites More sharing options...
swapd0 Posted February 21, 2019 Share Posted February 21, 2019 It should align data on the natural boundary, that is char on byte, short on two and int on four bytes. From gnu.org: -malign-int -mstrict-align With -malign-int I got a nice internal compiler error: Segmentation fault: 11, lol. Not sure if it would work but define your own types with that included? Or a way that should certainly work, create your own macro's for types you wish to be 4 byte aligned? I know a lot of people view macro's as dirty, but that should work if you can stop yourself from using the actual real types by mistake. There is probably a cleaner way, just my 2p Yes I've some struct with that defined, I'm gonna try the macro solution. Quote Link to comment Share on other sites More sharing options...
swapd0 Posted April 4, 2019 Share Posted April 4, 2019 WTF!!!!!!!!1!! With the skunk_print line commented it doesn't works, when I draw a string I get the first char of the string with garbage(actually I think that it draws the last character from the last string), but with the line uncommented it works... I got a lot of issues like these with Classic Kong compiled with gcc, but with vbcc compiler it worked. void draw_char(char ch, uint8_t *dst) { const char *font = _font + (((uint16_t)ch - ' ') << 6); // skunk_print("char %d\n", ch); for ( int i = 0; i < 8; ++i ) { *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; *dst++ = *font++; // next line dst += 256 - 8; } } void draw_text(const char *text, uint8_t *dst) { int16_t col = 0; while ( *text ) { draw_char(*text, dst); ++text; ++col; dst += 8; if ( col == 32 ) { col = 0; dst += 7*256; } } } Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted April 4, 2019 Share Posted April 4, 2019 Rather than dropping a char directly into a decimal, perhaps convert it 1st? skunk_print("char %d\n", ord(ch)); Might be down to how the different compilers are treating the translation between char and numerical value? When you say it works with it commented out, do you mean the string appears as you intend or is the graphical string being displayed incorrect? Quote Link to comment Share on other sites More sharing options...
swapd0 Posted April 4, 2019 Share Posted April 4, 2019 (edited) Sorry, the bug it's what I get on the screen(Jaguar), not on the PC through the skunk. That routine it's called to draw the score, bonus and lives in Classic Kong, the lives are drawn as two string of 10 chars, but the first char of each string gets garbage so I included the skunk_print for test purposes but then it worked. WTF!?!? Also I've tested to send the string to the skunk board and it's ok, but if I remove some code (like the skunk_print) the first char it's wrong (on the screen) although the string it's ok (at the PC). I'm getting a lot of weird issues like these. I wish I could use gdb... Edited April 4, 2019 by swapd0 Quote Link to comment Share on other sites More sharing options...
LinkoVitch Posted April 4, 2019 Share Posted April 4, 2019 I get the feeling this *might* be an alignment issue, where the code is moving a data structure further down in the code out of long alignment, or even word alignment. I am not sure how you could add 1 or 2 bytes via C however. I have had things mysteriously stop working when I added a nop once, and then add another nop and it worked again in sections of code that were not being called even. It was an alignment issue. Quote Link to comment Share on other sites More sharing options...
42bs Posted April 4, 2019 Share Posted April 4, 2019 Did you check the assembly code? 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.