Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 12:03 12 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Bypic PIC32 Basic

Author Message
memberx
Newbie

Joined: 20/04/2012
Location: Australia
Posts: 24
Posted: 02:42am 31 Jul 2014
Copy link to clipboard 
Print this post

Has anyone used Bypic BV500(MX1) and compared to micromite, same PIC32 chip?

Looks like it has more functions, and even user functions are compiled before used in Basic interpreter.

Compiled Basic user functions could make it very fast and powerful?

Has Integer and Double float data types.

Micromite has single floats, and has caused a number of conversion and accuracy issues.

http://www.bypic.co.uk/index.php/What_Is_It



http://www.bypic.co.uk/index.php/Key_Words

http://www.bypic.co.uk/index.php/Language_Guide


http://www.bypic.byvac.com/index.php/Products

  Quote  Execution speed 200,000 lines per second


http://www.bypic.byvac.com/index.php/BV500 Edited by memberx 2014-08-01
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 02:56am 31 Jul 2014
Copy link to clipboard 
Print this post

I've a couple of their boards but bought them as cheap boards to use with C - partly because their Basic isn't open source in any sense. (I'm unlikely to use MMBasic for the same reason.)

It looks a reasonable "just another" non-open BASIC, to me.

The boards I have are like a typical 44-pin umite one (and run the 44-pin umite firmware apparently fine).

I did try a "flash LED quickly" loop out of curiosity and came up with this
constant ANSELBCLR 0xBF886104
constant TRISBCLR 0xBF886114
constant LATBINV 0xBF88613C
@ANSELBCLR = 1
@TRISBCLR = 1
function led()
while 1
@LATBINV = 1
wend
endf


maybe gives you a flavour of what can be done.

16M loops (measured using a couple of 12-bit counters) took about 70 secs.

John
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 04:56am 31 Jul 2014
Copy link to clipboard 
Print this post

@memberx

I've just received one of their MX150s loaded with ByPic, and first impressions are that the entry effort is much greater than uMite, but because it's more "raw"/close to the bare metal, one could probably get more done with it, and it does seem quick.

ByPic also has more in common with C than Basic IMHO, eg pointers, and it is case sensitive.

The MX150 loaded with ByPic comes in at about GBP 5.00 here in the UK, so not a lot of money to get one or two and have a play with.

The C plugin facility is very interesting but limited, eg the C function cannot call another function, so everything U need to do has to be in the one function, but still useful I would have thought.

The MX150 ByPic doesn't have a proper interactive environment because of memory limitations, eg type list, and nothing shows up (apparently list works on the larger PIC32 chips). And, there is no IDE like MMEdit - PSPad is very good as an editor, but it is just an editor, whereas MMEdit is much more like an IDE.

So in summary, ByPic is a lot more rougher around the edges, more raw, needs more effort to use than uMite mmBasic, but can probably go faster. (Custom car vs Production car analogies)

Whilst playing with ByPic, I got the distinct sense/flavour that FORTH was somehow involved - nothing wrong with that. Don't know why, but it just had that whiff of FORTH. Perhaps I was imagining things or wishful thinking of late 70s/early 80s !

Peter

The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 07:37am 31 Jul 2014
Copy link to clipboard 
Print this post

@memberx

see this MX1 ByPic Data Types

  Quote  It is probably a good idea to have some familiarity of the data types that ByPic handles. There are four data types, Integer, Float, String and Double. Float and Double are not available for the MX1 due to space restrictions on the IC but are described here out of interest.


I tried print 10+2.5 as a double check, and it error'ed out.

The 'MX150 version of ByPic definitely doesn't have any floating point capability at all :(

Peter
The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 06:50am 02 Aug 2014
Copy link to clipboard 
Print this post

I posted this into the wrong topic previously so I'm reposting it here because this post is about ByPic.

I've just completed benchmarking some code on the ByPic 'MX150 which runs at 40MHz, specifically 18 decimal digit ADD and SUBTRACT, and the ByPic performs an 18 digit Add/subtract in around 800uS compared to about 2.5 mS for the uMite, ie about 3 x faster.

Here's the ByPic code. I've previously posted 24 digit BCD library in mmBasic on TBS, and the equivalent 18 digit Add/Subtract routines may be found in the AD9850Controller.bas mmBasic code I have previously posted on TBS.

The simplicity of the Add and Subtract functions makes them ideal candidates to try and code them in MIPS assembler/C and use the plugin feature of ByPic.

Peter


constant Billion 1000000000
constant Million 1000000
constant Thousand 1000
constant HalfMillion 500000
constant SizeOfInt 4
constant MillionX10 10000000

//
// Add 2 x 18 digit integers, return result in p
// m, n, p are the base addresses of integer arrays
// p()=m()+n()
//
function AddMN2P(m,n,p)
dim i,Cy

i=peek(m) + peek(n)
Cy=i / Billion
i=i % Billion
poke(p+0,i)

i=peek(m+SizeOfInt) + peek(n+SizeOfInt) + Cy
i=i % Billion
poke(p+SizeOfInt,i)

endf

//
// Add 2 x 18 digit integers, return result in m
// m, n are the base addresses of integer arrays
// m()=m()+n()
//
function AddMN2M(m,n)
dim i,Cy

i=peek(m) + peek(n)
Cy=i / Billion
i=i % Billion
poke(m,i)

i=peek(m+SizeOfInt) + peek(n+SizeOfInt) + Cy
i=i % Billion
poke(m+SizeOfInt,i)

endf


//
// Sub 2 x 18 digit integers, return result in p
// m, n, p are the base addresses of integer arrays
// p()=m()-n()
//
function SubMN2P(m,n,p)
dim i,Cy

i=peek(m) - peek(n) + Billion
Cy=1 - i / Billion
i=i % Billion
poke(p+0,i)

i=peek(m+SizeOfInt) - peek(n+SizeOfInt) - Cy +Billion
i=i % Billion
poke(p+SizeOfInt,i)

endf


//
// Sub 2 x 18 digit integers, return result in m
// m, n are the base addresses of integer arrays
// m()=m()-n()
//
function SubMN2M(m,n)
dim i,Cy

i=peek(m) - peek(n) + Billion
Cy=1 - i / Billion
i=i % Billion
poke(m,i)

i=peek(m+SizeOfInt) - peek(n+SizeOfInt) - Cy + Billion
i=i % Billion
poke(m+SizeOfInt,i)

endf

//
// m, p are the addresses of the first element of the arrays
// p()=m() / 1,000,000
//
function Div1e6M2P(m,p)
dim i,j,Cy,n
dim r$[32]

//m(0)
i=peek(m)

//m(1)
j=peek(m+SizeOfInt)

//Add 500000 to make sure we round correctly
i=i+HalfMillion

//Any Carry
Cy=i/Billion

if Cy
i=i % Billion
j=j+Cy
endif

//Now throw away the bottom six digits
i=i / Million

Cy=j % Million

j=j / Million

//9 Digits per integer var so we divided by 1E6 so the remainder
//has to be multiplied by 1E3
i=i+(Cy*Thousand)

//Return the results
poke(p+0,i)
poke(p+SizeOfInt,j)

endf


//
// Return String representation of 18 digit BCD variable
//
function BCD2Asc$(m)
return format$( "%9u", peek(m+SizeOfInt) ) + format$( "%9u", peek(m) )
endf


//
// This is a test harness is for testing ByPic's capabilities to calculate
// the 32 bit tuning word for an AD9850 DDS chip. The assumptions are that
// the AD9850 is clocked at 125,000,000 Hz, ie as commonky found on eBay
// for the cheap modules.
//
function start()
dim I(2),J(2),K(2),L(2),R$[24]
dim n,i

//10MHz Tuning Word for an AD9850 with CLK=125MHz scaled by 1e6
I(0)=383680000
I(1)=343597
print "Starting I()=";print BCD2Asc$(?I(0));print "\n"

//Increment to add/subtract to the tuning word for a 10,000Hz shift in frequency
J(0)=597383680
J(1)=343
print "Starting J()=";print BCD2Asc$(?J(0));print "\n"

//Move frequency up 10 KHz
//Result should be 343940981063680
tmr_set(?TIMER23, MillionX10)
for i=1 to 100
//AddMN2P(?I(0),?J(0),?I(0))
AddMN2M(?I(0),?J(0))
next i
n=tmr_get(?TIMER23);tmr_set(?TIMER23, 0)
print n/100 ;print " uS AddMN2M";print ""
print BCD2Asc$(?I(0));print "\n"

//Move frequency down 10 KHz
//Result should be 343253786296320
tmr_set(?TIMER23, MillionX10)
for i=1 to 100
//SubMN2P(?I(0),?J(0),?I(0))
SubMN2M(?I(0),?J(0))
next i
n=tmr_get(?TIMER23);tmr_set(?TIMER23, 0)
print n/100 ;print " uS SubMN2M";print ""
print BCD2Asc$(?I(0));print "\n"

//Divide RawTuning Word by 1E6 to get actual tuning word we will send
//to the DDS chip
//Result should be 347033358
tmr_set(?TIMER23, MillionX10)
for i=1 to 100
Div1e6M2P(?I(0),?L(0))
next i
n=tmr_get(?TIMER23);tmr_set(?TIMER23, 0)
print n/100 ;print " uS Div1E6";print ""

print BCD2Asc$(?L(0));print "\n"

print "Tuning Word is ";print toupper$(hex$(L(0)));print "\n"

endf


The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 02:20pm 02 Aug 2014
Copy link to clipboard 
Print this post

Hi

I've implemented the 18 digit BCD Add as a ByPic C plugin, and the benchmark result for the 18 digit Add is 107 uS which is a phenomenal improvement. The C code is shown below. I am using MPLab v8.84 with PIC32-gcc v2.02.

Now when Geof implements 32 bit integers in MMBasic, and the ability to pass arrays to/from MMBasic functions, we should see some huge performance improvements in this extended precision area.

I'm beginning to be really torn between the ease of use, development time, and support from Geoff and everybody on TBS of MMBasic+MMEdit, against the raw power of ByPic. I don't think I'll be able to decide what to do until I've implemented something really serious in ByPic, so I guess that means porting my MMBasic AD9850Controller.bas over to ByPic and seeing what problems I hit along on the way, that stuff uses Rotary Encoder, Push-Button, I2C LCD, I2C Keypad, and drives the AD9850 eBay module, so something fairly meaty and diverse.

I hope this helps other people.

Peter


// This simple plugin will take 2 x 18 digit BCD digits and add them
// The digits are stored in consecutive quad byte words
// ie +0 is lo 9 digits of first number, ie a
// +1 is hi 9 digits of first number
// +2 is lo 9 digits of second number, ie b
// +3 is hi 9 digits of second number
//
// Result is returned in +0, +1, ie a
// a = a + b

int addab2aR(char *c)
{
unsigned long *ip;
register unsigned long a;
register unsigned long b;
register unsigned long cy;

ip = (unsigned long*)c; // pointer to long (32 bit unsigned integer)

//Add lo parts of a & b
a = *(ip); // contents of memory as integer
b = *(ip+2); // contents of memory as integer

a += b;
cy = a / 1000000000;
a %= 1000000000;
*ip++=a; //save lo result and point at high parts

//get high parts
a = *(ip); // contents of memory as integer
b = *(ip+2); // contents of memory as integer

//Add high parts together with Carry from lo parts
a += b;
a += cy;
a %= 1000000000;
*(ip)=a;

return (0);
}


and here's the disassembly of the Compilers's output - the opcodes are what is stored in ByPic as a constant array, and call'ed. (it looks like the compiler has ignored my 'register' hint and used the stack anyway !)


9d00012c <addab2aR>:
9d00012c: 27bdffe8 addiu sp,sp,-24
9d000130: afbe0014 sw s8,20(sp)
9d000134: afb20010 sw s2,16(sp)
9d000138: afb1000c sw s1,12(sp)
9d00013c: afb00008 sw s0,8(sp)
9d000140: 03a0f021 move s8,sp
9d000144: afc40018 sw a0,24(s8)
9d000148: 8fc20018 lw v0,24(s8)
9d00014c: afc20000 sw v0,0(s8)
9d000150: 8fc20000 lw v0,0(s8)
9d000154: 8c500000 lw s0,0(v0)
9d000158: 8fc20000 lw v0,0(s8)
9d00015c: 24420008 addiu v0,v0,8
9d000160: 8c510000 lw s1,0(v0)
9d000164: 02118021 addu s0,s0,s1
9d000168: 00101a42 srl v1,s0,0x9
9d00016c: 3c020004 lui v0,0x4
9d000170: 34424b83 ori v0,v0,0x4b83
9d000174: 00620019 multu v1,v0
9d000178: 00001010 mfhi v0
9d00017c: 000291c2 srl s2,v0,0x7
9d000180: 00101a42 srl v1,s0,0x9
9d000184: 3c020004 lui v0,0x4
9d000188: 34424b83 ori v0,v0,0x4b83
9d00018c: 00620019 multu v1,v0
9d000190: 00001010 mfhi v0
9d000194: 000219c2 srl v1,v0,0x7
9d000198: 3c023b9a lui v0,0x3b9a
9d00019c: 3442ca00 ori v0,v0,0xca00
9d0001a0: 70621002 mul v0,v1,v0
9d0001a4: 02021023 subu v0,s0,v0
9d0001a8: 00408021 move s0,v0
9d0001ac: 8fc20000 lw v0,0(s8)
9d0001b0: ac500000 sw s0,0(v0)
9d0001b4: 8fc20000 lw v0,0(s8)
9d0001b8: 24420004 addiu v0,v0,4
9d0001bc: afc20000 sw v0,0(s8)
9d0001c0: 8fc20000 lw v0,0(s8)
9d0001c4: 8c500000 lw s0,0(v0)
9d0001c8: 8fc20000 lw v0,0(s8)
9d0001cc: 24420008 addiu v0,v0,8
9d0001d0: 8c510000 lw s1,0(v0)
9d0001d4: 02118021 addu s0,s0,s1
9d0001d8: 02128021 addu s0,s0,s2
9d0001dc: 00101a42 srl v1,s0,0x9
9d0001e0: 3c020004 lui v0,0x4
9d0001e4: 34424b83 ori v0,v0,0x4b83
9d0001e8: 00620019 multu v1,v0
9d0001ec: 00001010 mfhi v0
9d0001f0: 000219c2 srl v1,v0,0x7
9d0001f4: 3c023b9a lui v0,0x3b9a
9d0001f8: 3442ca00 ori v0,v0,0xca00
9d0001fc: 70621002 mul v0,v1,v0
9d000200: 02021023 subu v0,s0,v0
9d000204: 00408021 move s0,v0
9d000208: 8fc20000 lw v0,0(s8)
9d00020c: ac500000 sw s0,0(v0)
9d000210: 00001021 move v0,zero
9d000214: 03c0e821 move sp,s8
9d000218: 8fbe0014 lw s8,20(sp)
9d00021c: 8fb20010 lw s2,16(sp)
9d000220: 8fb1000c lw s1,12(sp)
9d000224: 8fb00008 lw s0,8(sp)
9d000228: 27bd0018 addiu sp,sp,24
9d00022c: 03e00008 jr ra
9d000230: 00000000 nop


Here's the no register version using pointers only - it's 4 uS slower


// This simple plugin will take 2 x 18 digit BCD digits and add them
// The digits are stored in consecutive quad byte words
// ie +0 is lo 9 digits of first number, ie a
// +1 is hi 9 digits of first number
// +2 is lo 9 digits of second number, ie b
// +3 is hi 9 digits of second number
//
// Result is returned in +0, +1, ie a
// a = a + b

int addab2a(char *c)
{
unsigned long *ip, cy;

ip = (unsigned long*)c; // pointer to long (unsigned int)

//Add lo parts of a & b, a(lo)=a(lo)+b(lo)

*(ip) += *(ip+2);
cy = *(ip) / 1000000000;
*(ip)++ %= 1000000000;

//Add high parts of a & b, a(hi)=a(hi)+b(hi)+Carry
*(ip) += *(ip+2);
*(ip) += cy;
*(ip) %= 1000000000;

return (0);
}

The only Konstant is Change
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 02:08am 03 Aug 2014
Copy link to clipboard 
Print this post

When I wrote a C plugin I tweaked the gcc flags beyond those they document.

If you want that code smaller/faster let me know the flags you used and I'll dig out what I did.

John
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 05:51am 03 Aug 2014
Copy link to clipboard 
Print this post

Hi John, thanks for the kind offer. This is what I used


-mlong-calls -fPIC -mno-gpopt -mshared -mno-abicalls


These were as given by Jim from ByVac. I have to admit that I have very little idea what these flags mean.

Thank you

Peter
The only Konstant is Change
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 10:49am 04 Aug 2014
Copy link to clipboard 
Print this post

try adding
-O3
or
-Os

You could also use const for some of the things so gcc knows it can safely optimise more.

Though it's already plenty fast enough for most things!

JohnEdited by JohnS 2014-08-05
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 02:53pm 04 Aug 2014
Copy link to clipboard 
Print this post

Hi Jonh

Thanks, will try that out right now.

Just done -Os, WOW, where did that come from !

117uS down to 107uS, 9.4% performance improvement just by specifying an option !

This ByPIC stuff is really interesting, especially the C plugin capability. The main problem I have with ByPIC is that if I commit to developing a product using ByPIC, what happens if ByVac/Jim Spence goes belly up ? I'd be stuffed. At least with MMBasic, the source/runtime is out in the public domain so I could continue to ship my product even in Geoff's absence, (which hopefully will outlive my lifetime) but with ByPIC, only ByVac/Jim can supply the chips with ByPIC installed. I'll have to ask Jim what escrow arrangements he has in place, and what code release arrangements he has in place in the unfortunate event of his/ByVac's demise - seems morbid, but ...

Hope all is well with you.

Thank you.

Peter
The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 02:56pm 04 Aug 2014
Copy link to clipboard 
Print this post

Hi John

I tend to use #define rather than const, I guess the PP makes #define transparent to gcc, whereas const tells the gcc what's going on. Is my thinking correct ? Therefore I should use const more frequently ?

Peter
The only Konstant is Change
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 09:21pm 04 Aug 2014
Copy link to clipboard 
Print this post

const & #define are in many cases probably no different to a decent optimising compiler but there are extra ways you can use const, such as:

const int * ptr;

or

const * const int ptr;

Sometimes an optimiser can figure out the way you use a pointer and then effectively add the const but it's tough for an optimiser to be sure (e.g. it has to be sure you're not using aliased or overlapping pointers).

Do bear in mind that over-optimised over-sped-up code tends to get unreadable at some point, though!

John
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 12:24pm 06 Aug 2014
Copy link to clipboard 
Print this post

Thanks once again

Peter
The only Konstant is Change
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025