Recent

Author Topic: DOS linked .obj file calling conventions  (Read 17443 times)

deathshadow

  • New member
  • *
  • Posts: 9
    • CutCodeDown - Minimalist Semantic Markup
DOS linked .obj file calling conventions
« on: July 22, 2016, 01:09:25 am »
In 16 bit operation for DOS, does FPC fallow TP's 6 byte stack offset and order for passing data? The documentation for DOS operation seems a bit "shallow" as yet...

Also, would the memory models where you're limited to 64k of code (TINY, SMALL, COMPACT) use a 4 byte offset? Since everything is near, are linked ASM still far calls?

I'd like to know for sure before I go blindly trying to link some code I've assembled with NASM given how... unpredictable the results can be. (though I guess I could always compile, link, then disassemble to see what it's doing)

The current entry/exit I'm using for TP7 is:
Code: [Select]
push  bp
mov   bp, sp
; passed parameters RTL starting at [BP+6]
pop  bp
retf #
; replace # above with total passed parameter size in bytes, rounded up to nearest 16 bits.

I'd like to move a current project to FPC 3 just to see how it stacks up to TP7, but there's a LOT of linked in ASM in there... I guess temporarily I could switch that stuff back to inline assembler, but that just increases the workload and I kind-of prefer keeping that stuff separate.

I would think using SMALL (which seems best suited to what I'm working on, can't QUITE squeeze it in under 64k) that would be BP+4 (copy of BP I just pushed, near return address) and a regular "ret", right?

Just looking for confirmation on that before I go whole hog.

Curious to see with the RTL out of the way (since I use none of it) how it REALLY compares. Hell, I don't even use write()... you'd almost thing I was working in the undocumented 160x100 16 color CGA mode or something...
« Last Edit: July 22, 2016, 01:13:12 am by deathshadow »
From time to time the accessibility of websites must be refreshed with the blood of owners and designers. It is its natural manure.

deathshadow

  • New member
  • *
  • Posts: 9
    • CutCodeDown - Minimalist Semantic Markup
Re: DOS linked .obj file calling conventions
« Reply #1 on: July 22, 2016, 01:52:03 am »
Another question, any way to stop it from linking in the entire joe-blasted system RTL? I really don't need or want it and it's not like I'm saying "unit system".

Seems a bit herpaderp the compiler doesn't even filter out all the garbage from the RTL you aren't actually calling... isn't that kind of a basic thing even TP3 managed?
From time to time the accessibility of websites must be refreshed with the blood of owners and designers. It is its natural manure.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: DOS linked .obj file calling conventions
« Reply #2 on: July 22, 2016, 06:22:06 am »
Another question, any way to stop it from linking in the entire joe-blasted system RTL? I really don't need or want it and it's not like I'm saying "unit system".

Seems a bit herpaderp the compiler doesn't even filter out all the garbage from the RTL you aren't actually calling... isn't that kind of a basic thing even TP3 managed?
Create your own, but keep in mind you will lose a lot of features that's RTL managed. There's really no documentation or guide to do this, you can start from rtl/dos folder. I forgot which asm is used for startup, but you should be able to have a very short asm startup file + unit system containing only HRESULT type identifier (of whatever type you want). I did this when I want to make a bootloader for my OS, which fits the limit of 512 bytes stage1 bootloader (was around 300-400 bytes). It's overkill, though. Better use it to create stage2 bootloader as stage1 is actually already very simple in asm (since its main job is to load stage2).

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: DOS linked .obj file calling conventions
« Reply #3 on: July 22, 2016, 12:26:18 pm »
I forgot which asm is used for startup
Nasm... and  Open Watcom linker and tools. See the wiki: http://wiki.lazarus.freepascal.org/DOS.
Specialize a type, not a var.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: DOS linked .obj file calling conventions
« Reply #4 on: July 22, 2016, 01:17:07 pm »
Why don't you simply look at the code generated by FPC with -a or so?

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: DOS linked .obj file calling conventions
« Reply #5 on: July 22, 2016, 01:43:43 pm »
Why don't you simply look at the code generated by FPC with -a or so?
Mmmwah, yes I forgot: the only dependency is recently only nasm  because the internal linker is implemented for the platform.
In trunk there is no need for the Watcom tooling.

I stand corrected. But the wiki needs an update in this case...
Specialize a type, not a var.

deathshadow

  • New member
  • *
  • Posts: 9
    • CutCodeDown - Minimalist Semantic Markup
Re: DOS linked .obj file calling conventions
« Reply #6 on: July 23, 2016, 01:12:36 am »
Laughably I switched to NASM in anticipation of this about a year ago, then promptly shelved the project due to health concerns...

I was kind of hoping to get the total project back under 64k (my target is DOS 2.0 on a unexpanded PCJr....) and squeeze a bit more speed out of it by swapping everything to near calls -- something TINY would let me do... but that 16k minimum size from the start tosses 14k on a project that really doesn't need 90%+ of the stuff built into SYSTEM.

It does make me wonder though, does FPC even HAVE smart linking? Or is the linker so dumb it just blindly includes everything "used or not"? One of TP's biggest features from the earliest of releases was that procedures, functions, types, and so forth were not just blindly included -- ESPECIALLY if it was coming from a Unit.

Is FPC not smart linking, or is the system unit just that bloated a mess once you're down in the 16 bit platform?

Ah well, back to TP7... Was kind of hoping for a 32 bit compiler so I could build completely from modern (since NASM is slow as **** under DOSBOX) and TPC32 drops the ball if you dare to state less than 8k of stack or no heap. Amazingly, what I'm working on only needs 2k of stack...

Back to plan B, rewriting all my units as includes so everything can be near calls... JUST to try and squeeze that last drop of blood from the stone known as the PCJr.

Wasn't there a Delphi flavor that was a 32 bit compiler but could still compile 16 bit DOS .exe from the command line?

I HATE to say it, but I'm half tempted to move the project to C... and I HATE C... it's just 99% of the time if you want the compiler to do something you can tell it to do it easy-peasy...

Like omitting stdio.h
« Last Edit: July 23, 2016, 01:15:32 am by deathshadow »
From time to time the accessibility of websites must be refreshed with the blood of owners and designers. It is its natural manure.

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: DOS linked .obj file calling conventions
« Reply #7 on: July 23, 2016, 01:23:12 am »
You need to build whole RTL with smartlinking enabled. If I recall correct, this should be enabled by default.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: DOS linked .obj file calling conventions
« Reply #8 on: July 23, 2016, 04:11:37 am »
I forgot which asm is used for startup
Nasm... and  Open Watcom linker and tools. See the wiki: http://wiki.lazarus.freepascal.org/DOS.
The startup file, not the assembler.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: DOS linked .obj file calling conventions
« Reply #9 on: July 23, 2016, 04:30:25 am »
It does make me wonder though, does FPC even HAVE smart linking? Or is the linker so dumb it just blindly includes everything "used or not"? One of TP's biggest features from the earliest of releases was that procedures, functions, types, and so forth were not just blindly included -- ESPECIALLY if it was coming from a Unit.

Is FPC not smart linking, or is the system unit just that bloated a mess once you're down in the 16 bit platform?
It does, if you activate it, and it's done from compiler side, regardless your stupid linker, with limitations where initialization and finalization sections are not removed since there's no way to prove that they're not used, so is RTL (string and memory) managers since many things depend on them as core feature.
I HATE to say it, but I'm half tempted to move the project to C... and I HATE C... it's just 99% of the time if you want the compiler to do something you can tell it to do it easy-peasy...

Like omitting stdio.h
Go ahead, no one will stop you. You will need to write your own RTL anyway, which you seem too lazy to do in Pascal and I don't understand if you're not lazy to do that in C.
You need to build whole RTL with smartlinking enabled. If I recall correct, this should be enabled by default.
He already got 16K for empty project, that's as expected for the default RTL (correctly stripped and smartlinked) since it's fully featured, but he couldn't accept it.

deathshadow

  • New member
  • *
  • Posts: 9
    • CutCodeDown - Minimalist Semantic Markup
Re: DOS linked .obj file calling conventions
« Reply #10 on: July 23, 2016, 09:34:59 pm »
Between this:

so is RTL (string and memory) managers since many things depend on them as core feature.

... and this:
He already got 16K for empty project, that's as expected for the default RTL (correctly stripped and smartlinked)

I'd be VERY interested in knowing what it's doing that TP/BP7's 2k of overhead isn't... Though if that's smartlinking, I'm the Pope. I don't call ASSIGN, why is ASSIGN being linked? I don't call POS, why is POS linked?

If 16k is the expected AFTER smart linking without a single UNIT declaration, just drop the pretense of offering SMALL and TINY targets.

As to:

which you seem too lazy to do in Pascal and I don't understand if you're not lazy to do that in C.
I already have one, mostly written in assembler using NASM... since my ONLY disk interaction is:

Code: [Select]
BITS 16
CPU 8086

%include "TURBOPAS.MAC"

segment CONST

scoreFile:
db 'PAKUHIGH.SCR', 0

segment CODE

extern highScores, highScoreSize

; function scoreRead:word;
pProcNoArgs scoreRead
mov   ax, 0x3D00 ; open file read only
mov   bh, 0x3F ; next operation
jmp   readWrite

; function scoreWrite:word;
pProcNoArgs scoreWrite
mov    ah, 0x3C ; create file
mov    bh, 0x40
mov    cx, 0x0020 ; Set archive bit only
jmp    readWrite

readWrite:
mov    dx, scoreFile
int    0x21
jc    .done
xchg  ax, bx ; moves file handle into AX and operation into BH
mov   cx, [highScoreSize]
mov   dx, highScores
int   0x21
jc    .done
mov   ah, 0x3E ; close file
int   0x21
jc    .done
xor   ax, ax
.done:
retf

It's a game where I only care about the most recent key-down.

Code: [Select]
segment CODE

gameKeyData  db  0
oldISR9      dd  0x00000000

gameKeyInt9h:
push  ax
in    al, 0x60
xor   al, 0x80
jns   .done     ; ignore key releases
mov   [cs : gameKeyData], al
.done:
in    al, 0x61
or    al, 0x80
out   0x61, al
mov   al, 0x20
out   0x20, al
pop   ax
iret

... and being a game, I'm doing 99.99% of my video access direct to video memory. What little text handling I have for maximum compatibility is being routed through int 0x21 function 0x02 since TP7's write bombs on DOS 2.x (and since Jr / T1K is my target...) Hence:
Code: [Select]
; procedure echo(str:string);
pProcArgs echo
push   ds
lds    si, [bp + 6]
xor    ch, ch
lodsb
mov    cl, al
mov    ah, 0x02
.loop:
lodsb
mov   dl, al
int   0x21
loop  .loop
pop   ds
pRet  4

For those curious about my macros...

Code: [Select]
; handy macros for creating Turbo Pascal compatible ASM

%macro pProcArgs 1
global %1
%1:
push bp
mov  bp, sp
%endmacro

%macro pRet 1
pop  bp
retf %1
%endmacro

%macro pProcNoArgs 1
global %1
%1:
%endmacro

If found the default ones that came with NASM a bit inefficient since I'm TRYING to keep my total memory footprint under 64k... Hence my distinguishing between having arguments and not having arguments, since then I can skip screwing with BP. What peaked my interest in FPC for this project (I use it a lot for 32 and 64 bit targets) is that it can make a COM file under TINY... but when it's adding 14k of overhead vs. TP7 for Christmas only knows what really guts that as an option.

Lands sake, yer bloody RTL AFTER smart linking is bigger than DOS 2.11's memory footprint!

I mean of the RTL functions that are programmer-facing, the only ones I am likely using is paramstr, paramcount and abs.... and I can likely replace those if I need to.

I'd be VERY interested in writing my own replacement to the RTL for the 16 bit target -- I suspect a LOT of the problem is just blindly recycling the existing codebase meant for 32 bit including a lot of things (like 64 bit values) that just shouldn't even be tried on the 16 bit platform.

Problem is trying to wade through the endless mess of includes, poor commenting, and "don't tug on that" codebase that is the system unit (No offense guys, but damn...) is making that a bit difficult. There's so much pointless and obvious commenting (though not as bad as some stuff I've seen in the HTML world -- ever see people do <!-- start header --><header>? HERPA-FREAKING-DERP...)

