Relearning MSX

Relearning MSX

by Unregistered user on 25-11-2015, 21:23
Topic: Development
Languages:

Since December 2014 Javi Lavandeira has been writing Relearning MSX, a series of tutorials about software development on the MSX.

The series starts with several posts explaining the MSX standard and a few other basic concepts for new MSX users. No previous experience is required or even assumed.

There are 35 tutorials published so far, most of them about programming in MSX-C using a real MSX computer or an emulator. Javi publishes new chapters at a rate of about 6-8 per month. New posts will be announced in the msx.org developer forums. Plans for future posts include learning how to work with graphics and sound in order to develop games and also Z80 assembler programming once the MSX-C part is covered.

Relearning MSX accepts donations via Patreon. All tutorials are free, but supporters can view them one week before they become public.

Relevant link: Relearning MSX

Comments (17)

By konamiman

Paragon (1156)

konamiman's picture

26-11-2015, 10:28

That's great, I strongly believe that C is a fine language for developing applications for MSX in the many cases where you don't need the top processing speed that direct assembler provides (and it is very easy to mix assembler and C anyway). I do cross development using sdcc, but developing directly in the MSX is fun too and these articles are comprehensive and thorough. Good work!

By anonymous

incognito ergo sum (116)

anonymous's picture

26-11-2015, 14:22

konamiman wrote:

That's great, I strongly believe that C is a fine language for developing applications for MSX in the many cases where you don't need the top processing speed that direct assembler provides (and it is very easy to mix assembler and C anyway). I do cross development using sdcc, but developing directly in the MSX is fun too and these articles are comprehensive and thorough. Good work!

Thanks!

By the way, what's your simplest tool? I'm wondering what the size of the binary and the difference in speed would be if one of your tools was ported to MSX-C. I know that function calls would execute much faster (MSX-C passes arguments on the CPU registers instead of the stack), but I'm curious about how SDCC's optimizations compare to MSX-C's.

By konamiman

Paragon (1156)

konamiman's picture

26-11-2015, 16:00

The simplest tool that I have developed in C is probably geturl, it is small and it doesn't have any dependencies on UNAPI.

By Marq

Champion (387)

Marq's picture

26-11-2015, 17:51

Based on my tiny loop test, SDCC blew MSX-C out of the water at least in that particular case.

By anonymous

incognito ergo sum (116)

anonymous's picture

26-11-2015, 17:57

Marq wrote:

Based on my tiny loop test, SDCC blew MSX-C out of the water at least in that particular case.

Can you post the code in order to take a look at it?

By Marq

Champion (387)

Marq's picture

26-11-2015, 18:35

By anonymous

incognito ergo sum (116)

anonymous's picture

27-11-2015, 03:53

Marq wrote:

See here: http://www.kameli.net/marq/?p=2697

I did a quick test with MSX-C and the results match yours. I wrote your Pascal benchmark like this:

BENCH.C

#include <stdio.h>

char    main(argc, argv)
int     argc;
char    *argv[];
{
        int     i, j, s;

        s = 0;

        for (i = 1; 1 <= 10000; i++) 
                for (j = 1; j <= 100; j++)
                        s++;

        printf("%u", s);
}

This program ran in 41.95 seconds in Z80 mode and 6.32 seconds in R800 DRAM mode.

However, the inner loop doesn't need to use a 16-bit variable, so we can declare it as char:

BENCH2.C

#include <stdio.h>

char    main(argc, argv)
int     argc;
char    *argv[];
{
        int     i, s;
        char    j;

        s = 0;

        for (i = 1; 1 <= 10000; i++) 
                for (j = 1; j <= 100; j++)
                        s++;

        printf("%u", s);
}

This version runs in 15.35 seconds in Z80 mode and 2.63 seconds in R800 DRAM mode.

See this in action in this video:

https://www.youtube.com/watch?v=bEaFk6WYZRs

In any case, I still believe that under normal conditions MSX-C will be faster (or at least comparable) to SDCC because of the way it handles function calls: MSX-C passes as many parameters as possible via CPU registers, while SDCC always uses the stack. C programs are mostly calls to functions, so I think this is relevant.

Could you please prepare another benchmark that uses functions so we can compare?

By Marq

Champion (387)

Marq's picture

27-11-2015, 18:01

My MSX-C setup might be busted, but writing a little snippet like that shouldn't be a big deal. edit: as a matter of fact, after reinstalling this machine I don't currently have even my SDCC toolchain at hand :/

By anonymous

incognito ergo sum (116)

anonymous's picture

28-11-2015, 03:43

Marq wrote:

My MSX-C setup might be busted, but writing a little snippet like that shouldn't be a big deal. edit: as a matter of fact, after reinstalling this machine I don't currently have even my SDCC toolchain at hand :/

I've prepared a simple benchmark to test function calls. This is the code:

#include <stdio.h>

#define void    char;

typedef unsigned u_int;

u_int   sum(a, b)
u_int   a;
u_int   b;
{
        return ((a << 1) + (b >> 1));
}

u_int   shift3(a)
u_int   a;
{
        return (a << 3);
}

