Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

discuss PC<>Acorn file transfer issues & the use of FDC, XFER, Omniflop/disk etc.
scruss
Posts: 144
Joined: Sun Jul 01, 2018 3:12 pm
Location: Toronto
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by scruss » Tue Aug 13, 2019 3:48 pm

Richard Russell wrote:
Tue Aug 13, 2019 11:58 am
VAL accepting a hexadecimal constant is non-standard, isn't it?
In BBC BASIC, maybe, but it's been standard in other BASICs since the early 80s. What they couldn't agree on was whether hex was denoted by & or &h. From MS BASIC-80 Rev. 5.21 (1981):

Code: Select all

10 A$="ff"
20 PRINT VAL("&h" + A$)
Ok
run
 255 
Ok
Last edited by scruss on Tue Aug 13, 2019 3:48 pm, edited 1 time in total.

julie_m
Posts: 17
Joined: Wed Jul 24, 2019 8:53 pm
Location: Derby, UK
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by julie_m » Tue Aug 13, 2019 5:52 pm

The meaning of a number depends heavily on context.

&FF could mean +255 decimal; or if signed 8-bit, it could mean -127 decimal. And when you convert a negative number to a longer representation, it's important to extend the sign all the way to the left if it really is negative.

We all know the rule for creating the twos-complement of a positive number: "Flip the bits and add one." But what does that really mean? Well, flipping a bit is the same as subtracting from 1. So performing the operation in 8 bits, we get

Code: Select all

 11111111
-01100100  (=100 decimal)
---------
 10011011
+00000001
---------
 10011100  (=156 or -100 decimal)
Now mathematically, a subtraction followed by an addition is equivalent to adding the addend to the minuend before taking away the subtrahend; so we could have said

Code: Select all

  11111111
+ 00000001
----------
 100000000
- 01100100  (=100 decimal)
----------
  10011100  (=156 or -100 decimal)
In other words, the twos-complement of an 8-bit number is equivalent to 256 minus that number. The twos-complement of a 16-bit number is equivalent to 65536 minus that number, and so forth. The extra bit gets lost (the 6502 keeps it in the Carry flag) but all is right with the bits we actually care about.

(The 6502's V flag indicates a false change of sign. This can happen if you either added a positive number to a positive number and the sum has bit 7 set, meaning it looks negative; or added a negative number to a negative number and the sum has bit 7 clear, meaning it looks positive. It indicates an overflow from the signed number space, i.e. -128 to 127.)

When you extend a number, you need to propagate the sign bit all the way to the left. So -100 in 16-bit representation would be 1111111110011100, but 156 in 16-bit representation would be 0000000010011100.

The problem is that you do not know for certain whether the 32-bit number &80000000 represents the decimal number 2 147 483 648 (32-bit unsigned, or longer than 32-bit) or -2 147 483 648 (32-bit signed).

This isn't so much of problem with different lengths floating-point numbers, because they are always signed, and not in a twos-complement way.

You really would need to call a function to do the sign extension from 32 to 64 bit integers, or not. Because you simply do not know whether &FFFFFFFF is supposed to represent - 1 or 4 294 967 295.

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Tue Aug 13, 2019 6:10 pm

julie_m wrote:
Tue Aug 13, 2019 5:52 pm
You really would need to call a function to do the sign extension from 32 to 64 bit integers, or not. Because you simply do not know whether &FFFFFFFF is supposed to represent - 1 or 4 294 967 295.
A very interesting and informative read, thank you.

In the case of gcc, when casting a 32-bit int to 64-bit (or even just storing a 32-bit into a 64-bit variable), gcc does the right thing. Which is REALLY handy.

julie_m
Posts: 17
Joined: Wed Jul 24, 2019 8:53 pm
Location: Derby, UK
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by julie_m » Tue Aug 13, 2019 6:58 pm

Ah, but that's because gcc has the concept of signed and unsigned integers. When you cast a signed 32-bit value to a signed 64-bit value, it pads to the left with copies of the sign bit so a negative number stays negative; when you cast an unsigned 32-bit value to a signed 64-bit value, it pads with zeros so the number stays positive.

But when you cast an unsigned value to a signed value of the same size, large positive numbers (with MSB set) can suddenly appear negative (because the MSB is now the sign bit). When you cast a negative value to an unsigned value, it will appear positive.

I had a miniature version of some of this fun myself, converting pairs of 12-bit co-ordinates (signed, naturally :) ) to 16-bit in BCP. The footprint for an 8-pin DIL package alone (8 pins, 8 vertexes in the silkscreen outline and 2 points defining the boundary) saved very nearly enough bytes to make the exercise worth it!
Last edited by julie_m on Tue Aug 13, 2019 7:00 pm, edited 2 times in total.

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Tue Aug 13, 2019 9:18 pm