But for now, can anyone at least TRY and point me the right direction of BS'ing the startup to the point I get a heapless small stack build? I'm lost as hell trying to make sense out of the RTL source for the MSDOS tree since it's all over the blasted place. I'd be half tempted to call it spaghetti coding.

Even just a example that gets me as far as a clean compile of "program demo; begin end." with zero RTL stuff would be a huge start as despite some attempts, I'm not even getting that far. Right now I'm being told:

test.pp(2,6) Fatal: Unknown compilerproc "fpc_initializeunits". Check if you use the correct run time library.

Which would be great, if I could find fpc_initializeunits ANYWHERE in the entire RTL source tree to give me an idea what that should even be doing... Though since I may be skipping units altogether for a TINY build, perhaps I should just bullshit with a empty proc? External to a ret to skip the BP overhead? Does FPC even do a no parameters check?

BTW Leledumbo, nice attitude; I rarely come across anyone as brusque as I am.
From time to time the accessibility of websites must be refreshed with the blood of owners and designers. It is its natural manure.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: DOS linked .obj file calling conventions
« Reply #11 on: July 23, 2016, 10:20:27 pm »
I'd be VERY interested in knowing what it's doing that TP/BP7's 2k of overhead isn't... Though if that's smartlinking,

Allowing for things to be overriden that are hardcoded in TP7 because it is an ancient obsolete thing from 1990. Things like localisation, unicode etc can be plugged in, and this works in dos too.

