BBC Basic syntax question

discussion of beeb/electron applications, languages, utils and educational s/w
Post Reply
User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

BBC Basic syntax question

Post by hoglet » Mon Oct 31, 2016 10:51 am

Hi all,

Has the following syntax ever been legal in BBC Basic?

Code: Select all

FOR J%=0 TO 2
[OPT0
.pt(J%) FNgap(2)
.offset(J%) FNB
.xaddr(J%) FNB
]NEXT J%
where

Code: Select all

........ STANDARD MACROS ........
DEFFNB:P%=P%+1:=0
DEFFNgap(A%):P%=P%+A%:=0
I can't get this to compile on any version of BBC Basic for the Master, and I've tried:
- Basic 2
- Basic 4
- Basic 4.32
- Basic 5 (Advanced Basic)

The problem seems to be the that FN is expected to be in an expression, not standalone.

I can think of two possibilities:
- the author somehow hacked BBC Basic to allow FN to be used like this as an assembler macro.
- this is not actually BBC Basic source, but is in fact source for an assembler that used BBC Basic like syntax.

BTW, this is from a Game of Life implementation for the 6502 Co Pro, written circa 1988. The source files seems to be *SPOOLed text files, and start with AUTO.

Dave

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

Re: BBC Basic syntax question

Post by Rich Talbot-Watkins » Mon Oct 31, 2016 11:32 am

Only in BASIC V in the Archimedes. 6502 BBC BASIC needs

Code: Select all

OPT FNgap(2)
and for the function to return the current OPT value.

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

Re: BBC Basic syntax question

Post by BigEd » Mon Oct 31, 2016 11:39 am

I did try this with HiBasic 3, but as now expected, no dice. The author (who wishes to remain anonymous) has no recollection of hacking Basic, but that feels to me a plausible explanation. I've had a look: it turns out the assembler, when expecting an opcode, has to deal with 3 cases where the opcode is (partially) tokenised: AND, EOR and OR. My idea at present is to adjust the final branch, where all those have failed, JSR to the expression evaluator and then JMP back into the assembler's parser. If that's enough, it's six bytes, and I can steal those six bytes from the string "Mistake" which is nearby - near enough to branch to.

However, this sketch is not the same as actually getting it working!

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

Re: BBC Basic syntax question

Post by BigEd » Mon Oct 31, 2016 11:42 am

But the idea of using OPT is quite sound, and would be far easier. This code almost always uses OPT I%, and the functions presently return zero.

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

Re: BBC Basic syntax question

Post by BigEd » Mon Oct 31, 2016 12:57 pm

So here's a test program tweaked to use OPT, which seems to be doing the right thing:

Code: Select all

   10 DIM P% 1000
   20 DIM pt(2),offset(2),xaddr(2)
   30 FOR J%=0 TO 2
   40 [OPT0
   50 .pt(J%) OPT FNgap(2)
   60 .offset(J%) OPT FNB
   70 .xaddr(J%) OPT FNB
   80 ]NEXT J%
   90 DEFFNB:P%=P%+1:=I%
  100 DEFFNgap(x):P%=P%+x:=I%
>RUN
0EC6          .pt(J%)   OPT FNgap(2)
0EC7          .offset(J%) OPT FNB
0EC8          .xaddr(J%) OPT FNB
0ECA          .pt(J%)   OPT FNgap(2)
0ECB          .offset(J%) OPT FNB
0ECC          .xaddr(J%) OPT FNB
0ECE          .pt(J%)   OPT FNgap(2)
0ECF          .offset(J%) OPT FNB
0ED0          .xaddr(J%) OPT FNB
>P.pt(0),offset(0),xaddr(0)
      3780      3782      3783
>P.pt(1),offset(1),xaddr(1)
      3784      3786      3787
