Is it possible to program C without using functions?

You can talk about almost anything that you want to on this board.

Moderator: Moderators

psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Is it possible to program C without using functions?

Post by psycopathicteen »

One of the biggest turnoffs for me regarding C is the fact you have work with all these mysterious functions that I have no clue where they came from, and how many of them there are. I don't even know if they themselves were programmed in assembly or C. If I'm doing an NES or SNES game in C is it possible to write to hardware registers directly?

This is a wild guess. I've been refreshing my brain on C pointers and I'm wondering if this how to do it:

int *screen_brightness
screen_brightness = 0x2100
*screen_brightness = 0x0f
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Is it possible to program C without using functions?

Post by thefox »

Yes, it's possible. That's exactly what I did in KNES (my simple C support library for NES development, https://kkfos.aspekt.fi/downloads/knes-0.2.zip) since I wasn't happy with the built-in libraries of cc65. You don't need any 3rd party functions, but the compiler itself might need some kind of support structure (initialization code at the very least).

You usually don't want to allocate a separate variable for the I/O pointer though, because the compiler might not be able to optimize it out. It's usually better to do something like this:

Code: Select all

/* macro for writing a byte to memory */
#define _M(a) (*(volatile unsigned char *)(a))
#define SCREEN_BRIGHTNESS 0x2100

void main(void) {
  _M(SCREEN_BRIGHTNESS) = 0x0F;
}
(There are other variations on this, but the basic idea is the same.)

EDIT: typo fix
Last edited by thefox on Sat Jul 16, 2016 2:03 am, edited 1 time in total.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
devmas
Posts: 19
Joined: Wed May 20, 2009 6:16 am
Location: New York City

Re: Is it possible to program C without using functions?

Post by devmas »

I'm not terribly familiar with C, but can't you just use GOTOs everywhere?

It brings be back to when I first learned to program in BASIC... Only thing is you can't return from them, so it'll be annoying to code.

In GCC I remember reading that there's a special extension that allows you to get the address of a label, and also allows you to goto an address. You could possibly utilize that. Push addresses to a stack, goto somewhere, then pop addresses to "return" to and goto that...
tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Is it possible to program C without using functions?

Post by tomaitheous »

devmas wrote: Push addresses to a stack, goto somewhere, then pop addresses to "return" to and goto that...
That's called a function.
__________________________
http://pcedev.wordpress.com
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: Is it possible to program C without using functions?

Post by psycopathicteen »

thefox wrote:Yes, it's possible. That's exactly what I did in KNES (my simple C support library for NES development, https://kkfos.aspekt.fi/downloads/knes-0.2.zip) since I wasn't happy with the built-in libraries of cc65. You don't need any 3rd party functions, but the compiler itself might need some kind of support structure (tinitialization code at the very least).

You usually don't want to allocate a separate variable for the I/O pointer though, because the compiler might not be able to optimize it out. It's usually better to do something like this:

Code: Select all

/* macro for writing a byte to memory */
#define _M(a) (*(volatile unsigned char *)(a))
#define SCREEN_BRIGHTNESS 0x2100

void main(void) {
  _M(SCREEN_BRIGHTNESS) = 0x0F;
}
(There are other variations on this, but the basic idea is the same.)
What does "volatile" mean, what does the * after "char" mean, and what does "void" mean?
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is it possible to program C without using functions?

Post by rainwarrior »

psycopathicteen wrote:One of the biggest turnoffs for me regarding C is the fact you have work with all these mysterious functions that I have no clue where they came from, and how many of them there are. I don't even know if they themselves were programmed in assembly or C.
There's no necessary need to use anyone's libraries full of "mysterious" functions just because you're programming in C. You can use or ignore whatever libraries you like.

There may be a required runtime library, but the use of this will be hidden from view (e.g. a multiply operator will probably generate code that calls a CRT library multiply function, but it won't look like a function call in your C code).
psycopathicteen wrote:If I'm doing an NES or SNES game in C is it possible to write to hardware registers directly?
Possible, but not usually recommended. Assembly is much better suited for direct register access. (Anything that requires precise or efficient timing, for example, should not be written in C.)

C and assembly can be freely integrated, by the way. You can call assembly functions from C and vice versa.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Is it possible to program C without using functions?

Post by koitsu »

psycopathicteen wrote:What does "volatile" mean, what does the * after "char" mean, and what does "void" mean?
* Understanding volatile (this may not make any sense to you unless you have more familiarity with C. The simple version is: compilers try to do a lot of things under the hood/automatically in attempt to relieve the programmer from having to worry about it. You come from an assembly background, where you pretty much do everything yourself, and there's no real typing -- as you know, to a CPU, data is data, you can do with it / treat it however you want)
* The * means pointer (think indirect addressing); char *foo is a declaring a variable called foo that is a pointer which points to a bunch of "chars" (8-bit bytes).
* void depends on context; variable declarations -- it means "I don't know what type this thing is" (please refer to this for what a "type" is in C), which in turn means it can't be dereferenced; function declarations -- it means "this function takes no arguments" or "this function returns no value".

Trying to do assembly-like things in C is often (almost always) horrid. Do people do it? Sure (esp. in embedded projects), but usually people write functions or macros that they can use to do the thing for them. Programming like this in C is painful and bleh, IMO. If someone's doing a very large project and has to defer to a *lot* of functions to address memory-mapped I/O registers and so on, I often tell them to just use assembly. (You CAN use both together! This is called inlined assembly and generally requires that the C compiler be well-documented so you know what to put in what register/memory location/stack so that the "other C-specific bits" work correctly).

There are not a lot of SNES titles in C. There are several Apple IIGS titles in C, but for "lower level management" of the system (MMIO registers, etc.) the majority of the code is assembly. In general, 65xx and 65816 are not very good architectures for C, given how its designed. There are also very (VERY) few C compilers for the 65816 (ORCA C (Apple IIGS) is one, and there are a few others, but precarious at best IMO). I never did any C programming on either the SNES or the Apple IIGS (I did assembly on both, as well as some Pascal on the IIGS for some system utilities (which also needed assembly because they interfaced with the Zilog serial chip directly) -- the Pascal things involved GS/OS, which is an operating system that the Apple IIGS can use).
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is it possible to program C without using functions?

Post by rainwarrior »

Volatile is one of the most useless keywords in the C language. It's more or less vestigial.

The original intent was to flag variables that might change without any C code being involved; example:

Code: Select all

// consider polling a hardware register:
unsigned char* ppu_status = 0x2001;
while (!(*ppu_status & 0x80)) {}

// without realizing that ppu_status can change without the code doing anything,
// an optimizer might think this code has identical meaning:
unsigned char* ppu_status = 0x2001;
if (!(*ppu_status & 0x80))
{
	while(true) {} // ppu_status isn't changed in the while loop, so it's just an infinite loop, right?
}

// volatile tells the compiler to expect ppu_status to change on its own
volatile unsigned char* ppu_status = 0x2001;
while (!(*ppu_status & 0x80)) {}
Basically it was intended to disable certain kinds of optimizations (e.g. loop invariants), mostly so that you could do things like poll hardware registers and not have the code break.

In practice, though, volatile proved ineffective. There was reason to just do the hardware access directly in assembly in almost all cases, because volatile alone wasn't good enough for what they needed (e.g. precise timing etc.). The way it was specified was too weak to make the kinds of guarantees people usually would hope, and it has pretty much no place in modern multi-threaded programming (stronger guarantees were needed, e.g. C++11's std::atomic). It's a real dud.


In CC65 it literally does nothing, because all variables are effectively "volatile" (its optimizer does not recognize invariants, anyway). It's the correct thing to put on a hardware register, semantically, but it might be more correct to write assembly code instead.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Is it possible to program C without using functions?

Post by Bregalad »

psycopathicteen wrote:One of the biggest turnoffs for me regarding C is the fact you have work with all these mysterious functions that I have no clue where they came from, and how many of them there are. I don't even know if they themselves were programmed in assembly or C. If I'm doing an NES or SNES game in C is it possible to write to hardware registers directly?
It sounds like you are looking to program without using libraries, not without using functions. That's completely different.
calima
Posts: 1376
Joined: Tue Oct 06, 2015 10:16 am

Re: Is it possible to program C without using functions?

Post by calima »

I find it really surprising someone expert in SNES asm would not know C. psychopathicteen, did you really learn programming by starting with asm?
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Is it possible to program C without using functions?

Post by DRW »

devmas wrote:I'm not terribly familiar with C, but can't you just use GOTOs everywhere?

It brings be back to when I first learned to program in BASIC... Only thing is you can't return from them, so it'll be annoying to code.

In GCC I remember reading that there's a special extension that allows you to get the address of a label, and also allows you to goto an address. You could possibly utilize that. Push addresses to a stack, goto somewhere, then pop addresses to "return" to and goto that...
That's not what the original poster meant. He was talking about not using any external library functions, he was not talking about not using any self-written functions and doing everything with goto.

And yes, as others have said: It is possible. You don't need the C standard library to program the NES.

But if you even want to prevent the compiler from calling some functions internally, this could be really hard. The compiler uses functions to turn the built-in C commands into Assembly code (like using multiplication or using parameters in functions etc.)

In my program, I don't include any header file except my own. But if I omit the -t nes from the compiler call and write -t none, then the compiler complains that labels like decsp1, incaxy, mulax7 etc. are not known.

So, you don't need anything like printf or memcpy in your code. But unless you never declare local variables or functions with parameters and unless you refrain from doing many other things that are built-in language features of C, the compiler itself will internally use some generic CRT functions. But those functions usually have nothing to do with the stuff that you find in "stdlib.h" or "time.h" etc.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Is it possible to program C without using functions?

Post by tepples »

calima wrote:I find it really surprising someone expert in SNES asm would not know C.
I learned Applesoft BASIC, HyperTalk, 6502 assembly language, and TI-BASIC on TI-83 before C.
DRW wrote:So, you don't need anything like printf or memcpy in your code. But unless you never declare local variables or functions with parameters and unless you refrain from doing many other things that are built-in language features of C, the compiler itself will internally use some generic CRT functions. But those functions usually have nothing to do with the stuff that you find in "stdlib.h" or "time.h" etc.
Analogy for someone who has used the GNU toolchain: The "generic CRT functions" needed for a freestanding C implementation come from libgcc (and libsupc++ if using C++), while the big heavyweight functions in headers like stdio.h and string.h come from libc (and libstdc++ if using containers or iostream).
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: Is it possible to program C without using functions?

Post by psycopathicteen »

calima wrote:I find it really surprising someone expert in SNES asm would not know C. psychopathicteen, did you really learn programming by starting with asm?
Yeah. That's been holding me back a lot.

I also learned to optimize code before I got any code to work.
calima
Posts: 1376
Joined: Tue Oct 06, 2015 10:16 am

Re: Is it possible to program C without using functions?

Post by calima »

Then it's hats off, that's one of the hardest ways to start. I had messed with Basic when I was 10, but when I decided to learn Real(tm) programming, I thought I'd go to the deep end and start with C instead of python, java or C#. The "I have to do WHAT to make a simple operation work" factor is times 100 for asm, lol.

/ramble
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Is it possible to program C without using functions?

Post by tokumaru »

calima wrote:that's one of the hardest ways to start.
The hardest part is actually switching paradigms, IMO. If you start with the freedom of assembly, you'll probably have a hard time conforming to the restrictions of a high-level language. If you start with high-level languages, you might have a hard time implementing from scratch things you take for granted.
Post Reply