tokumaru wrote:na_th_an wrote:once I started coding for 8 bits platforms in C, I had to forget about readability, proper use of semantics, good practice and readability if I wanted to get proper results.
If you get to the point where tou have to sacrifice even readability, wouldn't it be better to just write well structured assembly code?
I sacrifice *some* readability. To my untrained eye (although I understand and can produce assembly code), even unreadable C code is easier to grasp, follow and understand. What I mean with unreadable code, of my own, could be something like where I have to add a comment to help me remember this si not a typo, or strange reordering of cases in a switch so I can share code and save bytes, using a less intuitive approach to an expression 'cause I know cc65 will generate better code, etc. And, as mentioned, the resulting mess is still easy to port to different systems.
Code: Select all
case 3:
// Gravity
envy = enems_lut_falling [enmy [enit]];
if (enmy [enit] < ENEMS_LUT_FALLING_MAXIDX) enmy [enit] ++;
// Correct! no break here. Move left/right
case 2:
case 7:
if (enx1 [enit] || half_life ) envx = enmx [enit];
break;
...
Code: Select all
if (en_ac [gpit] == 8) {
// Killed baddie
if (0 == --en_x2 [gpit]) en_ac [gpit] = 0;
oam_meta_spr (en_x [gpit] >> FIXBITS, (en_y [gpit] >> FIXBITS) - camera_position, gpit << 4, spr_explosion);
} else if (gpjt = en_ac [gpit]) switch (gpjt) {
// Yeah, this is an assignment. Don't panic
case 1:
if (rand8 () < SHOOT_TE...
They joy of cc65 is that when it doesn't behave you can always inline a better solution, as in:
Code: Select all
// cc65 could do better, so:
/*
rda = c_enems_t [enidx];
rdb = c_enems_yx1 [enidx];
rdc = c_enems_yx2 [enidx];
rdd = c_enems_mn [enidx];
*/
__asm__ ("ldy %v", enidx);
__asm__ ("lda (%v), y", c_enems_t);
__asm__ ("sta %v", rda);
__asm__ ("lda (%v), y", c_enems_yx1);
__asm__ ("sta %v", rdb);
__asm__ ("lda (%v), y", c_enems_yx2);
__asm__ ("sta %v", rdc);
__asm__ ("lda (%v), y", c_enems_mn);
__asm__ ("sta %v", rdd);
The code produced for the commented section was five times as long and fiddly, as it did recalculate the offset for each access when you'd rather use indirect addressing sharing the smae index register as enidx is unsigned char.