The default RTL is mostly unified over all targets, and while ports (like 16-bit msdos) can skip some parts, the choices are more made from a maintenance viewpoint.

Quote
I'm the Pope. I don't call ASSIGN, why is ASSIGN being linked? I don't call POS, why is POS linked?

Your Holiness, stdin and stdout are opened on startup (assign) and commandlines are parsed into parameters. ( what probably explains pos?). Things like this can be learned from the RTL sources in mere minutes.

Quote
If 16k is the expected AFTER smart linking without a single UNIT declaration, just drop the pretense of offering SMALL and TINY targets.

This is nonsense. Most people obsessing with binary sizes will maintain their own RTLs in the end. Such targets are specialist domains nowadays.  And cutting things to customize an RTL is easier than make your own (+compiler)

But for development and, more importantly testing it, there must be an RTL, and it must support many features that "big" FPC does, so that it can be tested. Even if most of the users will cut and keep only the parts they are interested in. At least for the lower memory models.
« Last Edit: July 23, 2016, 10:25:34 pm by marcov »

deathshadow

  • New member
  • *
  • Posts: 9
    • CutCodeDown - Minimalist Semantic Markup
Re: DOS linked .obj file calling conventions
« Reply #12 on: July 23, 2016, 11:02:40 pm »
stdin and stdout are opened on startup (assign) and commandlines are parsed into parameters.
... and what the *** is it using func... wait, nevermind. Soft-coded to be cross-platform compatible off one codebase. Something that one would generally NOT do if you were optimizing for a specific platform and why the RTL is a bloated mess on x86 DOS. Laugh being the overhead of the function on POS and what it returns likely being more code than if you just hardcoded it in ASM... but again there's likely little to nothing in the RTL hardcoded in ASM thanks to the cross-platform nature.

