You are not logged in.
Lost Password?


Register To Post



 Bottom   Previous Topic   Next Topic

#31
Re: A newer GCC compiler.
Posted on: 2016/4/18 5:58
Virtual Freak
Joined 2014/8/31
USA
83 Posts
Long Time User (5 Years)App Coder
Quote:

ElmerPCFX wrote:
OTOH ... It's getting really, really hard to compile a working GCC 2.95 anymore because modern linux toolchains barf on some of the early-GCC-specific code that's in there. You pretty much need to find an old GCC 3.x compiler from somewhere.


This is a bit ironic, considering 2.95 can in theory be built with a K&R compiler. I recall there being a "make bootstrap" target in 2.95 that provides an alternate "Stage 1" for compilers that choke on the code?

Also, re: the interrupt handlers, the 4.4 startup code (presumably the 2.95 code as well) provides a few extern vars which map directly to where the CPU jumps on an interrupt. You create your interrupt handler in C, and then convert the handler's addr to a void pointer and assign them to the desired external vector addresses.

[pedantic]Of course, this can't be done in ANSI C, but because POSIX compilers require being able to convert function pointers to void, and since [jest]nobody cares about compatibility with VUCC[/jest], no harm done.[/pedantic]
Top

#32
Re: A newer GCC compiler.
Posted on: 2016/4/18 7:09
VB Gamer
Joined 2016/3/13
42 Posts
Long Time User (3 Years)
Quote:

cr1901 wrote:
This is a bit ironic, considering 2.95 can in theory be built with a K&R compiler. I recall there being a "make bootstrap" target in 2.95 that provides an alternate "Stage 1" for compilers that choke on the code?


There may well be some magic incantation and combination of barely-documented "configure" commands and environment variables to make it work ... but I could only find recommendations to go back to a previous linux distribution that had a GCC 3 compiler.

I hate the GNU build process!

IIRC, my problems were less to do with the actual source code, and more to do with the build failing on things that weren't really errors.

At least, until you get to the part of the build that wants to process the GCC documentation ... which is just horribly broken and dependent upon very specific versions of various tools.


Quote:
You create your interrupt handler in C, and then convert the handler's addr to a void pointer and assign them to the desired external vector addresses.


void pointers??? They're not declared as function pointers???
Top

#33
Re: A newer GCC compiler.
Posted on: 2016/4/18 8:15
Nintendoid!
Joined 2007/12/14
169 Posts
CoderLong Time User (11 Years) App Coder
IMO the startup code that comes with 2.95 (and thereafter crept in to version 4 and later) already does way too much. All the crt0.s file *must* do, from my own experiments, is initialize the registers, set up the data and bss sections, provide the vector table, and call main(). That's it. The 2.95 crt0.s does a whole bunch of other possibly unnecessary stuff like clearing VRAM, clearing audio RAM, setting the column table, etc. With *maybe* the exception of the column table, these things should be done as necessary either at the beginning of main() or where appropriate. I don't use the crt0.s that comes with gccVB but instead provide my own as tailored to the specific project. This includes the interrupt handler as well-- in many cases I don't even use interrupts at all, so I stub out those vectors with reti instructions. I figure since each project needs its own crt0.s anyway because of the ROM info table, I may as well customize it to the project's needs.

Maybe the ROM info table doesn't belong in crt0.s. It should be possible to create a separate .s file that when assembled just contains the ROM info table, and then place that in its proper location within the ROM at link time. In any case, I don't know where this base crt0.s came from, but I think it could stand to be pared down quite a bit.
Top

#34
Re: A newer GCC compiler.
Posted on: 2016/4/18 8:22
Nintendoid!
Joined 2007/12/14
169 Posts
CoderLong Time User (11 Years) App Coder
For example, here is a crt0.s that I use for a small project I wrote to test the timer interrupt. It assumes an interrupt handler exists at $07000000 (in my case, provided in a separate .S file) and enables the instruction cache immediately before jumping to it. However if the timer interrupt is not used, that vector can easily be stubbed out as the others are.

Attach file:


s crt0.s Size: 3.58 KB; Hits: 156
Top

#35
Re: A newer GCC compiler.
Posted on: 2016/4/18 12:03
Virtual Freak
Joined 2014/8/31
USA
83 Posts
Long Time User (5 Years)App Coder
Quote:

ElmerPCFX wrote:
void pointers??? They're not declared as function pointers???


They're u32s :P. I just called them void pointers b/c that's really what they represent. https://github.com/cr1901/vbdemo/blob/ ... vers/timedriv.c#L110-L113
Top

