Hare Basic - Fast integer BASIC for VIC 20 and C-64

Basic and Machine Language

Moderator: Moderators

Post Reply
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

What if BASIC was fast?

To celebrate the BASIC (Beginners' All Purpose Symbolic Instruction Code) turning 60 years old, I'm releasing a big update to my old Bunny Basic from 2019, now called Hare Basic.

Hare Basic is a fast, limited instruction set, integer-only basic interpreter (not a compiler) for Commodore 64 and VIC 20. Requires 32K/35K expansion on VIC 20 (RAM in block 5).

There's a bunch of system calls available through instruction GO that go "beyond basic", such as turn IRQ on/off, copy or fill memory areas very fast, sync to display to avoid flickering, view disk directory, copy character ROM to RAM and move program data higher in RAM to reserve space for graphics, do bit shifts, 16-bit pokes, instantly calculate screen and color memory locations for given coordinates, etc. (See Handbook: GO System Calls)

Mostly everything is at least 6 times faster than CBM BASIC.

Hare Basic (VIC 20).png
Hare Basic (VIC 20).png (890 Bytes) Viewed 2150 times
vicraster.png
vicraster.png (6.57 KiB) Viewed 2150 times

It's easy to mix Hare Basic code with CBM BASIC code by just treating Hare Basic code as subroutines, called by A=USR(linenumber). Final Hare Basic program, including any data loaded into memory and the interpreter itself, can be linked into a single file (see Handbook: Packacing a final Hare Basic program).

Download: https://bit.ly/harebasic or
Hare Basic.zip
(24.25 KiB) Downloaded 97 times
or
singlefiles.zip
(31.95 KiB) Downloaded 110 times
Handbook: https://bit.ly/harebasichandbook or
Hare Basic Handbook.zip
(150.71 KiB) Downloaded 109 times

Commands: PRINT, INPUT, GET, POKE, SYS, GOTO, CLR, GOSUB, RETURN, IF/THEN, END, FOR/NEXT, LOAD, SAVE, REM, LET, RND (as command), CMD (repurposed for POKE mode)

Functions: AND, OR, PEEK, VAL, LEN, ASC, <, =, >, <>, <=, >=, +, -

Variables: 26 one-letter variables A-Z, 16-bit unsigned integer (not shared with CBM BASIC)

Arithmetics: 16-bit unsigned integer addition, subtraction, multiplication, division, negation

Limited string functions: CHR$, STR$ (repurposed to display strings), POKE12345,"TEXT"

Hare Basic syntax is very similar to CBM BASIC, but there's quite a few restrictions and some critical differences. You should still feel like at home right away, just dive in!

A=USR(10) in CBM BASIC starts running a Hare Basic program starting from line 10.

If you're writing your entire program in Hare Basic, just type A=USR(10):END on the first basic line before line 10. Start writing Hare Basic code from line 10. This way you can start your program normally with a RUN.

Hare Basic syntax is very similar to CBM BASIC, but there's quite a few restrictions and some critical differences. You should still feel like at home right away, just dive in!

There is no string variables. However, there's simple support for null-terminated strings that can be freely located in the memory. Some commands work a little differently: For example GET gives the PETSCII code of a key and INPUTA uses variable A as a pointer to memory where it stores the user input as a null-terminated string. (You can also type for example INPUT832 to read input to tape buffer).

There is no arrays. Access memory directly with POKE and PEEK to create larger data structures.

All variables are 16-bit unsigned integers. Negative numbers, if entered, are handled as two's complement.

Only one arithmetic operation can be done at once. Arithmetics may only be done as separate instructions and not as regular expressions in command parameters.

See the Handbook for details!

--

Comparison to old Bunny Basic: Bunny Basic was only 1300 bytes in size, while Hare Basic interpreter now takes a whole 4K block. Unexpanded VIC 20 is no longer supported. New commands: INPUT, GET, POKE string, FOR/TO/STEP/NEXT, LOAD, SAVE, RND, CMD, GO (system calls). New functions: VAL, LEN, ASC, variable increment/decrement (A-/A+), STR$ (repurposed to display null-terminated strings from memory). Bunny Basic started with a SYS, but Hare Basic starts by the less often used USR function of CBM BASIC
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

Some benchmarks:

Task: Fill screen memory 15 times
CBM BASIC: 3191
Hare Basic FOR loop: 303 (10.5X faster)
Hare Basic GO system calls (GO3 block fill): 14 (228X faster)

Task: Generate 1000 random numbers (0-65534)
CBM BASIC: 958
Hare Basic: 17 (56X faster)

Task: 1000 multiplications, 1000 divisions, draw 1000 characters on screen in various colors
CBM BASIC: 1228
Hare Basic: 199 (6X faster)

Task: B=12345, add 5 to B, repeat 1000 times
CBM BASIC: 240
Hare Basic: 31 (7.7X faster)

Task: B=0, add 1 to B 1000 times
CBM BASIC: 239
Hare Basic (same code): 30 (8X faster)
Hare Basic (using B+ increment): 14 (17X faster)

Task: delay loop, count from 1 to 10000
CBM BASIC: 672
Hare Basic: 86 (7.8X faster)

Task: Fill screen with random characters
CBM BASIC: 387
Hare Basic (byte-by-byte): 14 (27X faster)
Hare Basic GO system calls (GO6 16-bit poke, for-loop step 2): 8 (48X faster)

Task: Move program to higher memory, copy character ROM to RAM, and display a full screen picture
CBM BASIC: Could be several minutes, don't even want to try
Hare Basic GO system calls (GO12 char ROM copy, 3 x GO4 copy memory): A second (at least 200X faster)
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 196
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by MrSterlingBS »

Hi aeb,

can you compare your hare BASIC with the Austro , BASIC Boss, and so on?
Here is a link to a german magazine where the author compare a lot of BASIC compilers.

https://archive.org/details/64er_sonder ... 1/mode/1up

Best regards
Sven
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

Interesting article! Hare Basic does quite well in those it can do, but it can't do all, since it's a rabbit:

Benchmark 1: FOR NEXT
0,13

Benchmark 2: IF THEN
1,07 (without optimizations)
0,83 (with optimization: using I+ instead of I=I+1)
0,55 (with extra optimization: max value in variable: E=1000, compare I<E instead of I<1000)

Benchmark 4: GOSUB
0.53 (condition: subroutine near start of program)

Benchmark 5: FELDER
1.15 (Hare has no arrays, so not doing exactly the same, but something very close: writing 1000 byte values to memory and writing 1000 times the string "TEXT",0 to memory at different addresses, so each item can be read back later)

compilers.jpg

The other benchmarks are not directly runnable in Hare Basic: 3 (no powers or floating point), 6 (no trigonometric functions), 7 (no read/data), 8 (no string comparison).

With Hare, you can always do operations in regular slow basic if necessary, and only call Hare subroutines when speed is needed and the limited instruction set is sufficient. Also, Hare is an interpreter, not a compiler, so there's zero compiling time (compared to 2-6 minutes with Austro etc.)

Hare interpreter adds 17 blocks (or 11 blocks compressed), if added to end of program (Handbook: Packacing a final Hare Basic program).

MrSterlingBS wrote: Fri May 17, 2024 5:12 am Hi aeb,

can you compare your hare BASIC with the Austro , BASIC Boss, and so on?
Here is a link to a german magazine where the author compare a lot of BASIC compilers.

https://archive.org/details/64er_sonder ... 1/mode/1up

Best regards
Sven
User avatar
huffelduff
Vic 20 Hobbyist
Posts: 128
Joined: Sat Sep 05, 2020 9:14 am

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by huffelduff »

aeb wrote: Thu May 16, 2024 9:58 am Some benchmarks:
Hi there Alexi,

Let met first complement you; Whenever I think I am progressing as a Vic-20 programmer I take one look at Vuokatti and/or Tammerfors and I rejoice in the fact that I still don't know anything. And when I think I maybe could attempt to write system type software I look at Pixels work on Tunix and decide I should just keep quiet. For graphics complexity, yeah its Mike. Ok enough of this...

So I've been looking at Hare and the precursor Bunny which I have now collectively dubbed: The Rabbit languages.
I have developed a bit of an obsession: That being Basic and your integer Basic is just up my alley for my attempt at the Basic 10 liner world championship crown. https://gkanold.wixsite.com/homeputerium/results-2024/

Preamble:
Those snooty guys/gals with their MSX 8-bit machines grind my gears because they get to do fancy graphics and sound without much seeming effort :D To dethrone them I need a Vic-20 Super weapon language to kick their behinds. Enter Integer Basic (Hare/Bunny)!
Hare and Bunny are great and your Benchmarks suggest that it will be able to compete speedwise easily.
The Vic-20 line limit of 86 characters is the biggest hurdle though.

So here's my plan:
1. Take Bunny combine it with a command interpreter I wrote for an incomplete Forth I work on now and again. This would allow the Basic to have a 256 character input limit per line giving a total of 2.5k worth of code. Now maybe I'll be able to get it right and maybe not, but I'm going to try.
2. Make a primitive 2x2 character set of sprite library routines and add those as keywords. (Still to be pondered/vexed over)
3. Incorporate my sound fx library routines as keywords.
4. Incorporate my primitive music tracker as basic keywords. (Oh how I dream of using the keyword PLAY)
5. Incorporate some joystick routines as keywords.
6. Build turbo IO routines for tape/disk (ha ha ha fat chance)
7. Submit my work to you so that you can add the Hare block copy keywords/ the increment/decrement keywords and so on.
8. Fit it all into 4k and make it a cartridge ROM and Christen it JACKRABBIT.
9. Write a banging game that blows everyone's socks off (WOW you wrote Fortnite in BASIC????!!!!!)
10. Submit the game to the EXTREME-256 Basic category.
11. Win ALL of everything and be crowned Empress of the moon!!!
12. ???
x3. Profit and retire on Mars Base 5.

I expect the work to be finished in 2035, but I can still dream can't I?

Anyhow thanks for the software and making me dream.

H
Last edited by huffelduff on Fri May 17, 2024 10:10 am, edited 2 times in total.
User avatar
huffelduff
Vic 20 Hobbyist
Posts: 128
Joined: Sat Sep 05, 2020 9:14 am

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by huffelduff »

MrSterlingBS wrote: Fri May 17, 2024 5:12 am Hi aeb,
Footnote: MrSterling I follow your struggles with Vector graphics with intense interest. I don't contribute to your threads because I don't know enough to make a real sensible contribution, but I think like myself many are watching. You and Mike are not alone!

I maybe have one tiny tip I picked up after reading one of your threads (The one with the fantastic spinning cube). You are probably aware of this already though so I apologize in advance: While perusing the Flicker Free Elite site I came upon something which it turns out is the KEY optimization to flicker free Elite; When drawing an update to a vector object;

1. DO NOT DELETE THE ENTIRE OLD VECTOR OBJECT.
2. DELETE ONE LINE AT A TIME AS YOU DRAW THE NEW OBJECT ONE LINE AT A TIME.

It sounds so stupid but I tested this with my single quadrant slow as dirt Bresenham algorithm and lo and behold, it works!

Greetings (and watching)

H
Cosmic wing - line draw test (32x32 single quadrant Bresenham - kek).png
I can't share my code, I don't want to be laughed at.
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 196
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by MrSterlingBS »

Thank you for the benchmark. Hare BASIC is extremly fast.

It's a shame that Commodore didn't release the Vic 20 with a slightly larger ROM (+4k) and faster BASIC with proper integer calculation routines. We see here how fast BASIC can be, even without a compiler. a very successful project. thanks for that.
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 196
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by MrSterlingBS »

Here are the results of the BASIC BOSS for comparison. I still believe this to be the fastest Commodore V2 BASIC compiler.

IMG_1534.jpeg

(mod: image attachment repaired. Use "Place inline", not an 'empty' image tag pair!)
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 196
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by MrSterlingBS »

Hare BASIC is very, very fast...

Her is the demo you are waiting for! :-)

