COMAL - some thoughts and a high version and disaasembly

bbc/electron apps, languages, utils, educational progs, demos + more
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

I got the COMAL ROM and manual with a BBC Master I bought, had a quick play and then didn't think much more of it. The manual has been re-mastered by DV8 and dhogan wondered if there was a way of making a high version for the 6502 2nd processor. Interested in the idea, I have disassembled it got a version to run high - see: https://github.com/SteveFosdick/AcornComal

The language seems to be a bit of a mix of Pascal and BASIC. From BASIC it keeps easy string operations, though the syntax for sub-strings is completely different, PRINT syntax, editing via line numbers and the overall interpretive approach. From Pascal it gains the assignment syntax, multi-line IF, REPEAT..UNTIL, WHILE.. functions and procedures and maybe CASE? though it doesn't copy the block structure as such - there is no BEGIN .. END or {} as in C. Clearly 6502 BBC BASIC had already started down a similar path with FN/PROC and REPEAT..UNTIL.

I am not sure to what extent it is limited to the implementation for BBC Micro, but this does syntax checking at line entry so providing immediate feedback on at least some errors and, when an error does occur, it places a ^ character at the point it thinks the error is - more friendly than BASIC. For example:
syntax-cropped.png
syntax-cropped.png (3.22 KiB) Viewed 2980 times
The error here is that integer variables in COMAL have a # suffix, not %.

So while messing around with it, I thought I'd implement the primes by trial division algorithm. There are loads of these already on the typewritten software site, some of which we have run in various languages before, but none in COMAL so I wrote one based on the Pascal version:
comal-trial-prog.png
or as text:

Code: Select all

   10 t#:=TIME
   20 numprimes:=1000
   30 DIM primes(numprimes)
   40 found:=0
   50 cnt:=2
   60 WHILEfound < numprimes DO
   70   found:+1
   80   primes(found):=cnt
   90   PRINT cnt
  100   cnt:+1
  110   index:=1
  120   REPEAT
  130     IF cnt MOD primes(index) = 0 THEN
  140       cnt:+1
  150       index:=0
  160     END IF
  170     index:+1
  180   UNTIL index > found
  190 END WHILE
  200 t#:=TIME-t#
  210 PRINT"Completed in ";t#/100;"s"
The nicely indented listing is the default, i.e. it doesn't need a LISTO command to enable it. It also takes a different approach in that, because it pretty-prints the listing, it doesn't preserve user-entered spaces in the same way that BASIC does. Here's the BBC BASIC version from Typewritten software:

Code: Select all

   10 DIM primes(100)
   20 index=1
   30 count=2
   40 found=1
   50 primes(index)=count
   60 PRINT primes(index)
   70 REPEAT
   80 count=count+1
   90 REPEAT
  100 v=(count MOD primes(index))
  110 index=index+1
  120 UNTIL v=0 OR index>found
  130 IF v=0 THEN GOTO 170
  140 PRINT count
  150 primes(index)=count
  160 found=found+1
  170 index=1
  180 UNTIL found=100
