[MSX-C] Q&A official thread

Pagina 51/57
44 | 45 | 46 | 47 | 48 | 49 | 50 | | 52 | 53 | 54 | 55 | 56

Van DarkSchneider

Paladin (942)

afbeelding van DarkSchneider

06-11-2016, 13:35

For use with MSX the port of the MSX-C libraries is mandatory IMO.

Van ARTRAG

Enlighted (6704)

afbeelding van ARTRAG

06-11-2016, 14:45

Well I did mine and hi-tech c is has ansi-c compatibility

Van DarkSchneider

Paladin (942)

afbeelding van DarkSchneider

26-12-2016, 11:24

I have a problem with recursive mode on MSX-C. Look here for table 12. Just before it talks about how to set recursive mode. I tried both but it fails. If i put "recursive" keyword prefix it says "improper function mode", if using the "#pragma recursive" (the pragma 'rec' is incorrect) it says "bad pragma statement".
It's strange as it includes a recursive function:
recursive TINY _uspr(str, n, radix)
This in the declaration (the H file).

If I use the recursive on implementation it has no effect at all. This function:

recursive VOID test(value)
BYTE value;
{
	value++;
}

Is compiled to:

test@:
	inc	a
	ret

It is using the parameter from register instead the stack.
Using the pragma in the code for passing parameters also has no effect. This:

	value = (BYTE)33;
#pragma recursive
	test(value);

Is compiled to:

	ld	a,33
	ld	(?50),a
	ld	a,(?50)
	call	test@

Any idea how to use the stack for passing parameters in MSX-C?

Van hit9918

Prophet (2911)

afbeelding van hit9918

26-12-2016, 20:25

well but there is nothing recursive.
recursive is when a function calls itself. or A calls B and then B calls A, things like that.
when a function got entered more than one time.

I dont know the compiler, I wonder, this here

	ld	(?50),a
	ld	a,(?50)

makes me guess that it makes RAM variables to hold things that normaly would be on the stack.
and in the not-recursive mode doesnt save them like registers need to be saved.

but, this quoted code is not in function test but in the caller function.
if you put the recursive keyword on that function, maybe the code changes.

this is simlar to the topic when I spoke of "RAM registers" for asm coders.
16bit RAM variables called r0...r7 .
and exactly like cpu registers they need to be pushed on the stack to save them.
then they can be used in every function.

function:       ld hl,(r0)
                push hl
                ld hl,(r1)
                push hl
                ... now one can use r0 r1 ...
                pop hl
                ld (r1),hl
                pop hl
                ld (r0),hl
                ret

in a non recursive mode the compiler seems to make a shortcut
that it doesnt use a generic RAM variable with saving
but a RAM variable made special for that function and doesnt save it
then crash upon recursive usage.

I don't know, maybe a whole complicated game can be written without needing recursion.

I heard that in the ancient days, before the stack was invented Big smile return addresses and local variables were such function-special variables. like

functionret:    dw 0
function:       .... do something ...
                ld hl,(functionret)
                jp (hl)

Van DarkSchneider

Paladin (942)

afbeelding van DarkSchneider

27-12-2016, 09:00

Well what I wanted really was the passing parameters on the stack. MSX-C calls it recursive mode, as it is an easy way to handle it in a global way. But it doesn't work even its supposed official method.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

27-12-2016, 12:58

Hi DarkSchneider,

I had a look at your code: the variable is local, and is not used or returned. So basically your function has no effect in C (it's just increasing the local parameter which is stored in register "a"), that might explain the generated code. Also check the code of the calling function: it might be that registers are "pushed" and "popped" to be preserved (enabling recursivity by saving registers on the stack, not by putting parameters on the stack - I just realize that's what hit9918 explained !).

Try with a function like:

BYTE test(value)
BYTE value;
{
	return value++;
}

and check the assembly generated this way, it should make more sense.

Note: You can also do something like that using pointers:

VOID test(value_pointer)
BYTE *value_pointer;
{
	(*value_pointer)++;
}

Or is there any specific reason you want the parameters to be on the stack ? I've checked other C compilers, they are all passing parameters through registers for efficiency when it's possible.

Van DarkSchneider

Paladin (942)

afbeelding van DarkSchneider

27-12-2016, 14:36

I wanted them for indirect calling, it was for inter-segment DOS2 functions. I've changed it as mentioned in its thread so no need really. But if for any reason it would be needed, it is good to know.
The results are, for the first:

test@:
	inc	a
	dec	a
	ret

main@:
	ld	a,3
	ld	(?70),a
	ld	a,(?70)
	call	test@

inc a, dec a? Question
For the second:

test@:
	inc	(hl)
	ret

main@:
	ld	a,3
	ld	(?70),a
	ld	hl,?70
	call	test@

I think the feature was in the "pending tasks" list.

Van Grauw

Ascended (10317)

afbeelding van Grauw

27-12-2016, 15:09

DarkSchneider wrote:

inc a, dec a? Question

That’s because you use post-increment. It returns the value prior to the increment.

Try return ++value;.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

27-12-2016, 16:44

Grauw wrote:
DarkSchneider wrote:

inc a, dec a? Question

That’s because you use post-increment. It returns the value prior to the increment.

Try return ++value;.

My bad, the common C-beginner mistake Smile

DarkSchneider wrote:

The results are, for the first:

test@:
	inc	a
	dec	a
	ret

main@:
	ld	a,3
	ld	(?70),a
	ld	a,(?70)
	call	test@

There's no push/pop around the call in the main function because there's no need to preserve anything in this case, but the code looks good. Same for the 2nd example.

Anyway, I'd be very surprised the C compiler does not handle recursive calls or is buggy, it would make it completely useless. You just need to know how parameters are passed depending on the parameters count and sizes (best way to be sure is to first write a dummy C function just like you did).

Also, some C compilers are expecting some registers not to be modified by the called function. Hitech C and IAR C do not like when IX or IY are not preserved, but it might be different on other compilers.

Van DarkSchneider

Paladin (942)

afbeelding van DarkSchneider

02-01-2017, 10:06

Ups, what happened to the MSX Info Pages?
http://msx.hansotten.com/index.php?page=msx-c-manual

Pagina 51/57
44 | 45 | 46 | 47 | 48 | 49 | 50 | | 52 | 53 | 54 | 55 | 56