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

discuss PC<>Acorn file transfer issues & the use of FDC, XFER, Omniflop/disk etc.
David1664
Posts: 57
Joined: Thu Feb 25, 2010 2:24 am
Contact:

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

Post by David1664 » Sat Nov 23, 2019 12:13 am

Soruk wrote:
Fri Nov 22, 2019 2:50 pm
I've developed and focused on the kit that I have. Certainly I see no reason why it won't build on the BSDs, and at a push, Mac OS X. The GUI might be harder, but if SDL 1.2 is available, then that should also work. I've never used an Amiga (or a Mac). Others have had more success than I have at building it on RISC OS - notably @jgharston has got that working, and I believe he might have had some luck with MS-DOS too.
Thanks for the prompt reply!

David.
--

http://www.proggies.uk/
http://www.proggies.uk/bbcsdl/index.html

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

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

Post by Soruk » Mon Nov 25, 2019 9:20 am

Hi,

I've just released V1.22.2 of Matrix Brandy BASIC VI. Changes since V1.22.1 include:
- Merge in 64-bit int capability
- Remove offset memory model, PAGE, HIMEM and indirection operators now use actual memory locations.
- Text-mode builds available for Windows with Cygwin build environment.
- Change to Escape handling (thanks Jonathan Harston), bringing it more in line with the way the Acorn MOS handles it.
- Many more keyboard fixes from Jonathan Harston.
- Separate out memory information from *HELP BASIC (in Debug mode) to *HELP MEMINFO (available on any build).
- Fixed VDU5 font painting in black. It now honours the graphics window and the GCOL action code.
- RECTANGLE FILL now honours the graphics window.
- GOTO and GOSUB no longer require parentheses around an expression.
- Tektronix graphics added to tbrandy (textonly.c), but not enabled by default.
- New graphics demos (converted from Teklib demos), and all non-Teklib graphics demos checked to work with both regular graphics and the newly Tek-enhanced text-mode build.
- RESTORE LOCAL (BB4W/BBCSDL extension) implemented.
- ON ERROR behaviour corrected, variables declared LOCAL shouldn't be restored to their global values when the stack is unwound.

Source and Windows binary downloads are available on the website, and the git repository is on Github.

scruss
Posts: 155
Joined: Sun Jul 01, 2018 3:12 pm
Location: Toronto
Contact:

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

Post by scruss » Tue Nov 26, 2019 12:08 am

Soruk wrote:
Thu Nov 21, 2019 2:11 pm
The 38h possibly comes from the codes used by xterm to switch the cursor between the VT (text) window and the Tek window. I suspect the tek4010 emulator won't recognise them as there's nothing for it to switch to.
I had a chat with Rene Richarz, the author of Tek4010, about this and he notes that the '38h's come from ANSI codes embedded in Matrix Brandy's output. xterm is lenient about filtering excess codes from its output, but the original Teks weren't. He's now re-written the input processor to filter out ANSI codes, and the results are great.

Here's a simulation ofGeorg Nees' “Schotter”, running through tek4010 — https://www.youtube.com/watch?v=4xRRFz8uKsg

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

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

Post by Soruk » Tue Nov 26, 2019 12:02 pm

scruss wrote:
Tue Nov 26, 2019 12:08 am
Soruk wrote:
Thu Nov 21, 2019 2:11 pm
The 38h possibly comes from the codes used by xterm to switch the cursor between the VT (text) window and the Tek window. I suspect the tek4010 emulator won't recognise them as there's nothing for it to switch to.
I had a chat with Rene Richarz, the author of Tek4010, about this and he notes that the '38h's come from ANSI codes embedded in Matrix Brandy's output. xterm is lenient about filtering excess codes from its output, but the original Teks weren't. He's now re-written the input processor to filter out ANSI codes, and the results are great.

Here's a simulation ofGeorg Nees' “Schotter”, running through tek4010 — https://www.youtube.com/watch?v=4xRRFz8uKsg
Very nice! You can get rid of most of the spurious ANSI codes by adding to your source code:

