Jump to content
IGNORED

Benchmarking Atari ST BASIC's (For simple Games)


Recommended Posts

Benchmarking Atari ST BASIC's
 

The BASIC's tested are Hisoft BASIC, STOS, Omikron & GFA

 

I wanted to know which BASIC would be best for coding simple block based games. The benchmark test is:

 

  1. Define an array of 40x25 integers
  2. Fill the array with random colours (0-15)
  3. Draw the array via the builtin rectfill procedures using color from map
  4. Each block is to be 7x7 in size and spaced 8x8 pixels so a screen of 320x200 pixels is covered in coloured blocks
  5. Repeat 10 times

 

The test is designed to see how suitable each BASIC would be for programs like Snake, Tetri$, Breakout, Pong, Game of Life, etc.

The same method can also be used for board games like Chess, Checkers, and RPG games. In which case, rectangle fill's can be replaced with
image blitting. Obviously, for each game type, you could optimize by using a "draw as you go" method, or record "dirty cells/cols/rows" to prevent overdraw.

All the BASIC's tested support integrating machine code and each supply a variety of extra graphics functions for various purposes.

I hope you find the test interesting. I coded these because I spent a few months coding in Hisoft BASIC, only to end up with less than Stella results.

The test is not designed to compare BASIC to C, Pascal, etc. BASIC has some very attractive attributes if you want to work on a 520ST/Floppy system.

 

BENCHMARK RESULTS (LOWER IS BETTER)

 

All* Tests were made under TOS 2.06 without any ACC's or screen accelerators.
Machine was a 520ST/E, except for Hisoft BASIC which required a 1040ST

* Omikron BASIC 2.2 failed to run on TOS 2.06, therefore the interpreter test was done under 1.0. The resulting compiled version runs on TOS 2.06

 

OMIKRON BASIC 2.2
Interpreted: 48 Secs (TOS1.0) / Compiled: 41 Secs (TOS1.0) / Compiled: 28 Secs (TOS 2.06)

 

OMIKRON BASIC 3.01
Interpreted: 24 Secs / Compiled: 17 Secs

 

GFA BASIC 2.0
Interpreted: 44 Secs / Compiled: NA

 

GFA BASIC 3.6
Interpreted: 39 Secs / Compiled: 26 Secs

 

STOS 2.6
Interpreted: 278 Secs / Compiled: About the same. PRG Crashed

 

Hisoft BASIC 2.10
Interpreted: NA / Compiled: 44 Secs

 

CONCLUSION

 

The clear winner is Omikron BASIC 3.01, which recorded an interpreted speed faster than GFA 3.6's compiled speed.

While GFA speed improved from 2.x to 3.x, the improvement only barely beats Omikron BASIC 2.2 from 1986

 

I was expecting good things from Hisoft BASIC, but its speed is a clear 3rd place. Hisoft BASIC was woefully slow to compile and requires more RAM and screen space
to accommodate its GEM interface. That said, Hisoft BASIC is the most advanced BASIC on the Atari ST and provides a fantastic experience when run in an emulator.

 

And STOS.... Well, what can I say? 278 seconds is a rotten result. I was able to compile the program, but the speed wasn't that much better. The PRG crashed during testing,
and I'm not overly interested to find out why. That said, STOS has been shown to work well, if you stick to using its builtin sprite engine.

 

FINAL WORD

 

Personally I love all this old software. While it's great to work with more modern software,
the question is then, where do you stop? Do you limit yourself to 1992 versions, 1995? 2000?

So, I'll be using Omikron BASIC. They all have faults, and really, 30+ years on, does it matter?

Cheers

 

Source and some PRG's are available here:

https://sourceforge.net/p/atari-st-basic-benchmarks/code/HEAD/tree/

 

' GFA BASIC VERSION
Map_x%=39
Map_y%=24
Dim Map%(Map_x%,Map_y%)
Cls
Ti=Timer
For Z%=1 To 10
  For X%=0 To Map_x%
    For Y%=0 To Map_y%
      Map%(X%,Y%)=Random(15)
    Next Y%
  Next X%
  For X%=0 To Map_x%
    For Y%=0 To Map_y%
      Deffill Map%(X%,Y%)
      Xx%=X%*8
      Yy%=Y%*8
      Pbox Xx%,Yy%,Xx%+6,Yy%+6
    Next Y%
  Next X%
Next Z%
Cls
Print Timer-Ti
Input A$

 