Code: Select all

10 a=usr(20)
20 poke36879,9
30 poke36878,15
35 x=4096:y=4600:a=32:go3
40 x=1:y=1
50 d=1:t=1
60 z=1:a=81
70 go14
100 forw=0to100:next
105 go2
110 a=32:go14
120 x=x+d
130 ifx=0thend=-d:poke36876,230
135 ifx=21thend=-d:poke36876,230
140 y=y+t
145 ify=0thent=-t:poke36876,220
150 ify=22thent=-t:poke36876,220
160 poke36876,0
200 goto60
Just drag and drop the code to VICE.
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

Haha! Neat, good old char 81 kicking it :D

I experimented with Bagdad game style 12x12 pixel 'semi' soft sprites that can be stamped anywhere at 4 pix accuracy, but didn't include this in the Hare Basic release, because this would be much more handy if written in machine code as a Hare user extension (GO15 command)...

(Also, this Hare version is a bit too slow on NTSC and the sprite ghosts away when near top of screen. Change f=0 to f=10 on line 33 to fix)

GO15 jumps through vector at $affe/$afff and hands you the low 8 bits of variable A in accumulator, and $fb/$fc pointing at 16-bit values of variables X, Y and Z (which the user extension can freely modify). Index registers x and y are zero at entry. RTS to return.

