I ported the BASIC benchmark to the C64, well really just copied as no changes were needed. I did add in the use of the Jiffy timer to automatically measure the execution time. The times are listed in the source code below. Also note that I ran this on WinVICE and a real C64 and the execution time was the same which is nice as in VICE I can run it in 'Warp' mode which is about 1,500% of the C64 speed
In the table showing times VBas is BASIC in VICE, CBas is BASIC on real C64, etc.
I then ported to DurexForth also on the C64. This is an ugly bit of code but it works and is still much faster than basic even though I wrote the integer square root function in Forth. I'm just dumping the Jiffy timer to the stack before the code starts and when it is done and calculating the difference by hand as I was too lazy to write a d- function (though I will likely do that and a better sqrt soon in assembly as once I figured out how to work with the Forth start from assembly it was quite easy.)
C64 BASIC
Code:
100 REM
110 REM B A S I C - B E N C H
120 REM
130 REM The program tests whether it is in the area [3.. a] of the natural
140 REM Numbers two consecutive prime numbers P1 < P2 whose
150 REM difference is greater than or equal to B (P2-P1 > = b).
160 REM
170 REM Test values - Results - VBas - CBas - VForth - CForth
180 REM A 1000,20 - 907, 887,20 - 48s 48s 18s 18s
190 REM B 2000,30 - 1361, 1327,34 - 118s 118s 30s 30s
200 REM C 9999,35 - 9587, 9551,36 - 1412s 1412s 374s 374s
210 REM D 32000,50 - 19661, 19609,52 - 3516s 3516s 1530s 1530s
220 REM E 32000,70 - 31469, 31397,72 - 10447s 10477s 2352s 2352s
230 REM F 500000,100 - 370373,3790261,112 - 45819s
240 REM
250 ZS = 3 : INPUT A,B
260 TIME$ = "000000":rem reset clock
270 FOR C = 3 TO A STEP 2
280 FOR D = 3 TO SQR(C) STEP 2
290 IF INT(C/D)*D = C THEN goto 330
300 NEXT D
310 IF C-ZS >= B THEN PRINT C,ZS,C-ZS : GOTO 350
320 ZS = C
330 NEXT C
340 PRINT " no solution " : GOTO 250
350 print "time", time$: goto 250
DurexForth on C64
Code:
variable ZS 3 ZS !
variable A
variable B
variable match 0 match !
code jiffy
dex, sei,
$a1 lda, msb sta,x
$a2 lda, lsb sta,x
dex,
$00 lda,# msb sta,x
$a0 lda, cli, lsb sta,x ;code
( isqrt(n):
x = n \ x == old guess
y = (x + 1) / 2 \ y == new guess
while y < x:
x = y
y = (x + n / x) / 2
)
( Integer square root based on above )
( Returns the largest integer x )
( for which x * x does not exceed n )
: sqrt ( n -- root )
dup 1 + 1 rshift
begin
2dup /include
over + 1 rshift
swap over >
while repeat
nip
;
: dloop ( cloopI -- )
-1 nomatch !
dup \ cloop value
sqrt 4 max 3 do
dup dup I / I *
= if 0 nomatch ! leave then
2 +loop
drop
;
( pops all three bytes of jiffy clock
onto the stack as two unsigned doubles )
( -- ud ud)
code jiffy
dex, sei,
$a1 lda, msb sta,x
$a2 lda, lsb sta,x
dex,
$00 lda,# msb sta,x
$a0 lda, cli, lsb sta,x ;code
( A B -- )
: benchmark
decimal
B ! A ! \ save A&B off stack
jiffy
A @ 3 do
I dloop nomatch @ if \ no match
I ZS @ - B @ -
0< invert if
I . ZS @ . I ZS @ - . leave then
I ZS !
then 2 +loop
jiffy
;