MSX FUSION-C, Talking about bugs, errors, mistakes

Страница 6/26
1 | 2 | 3 | 4 | 5 | | 7 | 8 | 9 | 10 | 11

By ducasp

Paladin (712)

Аватар пользователя ducasp

25-03-2019, 15:07

Hi, about LSeek, the documentation and header could be updated telling that the second parameter is an long pointer instead of an unsigned int containing the address... Both are the exact same thing size wise, but if you do:

long lPosition = 10;

LSeek(myFileHandle,&lPosition,SEEK_CUR);

Compiler will error telling that a long pointer is not an unsigned int (and they are not, just they are the same size). As the function really uses a pointer to a long and then copy the four bytes int DE/HL, the header and documentation should be updated about it. Otherwise, you need to type cast, which is not really nice:

long lPosition = 10;

LSeek(myFileHandle,(unsigned int)&lPosition,SEEK_CUR);

By ericb59

Paragon (1126)

Аватар пользователя ericb59

25-03-2019, 18:54

@ducasp : Thank you. I will fix that in the header and manual ...
I suppose the LTELL function must be adapted too ?

By ducasp

Paladin (712)

Аватар пользователя ducasp

26-03-2019, 15:11

Eric, it seems so by looking at the code, but to be honest I haven't tested lTell after finding about lSeek and I'm tending to not use the functions declared in io.h...

For instance, lSeek, it uses DOS2 CALL 0x4A that will try to seek the position, and return the final position (that could not be the required one, i.e.: file end)... But lSeek, even though it uses a pointer to memory area, won't copy the final position... So, if you want to check it, or, for example, want to just get file size (SEEK SET relative to position 0 will return file size), instead of a simple call to lseek you neet to do lSeek and lTell, plus lots of stacking and un-stacking that will be re-done to get an information that was there in first place...

Another one is file Read... You generally would expect it to return the number of bytes that were read from file (i.e.: you want to read 200 bytes, but it could read 100 and then end of file), this is the usual for abstraction of File Reading operation and also what the DOS call does (return the number of bytes actually read from file)... But it doesn't.

I mostly understand that those were choices done to keep a single function for DOS1 or DOS2... But I find those quite limiting and end-up using direct DOS2 calls in my current project due to that... And trying to not look harsh or ungrateful, I don't know about the book, but the user guide is quite poor documenting those IO functions, parameters and behaviors/returns (I don't have the book as there is no electronic format, if there was a kindle or epub version I would gladly buy it to emphasize my support to it). For instance, if Read/Write had the regular behavior, this could be fine, but since it doesn't return the number of bytes read/written and documentation don't even tell what the function returns, most people would just assume it is like other standard write functions in C, and end-up ditching it because they do not understand why it is not working (as I believe most people looking into using Fusion-C do not want/have the knowledge/will to dig into ASM files).

Again, please don't take this badly, I really appreciate all the hard work poured into the fusion-c library and I'm doing all I can to push people that ask about programming for MSX to use it, as I really think this is a pretty good solution that might shape a future of more apps/games being developed just because it is way easier than ASM while delivering, in most cases, more performance than one might need and much better performance than any basic/turbo basic/x-basic, etc. I understand that this is a constant work in progress, so, please don't take those words personally, just thoughts that perhaps can be considered to improve fusion-c as it matures and evolve over time.

By ericb59

Paragon (1126)

Аватар пользователя ericb59

26-03-2019, 21:01

The book doesn't give more information about functions than the manual provided with Fusion-C. The book talk about other aspects, but all informations about Fusion-c 's functions are the same.

I know there are many functions that are poorly explained. As you know Fusion-C is based on multiple existing sources. I did not have all the information about all the functions and I did the best with what I had. I could have waited before publishing, but I left too many projects suspended because they were not finished at 100%, and now I am not able to resume them. I did not want the same thing happen to Fusion-c, that's why I published it, even in an imperfect state.

I 'm not 100% sure of all the functions I included in io.h, that's why I also add other file support functions implemented in fusion-c.h : FCB_open, FCB_READ etc ...

I did not find a simple way to retrieve the full size of a file. But the function fcb_read returns the number of bytes read, until the end of a file.

By DamnedAngel

Champion (286)

Аватар пользователя DamnedAngel

29-03-2019, 14:57

Hi all,