and here it is on screen with LISTO7. The lack of multi-line IF gives rise to a GOTO and BASIC`s pretty printing has an anomaly in that it keeps the indent until after the keyword that should close it. To do otherwise, a line would have to be pre-scanned for closing keywords to adjust the indentation and then the line processed again to actually list it.:
basic-trial-code.png
This COMAL implementation, interestingly, does do that and stores in the indentation level as part of the line in memory in a variation of the program storage structure used by BBC BASIC.

What about performance? Using B-Em, no tube, BASIC 2, the BASIC version completed in 48.68s. The COMAL version, same setup, original (low) COMAL ROM, completed in 60.62s. I also translated CLOCKSP into COMAL:

Code: Select all

   10 //> ComalSP
   20 PRINT"COMAL Timing Program"
   30 PRINT"Equivalent to BBC BASIC ClockSP"
   40 setup
   50 p(41000,realrpt)
   60 p(23900,intrpt)
   70 p(51200,realfor)
   80 p(17800,intfor)
   90 p(68800,triglog)
  100 p(80500,proced)
  110 p(72750,string)
  120 tm:=tm/(78/10)
  130 PRINT"Combined average   ";tm DIV 100;".";tm MOD 100;"Mhz, ";tc;"cs";CHR$(8)
  140 END
  150 PROC setup
  160   a#:=0
  170   t#:=TIME
  180   REPEAT
  190     a#:=a#+1
  200   UNTIL TIME>t#+50
  210   z:=0
  220   z#:=0
  230   b:=1
  240   b#:=1
  250   f:=1/10
  260   c:=100
  270   c#:=100
  280   d:=510
  290   d#:=510
  300   f#:=3
  310   REPEAT
  320     c:=c*10
  330     c#:=c#*10
  340     d:=d*10
  350     d#:=d#*10
  360     f#:=f#*10
  370     f:=f*10
  380     a#:=a# DIV 10
  390   UNTIL a#<50
  400   tm:=0
  410   tc:=0
  420 END PROC setup
  430 FUNC realrpt
  440   PRINT"Real REPEAT loop    ";
  450   t#:=TIME
  460   a:=z
  470   REPEAT
  480     a:=a+b
  490   UNTIL a>c
  500   RETURN TIME-t#
  510 END FUNC realrpt
  520 FUNC intrpt
  530   PRINT"Integer REPEAT loop ";
  540   t#:=TIME
  550   a#:=z#
  560   REPEAT
  570     a#:=a#+b#
  580   UNTIL a#>c#
  590   RETURN TIME-t#
  600 END FUNC intrpt
  610 FUNC realfor
  620   PRINT"Real FOR loop       ";
  630   t#:=TIME
  640   FOR a:=z TO d STEP b DO
  650   NEXT a
  660   RETURN TIME-t#
  670 END FUNC realfor
  680 FUNC intfor
  690   PRINT"Integer FOR loop    ";
  700   t#:=TIME
  710   FOR a#:=z# TO d# STEP b# DO
  720   NEXT a#
  730   RETURN TIME-t#
  740 END FUNC intfor
  750 FUNC triglog
  760   PRINT"Trig/Log test       ";
  770   t#:=TIME
  780   FOR j#:=1 TO f# DO
  790     a:=TAN(ATN(EXP(LN(SQR(a*a)))))+1
  800   NEXT j#
  810   RETURN TIME-t#
  820 END FUNC triglog
  830 FUNC string
  840   PRINT"String manipulation ";
  850   DIM a$ OF 160
  860   t#:=TIME
  870   a$:="STRINGMANIPULATIONTEST"
  880   FOR a#:=0 TO f#*4 DO
  890     a$:=(a$(LEN (a$)/4:LEN (a$)/4+1)+a$(LEN (a$)/4:)+a$(LEN (a$)/2:2)+a$(1:LEN (a$)/4)+a$(LEN (a$)/4:LEN (a$)/4+1))(:20)
  900   NEXT a#
  910   RETURN TIME-t#
  920 END FUNC string
  930 FUNC proced
  940   PRINT"Procedure call      ";
  950   t#:=TIME
  960   FOR a#:=z# TO d# DO
  970     tproc
  980   NEXT a#
  990   RETURN TIME-t#
 1000 END FUNC proced
 1010 PROC tproc
 1020 END PROC tproc
 1030 PROC p(s,t)
 1040   m:=f*s/t
 1050   tm:+m
 1060   tc:+t
 1070   PRINT m DIV 100;".";m MOD 100;"Mhz, ";t;"cs";CHR$(8)
 1080 END PROC p
. Running that gives:
comalsp.png
so it is noticeably slower. I wonder why. A while back there was a discussion Why was BBC BASIC so fast? with some people convinced it was completely due to the BBC B being a fast machine. While the machine definitely is fast, compared to contemporaries, the performance of this COMAL interpreter is ample evidence to me that the efficiency of the interpreter makes a difference too and that the assumption that the writers of MS BASIC for the 6502 must have been people who only did 6502 assembler part time and that, if BBC BASIC wasn't faster then MS BASIC (for non-optimised programs), then Sophie hadn't done anything special, must be false.

I don't think there is anything inherent in the COMAL language that makes it slower to interpret than BASIC but maybe this particular COMAL has used more ROM space on parsing the text as it is entered and friendly error reporting that the execution part doesn't have space for faster algorithms? Maybe, if I get more chance/enthusiasm to work on the disassembly this may become clear.

But if you don't mind the lack of speed, it seems like a nice language.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by scruss »

Since I have a (nominally official) position in one of the organizations responsible for promoting and funding COMAL*, I thought I'd give it a shot on the “home” machine for COMAL, the C64.

First impression: whoa, Acornsoft COMAL is a weird, incompatible dialect! Where's the ENDIF and ENDWHILE? The Prime code wouldn't run at all on the Commodore/UniComal ApS COMAL 2.0 cartridge for the C64 (or the OpenCOMAL interpreter for Linux, either). I had to make the following changes:

Code: Select all

0010 t#:=TIME
0020 numprimes:=100
0030 DIM primes(numprimes)
0040 found:=0
0050 cnt:=2
0060 WHILE found<numprimes DO
0070  found:+1
0080  primes(found):=cnt
0090  PRINT cnt
0100  cnt:+1
0110  index:=1
0120  REPEAT
0130   IF cnt MOD primes(index)=0 THEN
0140    cnt:+1
0150    index:=0
0160   ENDIF
0170   index:+1
0180  UNTIL index>found
0190 ENDWHILE
0200 t#:=TIME-t#
0210 PRINT "Completed in ";t#/60;"s"
This ran in 64.8 s on an NTSC C64 (a 1 MHz 6502). What was the Acorn version playing at? It should've been done in around 32 s, what with its 2 MHz CPU. The Primes by Trial Division - Commodore BASIC code ran in 80.4 s on the same C64.

It would take more time to understand ComalSP and get the AcornSoft version back to standard COMAL. Unpicking the 0.01 s timer may take more time than I want to give it.
While the machine definitely is fast, compared to contemporaries, the performance of this COMAL interpreter is ample evidence to me that the efficiency of the interpreter makes a difference too and that the assumption that the writers of MS BASIC for the 6502 must have been people who only did 6502 assembler part time and that, if BBC BASIC wasn't faster then MS BASIC (for non-optimised programs), then Sophie hadn't done anything special, must be false.
I don't think that assertion can be made. Commodore BASIC, while limited, runs the same source in twice the time that BBC BASIC on a Beeb will take. The C64's CPU runs at 1 MHz, half the rate of the Beeb. As soon as you optimize code such that it'll only run on a Beeb, you've lost the means of comparison. I did a comprehensive rundown on this issue, and it's the Beeb's fast processor and uncluttered RAM access that makes it fast. Sophie's code is good, but not magic.

---
*: TPUG, Toronto PET User Group, of which I'm nominally a director. Back when TPUG was a corporation, it had a contract to develop curriculum around COMAL and to write the manual. This was done by the late Jim Butterfield. TPUG had a huge program library, and a corner of that was dedicated to COMAL programs.
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by BigEd »

So... on the C64 COMAL is much faster than Basic but on the Beeb Acorn's COMAL is somewhat slower than Basic... and the C64's COMAL is much faster per MHz than Acorn's. So Acorn's COMAL is a rather suboptimal implementation, performancewise - does that sound right?
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by julie_m »

if you're doing syntax checking at line entry, you can do some other interesting stuff that might speed up interpretation at the slight expense of taking longer to produce a listing, like storing the binary representations of numeric constants in the source code; or even building up the symbol table "live" from any definitions in the line, maintaining it at all times and storing the addresses of variables in the source code.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by scruss »

BigEd wrote: Sat Nov 05, 2022 6:30 pm So Acorn's COMAL is a rather suboptimal implementation, performancewise - does that sound right?
Suboptimal, and incompatible too. COMAL had a well-defined language spec, and Acorn COMAL is nowhere close
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by BigEd »

It does sound like a port of the (a?) C64 version to the Acorn world would be a good thing...
User avatar
SKS1
Posts: 327
Joined: Sat Sep 19, 2020 12:04 am
Location: Highland Perthshire
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by SKS1 »

"Suboptimal"

Isn't the Acornsoft COMAL using five byte floating point though? And four byte integers.

"Where's the ENDIF and ENDWHILE"

END IF and END WHILE it would seem.
Miserable old curmudgeon who still likes a bit of an ARM wrestle now and then. Pi 4, 3, ARMX6, SA Risc PC, A540, A440
User avatar
Bobbi
Posts: 824
Joined: Thu Sep 24, 2020 12:32 am
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Bobbi »

We used COMAL for AO level Computer Studies. It's really pretty decent. Pity it is not as fast as BBC BASIC though :(
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

SKS1 wrote: Tue Nov 08, 2022 9:22 am Isn't the Acornsoft COMAL using five byte floating point though? And four byte integers.
Do I assume the C64 version is using variables with fewer bytes?

The Acornsoft COMAL user guide says that integer variables take up less space but does not say they are faster. I wonder, therefore, if it does integer calculations at all or whether everything is done in floating point and then stored back to an integer if the destination variable is integer. The disassembly should make that apparent but I have had almost no time to spend on it recently.
SKS1 wrote: Tue Nov 08, 2022 9:22 am END IF and END WHILE it would seem.
I know the Acornsoft version stores these as the two tokens END and IF and likewise END and WHILE which means the end of the construct can be implemented without introducing extra tokens. Then, unlike BASIC, the Acornsoft COMAL has a built-in pretty printer so one does not normally have to add extra white space to the program. During a listing the lines are indented (though BASIC can do this too with LISTO) and white space is printed with the tokens. If the only affect was that ENDIF and ENDWHILE were printed with an intervening space then it would still accept standard programs but it seems this is not the case either as the tokeniser also seems to need the space to distinguish tokens from variables as seen here:
comal.png
ENDIF has been stored as endif in lower case and hasn't affected the indentation level indicating it has been interpreted as a variable or function name.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disassembly

Post by scruss »

SKS1 wrote: Tue Nov 08, 2022 9:22 am "Where's the ENDIF and ENDWHILE"

END IF and END WHILE it would seem.
COMAL is defined as using ENDIF and ENDWHILE. Use anything else, it ain't COMAL
User avatar
Bobbi
Posts: 824
Joined: Thu Sep 24, 2020 12:32 am
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Bobbi »

I have COMAL-80 (for CP/M) somewhere. I should see how that handles `END IF` vs `ENDIF` etc.
User avatar
SKS1
Posts: 327
Joined: Sat Sep 19, 2020 12:04 am
Location: Highland Perthshire
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by SKS1 »

I'd guess that the 16KB ROM on the BBC Micro didn't have space for ENDIF and ENDWHILE as separate keywords.

From what I'd read, the C-64 version used four byte floats and two byte integers.

"I wonder, therefore, if it does integer calculations at all or whether everything is done in floating point and then stored back to an integer if the destination variable is integer." This was my suspicion, too, if it's that space constrained.
Miserable old curmudgeon who still likes a bit of an ARM wrestle now and then. Pi 4, 3, ARMX6, SA Risc PC, A540, A440
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by julie_m »

WHILE-ENDWHILE loops will always end up slowing down an interpreted language; because if the test fails ab initio, the interpretator has to search for the end of the loop.
User avatar
SKS1
Posts: 327
Joined: Sat Sep 19, 2020 12:04 am
Location: Highland Perthshire
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by SKS1 »

Oh, the original test is all in f.p. too for a problem which is distinctly in the integer domain (at least for primes that you're going to find on a BBC Micro before hell freezes over). Or is it true that all the arithmetic is done in f.p. anyhow???
Miserable old curmudgeon who still likes a bit of an ARM wrestle now and then. Pi 4, 3, ARMX6, SA Risc PC, A540, A440
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

julie_m wrote: Wed Nov 09, 2022 4:50 pm WHILE-ENDWHILE loops will always end up slowing down an interpreted language; because if the test fails ab initio, the interpretator has to search for the end of the loop.
This is a property of the desired behaviour, though, not the syntax that enables it to be expressed succinctly. You can replace:

Code: Select all

WHILE condition DO
    something
END WHILE
with:

Code: Select all

IF condition THEN
    REPEAT
        something
    UNTIL NOT condition
END IF
and the interpreter will still have to search forward for the END IF when the 'something' should not be done at all. Even in 6502 BBC BASIC, with no multi-line IF, when an IF condition is FALSE the interpreter still has to search forward for a possible ELSE. The loop to do that is as tight as possible, hence the discussions about how line numbers are stored, but it is a search none the less.
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by julie_m »

Yes, I get that -- it's in the nature of doing the test first thing, as opposed to always going through the loop once before the test. I suppose you could remember where the end of the loop was, at the cost of a couple of bytes on a stack, if you did go through it, which would save you a search when the test failed.

I've been working on an extension language for AdveBuilder, to implement puzzle logic; and it's based on nested, multi-line

Code: Select all

IF test THEN
    statements ...
ELIF test THEN
    statements ...
... more ELIFs with their own THENs ...
ELSE
    statements ...
FI
constructs. But that's compiled, not interpreted; and the compiler is itself written in a high-level language, which is doing all the hard work of keeping track of branch destinations. And it produces actual 6502 instructions, using the flow of control as the engine of state (which is a fancy way of saying, spaghetti code .....)
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disassembly

Post by scruss »

Bobbi wrote: Wed Nov 09, 2022 4:21 am I have COMAL-80 (for CP/M) somewhere. I should see how that handles `END IF` vs `ENDIF` etc.
Correctly:

Code: Select all

0010 n:=1
0020 WHILE n<10 DO 
0030   PRINT n
0040   n:+1
0050   IF n=4 THEN 
0060     PRINT "*** FOUR!!! ***"
0070   ENDIF 
0080 ENDWHILE 
0090 END 
This is from Comal/80 v2.1, from z80pack

In Comal, integer variables have a '#' suffix; everything else is treated as a real. If you want to see the precision of a float:

Code: Select all

0010 x:=1
0020 j#:=-1
0030 WHILE (x+1)<>x DO
0040  x:=x*2
0050  j#:+1
0060 ENDWHILE
0070 PRINT j#
0080 PRINT j#*LOG(2)/LOG(10)
0090 END
Comal-80 on the C64 (and CP/M-80) use 32 bit floats
User avatar
Bobbi
Posts: 824
Joined: Thu Sep 24, 2020 12:32 am
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Bobbi »

Good to know COMAL-80 is correct. I still have a soft spot for Acornsoft COMAL.

(Waves to fellow Torontonian. Are we the only two?)
User avatar
dhoggan
Posts: 465
Joined: Tue Jul 10, 2018 11:45 pm
Location: UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by dhoggan »

scruss wrote: Tue Sep 27, 2022 3:53 am First impression: whoa, Acornsoft COMAL is a weird, incompatible dialect! Where's the ENDIF and ENDWHILE? The Prime code wouldn't run at all on the Commodore/UniComal ApS COMAL 2.0 cartridge for the C64 (or the OpenCOMAL interpreter for Linux, either). I had to make the following changes:

Code: Select all

0010 t#:=TIME
0020 numprimes:=100
0030 DIM primes(numprimes)
This ran in 64.8 s on an NTSC C64 (a 1 MHz 6502). What was the Acorn version playing at? It should've been done in around 32 s, what with its 2 MHz CPU. The Primes by Trial Division - Commodore BASIC code ran in 80.4 s on the same C64.
Out of interest is that code snippet right? In your example numprimes=100 but in Coeus' is is set to 1000. I'm assuming you ran the test with equal values?

You also mentioned you had to make some changes to Coeus' example just to get it to run on the C64. I might be misisng something but the two programs are the same (aside from spacing and the 100/1000 point).

Suboptimal, and incompatible too. COMAL had a well-defined language spec, and Acorn COMAL is nowhere close
To quote Acornsoft...
"The Acornsoft implementation of COMAL exceeds the COMAL-80 Standard as published in May 1982 and in addition has many extensions to take full advantage of the facilities of the BBC Microcomputer or Acorn Electron"
So to be fair they never claimed they implemented a COMAL-80 version. However, you mentioned it it nowhere close which would suggest multiple, significant differences. Can you list some of the differences you've found?
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

dhoggan wrote: Tue Nov 22, 2022 1:41 pm You also mentioned you had to make some changes to Coeus' example just to get it to run on the C64. I might be misisng something but the two programs are the same (aside from spacing and the 100/1000 point).
The difference between ENDWHILE and END WHILE is indeed the presence of a space, but it seems neither version will accept that piece of syntax with the opposite spacing and Stewart us telling us the C64 is the one that implements the standard correctly.
dhoggan wrote: Tue Nov 22, 2022 1:41 pm To quote Acornsoft...
"The Acornsoft implementation of COMAL exceeds the COMAL-80 Standard as published in May 1982 and in addition has many extensions to take full advantage of the facilities of the BBC Microcomputer or Acorn Electron"
So to be fair they never claimed they implemented a COMAL-80 version. However, you mentioned it it nowhere close which would suggest multiple, significant differences. Can you list some of the differences you've found?
To me, "exceeds the COMAL-80 Standard" suggests "implements a superset of the COMAL-80 Standard" not "implements a language that intersects with the standard". Perhaps it is weasel words from a marketing person or else they didn't consider the need to put a space into END WHILE and END IF significant enough to count as not complying with the standard.

The extensions are presumably the ability to call the BBC Micro OS features.
Last edited by Coeus on Wed Nov 23, 2022 12:27 am, edited 1 time in total.
User avatar
dhoggan
Posts: 465
Joined: Tue Jul 10, 2018 11:45 pm
Location: UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by dhoggan »

To be fair I also would assume that "exceeds" means it builds upon the standard, not ignores it.

It was the strongly worded "Acornsoft COMAL is a weird, incompatible dialect" and "COMAL had a well-defined language spec, and Acorn COMAL is nowhere close" that caught my eye. It seems a bit of a nuclear response to, frankly, a couple of spaces in keywords. So that's why I'm curious what the other differences are - if there are actually any.

As for speed though - it is slower than Beeb BASIC - by about 30% in my estimates. That said, I' not sure Stewart's test was valid, based upon the code sample he posted. Unless both were run with a loop of 100 or 1000 - just not clear from the post.
Last edited by dhoggan on Tue Nov 22, 2022 6:12 pm, edited 1 time in total.
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by BigEd »

(Umm, scruss is Stewart, not Russ...)
User avatar
dhoggan
Posts: 465
Joined: Tue Jul 10, 2018 11:45 pm
Location: UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by dhoggan »

Edit to reflect that :-) Always get confused with real names and aliases.

I've been doing some digging on this and whilst I'm not going to state that Acornsoft Comal includes a precise implementation of COMAL-80, it absolutely is COMAL - at least the COMAL-80 Standardisation & Develoment Group thought so:
comal1.JPG


It looks like the creator of Acornsoft COMAL, David Christensen wrote it before he and Acornsoft became members of the COMAL-80 Standardisation committe, so whatever reason that the spaces appeared in reserved words, the standards committee were OK with.
comal2.JPG
Still, it is curious that such a tightly specified language such as COMAL allowed this deviation from the standard. I mean, it is a small and easily accounted for deviation, but one nonetheless. I'm guessing that between a choice of disallowing official recognition as COMAL and not having another implementation (when they really wanted widespread acceptance), they chose having a wider audience.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by scruss »

dhoggan wrote: Tue Nov 22, 2022 1:41 pm Out of interest is that code snippet right? In your example numprimes=100 but in Coeus' is is set to 1000. I'm assuming you ran the test with equal values?
Yes. For 100 primes, Acornsoft COMAL takes ~ 60 seconds. 100 primes on the C64 COMAL cartridge takes ~ 65 seconds. There's a typo in Coeus' post. numprimes=1000 overflows the timer on C64 COMAL and takes ~ 5000 seconds on Acornsoft COMAL.

Here's the code that took 60 seconds on the Beeb:

Code: Select all

10 t#:=TIME
20 numprimes:=100
30 DIM primes(numprimes)
40 found:=0
50 cnt:=2
60 WHILE found<numprimes DO
70 found:+1
80 primes(found):=cnt
90 PRINT cnt
100 cnt:+1
110 index:=1
120 REPEAT
130 IF cnt MOD primes(index)=0 THEN
140 cnt:+1
150 index:=0
160 END IF
170 index:+1
180 UNTIL index>found
190 END WHILE
200 t#:=TIME-t#
210 PRINT "Completed in ";t#/100;"s"
We can't blame longer floating-point representation in Acornsoft COMAL for its pedestrian speed, because it uses 4-byte floats just like C64 COMAL. This modified from Meeus for Acornsoft COMAL:

Code: Select all

       10 x:=1
       20 j#:=-1
       30 WHILE (x+1)<>x DO
       40   x:=x*2
       50   j#:+1
       60 END WHILE
       70 PRINT j#
       80 PRINT j#*LOG(2)/LOG(10)
       90 END
... aside from spacing ...
Acornsoft COMAL puts a space in the middle of the ENDIF and ENDWHILE keywords. That meant (at the time) that programs would have to be re-keyed manually, especially since COMAL's editor blocks lines with errors.

It's neat that you've got some COMAL working group docs, but those excerpts don't say anything about compatibility or certification
User avatar
dhoggan
Posts: 465
Joined: Tue Jul 10, 2018 11:45 pm
Location: UK
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by dhoggan »

This might be as close as we'll get:
comal3.JPG


Oddly this seems to suggest it was a COMAL-80 implementation but as you say, those spaces do mean it is not in strict adherence. Maybe they considered it minor enough not to fail certification/not enough that it wasn't COMAL-80. All other aspects do seem to be in line with the standard.

This was taken from https://datamuseum.dk/w/images/f/f0/KR_ ... t_1984.pdf. By the looks of it there wen't many implementations at the time.
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

scruss wrote: Thu Nov 24, 2022 2:36 am
dhoggan wrote: Tue Nov 22, 2022 1:41 pm Out of interest is that code snippet right? In your example numprimes=100 but in Coeus' is is set to 1000. I'm assuming you ran the test with equal values?
Yes. For 100 primes, Acornsoft COMAL takes ~ 60 seconds. 100 primes on the C64 COMAL cartridge takes ~ 65 seconds. There's a typo in Coeus' post. numprimes=1000 overflows the timer on C64 COMAL and takes ~ 5000 seconds on Acornsoft COMAL.
The version I posted, including the screenshot, did indeed have the number of primes set to 1000 and in the screenshot you can just see the timing for that which is 5074.82s but the 60.62s was for 100 primes.
scruss wrote: Thu Nov 24, 2022 2:36 am We can't blame longer floating-point representation in Acornsoft COMAL for its pedestrian speed, because it uses 4-byte floats just like C64 COMAL...
That test program confirms that Acornsoft COMAL uses floats with a 4-byte mantissa, hence the multiplier gets to 32 before the addition loses precision. There is also another byte for the exponent, making five in total - just as in BBC BASIC. Normally I would expect the term 4-byte float to mean something like IEEE single-precision which has both the mantissa and exponent contained within 32 bits.

Even so, I am not sure this is the reason for the poor performance, though using floating point arithmetic rather than integer arithmetic could be. When I get a chance I will compare COMAL with BASIC to see where the relevant interpreters are spending most of their time on ostensibly the same program.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by scruss »

Coeus wrote: Thu Nov 24, 2022 11:52 pm That test program confirms that Acornsoft COMAL uses floats with a 4-byte mantissa, hence the multiplier gets to 32 before the addition loses precision. There is also another byte for the exponent, making five in total - just as in BBC BASIC.
Ahh - good point: it's the size of the mantissa. Running equivalent code on a 4-byte float machine would return something like 23 bits, or ~ 6.9 digits of precision. The only BBC BASIC implementation I know of that used shorter floats was "The Emulator" for the Commodore Amiga. It used 4-byte Motorola FFP for its floats
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by Coeus »

scruss wrote: Fri Nov 25, 2022 4:11 am Ahh - good point: it's the size of the mantissa. Running equivalent code on a 4-byte float machine would return something like 23 bits, or ~ 6.9 digits of precision. The only BBC BASIC implementation I know of that used shorter floats was "The Emulator" for the Commodore Amiga. It used 4-byte Motorola FFP for its floats
I didn't realise you were comparing with BBC BASIC implementations. I thought you were comparing with COMAL on the C64. That doesn't change my suspicion that the floating point routines themselves are not at the centre of the problem with the Acornsoft COMAL's lack of performance.
User avatar
scruss
Posts: 653
Joined: Sun Jul 01, 2018 4:12 pm
Location: Toronto
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by scruss »

I wasn't really: I was scratching about to find implementations of any language that use a 4-byte floating point format
User avatar
SKS1
Posts: 327
Joined: Sat Sep 19, 2020 12:04 am
Location: Highland Perthshire
Contact:

Re: COMAL - some thoughts and a high version and disaasembly

Post by SKS1 »

I think BASIC on my Ohio Superboard II had 4 byte f.p.
Miserable old curmudgeon who still likes a bit of an ARM wrestle now and then. Pi 4, 3, ARMX6, SA Risc PC, A540, A440
Post Reply

Return to “8-bit acorn software: other”