julie_m wrote:
Tue Aug 13, 2019 5:52 pm
Because you simply do not know whether &FFFFFFFF is supposed to represent - 1 or 4 294 967 295.
Hence a human (the programmer) must intervene to eliminate the ambiguity. This is precisely the purpose of the *HEX command in BBC BASIC for Windows and BBC BASIC for SDL 2.0, and the SYS "Brandy_Hex64" command recently added to Matrix Brandy: they specify which interpretation is wanted:

Code: Select all

>@%=&A0A
>*hex 32
>PRINT &FFFFFFFF
        -1
>*hex 64
>PRINT &FFFFFFFF
4294967295
>*hex 32
>PRINT %11111111111111111111111111111111
        -1
>*hex 64
>PRINT %11111111111111111111111111111111
4294967295
>
Last edited by Richard Russell on Tue Aug 13, 2019 9:21 pm, edited 1 time in total.

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by BigEd » Tue Aug 13, 2019 9:21 pm

Would it help at all to introduce an && syntax for long hex constants, with analogy to %%, so & is always to be interpreted as 32 bit? And, perhaps, as a signed 32 bit value, if that's what compatibility demands.

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Tue Aug 13, 2019 10:43 pm

BigEd wrote:
Tue Aug 13, 2019 9:21 pm
Would it help at all to introduce an && syntax for long hex constants, with analogy to %%, so & is always to be interpreted as 32 bit? And, perhaps, as a signed 32 bit value, if that's what compatibility demands.
From my perspective the trouble with that suggestion (apart from splintering BBC BASIC into even more branches with incompatible extensions!) is that the 32/64 hexadecimal issue affects both input (for example is &FFFFFFFF -1 or 4294967295) and output (for example is -1 FFFFFFFF or FFFFFFFFFFFFFFFF). So whilst the && idea would provide a solution to the input case, it doesn't help with the related output case. That's why it seemed to me more satisfactory to use a solution which can be used for both, such as my *HEX or Soruk's SYS "Brandy_Hex64".

Incidentally, as you probably realise, if your suggestion was adopted there would need to be a %% too for binary numbers, which are affected by the same issue.
Last edited by Richard Russell on Tue Aug 13, 2019 10:43 pm, edited 1 time in total.

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by BigEd » Wed Aug 14, 2019 7:24 am

Yes... it is a bit of a can of worms.

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Wed Aug 14, 2019 7:44 pm

BigEd wrote:
Tue Aug 13, 2019 9:21 pm
Would it help at all to introduce an && syntax for long hex constants, with analogy to %%, so & is always to be interpreted as 32 bit? And, perhaps, as a signed 32 bit value, if that's what compatibility demands.
I did actually look at trying to do this, but (like the int64 stuff) it had its tentacles all over the place, not just in the number decoding, but also the tokeniser, memory allocations etc - and as Richard said, it would be a number format supported nowhere else. So I dropped it in favour of a SYS call that mirrored Richard's *HEX.