#36
Re: A newer GCC compiler.
Posted on: 2016/4/18 19:44
VB Gamer
Joined 2016/3/13
42 Posts
Long Time User (3 Years)
Quote:

blitter wrote:
IMO the startup code that comes with 2.95 (and thereafter crept in to version 4 and later) already does way too much. All the crt0.s file *must* do, from my own experiments, is initialize the registers, set up the data and bss sections, provide the vector table, and call main(). That's it. The 2.95 crt0.s does a whole bunch of other possibly unnecessary stuff like clearing VRAM, clearing audio RAM, setting the column table, etc. With *maybe* the exception of the column table, these things should be done as necessary either at the beginning of main() or where appropriate.
...
Maybe the ROM info table doesn't belong in crt0.s. It should be possible to create a separate .s file that when assembled just contains the ROM info table, and then place that in its proper location within the ROM at link time. In any case, I don't know where this base crt0.s came from, but I think it could stand to be pared down quite a bit.


Thanks for the example of the cut-down crt0.S, it was very interesting to compare it to the crt.S in VBJaEngine/GCC4.4.

I personally favor doing as-little-as-possible in crt0.S, and leaving non-critical startup functions to calls inside main().

Since you guys need a ROM header, then I really suspect that there should be a seperate "rom.S" project file so that folks can just change the bits that they need.

Having said which, I did notice some things that I found puzzling in the GCC4.4 (and your) crt0.S.

The VirtualBoy docs are pretty insistent that you wait 200us before accessing WRAM, and I don't see that crt0.s is actually complying with that warning.

I can't see that the linker script is actually mapping the .sdata/.sbss sections into the VirtualBoy's WRAM, and I certainly don't see the GP register being set to a "reasonable" value for using GP-relative addressing.

Unless I'm missing something, that means that all your C variable accesses are going to go through slow 32-bit loads, which seems like a terrible waste when you've got the capability for fast-access to 64KB of GP-relative variables.

Perhaps someone modified GCC so that ALL variable-access is GP-relative and I just missed it???

I can't understand why the .data and .bss segments aren't 4-byte-aligned so that crt0.S can clear stuff a word at a time rather than doing those slow byte copies.

The interrupt vectors in the GCC4.4 crt0.S seem a little overly-complex ... all that loading and indirect jumping could just be replaced with a "jr" directly into a 4-byte executable vector at the end of WRAM, which could then "jr" into your program ROM, or just "reti".


Quote:

cr1901 wrote:
They're u32s :P. I just called them void pointers b/c that's really what they represent. https://github.com/cr1901/vbdemo/blob/ ... vers/timedriv.c#L110-L113


Thanks! I guess that I was expecting executable "jr" vectors since that's the fastest.
Top

#37
Re: A newer GCC compiler.
Posted on: 2016/4/19 5:03
Nintendoid!
Joined 2007/12/14
169 Posts
CoderLong Time User (11 Years) App Coder
Quote:

ElmerPCFX wrote:
I personally favor doing as-little-as-possible in crt0.S, and leaving non-critical startup functions to calls inside main().


:)

Quote:

The VirtualBoy docs are pretty insistent that you wait 200us before accessing WRAM, and I don't see that crt0.s is actually complying with that warning.


I've tested this particular project on real hardware many times, and never ran into problems. 200us translates to about 4000 clock cycles on the VB, which would pass long before the initialization of data and bss is finished. It is very possible that my luck is due to this project not being terribly dependent on the initial state of RAM, though, so if prematurely accessing WRAM produces garbage, my guess is it simply isn't affecting my code.

One thing is pretty apparent to me though: it doesn't seem to have any other effects on the hardware.

Quote:

I can't see that the linker script is actually mapping the .sdata/.sbss sections into the VirtualBoy's WRAM, and I certainly don't see the GP register being set to a "reasonable" value for using GP-relative addressing.

Unless I'm missing something, that means that all your C variable accesses are going to go through slow 32-bit loads, which seems like a terrible waste when you've got the capability for fast-access to 64KB of GP-relative variables.


For the VBJaEngine/GCC4.4 versions, you are correct. However in my version, notice that I set sp and gp to the same value-- the top of WRAM. Thanks to WRAM being mirrored every 64KB, gp-relative accesses work just fine. ;)
Top

#38
Re: A newer GCC compiler.
Posted on: 2016/4/19 22:25
VB Gamer
Joined 2016/3/13
42 Posts
Long Time User (3 Years)
Quote:

blitter wrote:
One thing is pretty apparent to me though: it doesn't seem to have any other effects on the hardware.