Code: Select all

245 VDU5
335 VDU4
...and should also draw faster as fewer codes are being generated.

Edit: Yep. Runs MUCH faster. Although without this it seems to generate twice as much data, something is causing the rendering to be even slower.

Edit 2: In a recent commit, I've (re)defined MODEs 72-75 to use a 1024x780 display window (rather than the 1024x576 size of my netbook screen!) so a doodle can look near identical in that mode in the SDL build and a Tek drawing in tek4010 or xterm. Also, for doodles using teklib (not the built-in Tek in the tbrandy build) I've added an option, enabled by default, to slow down the drawing to approximate a 9600bps connection of a 4010. As teklib requires a call to PROCmode(mode%) to initialise, but mode% was ignored, I've set it so if mode% >= 128 then the slowdown is bypassed.

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

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

Post by Soruk » Wed Nov 27, 2019 2:44 pm

More Tek tweaking: I've just pushed an update that extends SYS "Brandy_TekEnabled" to take a second parameter. If non-zero, it is used as an approximate bit rate for drawing the graphics. For example,

Code: Select all

SYS "Brandy_TekEnabled",1,9600
will simulate the maximal speed of a Tektronix 4010. Possibly useful(?) for the xterm Tektronix emulation which, unlike Rene Richarz's tek4010 emulator, doesn't simulate the slowish drawing speed of these things.

Edit: Also, bugfix. ORIGIN was being double-counted on plotting single points. And some new Tek-enabled demos.

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

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

Post by Soruk » Thu Nov 28, 2019 1:06 pm

And, to more useful stuff. A handful of regressions were fixed (as a result of the 64-bit int work):
* Assigning a float array from a list wasn't being instantiated correctly
* Incorrectly trying to pop a 64-bit int when it should have been a 32-bit, thus completely breaking the stack pointer and corrupting the stack. OOPS!
* Fix a crash in the flood fill code where an infinite loop (blowing the application stack) if the old colour and new colour are the same.

Since these are quite significant bugs, I've forced a rebuild of today's nightly Windows build, and might do a new release later this week.

Edit (29-11-2019): V1.22.3 has been released, with these fixes (and the above Tek tweaks).

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

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

Post by Richard Russell » Sun Dec 01, 2019 12:04 pm

Soruk wrote:
Wed Nov 27, 2019 2:44 pm

Code: Select all

SYS "Brandy_TekEnabled",1,9600
Sorry if this is something I should already know, but where can I find a full list of these special SYS calls which affect the internal workings of the interpreter? Are there too many to be included in the *HELP summaries?

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

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

Post by Soruk » Sun Dec 01, 2019 1:09 pm

Richard Russell wrote:
Sun Dec 01, 2019 12:04 pm
Soruk wrote:
Wed Nov 27, 2019 2:44 pm

Code: Select all

SYS "Brandy_TekEnabled",1,9600
Sorry if this is something I should already know, but where can I find a full list of these special SYS calls which affect the internal workings of the interpreter? Are there too many to be included in the *HELP summaries?
In the release (not nightly) zip files, they're in docs/swis.txt.

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

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

Post by Richard Russell » Sun Dec 01, 2019 1:53 pm

Soruk wrote:
Sun Dec 01, 2019 1:09 pm
In the release (not nightly) zip files, they're in docs/swis.txt.
Ah, OK. I would never have thought to look for SYS under SWI; to somebody not familiar with RISC OS, the link isn't obvious. Indeed, the keyword SYS doesn't appear anywhere in that file!

Another quick question if I may: the 'experimental' Windows version of Matrix Brandy (which is the only one I ever run) is described at the website as a "32-bit build". Is that still the case, now support for 64-bit addresses is, as I understand it, a standard feature?

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

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

Post by Soruk » Sun Dec 01, 2019 4:49 pm

Richard Russell wrote:
Sun Dec 01, 2019 1:53 pm
Soruk wrote:
Sun Dec 01, 2019 1:09 pm
In the release (not nightly) zip files, they're in docs/swis.txt.
Ah, OK. I would never have thought to look for SYS under SWI; to somebody not familiar with RISC OS, the link isn't obvious. Indeed, the keyword SYS doesn't appear anywhere in that file!