... though I'm seeing enough inline assembler I'm still wondering where the overhead is coming from -- probably the unicode stuff which for a tiny or small I wouldn't waste the overhead on, but I could see the use on a larger memory platform; might even come in handy later.

I think for the project I'm working on, FPC is just the wrong tool for the job. ESPECIALLY if what I want to do -- actually build a clean minimalist system.pp with jack in it just to BS the compiler into working is undocumented.

Back to TP7 and removing all units for includes to get rid of the far call overhead... Sadly that means a lot of my external ASM is going back into inline ASM, but it will probably still pay off better in the long run for my overall objective... though some of it really needs to remain external thanks to the lack of macro's in the inline assembler... unless I REALLY want to unroll sections that read:

Code: [Select]
charH_e:
char_X.X.
char_X.X.
char_XXX.
char_X.X.
char_X.X.
charEnd 4, 4

charH_o:
char_.X.X
char_.X.X
char_.XXX
char_.X.X
char_.X.X
charEnd 4, 4

As I'm using coded sprites... probably NOT worth the effort. Besides, a string write might be a far call, but internal calls to the characters would be near anyways. likely not worth my time or any savings to try and get around that.

for the morbidly curious:
Code: [Select]
%define char_.X.X   charLine ah, ah

Code: [Select]
%macro charLine 1-3
mov   [si + tgCharIndex], %1
%ifid %2
mov   [si + tgCharIndex + 2], %2
%ifid %3
mov   [si + tgCharIndex + 4], %3
%endif
%endif
%assign tgCharIndex tgCharIndex+160
%endMacro