(In this case the OPT regime we're in happens not to be OPT I%, but no harm done. Is there a nifty way to get the current OPT value?)

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

Re: BBC Basic syntax question

Post by Rich Talbot-Watkins » Mon Oct 31, 2016 2:15 pm

BigEd wrote:Is there a nifty way to get the current OPT value?)
It seems to be stored in ?&28 in BASIC 4, not sure about other versions though I wouldn't expect it to have changed. Not sure if that counts as a nifty way, but I doubt there's any other way!

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

Re: BBC Basic syntax question

Post by jgharston » Mon Oct 31, 2016 8:31 pm

BigEd wrote:(In this case the OPT regime we're in happens not to be OPT I%, but no harm done. Is there a nifty way to get the current OPT value?)
Yes, it's there in your FOR/NEXT loop.
FOR opt%=0 TO 2
P%=...:O%=...
[OPT opt%
OPT FNfred
...
DEFFNfred:....:=opt%

See the FNif/FNendif functions in things like Client65.src and Basic2.zip.

Code: Select all

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

User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: BBC Basic syntax question

Post by hoglet » Tue Nov 01, 2016 9:01 pm

A second anomaly has turned up with this "Life-from-the-Grave" program Ed and I are trying to resurrect.

It seems to use offset assembly (i.e. bit 2 of OPT is set), and:
P%=&A000
O%=&FFFF2000

So this looks like it's trying to make use of memory on the host for the assembled program.

I didn't know this was possible, and it certainly doesn't work in Basic II, as a Bas Program soon results.

Is anyone aware of any version of BBC Basic that supports this?

Back in 1988 this was being done with a 6502 Co Pro, so it would have to have been a version that existed then, and that would run on the 6502 Co Pro.

Dave

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 1:01 am

hoglet wrote:It seems to use offset assembly (i.e. bit 2 of OPT is set), and:
P%=&A000
O%=&FFFF2000
So this looks like it's trying to make use of memory on the host for the assembled program.
I didn't know this was possible, and it certainly doesn't work in Basic II, as a Bas Program soon results.
Is anyone aware of any version of BBC Basic that supports this?
No, a language, any language only has access to and only uses the language memory. The assembler in 6502 BASIC only uses the bottom 16 bits of the assembly variables. It looks like your program was noting in the top 16 bits of O% the correct processor address to use when the code was saved - though it would normally be P% that would do that as P% is the Program address, not the address the Object code is stored in.

You normally would do something like:

load%=&FFFF0900:DIM mcode% &200
FOR opt%=4 TO 6 STEP 3
O%=mcode%:P%=load%
[OPT opt%
...etc...
]NEXT
OSCLI "SAVE file "+STR$~mcode%+" "+STR$~O%+" "+STR$~load%+" "+STR$~load%

so that the final OSCLI saves the assembled code from where it has been stored - mcode% to the last location O% has been left at - with load/exec addresses correctly specified for the correct processor. For example, the command may end up as:
SAVE file 168C 1824 FFFF0900 FFFF0900

Code: Select all

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

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

Re: BBC Basic syntax question

Post by BigEd » Wed Nov 02, 2016 6:58 am

Thanks JGH.

Although the author wishes to remain anonymous, there's no harm in sharing the original code. There are two Life programs, both found as text files to be EXECed - they are Basic, but without line numbers. Here's the larger of the two, which I happen to have to hand - see attached. I think this version may have converted line ends, so it can be viewed on a non-Beeb system, but might no longer be EXECable as-is.

Digging into this is a bit of a work in progress: we can share more as we proceed. Any assistance would be welcome!
Attachments
6HUNT.basic.spool.zip
(8.73 KiB) Downloaded 23 times

User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: BBC Basic syntax question

Post by hoglet » Wed Nov 02, 2016 7:28 am

jgharston wrote: You normally would do something like:

load%=&FFFF0900:DIM mcode% &200
FOR opt%=4 TO 6 STEP 3
O%=mcode%:P%=load%
[OPT opt%
...etc...
]NEXT
OSCLI "SAVE file "+STR$~mcode%+" "+STR$~O%+" "+STR$~load%+" "+STR$~load%

so that the final OSCLI saves the assembled code from where it has been stored - mcode% to the last location O% has been left at - with load/exec addresses correctly specified for the correct processor. For example, the command may end up as:
SAVE file 168C 1824 FFFF0900 FFFF0900
But our code is definitely trying to do the opposite:

Code: Select all

grid=&6000:gridlen=&4000
loc=grid+gridlen
code=&FFFF2000
FOR I%=4 TO 6 STEP2
O%=code:P%=loc
[OPT I%
.life
LDX#255:TXS
BITinitflg:BMI T11
....
INPUT"Filename: "A$
OSCLI("S."+A$+" "+STR$~code+" +"+STR$~(last-code)+" "+STR$~life+" "+STR$~loc)
In the case the command ends up as something like:
SAVE file FFFF2000 FFFF5824 A000 A000

Hence the mystery.

Dave

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 10:12 am

hoglet wrote:But our code is definitely trying to do the opposite:

Code: Select all

grid=&6000:gridlen=&4000
loc=grid+gridlen
code=&FFFF2000
(snippy)
OSCLI("S."+A$+" "+STR$~code+" +"+STR$~(last-code)+" "+STR$~life+" "+STR$~loc)
In the case the command ends up as something like:
SAVE file FFFF2000 FFFF5824 A000 A000
If that is run on a second processor the SAVE will completely ignore the assembled code and save a chunk of memory from the I/O processor instead. Looks like a thinko.

Code: Select all

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

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

Re: BBC Basic syntax question

Post by BigEd » Wed Nov 02, 2016 10:21 am

May not be a thinko. May be that our mysterious author has also patched Basic to write the object code back to the host. That would allow for larger source programs. (Although he does say he doesn't remember patching Basic.)

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 10:29 am

BigEd wrote:Digging into this is a bit of a work in progress: we can share more as we proceed. Any assistance would be welcome!
As the code is assembled from &300, and other "load to beeb side" and "send byte to beeb side" I presume this runs on the second processor. It uses the "call code in the I/O processor" method mentioned in another thread - point USERV to the code then call USERV with OSBYTE &88 (*CODE).

If the source is run on a copro it will definitely fail by saving the wrong memory. code% should definitly be &2000. Even better, it should be DIM code% an_appropriate_size otherwise if the program and/or variables creeps over &2000 then the assembly is going to stomp on top of them and the variables will stomp on the assembly. If you're going to use a fixed location for the output buffer it's best to do, eg code%=&2000:HIMEM=code% to prevent the variable heap creeping over the output buffer.

Code: Select all

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

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 11:21 am

Half an hour of editing has got it to assemble. The code%=&FFFF2000 and the FNxxx calls with no OPT definitely suggest it was originally written to be assembled with a special version of BASIC with extensions to the assembler.

Changed it to the standard DIM code size, OPT FNxxx and the DEFFNs return the OPT value, and tidied up some formatting to make it readable - edited with BB4W ;). You need a version of BASIC that assembles 65C12 code (STZ etc) and has at least 40K of memory - so HiBasic 4 or ARM BASIC+6502 assembler (link)
Attachments
LIFESRC.txt
(36.88 KiB) Downloaded 21 times

Code: Select all

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

User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: BBC Basic syntax question

Post by hoglet » Wed Nov 02, 2016 11:39 am

jgharston wrote:Half an hour of editing has got it to assemble. The code%=&FFFF2000 and the FNxxx calls with no OPT definitely suggest it was originally written to be assembled with a special version of BASIC with extensions to the assembler.
I'm very intrigued at the possibility there was a version of BBC Basic that we don't know about for the 6502 Co Pro.

It seems two extensions are required:
- ability to assemble directly to host memory by specifying O% of &FFFFxxxx
- ability to use FN as an assembler macro, without faffing about with OPT (or EQUS and ="")

Now, I'm convinced 100% this did assemble correctly back in April 1988, so there are two possibilities:
A - Ed's friend made the the above modifications to BBC Basic himself
B - Acorn released a version for the Co Pro that did this, but was not widely distributed, and no longer exists.

I'm leaning towards B, because there is evidence that at some point Acorn did later improve the assembler to allow direct use of FN:
ARM Assembly Language Programming - Chapter 4
Now, this is referring to ARM Basic V, but it's possible this construct was added to a late version of 65C02 Basic IV?

I guess we may never know.

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

Re: BBC Basic syntax question

Post by BigEd » Wed Nov 02, 2016 12:03 pm

Well done on the editing front, JGH!

One thing I'm struggling with - is there room in a copro for both the source and the object and hibasic? Indeed, if there were a trick for writing to the host memory instead, is there room in the copro for the object? I'm not sure there is. Edit: I think I got that wrong - the object is not so large!

I've started a new thread with the original data, so we can talk about that specific program. See here:
viewtopic.php?f=2&t=12074
Last edited by BigEd on Wed Nov 02, 2016 12:48 pm, edited 1 time in total.

User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: BBC Basic syntax question

Post by hoglet » Wed Nov 02, 2016 12:41 pm

Rich Talbot-Watkins wrote:Only in BASIC V in the Archimedes. 6502 BBC BASIC needs

Code: Select all

OPT FNgap(2)
and for the function to return the current OPT value.
A simpler way to do macros might be to use EQUS FN_somemacro, and have the macro DEF FN_somemacro end with =""

This avoids disrupting the current OPT value.

Dave

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 3:22 pm

BigEd wrote:One thing I'm struggling with - is there room in a copro for both the source and the object and hibasic? Indeed, if there were a trick for writing to the host memory instead, is there room in the copro for the object? I'm not sure there is. Edit: I think I got that wrong - the object is not so large!
Yes, plenty of space, VARTOP ends up at about &AD00, leaving about 3K free below HIMEM at &B800.
hoglet wrote:I'm very intrigued at the possibility there was a version of BBC Basic that we don't know about for the 6502 Co Pro.
(....)
I wonder if BASIC 65C02 is it? It's a 6502 BASIC (ie, for the BBC) with the assembler extended to assemble 65C02 opcodes (eg, STZ, etc.) I haven't got around to disassembling it to work out what differences it has.

Or it might have been 6502 BASIC V (Advanced BASIC). This ran on the 6502 second processor with many ARM BASIC V features, I'd have to dig out the manual to see what assembler extensions it had.

Code: Select all

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

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

Re: BBC Basic syntax question

Post by BigEd » Wed Nov 02, 2016 3:29 pm

It seems that O% cannot, in official known Basics, refer to host memory. But I wondered what it would take to change that, as a patch, so I added some comments to JGH's Basic 4 disassembly. We need to do an OSWORD 6, so would need to find a place to cram in some new code and call it.

Code: Select all

\ Tokenised opcode found
\ ----------------------
.L8A53
LDA L88FF-&29,X
STA &29
LDY #&01
CPX #&20:BCS L8AA6
.L8A5E
LDA &0440   \ preload P% as the destination
STA &37
STY &39     \ Y is the number of bytes to write
LDX &28     \ check the OPT value
CPX #&04:LDX &0441
STX &38
BCC L8A76   \ branch around the loading of O%
LDA &043C
LDX &043D
.L8A76
STA &3A     \ store the target address at 3A, 3B
STX &3B
TYA
BEQ L8AA5   \ bale if Y is zero
BPL L8A83   \ some trick if Y was negative
LDY &36
BEQ L8AA5   \ and bale 
.L8A83
DEY         \ Y was a counter and is now an index
LDA &0029,Y \ presumably 0029 is a buffer of bytes
BIT &39
BPL L8A8E
LDA &0600,Y \ and 600 is an alternate buffer
.L8A8E
STA (&3A),Y \ perform the store!
INC &0440   \ and increment P%
BNE L8A98
INC &0441
.L8A98
BCC L8AA2   \ check the OPT mode again
INC &043C   \ increment O%
BNE L8AA2
INC &043D
.L8AA2
TYA
BNE L8A83
.L8AA5
RTS

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 3:35 pm

Yes, it's 6502 BASIC V/Advanced BASIC. From the documentation:
OPT
---
Values of OPT outside the range 0-7 may be used, in order to assemble code
directly to the I/O processor, to sideways RAM, or to a file. Below is a
summary of output destinations:

0 - 3 to P% in 2nd processor
4 - 7 to O% in 2nd processor
8 - 11 to OPENout file
12 - 15 to OPENup file, PTR# = O%
16 - 19 to P% in I/O processor
20 - 23 to O% in I/O processor
24 - 27 to P% in sideways RAM
28 - 31 to O% in sideways RAM
32 - 63 no code generated
The documentation doesn't mention FN without OPT explicity, but that's a standard BASIC V feature.

Code: Select all

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

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

Re: BBC Basic syntax question

Post by BigEd » Wed Nov 02, 2016 3:43 pm

Interesting - Basic V is dated 1987 and the source in question is from 1988, so that's not impossible. Just one little thing, we don't seem to be using large values of OPT:

Code: Select all

FOR I%=4 TO 6 STEP2

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

Re: BBC Basic syntax question

Post by jgharston » Wed Nov 02, 2016 3:50 pm

BigEd wrote:Interesting - Basic V is dated 1987 and the source in question is from 1988, so that's not impossible. Just one little thing, we don't seem to be using large values of OPT:

Code: Select all

FOR I%=4 TO 6 STEP2
Maybe "4 - 7 to O% in 2nd processor" means "as long as O%<>&FFxxxxxx, and I/O if O%=&FFxxxxxx", as per similar phrasing for the CALL command.

Code: Select all

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

User avatar
hoglet
Posts: 8192
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: BBC Basic syntax question

Post by hoglet » Wed Nov 02, 2016 5:04 pm

jgharston wrote:
BigEd wrote:Interesting - Basic V is dated 1987 and the source in question is from 1988, so that's not impossible. Just one little thing, we don't seem to be using large values of OPT:

Code: Select all

FOR I%=4 TO 6 STEP2
Maybe "4 - 7 to O% in 2nd processor" means "as long as O%<>&FFxxxxxx, and I/O if O%=&FFxxxxxx", as per similar phrasing for the CALL command.
Just tried Advanced Basic 1.02:
ab102.png
And that doesn't have the above behaviour with OPT 4-7, not does it support FN macros directly.

Dave

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

Re: BBC Basic syntax question

Post by BigEd » Thu Nov 03, 2016 3:09 pm

Aha - another backup disk from my friend, and we see the beginnings of an answer. A Basic program from 1986, by Martin Chaplin, which supplements HiBasic3 with 65C02 instructions:

Code: Select all

   10REM HIBASIC extended assembler
   20REM by Martin Chaplin
   30REM BBC B/B+ with 6502SP
   40REM (c) Acorn User March 1986
And then, a second copy, modified to allow macros - aka FN calls where mnemonics are expected:

Code: Select all

   46REM Modified by <anon> September 1986
   47REM Now includes a macro facility
This is relatively invasive, lowering HIMEM to make space and patching the HiBasic3 in place. See attached!

Dave (hoglet) informs us that with this in place, the original code will assemble, once O% is put back to normal. So, we still need the O% functionality, but we have proof that a patched HiBasic is in scope - and this work here is a couple of years before the program which uses the O% trick to place the binary in host memory.
Attachments
Macro86.zip
(22.77 KiB) Downloaded 20 times

Post Reply