Another quick question if I may: the 'experimental' Windows version of Matrix Brandy (which is the only one I ever run) is described at the website as a "32-bit build". Is that still the case, now support for 64-bit addresses is, as I understand it, a standard feature?
That's a very fair point about SWI vs SYS, certainly the RISC OS docs all talk about SWI calls rather than SYS calls. But, since these aren't real SWI calls (except perhaps on a RISC OS build), I should change that.

As for the Windows builds, no, these are 32-bit binaries so can only see a 32-bit address space - though it CAN handle 64-bit integers. I need to build myself a 64-bit Windows VM to make 64-bit binaries (which won't run on 32-bit Windows at all).

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

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

Post by Richard Russell » Sun Dec 01, 2019 5:28 pm

Soruk wrote:
Sun Dec 01, 2019 4:49 pm
As for the Windows builds, no, these are 32-bit binaries so can only see a 32-bit address space - though it CAN handle 64-bit integers.
Understood. Admittedly the 64-bit Windows edition of BBCSDL isn't something I advertise or distribute, but I do use it in-house as a first-line check for 64-bit compatibility of BASIC programs. It's of limited value for that however, because (at least with the build process I use) memory always seems to be allocated in the bottom 2 Gbytes so typically it won't pick up addresses/pointers being stored in 32-bit variables.

Interestingly, although Linux is better at detecting 64-bit compatibilty it's nothing like as good as Mac OS. I thought I had fully adapted David Williams' 'Forces of Darkness' game to be 64-bit compatible, because it ran perfectly on 64-bit Ubuntu. But as soon as I tried it on Mac OS it fell over, and it turned out there were a lot more changes necessary.

So if you're only able to check Matrix Brandy on Linux there's a possibility that you're not exercising the 64-bit features as much as you think!

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

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

Post by Soruk » Sun Dec 01, 2019 6:32 pm

Richard Russell wrote:
Sun Dec 01, 2019 5:28 pm
Interestingly, although Linux is better at detecting 64-bit compatibilty it's nothing like as good as Mac OS. I thought I had fully adapted David Williams' 'Forces of Darkness' game to be 64-bit compatible, because it ran perfectly on 64-bit Ubuntu. But as soon as I tried it on Mac OS it fell over, and it turned out there were a lot more changes necessary.

So if you're only able to check Matrix Brandy on Linux there's a possibility that you're not exercising the 64-bit features as much as you think!
On my 64-bit CentOS 6 machine...

Code: Select all

[soruk@Xenon ~]$ tbrandy

 Matrix Brandy BASIC VI version 1.22.3 (Linux) 29 Nov 2019

 Starting with 524288 bytes free

 >*HELP MEMINFO

 Matrix Brandy BASIC VI version 1.22.3 (Linux) 29 Nov 2019
 Memory allocation information:

 Workspace is at &7F691173E010, size is &80000
 PAGE = &7F691173E010, HIMEM = &7F69117BE010
 stacktop = &7F69117BDFB4, stacklimit = &7F691173E114

 >_
Though, on the SDL builds, the default 512K workspace gets put in the bottom 2GB on my kit. Not sure why that is.

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

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

Post by Richard Russell » Sun Dec 01, 2019 6:46 pm

Soruk wrote:
Sun Dec 01, 2019 6:32 pm
On my 64-bit CentOS 6 machine...

Code: Select all

 PAGE = &7F691173E010, HIMEM = &7F69117BE010
I think I'm right in remembering that what broke 'Forces of Darkness' on MacOS was not workspace pointers (which as you say need 64-bit variables in Linux too) but 64-bit values returned from SYS calls. For whatever reason, those returned values did fit in 32-bit variables in Linux, but not in MacOS. It may be, given limitations in what you can do with SYS in Matrix Brandy, that this is currently not an issue, but it certainly is for me and now I tend to test on Mac OS first.

Mac OS also seems to be fussier about thread affinity, and calls that you can safely make from a worker thread in Linux may only work if made from the UI thread in Mac OS.

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

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

Post by Soruk » Sun Dec 01, 2019 8:56 pm

Richard Russell wrote:
Sun Dec 01, 2019 6:46 pm
Soruk wrote:
Sun Dec 01, 2019 6:32 pm
On my 64-bit CentOS 6 machine...

Code: Select all

 PAGE = &7F691173E010, HIMEM = &7F69117BE010
I think I'm right in remembering that what broke 'Forces of Darkness' on MacOS was not workspace pointers (which as you say need 64-bit variables in Linux too) but 64-bit values returned from SYS calls. For whatever reason, those returned values did fit in 32-bit variables in Linux, but not in MacOS. It may be, given limitations in what you can do with SYS in Matrix Brandy, that this is currently not an issue, but it certainly is for me and now I tend to test on Mac OS first.
Since I'm not strictly bound by the RISC OS SWI interface, I have as part of the 64-bit int work extended SYS to be able to return 64-bit ints. However, annoyingly the call to return the base of video memory tells me that it's in the first 2GB - no matter what I try. So, as of tomorrow's nightly build I've extended the Brandy_Version call to return &123456789ABCDEF0 in R6. This also works on 32-bit builds.
Richard Russell wrote:
Sun Dec 01, 2019 6:46 pm
Mac OS also seems to be fussier about thread affinity, and calls that you can safely make from a worker thread in Linux may only work if made from the UI thread in Mac OS.
I've only recently started playing with threading, but the only worker thread is the one that keeps the centisecond timer up to date. Everything else runs in the same thread as the UI.

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

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

Post by Richard Russell » Sun Dec 01, 2019 11:06 pm

Soruk wrote:
Sun Dec 01, 2019 8:56 pm
annoyingly the call to return the base of video memory tells me that it's in the first 2GB - no matter what I try.
That's very similar to what I was finding, except I think it was something like a texture pointer that was always below 2 GB on Linux but not on Mac OS (bearing in mind that I'm using SDL 2.0 whereas you are using SDL 1.2).
Everything else runs in the same thread as the UI.
In BB4W and BBCSDL the interpreter runs in a worker thread, for the simple reason that I can't otherwise guarantee servicing events (keyboard, mouse, vertical sync etc.) in a timely fashion, especially if the interpreter is waiting for a blocking SYS call to return, or something. How does Brandy deal with that situation; do events just queue up if the interpreter makes a call that blocks?

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

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

