[MSX-C] Q&A official thread

Page 24/57
17 | 18 | 19 | 20 | 21 | 22 | 23 | | 25 | 26 | 27 | 28 | 29

By anonymous

incognito ergo sum (116)

anonymous's picture

17-09-2015, 08:16

In C it's very simple as well. Look at these two programs:

PROG1.COM prints a string in the screen, then runs PROG2.COM with the parameter "GOODBYE":

PROG2.COM prints the parameter and exits:

This is the result:

There are four functions in MSX-C to handle process launching:

  • execl() and execlp()
  • execv() and execvp()

execl() and execlp() take a variable number of arguments: first the program name and then several arguments one after the other. execlp() looks for the program using the PATH environment variable if it can't find it in the current directory.

execv() and execvp() take two arguments: the program name and an array of arguments to pass to the program. As with execlp(), execvp() searches the PATH variable.

Note that using these functions replace the program in memory with the program loaded from disk, exactly like in BASIC.

I prefer to use a different approach: load the sub-program from disk into a buffer, then use a pointer to a function pointing to that buffer and run the function. This keeps the main program in memory and on control.

By AxelStone

Prophet (3108)

AxelStone's picture

17-09-2015, 08:30

JaviLM wrote:

I prefer to use a different approach: load the sub-program from disk into a buffer, then use a pointer to a function pointing to that buffer and run the function. This keeps the main program in memory and on control.

This is really a very interesting aproach, but I didn't though it was possible in C. Is this perhaps the equivalent to Overlays in Pascal? I summary how overlays works in Pascal.

To save memory in Turbo Pascal, you can declare several functions as overlays. They must be functions that will not execute at same time, since they will occupy the same space in RAM. For example:

overlay function1() -> suposse it takes 5Kb.
overlay function2() -> suposse it takes 10kb
overlay function3() -> suposse it takes 3 Kb

If you don't declare them as overlays, you will need 18Kb to store this functions. However with overlays, the compiler reserves the equivalent space to biggest of them (10Kb in this case) and they are switched in memory on demand, saving a valuable space. By this way, as you say in MSX-C, the main program remains in background and the execution simply switches from one to other.

Is this what you are talking about in MSX-C?

By anonymous

incognito ergo sum (116)

anonymous's picture

17-09-2015, 08:43

It's not exactly the same thing. I don't have experience in Turbo Pascal, but in MSX-C it would much more involved. Let's say that you prepare a buffer at address 0x2000. The code you want to load from disk must be assembled to run from that address, and it doesn't have to touch any of the existing code in memory. This is easily doable with simple assembler routines, but for more complex stuff it's better to stick with the exec*() functions.

By DarkSchneider

Paladin (944)

DarkSchneider's picture

17-09-2015, 11:27

The problem is that

Quote:

replace the program in memory with the program loaded from disk

is not an option. And the desired overlay functions are C not ASM.

Maybe the ROM making with C part of manual could help, something required by ROMs using more than 16KB of RAM or mega-ROMs. Then using the same memory block for all functions.

By AxelStone

Prophet (3108)

AxelStone's picture

17-09-2015, 13:06

DarkSchneider wrote:

The problem is that

Quote:

replace the program in memory with the program loaded from disk

is not an option. And the desired overlay functions are C not ASM.

Yes this is the problem, for example. You are playing your RPG in the town, then you enter a house and it makes a loading (similar to Xak). Once you leave the house, yo don't need to load again the town engine since it's being executed in foreground. The operation of Xak seems like some kind of overlay, since you play the town and there is only 1 place reserved for "enter a building" since you are only go to enter one building at time. One of them will be house, other will be a store, etc. Without overlay usage you will need separated functions (and so more memory) for house, store or whenever building with differente behaivour to others.

By AxelStone

Prophet (3108)

AxelStone's picture

19-09-2015, 19:09

Hi verybody, I'd like to recover the question of Sylvester.

