Page 6 of 20

Re: Introduction to BBC BASIC

Posted: Mon May 20, 2019 8:50 pm
by Heater
Cool.

I stopped at unsigned add, sub, mul with my C++ version as well. Just enough to get the fibo done. No point in doing more when GMP is available.

Re: Introduction to BBC BASIC

Posted: Mon May 20, 2019 9:36 pm
by ScriptBasic
Sorry to hear that Richard. My approach with GMP is a secondary extension module. ALL extensions are optional with ScriptBasic. In reality only scriba is needed to run code.

Maybe your time would be better spent creating an extension module API?

Re: Introduction to BBC BASIC

Posted: Tue May 21, 2019 6:57 am
by RichardRussell
ScriptBasic wrote:
Mon May 20, 2019 9:36 pm
Maybe your time would be better spent creating an extension module API?
There's no need. As I said, there's no technical problem in creating a BBC BASIC for SDL 2.0 library based on GMP - it's no different in principle from the existing BigInt library for BBC BASIC for Windows (which happens to be based on MAPM). It doesn't require any 'extension' to BBC BASIC itself, just the existing INSTALL statement.

The attractions of a library coded in 100% BBC BASIC are as a demonstrator of what can be achieved - and what I've got so far runs very nicely for more typical applications than a million-digit Fibonacci number! - and to avoid the need to package or link to GMP in the cross-platform distributions.

Re: Introduction to BBC BASIC

Posted: Tue May 21, 2019 7:25 am
by jahboater
RichardRussell wrote:
Tue May 21, 2019 6:57 am
The attractions of a library coded in 100% BBC BASIC are as a demonstrator of what can be achieved - and what I've got so far runs very nicely for more typical applications than a million-digit Fibonacci number! - and to avoid the need to package or link to GMP in the cross-platform distributions.
Impressive! Reducing the number of dependencies is good, I wish more software did that.

But GMP and MPFR offer a lot more than basic arithmetic.

MPFR offers arbitrary precision floating point (with IEEE semantics) and a large collection of well documented math library functions.
https://www.mpfr.org/mpfr-current/mpfr. ... -Interface
https://www.mpfr.org/mpfr-current/mpfr. ... -Functions
That would be quite a bonus for BBC BASIC to offer, I doubt any other version of BASIC can do anything close.

And for example GMP has a Fibonacci function, that I suspect is much much faster and smaller than one created using individual arithmetic functions, and of course easier for the user.

There is also MPC for complex numbers.

:) Long long ago I was using a Sinclair ZX80 (BASIC) which didn't have floating-point. For fun, I tried to implement some limited floating-point math on it, but found that it took the entire memory of the machine just to implement simple addition :)

Re: Introduction to BBC BASIC

Posted: Tue May 21, 2019 8:49 am
by RichardRussell
jahboater wrote:
Tue May 21, 2019 7:25 am
But GMP and MPFR offer a lot more than basic arithmetic.
Indeed, as does MAPM (which is what the BB4W library uses).although I think it's no longer supported. I don't know that I would fancy trying to write a comparable library in BBC BASIC code however!
I tried to implement some limited floating-point math on it, but found that it took the entire memory of the machine just to implement simple addition :)
I'm a little surprised. For BBC BASIC (Z80) I wrote the floating-point code entirely from scratch, even 'bootstrapping' the transcendental functions by using what I'd already written (FP add, subtract, multiply, divide) to optimise the coefficients of the power-series expansions. I thought that was rather neat! But I don't remember the code being very large: everything was done in CPU registers, not memory, because the Z80 had a good architecture for the 40-bit float format (32-bit mantissa, 8-bit exponent) used by BBC BASIC in those days. I held one FP argument in HLH'L'C and another in DED'E'B which left B'C' and A (and A') to hold, for example, a temporary extension to the mantissa and an operator. It was a tight fit, but it worked really nicely.

Re: Introduction to BBC BASIC

