Why was BBC BASIC so fast?

bbc/electron apps, languages, utils, educational progs, demos + more
User avatar
BigEd
Posts: 3721
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Why was BBC BASIC so fast?

Post by BigEd » Sun Oct 25, 2020 12:24 pm

Yikes for MS Basic on the Beeb and double-yikes for finding it's a tad faster.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Sun Oct 25, 2020 12:45 pm

BigEd wrote:
Sun Oct 25, 2020 12:24 pm
Yikes for MS Basic on the Beeb and double-yikes for finding it's a tad faster.
Here's another comparison - vanilla MBASIC, i.e. Microsoft BASIC for generic CP/M on the Z80 2nd processor:
ss6.png
ss7.png
43.28s vs Richard Russell's Z80 BBC BASIC:
ss8.png
ss9.png
32.68s. These results are not directly comparable with the 6502 ones, though, as the Z80 is running at 6Mhz.

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

Re: Why was BBC BASIC so fast?

Post by BigEd » Sun Oct 25, 2020 1:12 pm

There is of course more than one way for BBC Basic to be fast: maybe it's faster with single-letter variable names? Maybe FOR would have been faster than REPEAT? Maybe it's fair game to use integer variables where applicable?

But overall it wouldn't be too surprising if the biggest advantage of the Beeb is a 2MHz 6502 when the obvious competition is at 1MHz. It's hard to get a factor of two out of small software optimisations, and as we've noted, extreme space-time tradeoffs aren't really applicable here.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Sun Oct 25, 2020 2:02 pm

BigEd wrote:
Sun Oct 25, 2020 1:12 pm
There is of course more than one way for BBC Basic to be fast: maybe it's faster with single-letter variable names? Maybe FOR would have been faster than REPEAT? Maybe it's fair game to use integer variables where applicable?
I think Richard's BASIC may have gained speed by his use of variants as previously described. Here's my version optimised for BBC BASIC:
ssa.png
This works in 16.92s

Kweepa
Posts: 31
Joined: Mon Dec 16, 2013 11:45 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Kweepa » Sun Oct 25, 2020 3:25 pm

MS BASIC on the Beeb. Seems like sacrilege! Nice work!
(Did you compile it with 32- or 40-bit floats?)

User avatar
lurkio
Posts: 3139
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Why was BBC BASIC so fast?

Post by lurkio » Sun Oct 25, 2020 4:34 pm

Coeus wrote:
Sun Oct 25, 2020 12:12 pm
just for interest I did a quick and dirty port of MS BASIC to the BBC
:shock: =D> =D> =D> Brilliant and intriguing!

Given that this isn't something that everyone is capable of doing, I wonder if you'd be interested in creating a full port of MS BASIC for the Beeb, or in making your current prototype available for those who can to play around with..?

:?:

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Sun Oct 25, 2020 6:23 pm

lurkio wrote:
Sun Oct 25, 2020 4:34 pm
Given that this isn't something that everyone is capable of doing, I wonder if you'd be interested in creating a full port of MS BASIC for the Beeb, or in making your current prototype available for those who can to play around with..?
Here's what I did: https://github.com/SteveFosdick/msbasic - that's a fork of the repository BigEd posted earlier.

Adding file I/O both as in LOAD and SAVE and OPEN,PRINT#,INPUT# would probably be straight forward as would trapping BRKV, reporting the error and going to the warm start point.

What may not be straightforward is to enable it to deal with both ends of the available memory varying and therefore having to query OSHWM and HIMEM - making the calls is easy enough it's working out how to make sure it then respects the limits thus obtained.

SteveF
Posts: 811
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by SteveF » Mon Oct 26, 2020 12:12 am

The idea of a Microsoft BASIC port is absolutely intriguing, even the existence of this quick and dirty port is very cool - thanks for doing it! I don't know why, but it is... The idea you could have a model B booting to a variant of the classic "BBC Computer 32K/Acorn DFS/BASIC" screen declaring *Microsoft BASIC* as the language tickles me.
Coeus wrote:
Sun Oct 25, 2020 6:23 pm
What may not be straightforward is to enable it to deal with both ends of the available memory varying and therefore having to query OSHWM and HIMEM - making the calls is easy enough it's working out how to make sure it then respects the limits thus obtained.
While I agree that ideally a not-so-quick-and-dirty port would want to deal with this properly, one possible angle of attack would be to create a HI-MSBASIC for the 6502 second processor first - that way the available memory would always be the same regardless of ROM memory use and screen memory.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 12:23 am

