BASIC weirdness

discussion of beeb/electron applications, languages, utils and educational s/w
Post Reply
rharper
Posts: 353
Joined: Sat Sep 01, 2012 5:19 pm
Location: Dunstable
Contact:

BASIC weirdness

Post by rharper » Wed Feb 07, 2018 3:05 pm

I have some code that contains the line:
1340DEFPROCpfn:PROCgfn:PROCinv(H%,V%):ENDPROC
This runs OK on a MASTER under ADFS 1.53
On an Electron with a Plus3 it fails. After BREAK, OLD, Line 1340 reads
1340DEFPROCpfn:PROCgfnv(H%,V%):ENDPROC
So 7 characters are lost!
This line of code runs once, then fails when it is run again.
Reload the file and it reads OK.
The code gets the next name into memory from the list stored in a file (some assembler), moves to the next location on the screen, prints it in inverse video (black on white).
STOP the program just before it fails when PROCpfn is run a second time and the underlying PROCs run OK.
I can't imagine anything that shrinks a line of code just on an Electron!
Any suggestions?
Ray
Raycomp

User avatar
jms2
Posts: 2021
Joined: Mon Jan 08, 2007 6:38 am
Location: Derby, UK
Contact:

Re: BASIC weirdness

Post by jms2 » Wed Feb 07, 2018 3:10 pm

What value was PAGE at on the Electron? If it was &1D00, can you try the same on the Master to see if that causes the fault to recur?

User avatar
Rich Talbot-Watkins
Posts: 1340
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: BASIC weirdness

Post by Rich Talbot-Watkins » Wed Feb 07, 2018 3:16 pm

It looks like the BASIC 2 bug where the PROC definition takes a parameter of type ?-operator. Check the definition of PROCinv - if it's something like DEF PROCinv(?&70, ?&71), that'll be what it is. I think it's overwriting some of the BASIC program with a bunch of zeroes which are invisible when printed.

rharper
Posts: 353
Joined: Sat Sep 01, 2012 5:19 pm
Location: Dunstable
Contact:

Re: BASIC weirdness

Post by rharper » Wed Feb 07, 2018 5:01 pm

Rich Talbot-Watkins wrote:It looks like the BASIC 2 bug where the PROC definition takes a parameter of type ?-operator. Check the definition of PROCinv - if it's something like DEF PROCinv(?&70, ?&71), that'll be what it is. I think it's overwriting some of the BASIC program with a bunch of zeroes which are invisible when printed.
Yes, I noticed the PROCinv was of that nature and remembered I had problems on the Electron before when doing that.
I changed the DEFPROCinv(?xx,?yy) to DEFPROC(val1%,val2%):?xx=val1% etc.
Then it hung on the Master!
I have checked the RAM on the Electron - OK.
jms2 - Yes, I have set the Master to &1D00.
Ray
Raycomp

rharper
Posts: 353
Joined: Sat Sep 01, 2012 5:19 pm
Location: Dunstable
Contact:

Re: BASIC weirdness

Post by rharper » Wed Feb 07, 2018 5:15 pm

I have changed PROCinv so that it's all done in BASIC.
Now it is OK on the Electron & Master.
Thanks,
Ray
Raycomp

User avatar
Rich Talbot-Watkins
Posts: 1340
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: BASIC weirdness

Post by Rich Talbot-Watkins » Wed Feb 07, 2018 5:18 pm

You would need to preserve the value of ?xx and ?yy within the PROCinv call to completely match the previous behaviour.

So

DEFPROCinv(v1%,v2%)
LOCALoxx%,oyy%
oxx%=?xx:oyy%=?yy
?xx=v1%:?yy=v2%
....
?xx=oxx%:?yy=oyy%
ENDPROC

Anyway it sounds like you have a solution, so that's great!

User avatar
jgharston
Posts: 3184
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: BASIC weirdness

Post by jgharston » Wed Feb 07, 2018 8:51 pm

I tripped over a similar gotcha when testing some code on BBC BASIC for Windows, which allows 65535-character strings. A subroutine was something like: DEFPROCfred($address), and the program kept falling over running out of memory, and in digging away suddenly realised that there was no <cr> anywhere near to $address, so it was trying to stack a 64K string to localise $address before setting it to the passed data. On Acorn/Wilson BASIC it would find no <cr> within 255 bytes and just stack a null string, Windows BASIC kept going for 65535 bytes, and would often eventually find a <cr> somewhere and try and stack a 40K/50K/60K string after I'd reduced the workspace to a couple of K. !

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

Coeus
Posts: 965
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: BASIC weirdness

Post by Coeus » Wed Feb 07, 2018 10:04 pm

jgharston wrote:I tripped over a similar gotcha when testing some code on BBC BASIC for Windows, which allows 65535-character strings. A subroutine was something like: DEFPROCfred($address), and the program kept falling over running out of memory, and in digging away suddenly realised that there was no <cr> anywhere near to $address, so it was trying to stack a 64K string to localise $address before setting it to the passed data. On Acorn/Wilson BASIC it would find no <cr> within 255 bytes and just stack a null string, Windows BASIC kept going for 65535 bytes, and would often eventually find a <cr> somewhere and try and stack a 40K/50K/60K string after I'd reduced the workspace to a couple of K. !
That rather reminds me of C on MS-DOS when you would find a Unix program that did something like this:

Code: Select all

void read_config(const char *filename) {
    char path[2048];
    FILE *fp;

    sprintf(path, "%s/%s", BASE_DIR, filename);
    fp = fopen(path, "r");
....
}
and you'd have to convert it to:

Code: Select all

void read_config(const char *filename) {
    char *path;
    FILE *fp;

    path = malloc(2048);
    sprintf(path, "%s/%s", BASE_DIR, filename);
    fp = fopen(path, "r");
....
    free(path);
}
(with error handling omitted for brevity). The lifetime of the buffer in which the pathname is assembled is naturally that of the function concerned, which being on the stack naturally does, but on DOS would run out of stack space.

crj
Posts: 834
Joined: Thu May 02, 2013 4:58 pm
Contact:

Re: BASIC weirdness

Post by crj » Thu Feb 08, 2018 1:46 am

Slightly beside the point, but that's still asking for trouble unless you can be certain the filename is short enough to fit in 2048 bytes with BASE_DIR prepended. If your system offers it, asprintf is your friend; if not, at the very least use snprintf and check for overflow!

(Meanwhile, if BASE_DIR is a macro, and known not to contain % characters, you can get a performance improvement by using BASEDIR"/%s" as your format string. Or, if you really care about performance, get the strlen of filename, allocate space just large enough then do a couple of memcpys. Conversely, if performance isn't that critical, just use C++ instead which makes it trivial to get string manipulation right. For preference, use the Boost path library, which makes it even more trivial to get path manipulation right.)

Coeus
Posts: 965
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: BASIC weirdness

Post by Coeus » Thu Feb 08, 2018 11:29 am

crj wrote:Slightly beside the point, but that's still asking for trouble...
Yes, the example is not good production code but was just the first thing I thought of to demonstrate the point. One would not normally have a fixed value (2048) in there either but I put it there to give an idea of the size. One would also check the return value of malloc etc. Some good points, though.

Post Reply