Posted: Tue May 21, 2019 8:57 am
by jahboater
RichardRussell wrote:
Tue May 21, 2019 8:49 am
I'm a little surprised. For BBC BASIC (Z80) I wrote the floating-point code entirely from scratch, even 'bootstrapping' the transcendental functions by using what I'd already written (FP add, subtract, multiply, divide) to optimise the coefficients of the power-series expansions.
I wrote it in BASIC and the Sinclair ZX80 only had 1k of ram! It was so long ago (very early 80's) I cant remember what dialect of BASIC it was, except that it was nowhere near as capable as the later BBC BASIC.

Re: Introduction to BBC BASIC

Posted: Tue May 21, 2019 4:14 pm
by RichardRussell
jahboater wrote:
Tue May 21, 2019 8:57 am
I wrote it in BASIC and the Sinclair ZX80 only had 1k of ram!
Tokenised BASIC was probably the best way to use that limited resource, but in a couple of respects it's not ideal for writing floating-point code. Firstly I suspect Sinclair BASIC's integers were only 16 bits (unlike BBC BASIC's 32-bits) and - more importantly - BASIC gives you no direct access to the CPU's carry and overflow flags which are so crucial in the efficient implementation of FP arithmetic.

That remains highly relevant today, because the lack of access to carry and overflow is forcing me to store no more than 62 bits in each 64 bit 'limb' so that I can detect those conditions by looking at the two remaining bits in BASIC.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 3:54 pm
by Heater
Richard,

Continuing from the discussion of first class functions in the ScriptBasic thread:
The principal aspect is creating a new function from scratch at run time, not so much the pointer passing.
Impressive.
Do you mean creating a composite function incorporating one of the built-in functions?
Sounds like you have it covered. I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.

An example in Scheme says what I mean:

Code: Select all

; Makes a binary operator from a string and returns a function that applies it to two parameters. 
(define binaryExpr (lambda (s)
  (define oper (eval (string->symbol s)))
  (lambda (x y)
    (oper x y)
  )
))

(define plus
  (binaryExpr "+")
)

(display (plus 3 2))
(newline)
I know nothing much of Scheme so that is probably a terrible example.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 4:57 pm
by RichardRussell
Heater wrote:
Fri May 24, 2019 3:54 pm
I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.
My BBC BASIC solution to the Rosetta Code task implements FNcompose() by taking two function pointers and creating a function which calls one followed by the other. That only works with user-defined functions because they are the only ones that have function pointers as such (so to satisfy the requirement that "at least one function should be built in" I have wrapped them in user-defined functions).

The more general solution would involve passing not function pointers to FNcompose() but actual code, in the form of a string. That's perfectly possible, but the code would be more complex. This is the sort of trick you can really only play with an interpreted language, because you know all the resources necessary to run the code are available (i.e. the interpreter itself). With a compiled language you can't be certain that the compiler will be available on the target machine.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 5:01 pm
by ejolson
Heater wrote:
Fri May 24, 2019 3:54 pm
Richard,

Continuing from the discussion of first class functions in the ScriptBasic thread:
The principal aspect is creating a new function from scratch at run time, not so much the pointer passing.
Impressive.
Do you mean creating a composite function incorporating one of the built-in functions?
Sounds like you have it covered. I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.

An example in Scheme says what I mean:

Code: Select all

; Makes a binary operator from a string and returns a function that applies it to two parameters. 
(define binaryExpr (lambda (s)
  (define oper (eval (string->symbol s)))
  (lambda (x y)
    (oper x y)
  )
))

(define plus
  (binaryExpr "+")
)

(display (plus 3 2))
(newline)
I know nothing much of Scheme so that is probably a terrible example.
Since there is no runtime input, there is nothing that needs to be changed at runtime, so what's the point of the lambda? While correct, I find it about as practical as using object oriented programming to represent zoo animals.

In my opinion a more reasonable task would be to accept user input (an algebraic expression in x) that represents a function f(x) and then lambda up a new function df(x) that computes the derivative of that function.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 5:08 pm
by Heater
I think you are right. A compiled language program could do it, possibly, if it carried the compiler around with itself!

At some point it's not worth the hassle and one might as well use an interpreter.

I guessed you had wrapped the builtins with user defined functions because you can't get pointers to builtins. That sounds fine to me.

I was not thinking as far ahead as composing functions. Only creating and returning one that did not exist in the original source. Perhaps from a string, or whatever. Think an expression parser that turns an input string into a function that becomes part of the program.

That is out of scope for most languages never mind the BASICs.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 5:19 pm
by RichardRussell
Heater wrote:
Fri May 24, 2019 5:08 pm
That is out of scope for most languages never mind the BASICs.
It's one of the things we have Acorn to thank for, because when they designed BBC BASIC, back in 1981, they created a hybrid of the Microsoft-style BASIC that the BBC had asked for (albeit extended to support structured programming) and their existing Atom BASIC which had the necessary low-level indirection operators to manipulate memory - including the program itself. So BBC BASIC is unusual in supporting self-modifying code and run-time function creation, albeit that the penalty you pay is a greatly increased likelihood of a catastrophic crash if you misuse those features!

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 5:24 pm
by Heater
ejolson,
Since there is no runtime input, there is nothing that needs to be changed at runtime, so what's the point of the lambda?
That is quite right, no point at all, not for my noddy example above.
In my opinion a more reasonable task would be to accept user input (an algebraic expression in x) that represents a function f(x) and then lambda up a new function df(x) that computes the derivative of that function.
Yes indeed.

Thing is, the example shows a way to turn a string into a Scheme operator. With a little imagination one starts to see how that can be used to turn a string input by the user into a Scheme operator. By the way, the "operator" in the example need not be a simple "+". "-" etc. It could be a complex piece of Scheme code in a string.

With a bit more imagination it shows how it's possible to build functions that evaluate complex expressions that are input as strings.

This is all a bit more than an interpreter of the input expression strings as one might create in C. It "compiles" the input expressions into Scheme functions.

I'm working on it....

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 5:53 pm
by RichardRussell
Heater wrote:
Fri May 24, 2019 5:24 pm
With a bit more imagination it shows how it's possible to build functions that evaluate complex expressions that are input as strings.
Many interpreted BASICs (BBC BASIC and Liberty BASIC among them) include an EVAL function so that "evaluating complex expressions input as strings" becomes trivial:

Code: Select all

      REPEAT
        INPUT LINE "Enter a numeric or string expression: " expression$
        ON ERROR LOCAL IF FALSE THEN
          REM 'Try' clause:
          PRINT EVAL(expression$)
        ELSE
          REM 'Catch' clause:
          PRINT REPORT$
        ENDIF : RESTORE ERROR
      UNTIL FALSE
      END
The expression can be as complex as you like and can contain both built-in and user-defined functions. The strange 'ON ERROR' construction is BBC BASIC's implementation of Structured Exception Handling (SEH) and avoids the need of a line number or label as would be necessary in the traditional ON ERROR GOTO statement.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 6:29 pm
by Heater
That is cool.

I guess it's restricted to only evaluating strings that contain valid BBC BASIC and returning the result. Not being able to create BBC BASIC functions from the string that can be called later. Or the interpretation of some other syntax in the string. Not that I would expect that.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 6:42 pm
by RichardRussell
Heater wrote:
Fri May 24, 2019 6:29 pm
Not being able to create BBC BASIC functions from the string that can be called later.
Correct. To achieve that needs an adaptation of the technique used in the Rosetta Code solution. Not particularly difficult, but not as straightforward as EVAL.

Re: Introduction to BBC BASIC

Posted: Fri May 24, 2019 7:24 pm
by jalih
Heater wrote:
Fri May 24, 2019 5:08 pm
Only creating and returning one that did not exist in the original source. Perhaps from a string, or whatever. Think an expression parser that turns an input string into a function that becomes part of the program.

That is out of scope for most languages never mind the BASICs.
Not the way that I would write it, but 8th can do:

Code: Select all

: plus  \ x y -- x+y
  "+" eval ;


3 2 plus . cr
"Hello " "world!" plus . cr
or just:

Code: Select all

"plus" (:) "+" eval ;
3 2 plus . cr
"Hello " "world!" plus . cr
Result is:

Code: Select all

5
Hello world!

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 2:38 pm
by RichardRussell
RichardRussell wrote:
Mon May 20, 2019 8:29 pm
I'll play a bit more, but if I can't improve the performance to at least match the classic BASIC solution I probably won't pursue it any further.
Progress! I've now got my 'native' (BBC BASIC) BigInt library to evaluate the million-digit Fibonacci number faster than the 'classic BASIC' version: 7 minutes compared with 12 minutes on the same (fairly fast) PC. Not a dramatic improvement, admittedly, but I'm reasonably satisfied because the library is general purpose rather than being in any way optimised for the Fibonacci challenge.

This is the program:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)
      f1%% = FNbignew(1000000)

      TIME = 0
      PROCfibonacci(4784969, f0%%, f1%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibonacci(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(a%%, f%%) : REM f = 0
        PROCbigcpy(b%%, g%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibonacci(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(b%%, b%%, c%%)
      PROCbigusub(c%%, a%%, d%%)
      PROCbigumul(d%%, a%%, c%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(a%%, a%%, d%%)
      PROCbigumul(b%%, b%%, a%%)
      PROCbiguadd(d%%, a%%, b%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(b%%, f%%)       : REM f = b
        PROCbiguadd(b%%, c%%, g%%) : REM g = b + c
      ELSE
        PROCbigcpy(c%%, f%%)       : REM f = c
        PROCbigcpy(b%%, g%%)       : REM g = b
      ENDIF
      ENDPROC
The library uses 64-bit pointers/handles to represent the big integers. I've tried to leverage 'unique' features of BBC BASIC as far as possible, so internally it makes extensive use of whole-array operations and indirection. For example adding two bigints together is done with the following code (carries between limbs are dealt with separately):

Code: Select all

      c%%() = a%%() + b%%()
This allows loops to be eliminated to a large extent: there is only one FOR...NEXT loop in the entire library! I'm still not sure whether to put in the extra effort to extend the library to cope with signed numbers and other operations such as division; I might set that as a challenge for the BBC BASIC community.

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 6:38 pm
by ejolson
RichardRussell wrote:
Mon May 27, 2019 2:38 pm
RichardRussell wrote:
Mon May 20, 2019 8:29 pm
I'll play a bit more, but if I can't improve the performance to at least match the classic BASIC solution I probably won't pursue it any further.
Progress! I've now got my 'native' (BBC BASIC) BigInt library to evaluate the million-digit Fibonacci number faster than the 'classic BASIC' version: 7 minutes compared with 12 minutes on the same (fairly fast) PC. Not a dramatic improvement, admittedly, but I'm reasonably satisfied because the library is general purpose rather than being in any way optimised for the Fibonacci challenge.

This is the program:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)
      f1%% = FNbignew(1000000)

      TIME = 0
      PROCfibonacci(4784969, f0%%, f1%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibonacci(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(a%%, f%%) : REM f = 0
        PROCbigcpy(b%%, g%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibonacci(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(b%%, b%%, c%%)
      PROCbigusub(c%%, a%%, d%%)
      PROCbigumul(d%%, a%%, c%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(a%%, a%%, d%%)
      PROCbigumul(b%%, b%%, a%%)
      PROCbiguadd(d%%, a%%, b%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(b%%, f%%)       : REM f = b
        PROCbiguadd(b%%, c%%, g%%) : REM g = b + c
      ELSE
        PROCbigcpy(c%%, f%%)       : REM f = c
        PROCbigcpy(b%%, g%%)       : REM g = b
      ENDIF
      ENDPROC
The library uses 64-bit pointers/handles to represent the big integers. I've tried to leverage 'unique' features of BBC BASIC as far as possible, so internally it makes extensive use of whole-array operations and indirection. For example adding two bigints together is done with the following code (carries between limbs are dealt with separately):

Code: Select all

      c%%() = a%%() + b%%()
This allows loops to be eliminated to a large extent: there is only one FOR...NEXT loop in the entire library! I'm still not sure whether to put in the extra effort to extend the library to cope with signed numbers and other operations such as division; I might set that as a challenge for the BBC BASIC community.
I suspect your underlying big-integer multiplication routines are more than 3 times faster than the code in the classic line-numbered Basic program. This is because the Fibonacci part of the line-numbered Basic code

1. Uses Cassini's identity to eliminate one out of the three multiplications used in each recursive application of the doubling formula compared to what your code does.

2. At the top level of the recursion classic.bas only computes b, thereby eliminating 2 of the 3 multiplications at the last step. This is surprisingly important as that step dominates the running time.

If you include the above two optimisations, I suspect your Fibonacci program will run in under 3 minutes. Note that in visual.bas the routines fibo and fibowork illustrate the same doubling formulas used in the classic.bas code. The comments at the beginning of either program are also helpful to understand the exact formulas for doubling which were employed in the code.

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 7:08 pm
by RichardRussell
ejolson wrote:
Mon May 27, 2019 6:38 pm
Note that the visual.bas routines fibo and fibowork illustrate the same doubling formulas used in the classic.bas code. The comments at the beginning of either program are helpful to understand the exact formulas for doubling which were employed in the code.
I'll take a look. I certainly didn't attempt to understand the 'classic BASIC' code - it's a perfect example of the non-readability of spaghetti code using GOTO!

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 8:47 pm
by RichardRussell
RichardRussell wrote:
Mon May 27, 2019 7:08 pm
I'll take a look.
I notice that one of the optimisations involves the use of 'biginc' and 'bigdec' routines, which I haven't provided in my library, so that's not something I can instantly implement. But not computing the tuple of Fibonacci values at the top level, when only one is needed, is an easy change which has reduced the execution time to a little under six minutes.

I'm a little concerned that I seem to have chosen a different parameter order for the 'big' arithmetic routines: yours have the output as the first parameter and mine as the last. Is there a convention I should have followed? I'll change mine if appropriate.

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 10:11 pm
by jahboater
RichardRussell wrote:
Mon May 27, 2019 8:47 pm
I'm a little concerned that I seem to have chosen a different parameter order for the 'big' arithmetic routines: yours have the output as the first parameter and mine as the last. Is there a convention I should have followed? I'll change mine if appropriate.
It probably doesn't matter, but it is common to have the destination as the first argument. See strcpy() etc, most assemblers,
and of course all the hundreds of GMP and MPFR functions are that way round.

System calls and the standard ABI have the return value in r0 - the first register, that was the first argument .....

Probably just convention though.

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 10:44 pm
by RichardRussell
jahboater wrote:
Mon May 27, 2019 10:11 pm
it is common to have the destination as the first argument. See strcpy() etc, most assemblers, and of course all the hundreds of GMP and MPFR functions are that way round.
OK. I knew about Intel assembly language, but I thought that was an anomaly (GAS has the operands the other way around, doesn't it?). The other examples are mostly outside my experience, but I will change my library to accord with the majority convention.
System calls and the standard ABI have the return value in r0 - the first register, that was the first argument .....
True, but I hadn't associated register names/numbers with parameter order.

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 11:00 pm
by RichardRussell
Code is now:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)

      TIME = 0
      PROCfibo(4784969, f0%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibo(N%, f%%)
      LOCAL S%, a%%, b%%, c%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibo2(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%)

      IF N% AND 1 THEN
        PROCbigumul(c%%, a%%, a%%)
        PROCbigumul(a%%, b%%, b%%)
        PROCbiguadd(f%%, c%%, a%%)   : REM f = a * a + b * b
      ELSE
        PROCbiguadd(f%%, b%%, b%%)
        PROCbigusub(c%%, f%%, a%%)
        PROCbigumul(f%%, c%%, a%%)   : REM f = a * (b * 2 - a)
      ENDIF
      ENDPROC

      DEF PROCfibo2(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(f%%, a%%) : REM f = 0
        PROCbigcpy(g%%, b%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibo2(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(c%%, b%%, b%%)
      PROCbigusub(d%%, c%%, a%%)
      PROCbigumul(c%%, d%%, a%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(d%%, a%%, a%%)
      PROCbigumul(a%%, b%%, b%%)
      PROCbiguadd(b%%, d%%, a%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(f%%, b%%)       : REM f = b
        PROCbiguadd(g%%, b%%, c%%) : REM g = b + c
      ELSE
        PROCbigcpy(f%%, c%%)       : REM f = c
        PROCbigcpy(g%%, b%%)       : REM g = b
      ENDIF
      ENDPROC

Re: Introduction to BBC BASIC

Posted: Mon May 27, 2019 11:56 pm
by jahboater
RichardRussell wrote:
Mon May 27, 2019 10:44 pm
GAS has the operands the other way around, doesn't it?
:) Yes, but I think GAS is itself the anomaly :)

The ARM CPU on the Pi has the destination on the left.