benchmark.png

Edited by derek.john.evans
Spelling
  • Like 5
  • Confused 1
Link to comment
Share on other sites

EXTRA INFORMATION

 

To compare Omikron's 17 second result to a theoretical max-speed, I tried my old favorite language Hispeed Pascal 1.5. I used the graph unit since it provides an easy way to fill rectangles without starting up a GEM app.

 

The result was 14 seconds, which i'm pretty sure would be close to the max. ie: the bottle neck would be GEM's fill rectangle code. As with Hisoft BASIC, HSPASCAL required a 1 meg machine to compile.

 

So, there you have it. While Omikron is "predictably" slower than HSPASCAL, its not by much. In fact, I only achieved 14 seconds after switching off range and stack checking. Something I'm unsure the Omikron compiler supports. With range checking, HSPASCAL returns a 16 second result.

 

I'm actually really impressed by Omikron's code generation. So, summing up....

 

If you want to relax on a 520ST/Floppy system, coding like its 1987 and let the annoying buzz of 2023 fade into the background, I highly recommend you try out Omikron BASIC 3.01+.

 

Cheers fellow coders
 

{$r-}
{$s-}

uses graph, bios;

const

  map_x=39;
  map_y=24;
 
var
  gd, gm: integer;
  map: array [0..map_x, 0..map_y] of integer;
  x, y, z, xx, yy: integer;
  ti: longint;
    
begin
  initgraph(gd, gm, '');
  ti := xgettime;
  for z := 1 to 10 do begin
    for x := 0 to map_x do begin
      for y := 0 to map_y do begin
        map[x, y] := random(15);
      end;
    end;
    for x := 0 to map_x do begin
      for y := 0 to map_y do begin
        xx := x * 8;
        yy := y * 8;
        setfillstyle(solidfill, map[x, y]);
        bar(xx, yy, xx+6, yy+6);
      end;
    end;
  end;
  clrscr;
  writeln(xgettime - ti);
  readln;
  closegraph;
end.

 

Edited by derek.john.evans
  • Like 2
Link to comment
Share on other sites

21 hours ago, zzip said:

Hard to believe STOS performs so poorly.  STOS games always seemed to perform better than GFA game

Maybe a wider variety of benchmarks should be tried?

STOS has a sprite engine with auto-movement. so, it can appear to be preforming better. The benchmark was designed for the specific games I listed. eg: Tetris: As you can see from the Omicron code below, there are a lot of 2D table look ups. And everything is rendered using filled rectangles. STOS is great, but I prefer to have access to procedures, functions and a better compiler.
 

