I'd assume that HuC implicitly casts a char to int ...
So far as I can tell, HuC does not cast either way. What you declare is what you get.
And changing variable sizes won't solve the problem you are having. All variables live in one 8K page.
incrementing a char variable requires 2 operations....
No. Those 'operations' are macros. To get an accurate idea of the operations, you need to look at what the macros consist of. Are you looking in the .lst file? That usually prints the unrolled the macros for you after they are used.
when doing an operation like multiplying a char, _ldwi and _pushw are being used
Multiplication is a subroutine; the processor lacks a hardware multiply operation.
I believe it is calling a generic routine, which needs to handle 16-bit numbers, so it uses the 16 bit macros.
I may be wrong about that, though. It may be doing things via addreses...
As it is, I'm really not seeing any advantage to using char instead of int. Am I missing something?
Quite a lot actually. This is an old 8-bit processor. Things modern processors do easily have to be done via software. Huc doesn't do a good job of optimizing, nor is it especially good at tracking variable types.
(It's up to you to do that.) It also does a poor job of array access.
But it's what we have to work with.
...................................................................
Now, to answer your original question.... Your problem is that your functions are too large. The assembler does a fair job of allocating space to functions, -if- they are small. It is quite easy in HuC to create a function in C that generates more than 8K of machine code. Once that happens, the assembler will allocate a second 8K page for the rest of the code. Unfortunately, the rest of that page will be unused, leaving large chunks of unsused space.
By using smaller functions, they can be packed into the pages better (since the assembler no longer has to treat 2 pages as one large block). Both TheOldRover and I have run into this phenomenon, and found that splitting up large functions and/or rearranging their order in the files can provide significant space savings.