Code: [Select]
%macro charEnd 2
%assign tgCharIndex 0
%assign tgNextIndex %2
add  bp, %1
ret
%endMacro

The charend parameters exist as this is a kerned font... variable width since, well... when working at 160x100 you need all the space you can get... most characters being only 3px wide, but some like M and W obviously needing another byte (aka two pixels) or write, and possibly two bytes of offset to the next cursor position. ... and yes, this **** is unrolled for a reason, it's called speed.

Be funny to dial back to TP3 just to make it a COM file and see the results... I am surprised how many pascal compilers seem to go tits up  if you try to say you don't want/need the heap.

Kind of strange... I can hand assemble my own Z80 machine language, was writing Pascal when there was UCSD and.. uhm, well... there was UCSD.... but I look at the entire rtl/msdos and rtl/inc directories for FPC with a blank dumbfounded stare.

Getting too old for this ****!

Pascal is still my favorite language, but it's always felt hobbled by the compilers and interpreters when it comes to doing the types of things I do. TP/BP7 is still the pinnacle for DOS, and FPC IMHO is the pinnacle for 32 and 64 bit win/lin (sorry EmbacardaWhateverThe***TheyreCalled), and xCode's implementation beats out FPC on OSX (at least THEN I can get OpenGL on SDL working)... but you really still can't seem to vary from that a whole lot.

REALLY wish out-of-box FPC was "ready' across all platforms so I'm not constantly switching between compilers and/or development environments... or re-inventing the wheel when it comes to having it NOT do things.

I mean all I want is stack management and dick else... I can handle the rest and I can't even get that far... is that so hard that it's not even documented and NOBODY can actually respond with a working example?
From time to time the accessibility of websites must be refreshed with the blood of owners and designers. It is its natural manure.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: DOS linked .obj file calling conventions
« Reply #13 on: July 23, 2016, 11:48:57 pm »
REALLY wish out-of-box FPC was "ready' across all platforms so I'm not constantly switching between compilers and/or development environments... or re-inventing the wheel when it comes to having it NOT do things.

I really wonder why you think you can desire to generate code for odd ball targets that are 30+ years out of date without any effort invested from your side.

This is not 1990, and this is not TP which was a projecta tenth of the size, but had a thousand times more users or more, and paying ones. FPC/8086 is done by one person in his spare time as a work of love.

Quote
I mean all I want is stack management and dick else... I can handle the rest and I can't even get that far... is that so hard that it's not even documented and NOBODY can actually respond with a working example?

You have a working system in source which compiles to a grand total of (by your own count) 16kb.  The startup assembler gives you the name of the entrypoint (so you don't even have to have dos knowledge to figure that out), you seem to have a symbol list of what ends up in the binary, how hard can it be to figure it out?   

You are not asking for support for people but to do the hard work for your specific circumstances for you.

If it is really important and way above your head you can always hire somebody who knows what he is doing.

« Last Edit: July 28, 2016, 11:40:08 pm by marcov »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: DOS linked .obj file calling conventions
« Reply #14 on: July 23, 2016, 11:59:55 pm »
@deathshadow:
Contact Nikolay Nikolov as the one and only maintainer of the i8086-msdos port and HIRE him properly to help you creating your very-own-specialized-super-duper-minimized-for-your-game-needs-only RTL. Most of us doing games in Windows, Linux and OS X, not 30++ years old DOS. And that requires the whole RTL capability + other packages and libraries, which your dream RTL won't quite cut.
« Last Edit: July 24, 2016, 12:02:01 am by Leledumbo »

 

TinyPortal © 2005-2018