SteveF wrote:
Mon Oct 26, 2020 12:12 am
While I agree that ideally a not-so-quick-and-dirty port would want to deal with this properly, one possible angle of attack would be to create a HI-MSBASIC for the 6502 second processor first - that way the available memory would always be the same regardless of ROM memory use and screen memory.
In the meantime I examined it more closely and despite the beginning of RAM being a compile-time option it then stores it in a variable in zero page so I have managed to make it dynamic - it queries OSHWM and HIMEM rather than starting from a fixed value and testing for the end of RAM. I have also added LOAD/SAVE though they are not that well tested. These changes are in the GitHub above.

I should add it assemble to a language ROM.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 12:28 am

And for anyone without ca65/ld65 here is a pre-assembled ROM.
Attachments
msbasic.zip
(7.21 KiB) Downloaded 15 times

User avatar
jgharston
Posts: 4242
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Why was BBC BASIC so fast?

Post by jgharston » Mon Oct 26, 2020 12:35 am

To add to all this, I wrote the appropriate I/O wrapper for EhBasic.

Code: Select all

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

User avatar
jgharston
Posts: 4242
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Why was BBC BASIC so fast?

Post by jgharston » Mon Oct 26, 2020 12:43 am

Code: Select all

        .byte   1       ; binary version number.
        .byte   "Microsoft BASIC",$00
copyw:  .byte   $00,"(C) Microsoft",$00
msbas:  .byte   "MSBASIC",$00
You've got too many zero bytes there, so inserting a zero-length version string. It should be:

Code: Select all

        .byte   1       ; binary version number.
        .byte   "Microsoft BASIC"
copyw:  .byte   $00,"(C) Microsoft",$00
msbas:  .byte   "MSBASIC",$00

Code: Select all

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

julie_m
Posts: 276
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Why was BBC BASIC so fast?

Post by julie_m » Mon Oct 26, 2020 2:35 am

BigEd wrote:
Sun Oct 25, 2020 1:12 pm
There is of course more than one way for BBC Basic to be fast: maybe it's faster with single-letter variable names? Maybe FOR would have been faster than REPEAT? Maybe it's fair game to use integer variables where applicable?
BBC BASIC is fastest of all with the permanent variables A%-Z%, then with short names, then as few variables as possible beginning with each letter. This is due to the way variables are stored in memory, indexed directly by initial letter and then the rest of the name searched linearly in assignment order.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 12:35 pm

jgharston wrote:
Mon Oct 26, 2020 12:35 am
To add to all this, I wrote the appropriate I/O wrapper for EhBasic.
I had never heard of that but it looks interesting. Do we know what happenned to Lee? I did find a PDF manual here: http://www.sunrise-ev.com/photos/6502/E ... manual.pdf

Several people have checked it into GitHub: https://github.com/jefftranter/6502/tre ... sm/ehbasic, Even Klaus Dormann, of the 6502 functional tests: https://github.com/Klaus2m5/6502_EhBASIC_V2.22 and it's on 6502.org: http://www.6502.org/source/monitors/ehb ... basic.html

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

Re: Why was BBC BASIC so fast?

Post by BigEd » Mon Oct 26, 2020 12:40 pm

Coeus wrote:
Mon Oct 26, 2020 12:35 pm
Do we know what happenned to Lee?
We do - Lee died in 2013, "peacefully in his sleep" but at the age of only 49.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 12:46 pm

jgharston wrote:
Mon Oct 26, 2020 12:43 am
You've got too many zero bytes there, so inserting a zero-length version string...
Now fixed and in GitHub.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 4:50 pm

jgharston wrote:
Mon Oct 26, 2020 12:35 am
To add to all this, I wrote the appropriate I/O wrapper for EhBasic.
And it looks like there may be a bug. I loaded the pre-assembled bin flle into the 2nd processor:
ehbss1.png
paste in the trial division test program:
ehbss2.png
and run it:
ehbss3.png

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 4:56 pm

And reducing the test program to a simple test still provokes it:
Attachments
ehbss4.png

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 5:56 pm

So in the source as part of the code for creating an array, we have:

Code: Select all

00CF62  2               LAB_1EC0
00CF62  2  A2 0B                LDX     #$0B            ; set default dimension value low byte
00CF64  2  A9 00                LDA     #$00            ; set default dimension value high byte
00CF66  2  24 17                BIT     Defdim          ; test default DIM flag
00CF68  2  50 07                BVC     LAB_1ED0        ; branch if b6 of Defdim is clear
00CF6A  2               
00CF6A  2  68                   PLA                     ; else pull dimension value low byte
00CF6B  2  69 01                ADC     #$01            ; +1 (allow for zeroeth element)
00CF6D  2  AA                   TAX                     ; copy low byte to X
00CF6E  2  68                   PLA                     ; pull dimension value high byte
00CF6F  2  69 00                ADC     #$00            ; add carry from low byte
00CF71  2               LAB_1ED0
00CF71  2  C8                   INY                     ; index to dimension value high byte
00CF72  2  91 63                STA     (Astrtl),Y      ; save dimension value high byte
00CF74  2  C8                   INY                     ; index to dimension value high byte
00CF75  2  8A                   TXA                     ; get dimension value low byte
00CF76  2  91 63                STA     (Astrtl),Y      ; save dimension value low byte
00CF78  2  20 18 D0             JSR     LAB_1F7C        ; does XY = (Astrtl),Y * (Asptl)
00CF7B  2  86 73                STX     Asptl           ; save array data size low byte
00CF7D  2  85 74                STA     Aspth           ; save array data size high byte
00CF7F  2  A4 2A                LDY     ut1_pl          ; restore index (saved by subroutine)
00CF81  2  C6 16                DEC     Dimcnt          ; decrement dimensions count
00CF83  2  D0 DD                BNE     LAB_1EC0        ; loop while not = 0
when executing this with the one-line test above:

Code: Select all

CF62: A2 0B       LDX #0B     >s
CF64: A9 00       LDA #00     >s
CF66: 24 17       BIT 17      >s
CF68: 50 07       BVC CF71    >s
CF6A: 68          PLA         >s
CF6B: 69 01       ADC #01     >s
CF6D: AA          TAX         >s
CF6E: 68          PLA         >r
CF6F: 69 00       ADC #00     >r
CF71: C8          INY         >s
CF72: 91 63       STA (63),Y  >r
CF74: C8          INY         >s
CF75: 8A          TXA         >s
CF76: 91 63       STA (63),Y  >s
CF78: 20 18 D0    JSR D018    >n
CF7B: 86 73       STX 73      >s
CF7D: 85 74       STA 74      >s
CF7F: A4 2A       LDY 2A      >s
CF81: C6 16       DEC 16      >s
CF83: D0 DD       BNE CF62    >s
this has incorrectly looped back to consider a 2nd dimension when the array has only one dimension. Checking $16 the value is now FF so was zero before it was decremented. Maybe the BNE should be a BPL or maybe the value of Dimcnt has been corrupted.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 6:08 pm

It looks like the bug is here:

Code: Select all

00CEEA  2  C8                   INY                     ; increment dimensions count
00CEEB  2  20 98 E0             JSR     LAB_GBYT        ; scan memory
00CEEE  2  C9 2C                CMP     #','            ; compare with ","
00CEF0  2  F0 D2                BEQ     LAB_1E1F        ; if found go do next dimension
00CEF2  2               
00CEF2  2  84 16                STY     Dimcnt          ; store dimensions count
The function LAB_GBYT clobbers Y:

Code: Select all

    E098: A0 00       LDY #00     
    E09A: B1 75       LDA (75),Y  
    E09C: C9 AC       CMP #AC     
...

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 6:47 pm

And another case where Y needs to be preserved but would be clobbered, part of IF handling:

Code: Select all

	LDX	Bpntrl		; save the basic pointer low byte
	LDY	Bpntrh		; save the basic pointer high byte
	JSR	LAB_IGBY	; increment and scan memory
	BCS	LAB_16FC	; if not numeric go do syntax error

	STX	Bpntrl		; restore the basic pointer low byte
	STY	Bpntrh		; restore the basic pointer high byte
LAB_IGBY is an earlier entry into the same subroutine that clobbers Y.

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

Re: Why was BBC BASIC so fast?

Post by BigEd » Mon Oct 26, 2020 7:04 pm

In discussions on the 6502 forum, it started seeming pretty likely that EhBASIC is built on a base of MSBASIC - you might be able to see that in the code. But I hadn't understood it to be unable to DIM a one-dimensional array.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Mon Oct 26, 2020 7:31 pm

BigEd wrote:
Mon Oct 26, 2020 7:04 pm
In discussions on the 6502 forum, it started seeming pretty likely that EhBASIC is built on a base of MSBASIC - you might be able to see that in the code. But I hadn't understood it to be unable to DIM a one-dimensional array.
If it is that would explain something. In the source there are labels of the form LAB_174B which are typical of those generated by a tracing disassembler and untypical of the type people come up with. So that does very strongly suggest that this version of the source started with the disassembly of something.

And I assume that 8K MS BASIC was the defacto standard against which this counts as an enhanced BASIC.

The cause of this particular bug, though is that the source from Lee assumes it has almost all of zero page and includes a small, self-modifying subroutine to fetch and classify the next byte from the BASIC program text. Someone, possibly JGH, has adapted it by adding conditional assembly whereby this subroutine is no longer in zero page and is also no longer self-modifying, presumably because it may run from ROM, thus it has to use indirect addressing. The rest of the interpreter uses X as an index register much more than Y so the new version uses LDA (xx),Y having previously set Y to zero but is seems there are a couple of places where Y needs to be preserved. It may be worth re-working those two cases rather than make GETBYT save Y as I can't see a way to do that without making it a bit long and it will be called for each byte of the program.