4-Tetris
5
6 Game_Init
7
8 WHILE 1
9   Game_Play
10 WEND
11
12 END
13
14 DEF FN Shape_Point(X,Y)
15   LOCAL Z=Shape_Size(Shape)
16   IF Shape_R=0 THEN A=Shape(Shape,X,Y)
17   IF Shape_R=1 THEN A=Shape(Shape,Y,Z-X)
18   IF Shape_R=2 THEN A=Shape(Shape,Z-X,Z-Y)
19   IF Shape_R=3 THEN A=Shape(Shape,Z-Y,X)
20 RETURN A
21
22 DEF FN Shape_Collide
23   LOCAL Result=0,X,Y,Z=Shape_Size(Shape)
24   FOR Y=0 TO Z
25     FOR X=0 TO Z
26       Result=FN Shape_Point(X,Y)<>0 AND Map_Colors(Shape_X+X,Shape_Y+Y)<>0
27       IF Result THEN EXIT
28     NEXT
29     IF Result THEN EXIT
30   NEXT
31 RETURN Result
32
33 DEF PROC Shape_Hide
34   LOCAL X,Y,Z=Shape_Size(Shape)
35   FOR Y=0 TO Z: FOR X=0 TO Z
36     IF FN Shape_Point(X,Y) THEN
37       PROC Map_Color(Shape_X+X,Shape_Y+Y,0)
38     ENDIF
39   NEXT : NEXT
40 RETURN
41
42 DEF PROC Shape_Show
43   LOCAL C,X,Y,Z=Shape_Size(Shape)
44   FOR Y=0 TO Z: FOR X=0 TO Z
45     C=FN Shape_Point(X,Y)
46     IF C THEN PROC Map_Color(Shape_X+X,Shape_Y+Y,C)
47   NEXT : NEXT
48 RETURN
49
50 DEF PROC Shape_Play
51   Shape_Show
52   Shape_Timeout= TIMER +Game_Delay
53   REPEAT
54     Game_Draw
55     IF TIMER >Shape_Timeout THEN
56       Shape_Timeout= TIMER +Shape_Delay
57       Shape_Hide:Shape_Y=Shape_Y+1
58       IF FN Shape_Collide THEN
59         Shape_Y=Shape_Y-1
60         Shape_Show
61         Game_Collaspe
62         EXIT
63       ENDIF
64       Shape_Show
65     ENDIF
66     K$= INKEY$
67     IF LEN(K$)=4 THEN
68       K= CVIL(K$)
69       IF K=$500000 THEN Shape_Delay=5
70       IF K=$390020 THEN
71         Shape_Hide:Shape_R=(Shape_R+1) AND 3
72         IF FN Shape_Collide THEN Shape_R=(Shape_R-1) AND 3
73         Shape_Show
74       ENDIF
75       IF K=$4B0000 THEN
76         Shape_Hide:Shape_X=Shape_X-1
77         IF FN Shape_Collide THEN Shape_X=Shape_X+1
78         Shape_Show
79       ENDIF
80       IF K=$4D0000 THEN
81         Shape_Hide:Shape_X=Shape_X+1
82         IF FN Shape_Collide THEN Shape_X=Shape_X-1
83         Shape_Show
84       ENDIF
85     ENDIF
86   UNTIL MID$(K$,4)="a"
87 RETURN
88
89 DEF PROC Map_Color(X,Y,C)
90   IF Map_Colors(X,Y)<>C THEN
91     Map_Colors(X,Y)=C
92     Map_Change(0,Y)=-1
93     Map_Change(X,Y)=-1
94   ENDIF
95 RETURN
96
97 DEF PROC Game_Init
98   LOCAL I,X,Y
99
100   CLS
101   PRINT CHR$(27);"f"
102
103   'PALETTE 0,$700,$70,$770,$7,$707,$77,$444,$222,$200,$20,$220,$2,$202,$22,$777
104   PALETTE 0,$700,$70,$770,$7,$707,$77,$444,$222,$730,$20,$220,$2,$202,$22,$777
105   'OUTLINE OFF
106
107   LINE COLOR =4
108   BOX 0,0,319,199
109   LINE COLOR =8
110   BOX 1,1,317,197
111
112   Map_X=14:Map_Y=26
113   DIM Map_Colors(Map_X,Map_Y),Map_Change(Map_X,Map_Y)
114
115   READ Shape_Max
116   DIM Shape(Shape_Max,3,3),Shape_Size(Shape_Max)
117
118   FOR I=0 TO Shape_Max
119     READ Shape_Size(I)
120     FOR Y=0 TO Shape_Size(I): FOR X=0 TO Shape_Size(I)
121       READ Shape(I,X,Y)
122     NEXT : NEXT
123   NEXT
124 RETURN
125
126 DEF PROC Game_Clear
127   LOCAL X,Y
128   FOR Y=0 TO Map_Y: FOR X=1 TO Map_X
129     IF X<3 OR X>Map_X-2 OR Y>Map_Y-2 THEN
130       PROC Map_Color(X,Y,9)
131     ELSE
132       PROC Map_Color(X,Y,0)
133     ENDIF
134   NEXT : NEXT
135 RETURN
136
137 DEF PROC Game_Draw
138   LOCAL X,Y
139   FOR Y=1 TO Map_Y: IF Map_Change(0,Y) THEN
140     Map_Change(0,Y)=0
141     FOR X=1 TO Map_X: IF Map_Change(X,Y) THEN
142       Map_Change(X,Y)=0
143       FILL COLOR =Map_Colors(X,Y)
144       PBOX X*7,Y*7,6,6
145     ENDIF : NEXT
146   ENDIF : NEXT
147 RETURN
148
149 DEF PROC Game_Collaspe
150   LOCAL X,Y,Z,Gap
151   FOR Y=Map_Y-2 TO 0 STEP -1
152     Gap=0
153     FOR X=3 TO Map_X-2
154       IF Map_Colors(X,Y)=0 THEN Gap=-1: EXIT
155     NEXT
156     IF NOT Gap THEN
157       FOR X=3 TO Map_X-2: PROC Map_Color(X,Y,1): NEXT
158       Game_Draw
159       FOR X=3 TO Map_X-2: PROC Map_Color(X,Y,0): NEXT
160       Game_Draw
161       FOR Z=Y TO 1 STEP -1: FOR X=3 TO Map_X-2
162         PROC Map_Color(X,Z,Map_Colors(X,Z-1))
163       NEXT : NEXT
164       Game_Draw
165       Y=Y+1
166     ENDIF
167   NEXT
168 RETURN
169
170 DEF PROC Game_Score(A)
171   IF Game_Score<>A THEN
172     Game_Score=A
173     A$= MID$( STR$(A),2)
174     PRINT @(1,16);"PLAYER"
175     PRINT @(2,16); STRING$(6- LEN(A$),"0")+A$;
176   ENDIF
177 RETURN
178
179 DEF PROC Game_Play
180   Game_Delay=50
181   Game_Score 10
182   Game_Clear
183   WHILE 1
184     Shape= RND(Shape_Max+1)
185     Shape_X=6:Shape_Y=0:Shape_R=0
186     Shape_Delay=Game_Delay
187     IF FN Shape_Collide THEN EXIT
188     Shape_Play
189   WEND
190 RETURN
191
192 DATA 6
193 DATA 1,6,6,6,6
194 DATA 2,0,10,0,0,10,0,0,10,10
195 DATA 2,0,4,0,0,4,0,4,4,0
196 DATA 2,0,7,0,7,7,7,0,0,0
197 DATA 2,0,3,3,3,3,0,0,0,0
198 DATA 2,2,2,0,0,2,2,0,0,0
199 DATA 3,0,0,5,0,0,0,5,0,0,0,5,0,0,0,5,0

 