Question: Do we know some tips to save memory? I have a curious example of 2 source codes where compiled code is bigger with the smallest source code. The 2 source codes are exactly equals except for the key capture mechanism:

	while(sc>=0 && sc<=15) {
		key=gtstck(JOY_CURSOR);
		if(key==3) {
			sc=sc+1;
			loadsc(sc);
		}
		if(key==7) {
			sc=sc-1;
			loadsc(sc);
		}
		if(key==1) {
			sc=sc-4;
			loadsc(sc);
		} 
		if(key==5) {
			sc=sc+4;
			loadsc(sc);
		}	 
	}
...

Source code 1, size=2031 bytes, compiled size=8280 bytes

	while(sc>=0 && sc<=15) {
		key=gtstck(JOY_CURSOR);
		sc=sc+(key==3)-(key==7)-4*(key==1)+4*(key==5)
		if(key!=0) {
			loadsc(sc);
		}
	}
...

Source code 2, size=1915 bytes, compiled size=8294 bytes

The second code is better, more compact, however with first code you save some bytes of memory and I supposse that is better to use it. May be?

Thanks!

By anonymous

incognito ergo sum (116)

anonymous's picture

19-09-2015, 20:09

I haven't done any actual tests with size or speed optimization yet, but have you tried using switch() instead of ifs?

This is what I have in one of my test programs:

Another thing to remember is that how compact the code looks in C doesn't always translate to how compact the final machine code will be. If you post the .MAC code for those of these versions then we can check how MSX-C translates that source.

By anonymous

incognito ergo sum (116)

anonymous's picture

19-09-2015, 20:20

By the way, you should be using else if:

AxelStone wrote:
	while(sc>=0 && sc<=15) {
		key=gtstck(JOY_CURSOR);
		if(key==3) {
			sc=sc+1;
			loadsc(sc);
		}
		if(key==7) {
			sc=sc-1;
			loadsc(sc);
		}
		if(key==1) {
			sc=sc-4;
			loadsc(sc);
		} 
		if(key==5) {
			sc=sc+4;
			loadsc(sc);
		}	 
	}
...

In this case all the if statements will execute. For example, if key == 3 then the program will still use some processing to test whether key is 7, 1 or 5. Better to use else if to save a little bit of time:

	while(sc>=0 && sc<=15) {
		key=gtstck(JOY_CURSOR);
		if(key==3) {
			sc=sc+1;
			loadsc(sc);
		} else if(key==7) {
			sc=sc-1;
			loadsc(sc);
		} else if(key==1) {
			sc=sc-4;
			loadsc(sc);
		} else if(key==5) {
			sc=sc+4;
			loadsc(sc);
		}	 
	}
...

By anonymous

incognito ergo sum (116)

anonymous's picture

19-09-2015, 20:44

AxelStone wrote:

The second code is better, more compact, however with first code you save some bytes of memory and I supposse that is better to use it. May be?

I did a quick test with almost the same code as you:

SIZE.C:

SIZE2.C:

In my case both programs compile to almost the same size. The second binary is only 3 bytes bigger.

The first code generates a very clean assembler source code with very simple operations (additions). The second code is much more convoluted and I can't tell at a glance how it works exactly.

Just for fun, I also tested with switch/case:

The switch/case version is much more compact:

It also generates MUCH easier and cleaner assembler code:

I would use the switch/case version without thinking twice about it.

By AxelStone

Prophet (3108)

AxelStone's picture

20-09-2015, 00:20

Yeah you are right, my if version is not good. Really is a simple test program, but I think it's good to have good habits even in tests, since they are used after in your codes. The compact notation is inheritance of Basic code, where the code itself occupies space and you have to use most compact notation possible in order to save memory (not like C, where more lines don't means bigger compiled, as we can see).

In any case it seems that switch / case option is a clear winner: clear source code and compact .com executable. I think your comparations will be very useful for anyone that reads this, since we have learned one thing: use switch / case whenever possible. By the moment, I'll use it in my project, I'd like to have something to show next monts Wink

Thanks!

Page 24/57
17 | 18 | 19 | 20 | 21 | 22 | 23 | | 25 | 26 | 27 | 28 | 29