It's purely a restriction on using WRAM within the first 200us.

Page 4-5-1 "Chapter 5 - Cautions when Using work RAM".


Quote:
I've tested this particular project on real hardware many times, and never ran into problems. 200us translates to about 4000 clock cycles on the VB, which would pass long before the initialization of data and bss is finished. It is very possible that my luck is due to this project not being terribly dependent on the initial state of RAM, though, so if prematurely accessing WRAM produces garbage, my guess is it simply isn't affecting my code.


The initialization of those data and bss sections in WRAM is precisely what developers are supposed to not do until 200us after power-on.

I just took a look at ...


Mario Clash    
Delay of 65535*4 cyclesfollowed by 8 dummy read cycles.

Red Alarm      Delay of 65536*4 cyclesfollowed by 8 dummy read cycles.

Vertical Force Delay of 400*36 cycle divisionsfollowed by 8 dummy read cycles.


Now, I don't know how folks are testing their code on a real VirtualBoy, but it could just be that whatever the flash-card is, it has a capacitor on the RESET line to stop the V810 from starting until 200us after the power is applied.

Or maybe everyone is just getting very lucky.

Either way ... the current startup code would fail Nintendo's Lot-Check.


Quote:
For the VBJaEngine/GCC4.4 versions, you are correct. However in my version, notice that I set sp and gp to the same value-- the top of WRAM. Thanks to WRAM being mirrored every 64KB, gp-relative accesses work just fine. ;)


Hahaha ... good point, you fooled little-old me!

But seriously ... how are you telling the compiler that the variables in the .data section can be accessed GP-relative?

That's one of the main reasons to put stuff in the .sdata/.sbss sections with the "-msda=??" compiler switch ... so that the compiler knows to generate GP-relative code.

Are you only accessing variables from assembly language that way?

Are you using your own linker script?

***************

As a side-note, while taking my quick-look at Mario Clash and the other games, it was interesting to see that Nintendo programmed their game as if the ROM were mapped into the top of the 4GB address range (i.e. the ROM is $F0000000-$FFFFFFF), wheras Hudson and T&ESoft programmed their game as if the ROM were mapped into the bottom of the 4GB address range (i.e. the ROM is $70000000-$7FFFFFF).

There are a couple of potential benefits to programming the game to believe that it's running at $F0000000-$FFFFFFF, although I can't see that Nintendo actually took any advantage of it.
Top

#39
Re: A newer GCC compiler.
Posted on: 2016/4/20 4:10
Nintendoid!
Joined 2007/12/14
169 Posts
CoderLong Time User (11 Years) App Coder
Quote:

ElmerPCFX wrote:
But seriously ... how are you telling the compiler that the variables in the .data section can be accessed GP-relative?

That's one of the main reasons to put stuff in the .sdata/.sbss sections with the "-msda=??" compiler switch ... so that the compiler knows to generate GP-relative code.


I'm not. ;) I write everything in assembly. And you're right-- gccVB doesn't know a thing about SDA variables.

Quote:

Are you only accessing variables from assembly language that way?


Yep.

Quote:

Are you using your own linker script?


Yep. I've attached it, though I can't say I'm all too proud of it. I just tweak it here and there.

Quote:

There are a couple of potential benefits to programming the game to believe that it's running at $F0000000-$FFFFFFF, although I can't see that Nintendo actually took any advantage of it.


Do tell! Shifting my ROM up to that area costs me nothing, so if there are extra benefits I'd love to know what they are.

Attach file:


ld vb.ld Size: 1.42 KB; Hits: 159
Top

#40
Re: A newer GCC compiler.
Posted on: 2016/4/20 17:07
PVB Elite
Joined 2008/12/28
Slovenia
633 Posts
Highscore Top ScoreHighscore Top ScoreCoderContributor10+ Game RatingsLong Time User (10 Years) App CoderPVBCC 2010 EntryPVBCC 2013 Entry
Quote:

blitter wrote:
Do tell! Shifting my ROM up to that area costs me nothing, so if there are extra benefits I'd love to know what they are.


I can think of three:

1. Your interrupt vectors can consist of a single JR instruction.

2. You can load certain ROM addresses into registers with a single MOVEA instruction. Of course, this requires using a compiler/assembler that does not always mindlessly generate MOVHI/MOVEA pairs. MV810ASM doesn't. ;)

3. If you arrange your data really carefully, you can load some of it (e.g. lookup tables) with a negative displacement from register 0.
Top

 Top   Previous Topic   Next Topic


Register To Post