Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

32-bit MSDOS (Announce)

posted by marcov, 03.07.2021, 14:30

> I decided to take a look at the assembler that
> was being generated by Free Pascal. I couldn't
> stop the assemble & link from happening, but
> I was able to keep the assembler which meant
> that I could simply redo the process.

Compile with -a -s. It will keep the assembler, and generate a script to assemble and link it (ppas.sh or ppas.bat)

> When I saw the generated assembler, ie
> fpc_write_text_shortstr etc, I had another
> thought. I don't know what the license is of
> the code that is currently being linked in to
> my world.exe,

LGPL+ static linking exception, roughly the same as gcc's libgcc. Nearly all linkable code has that license, only the compiler and the IDEs are GPL (again, much like gcc)

> I can produce my own executable
> consisting of nothing but public domain code,
> just like my C90-based executables.

C90 is a source standard. Calling binaries "C90" has no meaning.

> Unfortunately I don't know how to get my C
> code to selectively generate "pascal" calling
> convention, or whether Free Pascal's convention
> is even that. I tried __pascal and __Pascal.
> __stdcall does something different.

The calling convention is called "register", used by Delphi and Free Pascal, and is somewhat related to stdcall in philosophy. Probably the only C(actually C++) compilers that do it are Borland's BCB.

> Is this approach likely to work, or am I
> missing something?

Yes. Register calling convention support in the gcc compiler. Let the Pascal code call C.

> void fpc_initializeunits(void)
> {
> return;
> }

This is an identifier that calls what is equivalent to CTORs (table with initialization code of varying units). Without it, initialization code in units (including the system unit) wont work.

> int fpc_get_output(void)
> {
> return ((int)stdout);
> }

Ok. Is afaik a function for thread variable (TLS) reasons.

> void fpc_write_text_shortstr(int handle, char *str)
> {
> fputs(str, (FILE*)handle);
> return;
> }

This signature doesn't match. shortstrings are complicated beasts. Only replace the final call to the OS (in rtl/win/sysfile).

> void fpc_iocheck(void)
> {
> return;
> }

Would disables all I/O checking, and among others checking for the existence of a file relies on that, so wouldn't work.

If you want any measure of compatibility, replace _only_ the user32 DLL calls to msvcrt DLL calls, and let the msvcrt initializing be done using normal ways (dll_initialize), and don't go rearranging.

> void fpc_do_exit(int x)
> {
> exit(x);
> }

That's probably ok.

> Cannot export FPC_RESOURCESTRINGTABLES: symbol not found
> Cannot export FPC_RESSTRINITTABLES: symbol not found
> Cannot export FPC_THREADVARTABLES: symbol not found
> Cannot export FPC_WIDEINITTABLES: symbol not found
> Cannot export INITFINAL: symbol not found
> Cannot export PASCALMAIN: symbol not found
> worldpas.o(.text.n__main+0x5):worldpas.pas: undefined reference to
> `fpc_initializeunits'
> worldpas.o(.text.n__main+0xa):worldpas.pas: undefined reference to
> `fpc_get_output'
> worldpas.o(.text.n__main+0x1d):worldpas.pas: undefined reference to
> `fpc_write_text_shortstr'
> worldpas.o(.text.n__main+0x22):worldpas.pas: undefined reference to
> `fpc_iocheck'
> worldpas.o(.text.n__main+0x29):worldpas.pas: undefined reference to
> `fpc_writeln_end'
> worldpas.o(.text.n__main+0x2e):worldpas.pas: undefined reference to
> `fpc_iocheck'
> worldpas.o(.text.n__main+0x33):worldpas.pas: undefined reference to
> `fpc_do_exit'
> worldpas.o(.data.n_INITFINAL+0x8):worldpas.pas: undefined reference to
> `INIT$_$SYSTEM'
> worldpas.o(.data.n_INITFINAL+0x10):worldpas.pas: undefined reference to
> `INIT$_$FPINTRES'
> worldpas.o(.data.n_FPC_THREADVARTABLES+0x4):worldpas.pas: undefined
> reference to `THREADVARLIST_$SYSTEM$indirect'
> [worldpas.exe] Error 1

You didn't link FPC libraries or startup code. I wouldn't go this route, at least not for first steps, let Free Pascal generate the linking. You can tell it to link .o and .a's by doing {$L myobject.o} in the main program.

Use the earlier parameters to look at how it calls the linker, and then manipulate the source again till it works.

 

Complete thread:

Back to the forum
Board view  Mix view
22632 Postings in 2109 Threads, 402 registered users, 407 users online (1 registered, 406 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum