C doesn't cut it for PCE. And even basic ASM knowledge really isn't enough if you're trying to push the system.
Genesis on the other hand, has a processor built for C.
Tom, I am going to make a comment that is totally off-topic, but I have a lot of curiosity about your post. Why did you say that C doesn't cut it for PCE, and Genesis does? I know that you have done lots of works for the PC Engine, and I would like to know your experiences...
The most important thing is the processor opcodes. On the 68k, the opcodes are
fairly slow - but you can do
alot quite a bit in a single opcode. It has a very powerful set of opcodes. And it has a
ton of addressing modes too. Probably more than I've seen for any other processor. It makes for relative addressing (dynamically moving the code into a certain address range and not having to worry about hard offsets or recompiling) really easy. The 68k also has native flat memory model. There is no far or near data. A lot of C operations translation nicely into the 68k opcode set. That's a HUGE advantage.
This isn't the case with the 65x architecture. It's more like RISC in this regard. You have simple, but very fast instructions. Speed comes from optimizing for near data, removing redundant steps or combing steps that fit within the instruction set design (more so that most processors because the instruction set is so simple). The down side is, that most RISC have 32bit instructions to help it along. This oftens means reorganizing your data in certain ways to gain speed, or doing out of order execution to remove redundant steps. C just isn't made for 65x arch. Most of the time, you have a macro layer between C and the assembler - just because it's soo complex to build out for. These macros act like normal instructions, instructions that don't exist on the 65x. Which means you get very non optimized assembly built from this C.
HuC itself has a whole slew of problems that go way beyond it just being a variant of C (it's small C). HuC has a lot of missing support for far data. It's impossible to pass a far data pointer to a user function, and then to an internal lib function that uses it - in huc. That's a huge problem for design. You have to make sure you use *direct* labels for functions that support far data, which limits the flexibility of the language. C is all about pointers. Or.. make sure you include any near data first in the list (first come, first serve). But that's only 8k. HuC is probably more CD friendly because of this. Making a serious hucard project would be even worse. Because you'd have tons of far data, where as on a CD project - you can load near data from the CD for different areas/levels/etc.
I ask this because I have made a couple of things with HuC, and in fact I have been surprised by this wonderful C compiler. What things does Genesis have and PC Engine does not have, as far as C programming is related? Are you talking about things like using bidimensional arrays (they don't exist in HuC) or similar things? Or maybe you are speaking about things at a lower level?
Well, you have
real C with the Genesis via GCC. HuC is Small C with some hacking for limited far data support for *some* lib functions. HuC really was made for computers that only had 64k of address space. HuC is fine, until you start to run into its limitations. Really slow static and dynamic pointer support, really slow shift function, nothing bigger than 16bit integers (16bit, 24bit and 32bit fixed point data types would be great as well), no real optimization option for the compiler, mostly restricted to near data access, only a small amount of ram/rom for user functions and main, opcodes can't land the middle of a bank boundary (this is an assembler problem). And to top it off, HuC totally ignores all the address vectors of zeropage. It treats a few as normal address regs, loading and unloading like it would any other processor. When really, it should be leaving them in memory. And finally, all internal data types for user define functions use a custom stack to access (it creates and destroys them on every function call). The 65x processor doesn't have direct support for this kind of address modes. So it uses a slow manual method everything it needs to read/write to that data type. Which probably wouldn't be so bad if the regs and bus weren't 8bit. The only way around this is to declare all data types as global and you know how much of a mess that can be. HuC has some serious limitations. HuC was never intended for *any* type of serious project. It was meant for *very* basic stuff. And as a stepping board to get people into assembly. Learn the hardware with HuC, then move onto assembly. The people who modified the original Small C compiler (it dates from 1983) have said so themselves. In my eyes, it's equivalent to BASIC for the most part (the limitations and the speed). And like BASIC, anything you can offset to inline ASM is where you get your speed back. But it begs the question, if a lot of it is going to be ASM functions - why even use C at all? Why not just fully optimize for assembly for some real speed