grab0001.png

Edited by derek.john.evans
spelling
Link to comment
Share on other sites

  • 3 weeks later...

In GFA random() returns a float which causes extra internal conversion, use rand() for an integer.

http://gfabasic.net/stg/gfabasic.htm#RAND

 

This bit of code is not seconds, it's 200th of a second:

ti=TIMER

' do some stuff

PRINT timer-ti

 

Correct way to get seconds:

ti%=TIMER   !returns a long

' do some stuff

PRINT (TIMER-ti%)/200

http://gfabasic.net/stg/gfabasic.htm#TIMER

 

If you don't need GEM, typical for a game, ARECT will outperform PBOX.

http://gfabasic.net/stg/gfabasic.htm#ARECT

 

All coordinates are in word range, perhaps word variables will impact the speed.

I can only conclude you didn't read that manual. The test is flawed. I'm not an expert at the other languages, but if this is how you conduct tests perhaps all of them are inconclusive.

 

FYI, GBE supports pointers to procedures with some limits.

 

Edited by lp060
typo
Link to comment
Share on other sites

RE: Timer. Yes, all results were converted to seconds by hand. Otherwise I would have been posting numbers like 7764 seconds...

RE: Rand() vs Random(). The doc's do state "Random() produces a random integer between 0 and x". That said, Rand() is slightly faster, and dropped the GFA result by 1 second.

RE: 16bit vs 32bit. I tried both, and didn't notice any change in speed.

RE: ARECT vs PBOX. yes, you are absolutely right. The LineA ARECT command is significantly faster than PBOX. So much so, the GFA time dropped to 5 seconds.

Omikron doesn't have builtin LINEA commands, but, after I added some, Omikron dropped to 6 seconds.

 

I've attached the PRG's below.

 

RE: inconclusive? I would say the test is valid.

 

I stated in my first post: "All the BASIC's tested support integrating machine code and each supply a variety of extra graphics functions for various purposes."

 

ie: I am well aware there are various optimizations options for each language. All source code is provided.

 

 

GFA3.PRG OMIKRON.PRG

Edited by derek.john.evans
Link to comment
Share on other sites

1 hour ago, derek.john.evans said:

RE: Timer. Yes, all results were converted to seconds by hand. Otherwise I would have been posting numbers like 7764 seconds...

RE: Rand() vs Random(). The doc's do state "Random() produces a random integer between 0 and x". That said, Rand() is slightly faster, and dropped the GFA result by 1 second.

RE: 16bit vs 32bit. I tried both, and didn't notice any change in speed.

RE: ARECT vs PBOX. yes, you are absolutely right. The LineA ARECT command is significantly faster than PBOX. So much so, the GFA time dropped to 5 seconds.

Omikron doesn't have builtin LINEA commands, but, after I added some, Omikron dropped to 6 seconds.

 