I think I found a bug in crt0msx_msxdos.s/crt0msx_msxdos_advanced.s.

Both sources have

_heap_top::
	.dw 0

gsinit: .area   _GSINIT

That, in principle, instructs the sdasz80 to reserve two bytes of memory in the _DATA area, points the symbol _heap_top to this position and creates the _GSINIT area afterwards and points the symbol gsinit (which is called in the very beginning of the execution of the MSXDOS program) to the start of it, 2 bytes after _heap_top.

Except (this will get confusing, sorry)...

When you include another module/REL in your SDCC command AFTER crt0msx_msxdos.rel/crt0msx_msxdos_advanced.rel, AND this new module has a _DATA section with contents. In this case, such contents will be placed AFTER _heap_top. But since gsinit is declared BEFORE the ".area _GSINIT" directive, it is anchored two bytes after _heap_top, and will end up pointing to the contents of the _DATA section of the module/ref placed after crt0msx_msxdos.rel/crt0msx_msxdos_advanced.rel, independently of the _GSINIT area.

This will cause the very first instruction of the MSXDOS program (in 0x0100, which is "call gsinit") to point PC to the middle of the _DATA area, with unpredictable results, and likely a crash.

If I was unclear to the point of incomprehensibility (which is likely LOL!), please let me know.

There is a workaround which is keeping your crt0msx_msxdos.rel/crt0msx_msxdos_advanced.rel as the last one in the command line. In my case, however, I edited crt0msx_msxdos.s this way:

_heap_top::
	.dw 0

	.area   _GSINIT
gsinit: 

This ensures that gsinit will be anchored to the _GSINIT area, regardless of the rel placement order. It is working, but I don't know if

  1. This somehow has a negative/undesired effect;
  2. Not adding crt0msx_msxdos.rel/crt0msx_msxdos_advanced.rel as the last rel has a negative/undesired effect.

Could any of you clarify if my solution is/isn't the best approach to solve this case (and if it is, register my suggestion as a possible update for next versions of Fusion-C)?

Thanks in advance,

By ericb59

Paragon (1126)

Аватар пользователя ericb59

29-03-2019, 15:05

Perhaps Konamiman could answer you, as he is the author of the crt0 used in Fusion-c

https://github.com/Konamiman/MSX/blob/master/SRC/SDCC/crt0-m...

By DamnedAngel

Champion (286)

Аватар пользователя DamnedAngel

29-03-2019, 21:46

Konamiman contacted. He replied he will take a look as soon as he can, since he is finishing other projects.
Anyway, my problem is solved - at least temporarily.
Thanks a lot!

By PingPong

Enlighted (4156)

Аватар пользователя PingPong

31-03-2019, 23:50

looking at circlefilled.c suggest me that the inner loop doing a lot of PSET calls could be optimized by using a LINE call (via VDP). Am I wrong ?
circlefilled.c

for ( i = x0 - x; i <= x0 + x; i++)
        {
            Pset(i, y0 + y,color,OP);
            Pset(i, y0 - y,color,OP);
        }
        for ( i = x0 - y; i <= x0 + y; i++)
        {
            Pset(i, y0 + x,color,OP);
            Pset(i, y0 - x,color,OP);
        }

suggested modification:

VDPLINE (x0 - x,y0 + y, x0+x, y0+y, COLOR, OP)
VDPLINE (x0 - x,y0 - y, x0+x, y0-y, COLOR, OP)

VDPLINE (x0 - y,y0 + x,x0 + y,y0 + x, COLOR, OP)
VDPLINE (x0 - y,y0 - x,x0 + y,y0 - x, COLOR, OP)

* VDPLINE does not really exists. only meaning to call the api that draw a line, using VDP
or something like this?

By ericb59

Paragon (1126)

Аватар пользователя ericb59

01-04-2019, 09:00

@DamnedAngel : Please let me know what Konamiman will answer you

@ PingPong : You can try with Line function which exists in the Library.
But the ASM drawing line function is quite slow.
There is a line function in MSX2 subrom, is there another possibility ?

By PingPong

Enlighted (4156)

Аватар пользователя PingPong

01-04-2019, 12:33

i think the best is to talk directly with VDP to draw a line.

Страница 6/26
1 | 2 | 3 | 4 | 5 | | 7 | 8 | 9 | 10 | 11