In other words, in K&R C (1978) the void keyword didn't exist.
The second edition of K&R (published in 1988) does include the void type. That's probably why LSI/ASCII decided to include the VOID type as a typedef of char, as a convenience for the programmer.
Ok, here's how you implement assembler routines in MSX-C.
There are three cases:
a) Assembler routines that don't require parameters
b) Assembler routines that require a fixed number of parameters
c) Assembler routines that require a variable number of parameters
Case a): Routines that don't require parameters
This is very, very simple. Just implement the assembler routine and label it public. The following example (HELLO.MAC) prints a text string in the screen:
This routine can be called from C just declaring it at the beginning of the C program:
VOID hello();
Case b): Routines that require a fixed number of parameters
All basic types in MSX-C are either 8 bits (char and everything that's a redefinition of char, such as VOID, TINY, STATUS, etc) or 16 bits (everything else: ints, unsigned, pointers, etc).
The way parameter passing works is very simple:
- If the first parameter is 8 bits, it goes into the A register. Else, it goes into HL.
- If the second parameter is 8 bits, it goes into the E register. Else, it goes into DE.
- If the third parameter is 8 bits, it goes into the C register. Else, it goes into BC.
- If there are more parameters, they're passed in the stack: 1 byte for 8-bit parameters and 2 bytes (low byte first) for 16-bit values
The following example takes a pointer to a string as a parameter and prints the string on the screen (remember that we're printing using the MSX-DOS STROUT function, so the string must end in $):
Case c): Routines that accept a variable number of parameters
All parameters are passed in the stack. Register HL contains the number of parameters. All parameters take 2 bytes in the stack, so if you pass an 8-bit value then the high order byte is undefined (that's why we have to cast to int when printing char values using printf()).
Returning values to MSX-C
Again, very simple. If the function returns an 8-bit value, then it goes into register A. If it returns a 16-bit value, it goes into register HL.
This example takes two chars as input, adds them, and returns them also as a char (so there could be overflow). The whole body of the function is just a single asm instruction:
Using them from C
This program uses these three assembler functions from C:
And I prepared a small batch script that does all the assembling, compiling, linking and cleanup required. It should be very easy to understand:
During the following days I'll write a more detailed explanation on Relearning MSX.
And I forgot to add the output of the test program. Here it is:
And by the way, you can also do it the other way around: call MSX-C functions from assembler programs. Let's say that you're coding an application in assembler and want to use MSX-C's printf() function. You can just put the parameters for printf() in the stack, declare PRINTF@ as an external symbol, and call it directly.
This is the example in the MSX-C manual:
extrn printf@ example: ld hl,msg ; push address of string push hl ld hl,1 ; load # of parameters call printf@ ; formatted output routine pop hl ; pop the parameter off the stack ret msg: defb ‘Hello world’,10,0
If you do this then you just need to link your program together with the C library and runtime:
L80 example,clib/s,crun/s,cend,example/n/y/e:exampl
(the L80 linker support symbol names up to 6 characters long, that's why we're telling it to start execution at "exampl" instead of "example")
Unfortunately there is no support for "inline asm", afaik.
btw: ag0ny I really like your style explaining and writing technical documentation
Unfortunately there is no support for "inline asm", afaik.
You're right. That's understandable, since the compiler and assembler are separate tools.
btw: ag0ny I really like your style explaining and writing technical documentation
Thanks.
Yeah it is all very well explained. You are doing a really good work for MSX development comunity with that info, probably a new wave of MSX-C programmers arrive. Thanks.
About integration of Asm it is really poweful I am very impressed with MSX-C capabilities. I hace started to port code from an abandoned Basic game (memory issues) and I hope to finish it
Javi: thanks, I guess I should read up more on K&R C
Javi: thanks, I guess I should read up more on K&R C
Actually, I didn't know either. Your question made sense, so I looked it up. I have a 1978 edition of The C Programming Language, but I hadn't realized that there was no void type.
So, I learnt something new yesterday too. :-)
And just for fun, this is the glossary from the original K&R's The C Programming Language. There's no void. I hadn't even noticed. :-)