When programming assembly, it was common to just indiscriminately use all RAM, not matter what the kernal[1]/basic used it for.

When programming basic, it was common to use memory regions that were meant for something else for yourself if you don’t need it, like you did, knowing that you won’t use the cassette routines.

On the C64, there were some common “autorun” tricks that loaded the program into a buffer overlapping with the keyboard/command buffer, so that after loading completed, the program would magically start without having to type “RUN” or “SYS” with some arcane address.

[1] Not a typo, Commodore called it “KERNAL” with an “A”.

There was also that 4k block of memory at $C000. It was in between the ROM blocks, and by default it was totally unused.

Basic couldn't utilize it, but in assembly it was a great area of extra memory, and you could use it without even switching the ROMs off.

Yep! For those reasons, it was more or less the "default" target for assembly programs without special requirements. So much so that even as a child I knew "SYS49152" ($C000 in decimal) by heart.

Basic interpreter used $a000 to $c000 if I remember correctly, and screen buffer characters was at $400. If you didn’t need to display anything you could use it for something else.

800/3.5k, a giant amount indeed!