There's some additional features in Bunny Basic though, such as GOTO statement accepts a variable:
A=10:GOTOA
Or using variables A, X, Y as input to KERNAL routines, and similarly reading the returning register values from A, X, Y variables as well (KERNAL GETIN in this example):
SYS65508:IFA=87THENPRINT"A PRESSED"
It's possible to mix Bunny Basic and CBM BASIC V2 and for example write fast subroutines or the main game loop in Bunny Basic. Or use CBM BASIC V2 to set up user-defined characters from DATA statements, as done in this programming example.
Here's an example program with full comments, a simple worm game with a twist. This is for unexpanded VIC 20, but there's also a Bunny Basic version available for VIC 20 with expansion memory and Commodore 64. Links after the program listing.
Code: Select all
Kakamato (Bunny Basic example program for unexpanded VIC 20)
Load Bunny Basic interpreter first:
LOAD"BUNNYUNEXP20",8,1
POKE56,24:NEW
Then load Kakamato and start with a RUN.
**** Program starts in slow CBM BASIC mode and calls a graphics init subroutine
**** then jumps to Bunny Basic code starting on line 2
1 gosub1000:sys6144,2:end
**** Bunny Basic code starts. CLR clears all Bunny Basic variables A-Z (otherwise
**** they're in last/unknown state). Draw screen and init game variables subroutine called
2 clr
3 gosub650
**** Start of main loop. Stop beep sound. Calculate frame speed, wait 'A' frames
**** GOSUB500 stores current head location in tail buffer at 7552-7679
10 a=u/2:gosub500:poke36874,0
11 poke37166,64:wait36868,128,128:wait36868,128:poke37166,192:a=a-1:ifa>0thengoto11
**** KERNAL GETIN called. Returns 6502 accumulator value in 'A'
**** Note: SYS always reads and changes Bunny Basic variables A, X, Y
**** WASD keys checked. GOSUB600 checks immediate crash in new direction
12 sys65508:ifa=87theno=-22:gosub600
13 ifa=65theno=-1:gosub600
14 ifa=68theno=1:gosub600
15 ifa=83theno=22:gosub600
**** Draw head at new location, GOSUB520 clears last step of tail. GOSUB915 if we
**** get an apple. After that any other but reverse-space-char (160) is a crash (800)
**** Play a short beep with frequency from worm speed, then go to start of main loop
16 c=w+z:pokew,43:pokec,5:w=w+l:a=peek(w):c=w+z:pokew,42:pokec,1:gosub520
17 ifa=41thengosub915:goto10
18 ifa<160thengoto800
20 a=240-u:poke36874,a:goto10
**** Subroutine: Store worm location in tail ring buffer at 7552-7679
500 e=w/256:f=wand255:g=g+2:ifg=7680theng=7552
510 pokeg,f:g=g+1:pokeg,e:g=g-1:return
**** Subroutine: Clear one step of worm tail at length Q
520 h=g-q:ifh<7552thenh=h+128
530 f=peek(h):h=h+1:e=peek(h):e=e*256:f=f+e:e=peek(f):ife=43thenpokef,160
540 return
**** Subroutine: After WASD key press, check for immediate crash in that direction.
**** Only allow turning into apples (41) and reverse-space-char (160), otherwise clear
**** keyboard buffer to prevent multiple illegal moves building up at slower speeds
600 v=w+o:d=peek(v):ifd=160thenl=o:return
601 ifd=41thenl=o:return
602 poke198,0:return
**** Subroutine: Draw screen and initialize game variables
**** Variables: W = worm location, L = worm direction, Z = constant to reach Color RAM,
**** G = pointer to worm tail buffer, U = worm speed, Q = worm length, S = score
650 poke36866,128:poke36867,0:poke36869,255:poke36879,10:print"{clr}{red}";:s=0:poke36878,15
651 gosub900:gosub900:a=1
652 gosub910:a=a+1:ifa<20thengoto652
653 gosub900:gosub920:poke36867,44:poke36866,150
655 w=7916:l=-1:z=30720:u=18:q=20:c=w+z:pokew,42:pokec,1
656 g=7680
657 g=g-1:pokeg,0:ifg>7552thengoto657
660 print"{home}{down}{down}{down}{down}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rvon}{wht}k{yel}a{wht}k{yel}a{wht}m{yel}a{wht}t{yel}o{left}{left}{left}{left}{left}{left}{left}{left}";:gosub700:poke198,0:wait198,1
666 print" ":return
**** Subroutine: Place an apple. Low 4 bits of timer low byte from 37140 used as 'random'
700 r=peek(37140):r=rand15:a=7749+r:r=peek(37140):r=rand15:r=r*22:a=a+r
705 b=peek(a):ifb<>160thengoto700
710 c=a+z:pokec,7:pokea,41:return
**** Crash. Flash head, roll in worm tail. Wait for a keypress and go to start
800 a=peek(37140):pokec,a
801 gosub520:ifq>0thenq=q-2:wait36868,128,128:wait36868,128:a=126+q:poke36877,a:goto800
802 pokec,2
810 poke198,0:wait198,1:goto3
**** Draw upper/lower wall (900), and side wall (910)
900 print"{rvof}((((((((((((((((((((((";:return
910 print"({rvon} {rvof}(";:return
**** Subroutine: Add 1 to score, play beep, excrement and slow down if maximum speed reached.
**** Add 1 step to worm length. Print out score (S) and best score (I)
915 poke36874,240:s=s+1:ifs>itheni=s
916 u=u-1:ifu=3thenu=10:gosub700:gosub520:c=f+z:pokec,2:pokef,44:poke36874,130
917 gosub700
918 ifq<126thenq=q+2
920 print"{home}{rght}{rvon}{yel}score:{wht}";:prints;:print"{home}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{yel}best:{wht}";:printi;:return
**** This graphics init code is executed in slow CBM BASIC at first run. Bunny Basic doesn't support the instructions FOR, NEXT and DATA
1000 fora=7488to7527:readb:pokea,b:next:return
1010 data247,247,247,0,223,223,223,0
1020 data12,16,110,255,254,254,255,110
1030 data102,126,219,255,189,195,102,60
1040 data24,28,63,255,255,252,56,24
1050 data8,16,56,28,98,189,207,114
Download from Dropbox (Kakamato in examples folder):
https://www.dropbox.com/sh/6khrwf1t0eex ... jIyVa?dl=0
Direct link to Bunny Basic manual:
https://www.dropbox.com/s/9sp53b2kxlfio ... l.pdf?dl=0
More info about Bunny Basic in Announcements:
http://sleepingelephant.com/ipw-web/bul ... 56#p104463