I've attached the PRG's below.

 

RE: inconclusive? I would say the test is valid.

 

I stated in my first post: "All the BASIC's tested support integrating machine code and each supply a variety of extra graphics functions for various purposes."

 

ie: I am well aware there are various optimizations options for each language. All source code is provided.

 

The gfa manual is notorious for inaccuracies and typos.

I don't have a vintage 520st. That said the gfa build runs on my 040 setup, the omikron build freezes it. Omikron is plagued with lots of other problems, if it don't run the speed means nothing. I fully agree STOS isn't great if one is used to a structured language, but there's lots of extensions that push it beyond it's default abilities. 

Edited by lp060
typo
Link to comment
Share on other sites

RE: That said the gfa build runs on my 040 setup, the omikron build freezes it. Omikron is plagued with lots of other problems,

 

Maybe, maybe not. My Omikron LINEA code just used some pokes and inline "A005". Which worked fine on ST's. Dont blame Omikron for that.

I have a feeling I need to add some register push/pulls for TOS 4+

I did avoid LINEA calls for this reason. I really am not overly fussed by what language I use. Personally I prefer C & Pascal. But, Im putting together some code for simple games using software from 1988, so that rules out Pure C/Highspeed Pascal and Pure Pascal.

 

As far as Falcon support, (Aranym for me), I have had the least problems with Omikron 5. (Other than trying to read German/French manuals)

 

Anyway, this test is one of ~4 which I've been running. The others include line, blit and GEM development. I'll always consider GFA, but so far Omikron has been more productive for me.

Edited by derek.john.evans
Link to comment
Share on other sites

Shouldn't have to do anything special on TOS 4 for a line-a call. I can tell you that gfa does nothing special for line-a calls on TOS 4 because I build the entire gfa library from source code. ;)  I'd bet it's something else causing the freeze.

 

The omikron build from your repo also freezes my system, but I see the boxes before it hangs.

 

 

 

 

Edited by lp060
updated
Link to comment
Share on other sites

Mmmm. Ok, So it looks like I might have to rethink my dev plan. I prefer Omikron 3.6+ code folding, GEM library and function pointers with parameters, but GFA does fly nicely with its LINEA function set.

I like the function pointers because my GUI library provides embed-able , autonomous reusable controls. ie: I need function pointers.

I'll give GFA another try over the next week.

My line drawing benchmark is: (GFA Source)

HIDEM
ti=TIMER
FOR j&=1 TO 15
  FOR i&=0 TO 199
    ALINE 0,i&,319,199-i&,j& AND 15,-1,0
  NEXT i&
  FOR i&=0 TO 319
    ALINE 319-i&,0,i&,199,j& AND 15,-1,0
  NEXT i&
NEXT j&
PRINT TIMER-ti

 

OMIKRON 3.01 Interpreter=2394 Compiled=2323

GFA 3.6 Interpreter=2117 Compiled=1914

 

So, it does look like GFA would improve my 3D rotation code and my 2D Vector Asteroids game which I'm coding.

 

Mmmm. I'll have rethink.

Edited by derek.john.evans
  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...
On 3/24/2023 at 2:06 PM, zzip said:

Hard to believe STOS performs so poorly.  STOS games always seemed to perform better than GFA games

 

Maybe a wider variety of benchmarks should be tried?

 

Looking at the code, there's no screen swapping between the physical screen (what you see) and the back screen (in memory) that was the common technique in STOS programming.  It makes the animation run at the same refresh rate as the screen (50 or 60 Hz).

 

The OP's code is a straight up drawing right on the screen which is what all BASIC programs do, and hence why they are all so slow for making arcade games.

Link to comment
Share on other sites

On 3/24/2023 at 8:06 PM, zzip said:

Hard to believe STOS performs so poorly.  STOS games always seemed to perform better than GFA games

 

Maybe a wider variety of benchmarks should be tried?

I don't think that's true at all. GFA is generally much faster. Can you point me to an example?

 

Link to comment
Share on other sites

19 hours ago, Christos said:

I don't think that's true at all. GFA is generally much faster. Can you point me to an example?

 

Just a feeling based on the games I used to see in STOS and GFA.  STOS seemed to have better games-  more fleshed out, better performing.

 

But since I've never coded in STOS, I don't know for sure.   As a GFA programmer, I often felt like I was using the wrong language when I saw what was being done with STOS 

 

Could just be a case of  "the grass is always greener..."  :)

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...