(Bagdad: https://www.youtube.com/watch?v=IIoAWN9RcLw)

Code: Select all

1 gosub900:a=usr(10):end
2 rem bagdad game style 'semi' soft sprites example in hare basic
10 go12:printchr$(147);:gosub800
20 e=5:f=10:q=1:r=1:cmd0:s=22
30 forw=0to1step0:e=e+q:f=f+r:gosub100
31 ife=0thenq=1
32 ife=41thenq=-1
33 iff=0thenr=1
34 iff=43thenr=-1
40 go2:a=o:pokea,"  ":a=a+s:pokea,"  ":next
99 rem *** draw sprite at e,f
100 c=128:b=eand1:ifb=1thenc=c+4
110 b=fand1:ifb=1thenc=c+8
115 a=e:z=1:go9:x=a:a=f:go9:y=a
120 go13:o=a:pokea,c:a+:d=c+2:pokea,d:a=a+21:c+:pokea,c:a+:c=c+2:pokea,c
130 return
800 rem *** preshift sprite in hare basic
810 fora=6176to6271:pokea,0:next
820 x=832:y=863:z=6144:go4:z=6212:go4
830 fory=6144to6155
835 b=peek(y):i=y+16:a=peek(i):i=i+32:b=b*256:a=a+b:z=4:go9:pokei,a:i=i+68:pokei,a
840 a=a/256:u=y+32:pokeu,a:u=u+68:pokeu,a:next:return
900 rem *** read sprite data in cbm basic
905 c=832:fory=0to11:reada$:n=8:gosub950:pokec,v:n=4:gosub940:pokec+16,v:c=c+1:next
910 fory=0to3:pokec,0:pokec+16,0:c=c+1:next
920 return
940 a$=right$(a$,4)
950 v=0:b=128:fora=1ton:ifmid$(a$,a,1)="*"thenv=v+b
955 b=b/2:next:return
1000 data..***.***...
1001 data.****.****..
1002 data.****.****..
1003 data.****.****..
1004 data..***.***...
1005 data.*********..
1006 data***.***.***.
1007 data***********.
1008 data****...****.
1009 data**.**.**.**.
1010 data.**.....**..
1011 data...*****....
MrSterlingBS wrote: Fri May 17, 2024 4:56 pm Hare BASIC is very, very fast...

Her is the demo you are waiting for! :-)