Post by Soruk » Mon Dec 02, 2019 10:58 am

Richard Russell wrote:
Sun Dec 01, 2019 11:06 pm
Soruk wrote:
Sun Dec 01, 2019 8:56 pm
annoyingly the call to return the base of video memory tells me that it's in the first 2GB - no matter what I try.
That's very similar to what I was finding, except I think it was something like a texture pointer that was always below 2 GB on Linux but not on Mac OS (bearing in mind that I'm using SDL 2.0 whereas you are using SDL 1.2).
Everything else runs in the same thread as the UI.
In BB4W and BBCSDL the interpreter runs in a worker thread, for the simple reason that I can't otherwise guarantee servicing events (keyboard, mouse, vertical sync etc.) in a timely fashion, especially if the interpreter is waiting for a blocking SYS call to return, or something. How does Brandy deal with that situation; do events just queue up if the interpreter makes a call that blocks?
Events just seem to queue, I don't specifically make a point of using a keyboard buffer, but SDL 1.2's event queue seems to give me that facility. (Yes, sometimes I get a bit lazy and let the library's facilities do the hard work for me!)

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

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

Post by Richard Russell » Mon Dec 02, 2019 12:28 pm

Soruk wrote:
Mon Dec 02, 2019 10:58 am
Events just seem to queue
I expect that was, and probably is, quite acceptable with the limited opportunities Brandy has to 'block' anyway (presumably when waiting in GET or WAIT it still services events, something which I don't have to bother with). But I wonder whether you will hit problems if you eventually support SYS calling arbitrary API functions, when it might not be so acceptable for display refresh, say, to stall if a function takes a long time to return.

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

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

Post by Soruk » Thu Dec 05, 2019 11:11 am

Richard Russell wrote:
Sun Dec 01, 2019 1:53 pm
Another quick question if I may: the 'experimental' Windows version of Matrix Brandy (which is the only one I ever run) is described at the website as a "32-bit build". Is that still the case, now support for 64-bit addresses is, as I understand it, a standard feature?
To update this, I've started building 64-bit nightly Windows builds as of today. These are still built with Cygwin, but under 64-bit Windows 7.

I've also extended "Brandy_Version", so R7 now returns 1 if a 64-bit build, 0 otherwise.

Edit: I've also pushed through an update that removes the 2GB ceiling, at least on 64-bit machines.

Edit 2: Just for a bit of fun, how's this for workspace?....
Image
Edit 3: Ooh, bug! Not displaying the size correctly in the *HELP MEMINFO output. How embarrassing.. :oops:
Edit 4: Fixed, along with some code simplification. Pic updated.

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

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

Post by Soruk » Tue Dec 10, 2019 12:25 pm

Latest changes:

Tek now only enabled on Unix-like platforms (not including Cygwin, the terminal mode build runs in a console window, so won't run in a Cygwin xterm). The call SYS "Brandy_TekEnabled" is simply ignored where not supported.

Large memory model available, neither 32-bit nor 64-bit builds limited to 2GB now (32-bit limited to a bit under 4GB), however DIMming memory is still limited to 2GB (there's a lot of signed 32-bit ints in use in the code...) but HIMEM can always be reduced and memory between new-HIMEM and old-HIMEM used. Reverted, it broke variable assignments! :(
Last edited by Soruk on Tue Dec 10, 2019 4:51 pm, edited 1 time in total.

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

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

Post by Richard Russell » Tue Dec 10, 2019 2:23 pm

Soruk wrote:
Tue Dec 10, 2019 12:25 pm
HIMEM can always be reduced and memory between new-HIMEM and old-HIMEM used.
So does Matrix Brandy default to setting HIMEM high and expecting the user to reduce it if necessary? My BASICs (BB4W and BBCSDL) work the other way: HIMEM by default is set quite low (2 Mbytes above PAGE) but can be raised if necessary. There's probably not a lot to choose between them, but (and this really applies only to Windows) I didn't like the idea of initially committing (rather then just reserving) a lot of memory. In Linux there's no distinction between committing and reserving, I think, so it may not be a relevant argument on that platform.

One thing to consider is that once SYS can make arbitrary calls (and I know you're not yet there with Matrix Brandy) you need to ensure that plenty of process address space is available for uses 'external' to BASIC, such as DLLs, memory hungry objects like textures and 3D meshes, memory allocated directly using SYS "malloc" or SYS "GlobalAlloc" etc. In my experience they can often be much bigger than BASIC's heap and stack needs.

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

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

Post by Soruk » Tue Dec 10, 2019 4:15 pm

Richard Russell wrote:
Tue Dec 10, 2019 2:23 pm
Soruk wrote:
Tue Dec 10, 2019 12:25 pm
HIMEM can always be reduced and memory between new-HIMEM and old-HIMEM used.
So does Matrix Brandy default to setting HIMEM high and expecting the user to reduce it if necessary? My BASICs (BB4W and BBCSDL) work the other way: HIMEM by default is set quite low (2 Mbytes above PAGE) but can be raised if necessary. There's probably not a lot to choose between them, but (and this really applies only to Windows) I didn't like the idea of initially committing (rather then just reserving) a lot of memory. In Linux there's no distinction between committing and reserving, I think, so it may not be a relevant argument on that platform.

One thing to consider is that once SYS can make arbitrary calls (and I know you're not yet there with Matrix Brandy) you need to ensure that plenty of process address space is available for uses 'external' to BASIC, such as DLLs, memory hungry objects like textures and 3D meshes, memory allocated directly using SYS "malloc" or SYS "GlobalAlloc" etc. In my experience they can often be much bigger than BASIC's heap and stack needs.
I've been running into some difficulties, not least the format of the tokenising leaves 4 bytes for an offset from bottom of BASIC workspace, meaning a variable can't exist > 4GB above the base of memory. So, much as it pains me to do this, I'll be backing out the large memory model, reinstating the 2GB limit. Sadly, extending the memory availability causes more problems than it solves.

But, for your other points there's no reason why some other memory outside of the main workspace can't be accessed, since we're not using the offset memory model any more, if I were to patch in a call to malloc() the space allocated could then be peeked and poked from BASIC, as you can with the 4KB block made available on the Raspberry Pi for its GPIO access (/dev/gpiomem is mmap()ed). Currently, HIMEM can't be raised above its initial value, but that is something I could look into, perhaps using realloc().
Last edited by Soruk on Tue Dec 10, 2019 5:02 pm, edited 1 time in total.

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

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

Post by Richard Russell » Tue Dec 10, 2019 4:56 pm

Soruk wrote:
Tue Dec 10, 2019 4:15 pm
So, much as it pains me to do this, I'll be backing out the large memory model, reinstating the 2GB limit. Sadly, extending the memory availability causes more problems than it solves.
Sorry to hear that, but I'm not surprised. A potentially huge heap/stack would be more valuable if BBC BASIC had a sophisticated memory manager that allowed you to free allocations (other than using the existing DIM ... LOCAL mechanism). Since it doesn't, I resort to calling SYS "malloc" and SYS "free" when I want that capability, so it's actually more useful for BASIC not to reserve too much address space so that plenty is still available for such 'external' allocations.

When I adapted BBC BASIC for SDL 2.0 for 64-bit compatibility I retained many internal 32-bit pointers (becoming an offset from the bottom of BASIC's memory rather than an absolute address); notably string pointers are still only 32-bits, as are the internal values of PAGE, HIMEM etc. (they are exposed to the programmer as full 64-bit addresses but they aren't internally). Arrays and structures have 64-bit pointers however so it's possible to locate them outside the heap/stack in memory allocated using malloc.

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

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

Post by Soruk » Wed Dec 11, 2019 1:41 pm

Richard Russell wrote:
Tue Dec 10, 2019 4:56 pm
Soruk wrote:
Tue Dec 10, 2019 4:15 pm
So, much as it pains me to do this, I'll be backing out the large memory model, reinstating the 2GB limit. Sadly, extending the memory availability causes more problems than it solves.
Sorry to hear that, but I'm not surprised. A potentially huge heap/stack would be more valuable if BBC BASIC had a sophisticated memory manager that allowed you to free allocations (other than using the existing DIM ... LOCAL mechanism). Since it doesn't, I resort to calling SYS "malloc" and SYS "free" when I want that capability, so it's actually more useful for BASIC not to reserve too much address space so that plenty is still available for such 'external' allocations.

When I adapted BBC BASIC for SDL 2.0 for 64-bit compatibility I retained many internal 32-bit pointers (becoming an offset from the bottom of BASIC's memory rather than an absolute address); notably string pointers are still only 32-bits, as are the internal values of PAGE, HIMEM etc. (they are exposed to the programmer as full 64-bit addresses but they aren't internally). Arrays and structures have 64-bit pointers however so it's possible to locate them outside the heap/stack in memory allocated using malloc.
I've got the beginnings of dlopen / dlsym working, at least under Linux. I think there's some oddness about how MinGW's dlopen/dlsym work that it seems unable to resolve anything I try, though that's likely down to my complete lack of knowledge of Windows internals. However, I've also added direct calls to malloc (Brandy_MAlloc) and free (Brandy_Free) to allow arbitrary memory allocation without the dlopen/dlsym headaches.

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

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

Post by Richard Russell » Wed Dec 11, 2019 3:25 pm

Soruk wrote:
Wed Dec 11, 2019 1:41 pm
I think there's some oddness about how MinGW's dlopen/dlsym work that it seems unable to resolve anything I try
I don't know whether this might be the reason, but in Windows dlsym doesn't accept the RTLD_DEFAULT parameter, which is what BBCSDL uses and is invaluable for SYS because it searches all the available libraries. Therefore I have included this implementation of dlsym for Windows only; feel free to use it in Matrix Brandy if it is helpful:

Code: Select all

#if defined __WINDOWS__
void *dlsym (void *handle, const char *symbol)
{
	void *procaddr ;
	HMODULE modules[100] ;
	long unsigned int i, needed ;
	K32EnumProcessModules ((HANDLE)-1, modules, sizeof (modules), &needed) ;
	for (i = 0; i < needed / sizeof (HMODULE); i++)
	    {
		procaddr = GetProcAddress (modules[i], symbol) ;
		if (procaddr != NULL) break ;
	    }
	return procaddr ;
}
#endif
However, I've also added direct calls to malloc (Brandy_MAlloc) and free (Brandy_Free) to allow arbitrary memory allocation without the dlopen/dlsym headaches.
Great, they should be very useful. I'd like to see code examples of how they can be used (if it's easily possible) to implement REDIMmable arrays in Matrix Brandy. This is the code I use for this but it won't be compatible because of differences in internal array layout (1D version shown):

Code: Select all

      REM usage: PROCredim1d(array(), ^array(1)-^array(0), newsize%)
      DEF PROCredim1d(RETURN p%%,S%,D%)
      LOCAL a%%,N%
      IF ?p%%<>1 ERROR 14, "Bad use of array"
      N% = 5+S%*(D%+1)
      IF p%%<LOMEM OR p%%>HIMEM SYS "free", p%%
      SYS "malloc", N% TO a%%
      IF @platform% AND &40 ELSE a%%=!^a%%
      IF a%%=0 ERROR 11, "DIM space"
      SYS "memset", a%%, 0, N%
      ?a%%=1 : a%%!1=D%+1
      p%% = a%%
      ENDPROC

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

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

Post by Soruk » Wed Dec 11, 2019 4:38 pm

Richard Russell wrote:
Wed Dec 11, 2019 3:25 pm
Soruk wrote:
Wed Dec 11, 2019 1:41 pm
I think there's some oddness about how MinGW's dlopen/dlsym work that it seems unable to resolve anything I try
I don't know whether this might be the reason, but in Windows dlsym doesn't accept the RTLD_DEFAULT parameter, which is what BBCSDL uses and is invaluable for SYS because it searches all the available libraries. Therefore I have included this implementation of dlsym for Windows only; feel free to use it in Matrix Brandy if it is helpful:

Code: Select all

#if defined __WINDOWS__
void *dlsym (void *handle, const char *symbol)
{
	void *procaddr ;
	HMODULE modules[100] ;
	long unsigned int i, needed ;
	K32EnumProcessModules ((HANDLE)-1, modules, sizeof (modules), &needed) ;
	for (i = 0; i < needed / sizeof (HMODULE); i++)
	    {
		procaddr = GetProcAddress (modules[i], symbol) ;
		if (procaddr != NULL) break ;
	    }
	return procaddr ;
}
#endif
After a little massaging for the MinGW64 interface, this is now in - and it works (with a few symbols - exit, malloc and free worked anyway). Thank you!

I've run a rebuild of the nightly for today's date.

Edit: It would help if I explained the usage!

An example that works under Linux:

Code: Select all

SYS "Brandy_dlcall", "write", 1, "Testing"+CHR$10, 8
will print "Testing" with newline at the calling shell.

And, ones that work under both Windows and Linux:

Code: Select all

SYS "Brandy_dlcall", "malloc", <size> TO m%%
...
SYS "Brandy_dlcall", "free", m%%
though Brandy_MAlloc and Brandy_Free are also available.

The difference in the syntax to the BBCSDL format is that the calls are routed via the "Brandy_dlcall" SYS call, rather than claiming the top-level call identifier.

Post Reply