As an aside, I'm using SYS calls to get and set aspects of the interpreter as I've never really been comfortable with *-commands altering the behaviour of BASIC, to me a *-command is a call to the operating system, outside the confines of BASIC (hence *NewMode talks to emulated OS components - I don't consider the graphical interface part of BASIC as such) but in RISC OS a SWI can be implemented by any module, not just the OS. I don't know if ARM BASIC V (or VI) implements any SWIs, but it seemed to make sense to me to implement some Brandy_<whatever> SYS calls to get and set aspects of Brandy.

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Wed Aug 14, 2019 8:25 pm

Soruk wrote:
Wed Aug 14, 2019 7:44 pm
I've never really been comfortable with *-commands altering the behaviour of BASIC, to me a *-command is a call to the operating system, outside the confines of BASIC
True, but so is SYS a "call to the operating system" so I don't think that points to one being more suitable than the other. My BASICs necessarily include a degree of 'operating system emulation', because there are features of the BBC Micro's MOS (and RISC OS) that programs expect to be available on all platforms (for example *EXEC, *SPOOL, *LOAD and *SAVE). Hence there is already a built-in mechanism for incorporating 'custom' OSCLI commands.

My reluctance to use SYS in this way is in part because it is often a time-critical statement. For example 3D graphics (via OpenGL or Direct3D) require a lot of SYS calls and they need to be as fast as possible to maximise performance. The same is true of SYS calls to SDL2's 2D graphics functions, or to the GDIPlus graphics library, or to the Box2D physics engine etc. All external libraries, for whatever purpose, are accessed using SYS. So the last thing I want is for every SYS call to have an overhead of first checking for 'internal' commands (which generally are not time-critical) before being passed to the OS for execution.

So although I agree that OSCLI is not ideal, SYS is worse in every way I can think of.

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by BigEd » Wed Aug 14, 2019 8:48 pm

Might one extend OPT to control other options?

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Wed Aug 14, 2019 9:19 pm

BigEd wrote:
Wed Aug 14, 2019 8:48 pm
Might one extend OPT to control other options?
I quite like that idea, bar one snag: it's not actually a keyword and doesn't have a token! I know the documentation implies otherwise in some places, but because it's only usable within the assembler it's actually more like an opcode mnemonic than a BASIC keyword (at least, that's how it's implemented in all my BASICs).

Of course that's not to say that it couldn't be added as a new keyword, but that raises the spectre of breaking any program that has used OPT as a variable name. The same issue applies to the addition of any new keywords, which is why at this stage in BBC BASIC's lifecycle I am reluctant to do so (I've not added any keywords since PRIVATE in 2004 and EXIT in 2007).

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Thu Aug 15, 2019 8:43 am

Richard Russell wrote:
Wed Aug 14, 2019 8:25 pm
Soruk wrote:
Wed Aug 14, 2019 7:44 pm
I've never really been comfortable with *-commands altering the behaviour of BASIC, to me a *-command is a call to the operating system, outside the confines of BASIC
So although I agree that OSCLI is not ideal, SYS is worse in every way I can think of.
While not an issue yet for Matrix Brandy, I'd be using a specific handler for dlopen()ed calls when I get there - so there's no reason I can't make the check for that call before any other checks which should negate the overhead of checking the other calls first.

In other news, as from tonight the nightly builds for Win32 will be built with NEWKBD enabled, and if all goes to plan 1.22.1 will also be built that way. No source change has been made for this, I'm just setting BRANDY_BUILD_FLAGS to do this. Edit 2: A small tweak to target.h and NEWKBD is now the build default for all platforms, define OLDKBD to override this.

