Want to fix some old 68k code, sources to which i have, but which unpossible to port to OS4 in acceptable timeframe due to lot of assembler and co, so want to fix just 68k binary to work properly on OS4.
And the issue which i noticed, that when i run binary, i have a DOS window saying:
Quote:
A process called a DOS function with a non longword-aligned Anchor.
Process: "game.exe" Function: "MatchFirst()"
You have recieve this message because the application has accesed as system function in a way that is contrary to normal operation system quidelines. This application may or may not actually perform as intended.
Now i search in the whole source, and fine MatchFirst usage just in one file, in 3 places, and it looks like this:
if ( (i = MatchFirst( temp, &myAnchor )) == 0 )
{
AddMovie( (const char*)&myAnchor.ap_Info.fib_FileName );
while ( (i = MatchNext( &myAnchor )) == 0 )
{
AddMovie( (const char*)&myAnchor.ap_Info.fib_FileName );
}
}
if ( i != ERROR_NO_MORE_ENTRIES )
printf_special( "InitMovies(): Match failed, error code %d...\n", i );
MatchEnd( &myAnchor );
free( temp );
}
So and this is the same in all 3 places.
What i tried to do so far is that:
/* Long word alignement (mainly used to get
* FIB or DISK_INFO as auto variables)
*/
#define D_S(type,name) char a_##name[sizeof(type)+3]; \
type *name = (type *)((LONG)(a_##name+3) & ~3);
if ( (i = MatchFirst( temp, myAnchor )) == 0 )
{
AddMovie( (const char*)&myAnchor->ap_Info.fib_FileName );
while ( (i = MatchNext( myAnchor )) == 0 )
{
AddMovie( (const char*)&myAnchor->ap_Info.fib_FileName );
}
}
if ( i != ERROR_NO_MORE_ENTRIES )
printf_special( "InitMovies(): Match failed, error code %d...\n", i );
MatchEnd( myAnchor );
free( temp );
}
See there i use macro, change . on -> in few places , and remove &.
But when i run binary, it bring me still the same warning window.
Maybe it can come from other DOS functions which inderectly run the MatchXXX functions ?
Remember that this is 68k code and should be keept as 68k one , and not os4 native, as whole os4 port is pain, and used SDK is NDK3.9, not OS4 SDK.
Any help/ideas welcome !
Maybe there any switches/flags which can be used like maybe some -D_OLD_ANCHOR_ or something of that sort ?
EDIT: interesting, when i comment out all MatchFirst() calls in the code, on the running game still bring me the same window! So seems MatchFirst still called somehow under the hood when anchors and stuff are used or something ?
Edited by kas1e on 2022/4/2 9:16:04 Edited by kas1e on 2022/4/2 9:17:10
Maybe it can come from other DOS functions which inderectly run the MatchXXX functions ?
The Match#?() functions were obsolete functions, only left for compatibility to ancient m68k software, which definitely shouldn't be used inside dos.library itself. Maybe it's not something directly in the sources you are using, but an old and broken (wrong data alignment) link library using those functions instead, or something in the m68k assembler parts with the same bugs?
IIRC some of the old C libraries (Lattice C, SAS C, etc.) used the dos.library Match#? functions as well.
Maybe it's not something directly in the sources you are using, but an old and broken (wrong data alignment) link library using those functions instead, or something in the m68k assembler parts with the same bugs?
Yes it very much looks like it in link librarys of the 68k compiler i use now : i use bebbo's cross-compiler (gcc 6.5x) so seems something going wrong there.
In meantime i will move everything to 68k VBCC instead : that one were proven to be most efficient and bug free C compiler for 68k in last years and better deal with bugs on VBCC which Frank will fix very fast (if there will be any).
GCC 6 has problems, I tried compiling NetSurf with it some time back and the resulting executable didn't work. If you can get it building with vbcc that will be better, alternatively an older GCC version is more likely to be stable. Which compiler was it built with originally?
It may be worth also switching to the 3.2 NDK, in case there's some weird bug in the headers.
And if i link it with -lmeees i happy crashes on libs:maths_something.library in petunia, so i had to compile with -lmsoft. Then no crash in those math libraries, but then i crashes after the first image shown.
So not sure what better way now .. Porting to OS4 native will be hard because of about 20 assembler files coming with.
I wonder if the same thing happens if you use AllocMem instead of using auto variables. AllocMem will handle the alignment for you. Just interesting to see if it would work.
If liberty means anything at all, it means the right to tell people what they do not want to hear. George Orwell.
@rjd324 I just recompile everything from scratch again via this bebbo's gcc, and this time i don't have MatchFirst errors. Weird random stuff ..
@Chris I have now make source to be build and for gcc and for vbcc (there almost wasn't any changes), and strangely that GCC version at least runs, go to the menu, etc, etc. But VBCC one, justs show first image and simple crashes..
I was in hope that it's about additional preprocessor options, but i just tried to build via GCC like this:
And still have those weird crashes exactly with VBCC version, while GCC version runs the same as before.
Sadly that is 68k, and i can't debug it normally on OS4, but maybe worth to try this VBCC version in WinUAE and at least make it works on WinUAE (if it didn't) and then made it works on OS4.
But that anyway strange .. the same C code , compiled the same, and reacts different when build with different compilers. But yeah.. includes/link-libs/inlines/etc all different..
Yeah, I built some SAS/C code with vbcc and it uncovered bugs that had been hidden. Some code should have never worked, just luck that it did. There's almost certainly a bug in there, which if you find will fix it for vbcc.
From DOS 50.77+, you MUST ABSOLUTELY allocate a struct AnchorPath
with AllocDosObject() to be able to transition to the new extended
structure layout, failing to use AllocDosObject() will cause DOS
to think you are using the old V36 style structure even though you
may not be, this will cause completely unpredictable and possibly
fatal results as some structure fields have moved entirely.
@All So how this code should looks like if it will be rewritten "good" and bein 68k/os4 compatible (with the same code, or with ifdefs, not that matter):
@rjd324 I mean some skilled programmer will rewrote it if one will have interest and i can just copy+paste it, without recreating a wheel and loosing time on things i didn't know good enough.
Is not an acceptable way to allocate space on the stack for an Anchor or FIB or anything that requires longword alignment, regardless of whether it's 68K or anything else, you are still going to trash memory, (except on OS4 where you get the warning and it does a workaround to prevent memory trashing.)
The reason here is that the Anchor has a FileInfoBlock (FIB) embedded inside it.
When old or new DOS calls an old style packet FileSystem with the fallback (or in the V40 68K case, the only) Examine() call, it has to pass the FIB as a BCPL pointer; It makes the BCPL pointer (BPTR) with the macros in dos.h MKBADDR() and converts it back with BADDR() to a CPTR (c-pointer) again.
The problem occurs due to the conversion of a non-longword C-address to a BPTR and back again to a CPTR.
As you can see, the middle one (non longword aligned) results in the filesystem writing the FIB data 2 bytes before the storage area, thereby corrupting whatever is behind the storage area in memory, or on the stack in this case.
The D_S macro will work well enough to prevent this memory trashing problem.
As far as these MatchXXX functions go, they are still supported in OS4 and have been recently updated with macros in dos/anchorpath.h to also handle 64 bit file sizes and all new extended features like multi-assignments and long names.
So when i compile it with newlib for os4 directly all fine. But when i compile it for os3 (via their gcc 6.5) then i have heavy crashes.
Also if i compile that with clib2 also for os4, it again bring DOS warning windowses about "bad usage of MatchFirst", and bring bugs and errors.
Seems it still bad enough anyway.. But i need that kind of code to be working on OS4 and OS3, so i can run both versions of different HW to check for bugs and compare how it all works, etc.
Firstly, you cannot use the new OS4 AnchorPath definition if you expect this to work on OS3 (68K), Incase you are using the OS4 includes, you will need to declare the USE_OLD_ANCHORPATH definition BEFORE including the OS4 dos/anchorpath.h include file, or anthing that may inadvertantly include it, (if that is what you are using) to make absolutely sure you are using the old 68K definition that OS3 DOS expects internally, otherwise you will crash your brains out.
So do this before including anything, (it won''t hurt for OS3); #define USE_OLD_ANCHORPATH #include dos/anchorpath.h
The line; "struct AnchorPath *myAnchor __attribute__ ((aligned));" is pointless, the pointer alignment is unimportant, it's the memory it points to that must be aligned to a 4 byte address, so lose the "__attribute__ ((aligned));"
OS4 is backwardly compatible to OS3 methods, OS3 is NOT forwardly compatible. So to get the backward compatibility, you need to use "backward" methods everywhere.
The OS4 AnchorPath call in AllocDosObject() is not available on OS3 so it can't be called, otherwise it will simply assume you are using the new structure definition, because you are obviously running on OS4, so it may not work as intended and may do OS4 initialisations on the OS4 structure it allocates that won't end up in the right places for OS3 structures.
So just use this OS3 method for both systems, and it will work; myAnchor = AllocMem( sizeof(struct AnchorPath),MEMF_ANY|MEMF_CLEAR);
That way, you won't get OS4 confused into thinking you have the new OS4 structure definition which automatically happens when you use OS4's AllocDosObject().
AFAIK, the malloc() call you are using does not appear to guarantee longword alignment either. I never used it, so i'm not sure what the various clib releases do, so to be safe, i'd use the exec AllocMem() and FreeMem() functions instead to guarantee longword alignment on both systems, those work and do guarantee longword alignment.
Also, for your sanity, add some error checking and test your return codes, it is possible for a memory allocation to fail you know.