Code: Select all

10 a=usr(20)
20 poke36879,9
30 poke36878,15
35 x=4096:y=4600:a=32:go3
40 x=1:y=1
50 d=1:t=1
60 z=1:a=81
70 go14
100 forw=0to100:next
105 go2
110 a=32:go14
120 x=x+d
130 ifx=0thend=-d:poke36876,230
135 ifx=21thend=-d:poke36876,230
140 y=y+t
145 ify=0thent=-t:poke36876,220
150 ify=22thent=-t:poke36876,220
160 poke36876,0
200 goto60
Just drag and drop the code to VICE.
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

Sounds like a plan :D Very detailed. A ten year plan, indeed!
huffelduff wrote: Fri May 17, 2024 8:42 am
aeb wrote: Thu May 16, 2024 9:58 am Some benchmarks:
So here's my plan:
1. Take Bunny combine it with a command interpreter I wrote for an incomplete Forth I work on now and again. This would allow the Basic to have a 256 character input limit per line giving a total of 2.5k worth of code. Now maybe I'll be able to get it right and maybe not, but I'm going to try.
2. Make a primitive 2x2 character set of sprite library routines and add those as keywords. (Still to be pondered/vexed over)
3. Incorporate my sound fx library routines as keywords.
4. Incorporate my primitive music tracker as basic keywords. (Oh how I dream of using the keyword PLAY)
5. Incorporate some joystick routines as keywords.
6. Build turbo IO routines for tape/disk (ha ha ha fat chance)
7. Submit my work to you so that you can add the Hare block copy keywords/ the increment/decrement keywords and so on.
8. Fit it all into 4k and make it a cartridge ROM and Christen it JACKRABBIT.
9. Write a banging game that blows everyone's socks off (WOW you wrote Fortnite in BASIC????!!!!!)
10. Submit the game to the EXTREME-256 Basic category.
11. Win ALL of everything and be crowned Empress of the moon!!!
12. ???
x3. Profit and retire on Mars Base 5.