The next on my roadmap having pretty much implemented 64-bit integers, is to modify the SYS call to be able to use 64-bit ints as parameters without them being shoved into 32-bit - then I can reverse the indirection I made earlier for strings, and would then allow for being able to implement dlopen() on 64-bit platforms (but that'll be quite a way away) - Edit: This is now implemented on the add_64int branch and in the (admittedly, 32-bit) Windows build here.
Last edited by Soruk on Fri Aug 16, 2019 9:18 am, edited 2 times in total.

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Thu Aug 15, 2019 11:46 am

Soruk wrote:
Thu Aug 15, 2019 8:43 am
While not an issue yet for Matrix Brandy, I'd be using a specific handler for dlopen()ed calls when I get there - so there's no reason I can't make the check for that call before any other checks which should negate the overhead of checking the other calls first.
Good point. Currently my code never calls dlopen() but rather calls dlsym() with the RTLD_DEFAULT switch so that it searches all the libraries loaded into the current process; this covers the great majority of APIs that a BASIC program is going to want to call. It's also the case that if a BASIC program is calling a time-critical SYS function it will be doing so via address, not by name, so as long as any overhead in calling 'internal' functions is on the 'call by name' code path it shouldn't impair performance.

So I take back my argument about speed, but personally I still don't see how SYS is any less a 'call to the operating system' than OSCLI is, so I don't feel inclined to make any changes to the way my BASICs work (for compatibility reasons any SYS mechanism would need to be in addition to, not instead of, the OSCLI mechanism). In any case you've not exactly made it easy for me to incorporate compatible SYS calls in BBCSDL, because you've included "Brandy" in the function name; perhaps you were hoping for some free publicity! :D
The next on my roadmap having pretty much implemented 64-bit integers, is to modify the SYS call to be able to use 64-bit ints as parameters without them being shoved into 32-bit
Yes, coping with the range of different ABIs is the most awkward feature of SYS. Raspbian is particularly troublesome in that regard because it uses the 'hard float' ABI (in which float parameters are passed on the stack rather than in registers).

julie_m
Posts: 17
Joined: Wed Jul 24, 2019 8:53 pm
Location: Derby, UK
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by julie_m » Thu Aug 15, 2019 12:01 pm

As long as there is a memory operator for 64-bit integers, then it should be possible for someone who really knows what they are doing to convert a 32-bit integer to a 64-bit representation with or without sign extension, or to extract the high or low halves of a 64-bit integer as 32-bit integers. Then the implicit type conversion can concentrate on behaving the way most people expect, most of the time, with the option of explicit signed or unsigned conversion where really needed.

If you are just using an integer variable as a convenient way of slinging around a whole bunch of bits in one go, you probably don't care much about its decimal representation being positive or negative anyway.

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Thu Aug 15, 2019 2:21 pm

Richard Russell wrote:
Thu Aug 15, 2019 11:46 am
Soruk wrote:
Thu Aug 15, 2019 8:43 am
While not an issue yet for Matrix Brandy, I'd be using a specific handler for dlopen()ed calls when I get there - so there's no reason I can't make the check for that call before any other checks which should negate the overhead of checking the other calls first.
Good point. Currently my code never calls dlopen() but rather calls dlsym() with the RTLD_DEFAULT switch so that it searches all the libraries loaded into the current process; this covers the great majority of APIs that a BASIC program is going to want to call. It's also the case that if a BASIC program is calling a time-critical SYS function it will be doing so via address, not by name, so as long as any overhead in calling 'internal' functions is on the 'call by name' code path it shouldn't impair performance.

So I take back my argument about speed, but personally I still don't see how SYS is any less a 'call to the operating system' than OSCLI is, so I don't feel inclined to make any changes to the way my BASICs work (for compatibility reasons any SYS mechanism would need to be in addition to, not instead of, the OSCLI mechanism). In any case you've not exactly made it easy for me to incorporate compatible SYS calls in BBCSDL, because you've included "Brandy" in the function name; perhaps you were hoping for some free publicity! :D
:D If I was after the publicity I'd have gone with Matrix_<whatever> - as I'm templating off RISC OS here (indeed, some RISC OS calls are recognised and implemented) Acorn used <module>_<function> as their naming convention, so for the purpose of naming I opted with the "Brandy_" prefix as all calls that don't have a RISC OS equivalent are in that namespace. As for an "operating system" call, yes, some OS_<name> calls are implemented, but in the Acorn worldview, SYS could call functionality from any module, whether it be from the OS ROM or any soft-loaded custom module. While I don't think BASIC implements any SWI calls, it's a module and I wouldn't be upset if a version existed that had "BASIC_<something>" that tweaked the behaviour in some way (such as my Brandy_INTusesFloat extension). I fully appreciate you weren't involved in the RISC OS side of things at all, and your BASICs diverged from probably around the time of the BBC Master.
Richard Russell wrote:
Thu Aug 15, 2019 11:46 am
The next on my roadmap having pretty much implemented 64-bit integers, is to modify the SYS call to be able to use 64-bit ints as parameters without them being shoved into 32-bit
Yes, coping with the range of different ABIs is the most awkward feature of SYS. Raspbian is particularly troublesome in that regard because it uses the 'hard float' ABI (in which float parameters are passed on the stack rather than in registers).
Yeah, I did read up about that, but Brandy makes no attempt (except on RISC OS) of calling real SWI calls on the host OS (so Raspbian is treated like any other Linux machine for this - the only special treatment for Raspbian is GPIO support) so I'm not too worried in that area.
julie_m wrote:
Thu Aug 15, 2019 12:01 pm
As long as there is a memory operator for 64-bit integers, then it should be possible for someone who really knows what they are doing to convert a 32-bit integer to a 64-bit representation with or without sign extension, or to extract the high or low halves of a 64-bit integer as 32-bit integers. Then the implicit type conversion can concentrate on behaving the way most people expect, most of the time, with the option of explicit signed or unsigned conversion where really needed.

If you are just using an integer variable as a convenient way of slinging around a whole bunch of bits in one go, you probably don't care much about its decimal representation being positive or negative anyway.
For the newly-modified SYS handler, that is indeed the main reason to widen the integers to 64 bits without having to resort to indirection hacks, otherwise returning pointers to strings can get problematic really fast (indeed, it has done for some Debian users in just such a way I couldn't repeat on CentOS!)

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Thu Aug 15, 2019 4:02 pm

Soruk wrote:
Thu Aug 15, 2019 2:21 pm
in the Acorn worldview, SYS could call functionality from any module, whether it be from the OS ROM or any soft-loaded custom module.
On 'modern' platforms SYS can call any function exported from a shared object, which in practice probably means a .dll file in Windows, a .so file in Linux/Android or a .dylib file in MacOS/iOS. However it doesn't (ordinarily) include a regular executable, so SYS calling a function in BBC BASIC itself is not something you would expect on those platforms.
your BASICs diverged from probably around the time of the BBC Master.
Probably before: my BASIC was supplied with Acorn's Z80 Second Processor.
Raspbian is treated like any other Linux machine for this - the only special treatment for Raspbian is GPIO support) so I'm not too worried in that area.
If my experience is anything to go by you may hit problems when it comes to SYS supporting floating point parameters. The complication arises because on some platforms the ABI specifies that floats are passed like any other parameter in strict sequence (e.g. on the stack) whereas on others floats are passed 'in parallel with' integer parameters in floating-point registers.

stephen_usher
Posts: 57
Joined: Sun Apr 10, 2016 1:47 pm
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by stephen_usher » Thu Aug 15, 2019 7:40 pm

Richard Russell wrote:
Wed Jul 24, 2019 1:10 pm
Soruk wrote:
Wed Jul 24, 2019 12:20 pm
I'm not 100% certain the "int" type would still be 32 bits on 64-bit hardware, I suspect it might be 64-bit.
That would be extremely unusual. In my experience int is invariably (no more than) 32-bits and long long is invariably (no fewer than) 64-bits (whilst long may sometimes be 32-bits and sometimes 64-bits). Indeed I've always assumed that one reason why x86-64 instructions default to 32-bits is because that's what the int type usually is.
The ANSI C specification states that an "int" is the natural size of a signed integer on the machine in question and hence its size cannot be relied upon. It merely needs to be as large or larger than a "char". (I've used machines where all types were 32 bits in size, for example.)

The there are the POSIX types "int32_t", "u_int32_t", "int64_t" and "u_int64_t" which will give you the correct sizes on any system, however. Just remember to include <sys/types.h>

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Thu Aug 15, 2019 8:12 pm

stephen_usher wrote:
Thu Aug 15, 2019 7:40 pm
The ANSI C specification states that an "int" is the natural size of a signed integer on the machine in question and hence its size cannot be relied upon.
I know what the ANSI specification says, but nevertheless my statement remains true: int being anything other than 32-bits is extremely unusual.

stephen_usher
Posts: 57
Joined: Sun Apr 10, 2016 1:47 pm
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by stephen_usher » Thu Aug 15, 2019 8:22 pm

Richard Russell wrote:
Thu Aug 15, 2019 8:12 pm
stephen_usher wrote:
Thu Aug 15, 2019 7:40 pm
The ANSI C specification states that an "int" is the natural size of a signed integer on the machine in question and hence its size cannot be relied upon.
I know what the ANSI specification says, but nevertheless my statement remains true: int being anything other than 32-bits is extremely unusual.
But not infinitely small. It depends upon how much work you wish to put in to make sure that the code is (a) portable and, (b) future-proof.

I've always been told that "Assumptions make an Ass of U and Me." :D

I've also been stung too many times by this porting issue in the past.

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by BigEd » Thu Aug 15, 2019 8:23 pm

(Just for fun, here's a round up of oddly-shaped machines which prove the dictum that "All the world is not a VAX!")

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Thu Aug 15, 2019 9:16 pm

stephen_usher wrote:
Thu Aug 15, 2019 8:22 pm
It depends upon how much work you wish to put in to make sure that the code is (a) portable and, (b) future-proof.
None! My code isn't portable (and isn't intended to be); it is full of platform-specific features and compiler-specific features. Within the limited set of platforms and compilers with which my code is compatible, I can say with certainty that ints are always 32-bits. So it's a total non-issue for me.

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Fri Aug 16, 2019 7:10 am

Richard Russell wrote:
Thu Aug 15, 2019 9:16 pm
stephen_usher wrote:
Thu Aug 15, 2019 8:22 pm
It depends upon how much work you wish to put in to make sure that the code is (a) portable and, (b) future-proof.
None! My code isn't portable (and isn't intended to be); it is full of platform-specific features and compiler-specific features. Within the limited set of platforms and compilers with which my code is compatible, I can say with certainty that ints are always 32-bits. So it's a total non-issue for me.
This is a useful mini program for seeing what sizes your platform uses:

Code: Select all

#include <stdio.h>
#include <inttypes.h>
#include <time.h>

int main() {
  printf( "    short int: %zd\n" , sizeof(short int) ) ;
  printf( "          int: %zd\n" , sizeof(int) ) ;
  printf( "     long int: %zd\n", sizeof(long int) ) ;
  printf( "long long int: %zd\n", sizeof(long long int) ) ;
  printf( "        float: %zd\n", sizeof(float) );
  printf( "       double: %zd\n", sizeof(double) );
  printf( "  long double: %zd\n", sizeof(long double) );
  printf( "       size_t: %zd\n", sizeof(size_t) ) ;
  printf( "       time_t: %zd\n", sizeof(time_t) ) ;
  printf( "        void*: %zd\n\n", sizeof(void *) ) ;
  return 0;
}
gcc on x86-64 shows an int as being 4 bytes (32 bits). long int is the one that is 32-bits on i686, 64-bits on x86-64. Also, long double is 12 bytes (96 bits) on i686, 16 bytes (128 bits) on x86-64.
Last edited by Soruk on Fri Aug 16, 2019 8:00 am, edited 1 time in total.

User avatar
Richard Russell
Posts: 877
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Richard Russell » Fri Aug 16, 2019 8:42 am

Soruk wrote:
Fri Aug 16, 2019 7:10 am
Also, long double is 12 bytes (96 bits) on i686, 16 bytes (128 bits) on x86-64.
That is more an alignment issue than anything else. If the FPU is being used to carry out the long double calculations, which is the only thing that makes sense on those CPUs, then only 10 bytes (80 bits) are actually significant. On a 32-bit x86 CPU it is usual for any data type of 32-bits or more to be aligned on a 4-byte boundary, resulting in the long double being padded from 10 bytes to 12. Similarly on a 64-bit x86 CPU it is usual for any type of 64-bits or more to be aligned on an 8-byte boundary, hence in that case the long double is padded to 16 bytes.

In my BASICs I ignore the size of long double as reported by the compiler and store only 10 bytes. This is particularly important for arrays, because I don't want to waste memory by storing more bytes than I need, and I also want to ensure compatibility between 32-bit and 64-bit editions so that a BASIC program can index into an array using indirection, by multiplying the index by 10 (not 12 or 16). Of course this would horrify a C purist, but it's the sort of evil trick that my code is full of!

On an ARM CPU there is no FPU support for floating-point numbers bigger than a 'double', and it's not usual for such numbers to be supported by a library (the performance would be unacceptable), so you will find that 'long double' is synonymous with 'double' on those CPUs (and indeed even on x86 CPUs in the case of Microsoft compilers, one reason of many why my code is incompatible with them).
Last edited by Richard Russell on Fri Aug 16, 2019 8:56 am, edited 1 time in total.

Soruk
Posts: 413
Joined: Mon Jul 09, 2018 10:31 am
Location: Basingstoke, Hampshire
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Soruk » Fri Aug 16, 2019 9:09 am

Richard Russell wrote:
Fri Aug 16, 2019 8:42 am
On an ARM CPU there is no FPU support for floating-point numbers bigger than a 'double', and it's not usual for such numbers to be supported by a library (the performance would be unacceptable), so you will find that 'long double' is synonymous with 'double' on those CPUs (and indeed even on x86 CPUs in the case of Microsoft compilers, one reason of many why my code is incompatible with them).
Yep, I see that on my Raspberry Pi 2:

Code: Select all

soruk@RaspberryPi2 ~/tmp $ ./intsizes 
    short int: 2
          int: 4
     long int: 4
long long int: 8
        float: 4
       double: 8
  long double: 8
       size_t: 4
       time_t: 4
        void*: 4
soruk@RaspberryPi2 ~/tmp $ _
(As a total aside, I also notice that time_t is 32-bits so will fall foul of the Y2038 bug...)

I've not tried using the Microsoft compiler, and with the way Matrix Brandy has grown I suspect it wouldn't work. I merely opted for MinGW (with Cygwin providing the build environment) as my background is very definitely Linux.
Last edited by Soruk on Fri Aug 16, 2019 9:13 am, edited 2 times in total.

Phlamethrower
Posts: 112
Joined: Fri Nov 24, 2017 1:35 pm
Contact:

Re: Matrix Brandy BASIC VI for Linux with SDL: V1.22.0 released

Post by Phlamethrower » Fri Aug 16, 2019 9:35 am

Soruk wrote:
Fri Aug 16, 2019 9:09 am
(As a total aside, I also notice that time_t is 32-bits so will fall foul of the Y2038 bug...)
Apparently that's a common limitation - POSIX defines time_t as an "unsigned long", and there's been no real consensus on how to fix it for platforms where long is 32 bits. So different OSes have been going with their own solutions, and Linux has yet to tackle the problem.

https://en.wikipedia.org/wiki/Year_2038 ... _solutions

Post Reply