User avatar
jgharston
Posts: 4242
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Why was BBC BASIC so fast?

Post by jgharston » Mon Oct 26, 2020 10:52 pm

Fixed.

While you were digging into it I also tracked down the bug. DIM holds a count in Y when it calls GETBYTE (get next character from program), and GETBYTE does LDY #0:LDA (lptr),Y so corrupting Y. (The original code uses self-modifying code copied into low RAM.) From scanning the code it looks like DIM is the only code that calls GETBYTE expecting Y to be preserved, but in the interim I've made GETBYTE preserve Y instead.

My to-do list includes merging the dozen or so bugfixes in the v2.22patch5 update, so I'll pass the DIM/GETBYTE update back to the main branch when I do that.

Edit: I see Y also needs preserving in IF. That makes it a nicer fix, just those two call points instead of slowing down the GETBYTE call for every single byte fetched. I've already worked out the DIM fix, which looks like it also saves two bytes.

Code: Select all

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

User avatar
jgharston
Posts: 4242
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Why was BBC BASIC so fast?

Post by jgharston » Mon Oct 26, 2020 11:00 pm

Coeus wrote:
Mon Oct 26, 2020 7:31 pm
If it is that would explain something. In the source there are labels of the form LAB_174B which are typical of those generated by a tracing disassembler and untypical of the type people come up with. So that does very strongly suggest that this version of the source started with the disassembly of something.
There was a discussion somewhere about how the source was build from a disassembly, I think Lee Davison started with some code where the source had been lost and built on that. My MkSrc proggies do the same sort of thing, you'll see a lot of my disassemblies and recreated sources use labels of the form Lxxxx.

MkSrc has also been useful a couple of times when I've foolishly overwritten my source code. Source code "KBD" saves object code "KBD", OOPS!

Code: Select all

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

julie_m
Posts: 276
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Why was BBC BASIC so fast?

Post by julie_m » Tue Oct 27, 2020 7:33 am

jgharston wrote:
Mon Oct 26, 2020 11:00 pm
MkSrc has also been useful a couple of times when I've foolishly overwritten my source code. Source code "KBD" saves object code "KBD", OOPS!
Ouch! I feel your pain.

If Dave Cutler had brought transparent file versioning -- surely the real killer feature of VAX/VMS -- over to Windows NT, it would have solved a lot of problems in one go.

User avatar
Lardo Boffin
Posts: 2288
Joined: Thu Aug 06, 2015 7:47 am
Contact:

Re: Why was BBC BASIC so fast?

Post by Lardo Boffin » Tue Oct 27, 2020 9:37 am

I ran the speed test on my Tatung Einstein TC01 using Z80 BBC BASIC:

03D12601-6FD6-40A0-AFDC-7134EDF18A71.jpeg
Adventure Language on GitHub
Atom, issue 5
Elk
A number of econetted (is that a word?) Beebs
BBC Master, Datacentre + HDD, pi co-proc, econet, NULA

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Tue Oct 27, 2020 11:04 am

jgharston wrote:
Mon Oct 26, 2020 10:52 pm
Fixed.
The primes program gets a little further but there is still a bug:
syntax.png
Edit: Oops, wrong version of BASIC!
Last edited by Coeus on Tue Oct 27, 2020 11:37 am, edited 1 time in total.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Tue Oct 27, 2020 11:12 am

julie_m wrote:
Mon Oct 26, 2020 2:35 am
BigEd wrote:
Sun Oct 25, 2020 1:12 pm
There is of course more than one way for BBC Basic to be fast: maybe it's faster with single-letter variable names? Maybe FOR would have been faster than REPEAT? Maybe it's fair game to use integer variables where applicable?
BBC BASIC is fastest of all with the permanent variables A%-Z%, then with short names, then as few variables as possible beginning with each letter. This is due to the way variables are stored in memory, indexed directly by initial letter and then the rest of the name searched linearly in assignment order.
Indeed, though it is interesting to find other BASICs and other machines but the general conclusion here seems to be that if you run a program that has not been written specifically for BBC BASIC it still likely to run faster than on many home computers of the time because the machine is fast. If you optimise it for BBC BASIC you may get a further speed improvement. Putting numbers to that, with this one example, the primes program would have been at least twice as fast in its non-optimised form on a BBC micro than on the machines with 1Mhz 6502s. Optimising it for BBC BASIC using exactly the things your describe makes a further 3x improvement making it 6x faster overall.

Coeus
Posts: 1944
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Why was BBC BASIC so fast?

Post by Coeus » Tue Oct 27, 2020 11:41 am

jgharston wrote:
Mon Oct 26, 2020 10:52 pm
Fixed.
I can't see any difference and the files on that page, both ZIP and BIN, seem to be the same as before.

Post Reply

Return to “8-bit acorn software: other”