I expect the work to be finished in 2035, but I can still dream can't I?

Anyhow thanks for the software and making me dream.

H
User avatar
AndyH
Vic 20 Afficionado
Posts: 379
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by AndyH »

I've just watched Robin's video. It looks most impressive, well done aeb. I wonder if I can interface my lbm8 library with it in some way? Can we add our own go commands?

You'd have been a millionaire if you'd released this back in 1984!

(edit): Read the manual. I see you have made it super easy to load in and execute machine code.
Bunny Basic was only 1300 bytes in size, while Hare Basic interpreter now takes a whole 4K block. Unexpanded VIC 20 is no longer supported.
Hey above you mention it is now 4k starting at address $a000. Does that mean I could use the other 4l at $b000 if I wanted to or is Hare basic using it all?
--
AndyH
HEWCO | Vic 20 blog
aeb
Vic 20 Dabbler
Posts: 76
Joined: Sat Jun 19, 2004 2:06 pm

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by aeb »

Ah, there was a human error in the documentation, $B000-$BFFF is indeed free for any use. I corrected the memory chart in the handbook (page 21) - https://bit.ly/harebasichandbook

GO15 is intended exactly for this purpose. SYS may be a few cycles faster (or not). The difference is:

- GO15 provides low 8 bits of Hare variable A in the accumulator, zeroes X & Y registers (good to know if writing tight code), and points $fb/$fc to memory where you can read and modify the 16-bit values of Hare variables X, Y and Z (6 bytes, lsb/msb pairs). GO15 jumps through the vector $AFFE/$AFFF (VIC 20) or $CFFE/$CFFF (C-64)

- SYS takes the low 8 bits of Hare variables A, X, Y to accumulator and registers X & Y, and sets the carry flag if Hare variable Z = 1, then calls the machine code routine. Values from accu, registers and carry flag are returned to the same variables (and MSB's are zeroed)

...so both methods do a bit of housekeeping before processor gets to the subroutine. Also, they store and restore reg y, which holds the position on current basic line.

Keeping the address in a variable and doing SYSU, SYSV, SYSW, etc. is probably the fastest way to access machine code subroutines, at least if there's more than one of them.

AndyH wrote: Sun May 19, 2024 10:51 am I've just watched Robin's video. It looks most impressive, well done aeb. I wonder if I can interface my lbm8 library with it in some way? Can we add our own go commands?

You'd have been a millionaire if you'd released this back in 1984!

(edit): Read the manual. I see you have made it super easy to load in and execute machine code.
Bunny Basic was only 1300 bytes in size, while Hare Basic interpreter now takes a whole 4K block. Unexpanded VIC 20 is no longer supported.
Hey above you mention it is now 4k starting at address $a000. Does that mean I could use the other 4l at $b000 if I wanted to or is Hare basic using it all?
User avatar
AndyH
Vic 20 Afficionado
Posts: 379
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Hare Basic - Fast integer BASIC for VIC 20 and C-64

Post by AndyH »

I will make some time to give it a go.

Huge thanks for including Vic20 support and if looks like you have everything covered in what the c64 and Vic needs.
--
AndyH
HEWCO | Vic 20 blog
Post Reply