void    count(add)
u_int   *add;
{
        (*add)++;
}

char    main(argc, argv)
int     argc;
char    *argv[];
{
        u_int   i, val, counter, result;

        /* Init */
        val = 2000;
        counter = 0;
        result = 0;

        /* Loop */
        for (i = 1000; i < 60000; i++) {
                count(&counter);
                val = shift3(val);
                result = sum(i, val);
        }

        printf("Counter: %u\n", counter);
        printf("Result : %u\n", result);
}

Compiled with openMSX this code runs in 2,8 seconds in R800 DRAM mode and 15,90 seconds in Z80 mode. Can you please try the same with SDCC?

Here's the video showing the compilation and results under openMSX:

https://www.youtube.com/watch?v=nbA08FDMPFw

By Marq

Champion (387)

Marq's picture

28-11-2015, 08:54

Takes around 22 seconds, so indeed MSX-C has some advantage if there's a lot of function calls. By the way, is there a reason to use those old K&R style parameters as opposed to the more common ANSI ones? Also wondering about that #define void char.

By anonymous

incognito ergo sum (116)

anonymous's picture

28-11-2015, 09:04

Marq wrote:

Takes around 22 seconds, so indeed MSX-C has some advantage if there's a lot of function calls.

Interesting. And probably the difference we saw in the first benchmark we did was the result of SDCC's optimization. It probably noticed that the loop counter could be an 8-bit valus instead of 16. We could tell if we look at the binary.

Marq wrote:

By the way, is there a reason to use those old K&R style parameters as opposed to the more common ANSI ones?

MSX-C was released before ANSI C and it only understands K&R syntax.

Marq wrote:

Also wondering about that #define void char.

It's one of my pet peeves. K&R C doesn't have the void type.I think void is nice because it helps you understand that a function doesn't return anything. Since the type doesn't exist in this version of C I just typedef it to be equivalent to char. It doesn't serve any purpose other than making the code look a bit nicer.

By ARTRAG

Enlighted (6567)

ARTRAG's picture

28-11-2015, 10:06

If you want to compare performance, MSX-C is inferior to to HiTech C v7.8.
In R800 DRAM mode your bench runs in 2,18 secs (131 Jiffy ticks at 60Hz)
In z80 mode it runs in 13,96 secs (838 ticks at 60Hz)

Files are here

Results are here

Note: I changed the function definitions to standard C

#include 

#define void    char;

typedef unsigned u_int;

u_int   sum(u_int a, u_int b)
{
        return ((a << 1) + (b >> 1));
}

u_int   shift3(u_int a)
{
        return (a << 3);
}

void    count(u_int *add)
{
        (*add)++;
}

u_int 	jiffy @ 0xFC9E;

char    main(int argc, char    *argv[])
{
        u_int   i, val, counter, result;
		
	jiffy = 0;

        /* Init */
        val = 2000;
        counter = 0;
        result = 0;

        /* Loop */
        for (i = 1000; i < 60000; i++) {
                count(&counter);
                val = shift3(val);
                result = sum(i, val);
        }

        printf("Jiffy : %u\n", jiffy);
	printf("Counter: %u\n", counter);
        printf("Result : %u\n", result);
		
}

By anonymous

incognito ergo sum (116)

anonymous's picture

28-11-2015, 10:10

ARTRAG wrote:

If you want to compare performance, MSX-C is inferior to to HiTech C v7.8.
In R800 DRAM mode your bench runs in 2,18 secs (131 Jiffy ticks at 60Hz)
In z80 mode it runs in 13,96 secs (838 ticks at 60Hz)

That's amazing! Thanks for sending the files. I'll see what differences there are between the two assembler files.

Did you use the MSX-DOS version of HiTech C, or the cross-compiler?

By ARTRAG

Enlighted (6567)

ARTRAG's picture

28-11-2015, 14:15

Cross compiler

By PingPong

Prophet (3793)

PingPong's picture

09-12-2015, 21:32

Marq wrote:

Takes around 22 seconds, so indeed MSX-C has some advantage if there's a lot of function calls. By the way, is there a reason to use those old K&R style parameters as opposed to the more common ANSI ones? Also wondering about that #define void char.

unfortunately all functions have code at least and here sdcc is faster than msx-c. a lot
i think sdcc does a better job in code generation. can we compare the assembly code generated for the "body" of a function?
( a function with a decent cyclomatic complexity not a simple for cycle on char variable)

By anonymous

incognito ergo sum (116)

anonymous's picture

10-12-2015, 08:26

PingPong wrote:

unfortunately all functions have code at least and here sdcc is faster than msx-c. a lot
i think sdcc does a better job in code generation. can we compare the assembly code generated for the "body" of a function?
( a function with a decent cyclomatic complexity not a simple for cycle on char variable)

You raise a good point. Can you provide a test function and compile it under SDCC? I'll do the same under MSX-C and then we can compare the generated assembly code.

By iamweasel2

Paladin (685)

iamweasel2's picture

25-11-2018, 19:15

This was a great series of articles. Too bad the author does not write new articles anymore...