Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 01:55 18 May 2024 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 : Shift Left or Right in MMBasic

     Page 2 of 2    
Author Message
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1141
Posted: 06:58am 21 Sep 2014
Copy link to clipboard 
Print this post

  Quote  The only benefit of << >> SHIFT etc is for performance compared to *2...N and \2...N where N is a power of 2 as far as I can tell cf. \10...T and *10...T where T is a power of 10.

That's not completly wrong! I think we should have a TBS-MMBasic standard lib for something like that. This includes mathematical (log10), string (trim$, InStr$) and bit operation (shift, reverse) functions. Today we may have all this somewhere/somehow but no one knows exactly where to look for.

And one day ... Geoff will integrate the entire library in MMBasic v10!

Or??

Michael
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 08:45am 21 Sep 2014
Copy link to clipboard 
Print this post

Hi

I'm more than happy to write some functions and act as the library editor if people want to contribute functions.

An editor is needed to ensure naming consistency, eliminate namespace collisions, packaging and distribution of the library, documentation standards and so on.

If this idea has legs then we probably need to establish the guidelines, eg naming conventions, documentation headers, error handling/reporting.

In the meantime here's some useful little functions.


'
'Returns 1 if X is Odd, 0 otherwise
'
FUNCTION Odd(X)
Odd=X AND &H1
END FUNCTION

'
'Returns 1 if X is even, O otherwise
'
FUNCTION Even(X)
Even=(X AND &H1) XOR &H1
END FUNCTION

'
'Shift X Left by N bits
'
FUNCTION ShiftL(X,N)
ShiftL=X*(2^N)
END FUNCTION

'
'Shift X Right by N Bits
'
FUNCTION ShiftR(X,N)
ShiftR=X\(2^N)
END FUNCTION

'
'Remove leading Spaces from string
'
FUNCTION LTrim$(X$)
LOCAL I,Z$ Length LEN(X$)

'Make copy of caller's string so that we don't damage it
Z$=X$

FOR I=1 TO LEN(Z$)

'Find first NON-Space character
IF MID$(Z$,I,1)<>" " THEN
Z$=MID$(Z$,I)
EXIT FOR
ENDIF

NEXT I

LTrim$=Z$

END FUNCTION

'
'Remove trailing Spaces from string
'
FUNCTION RTrim$(X$)
LOCAL I,Z$ Length LEN(X$)

'Make copy of caller's string so that we don't damage it
Z$=X$


FOR I=LEN(Z$)-1 TO 1 STEP -1

'Find first NON-Space character
IF MID$(Z$,I,1)<>" " THEN
Z$=MID$(Z$,1,I)
EXIT FOR
ENDIF

NEXT I

RTrim$=Z$

END FUNCTION

'
'Remove spaces from LHS and RHS of string
'
FUNCTION Trim$(X$)
LOCAL Y$ length LEN(X$)

'MMBasic doesn't like Trim$=RTrim$(LTrim$(X$))

Y$=LTrim$(X$)
Trim$=RTrim$(Y$)

END FUNCTION



PeterEdited by G8JCF 2014-09-22
The only Konstant is Change
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 10:48am 21 Sep 2014
Copy link to clipboard 
Print this post

why not

Shl / Shr / Rol / Ror / Asr / Asl
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 10:58am 21 Sep 2014
Copy link to clipboard 
Print this post

  plasma said   why not

Shl / Shr / Rol / Ror / Asr / Asl

Because I believe that would mean using six command indexes from a very limited remaining quantity!

I have 'guessed' the first four; but what are the last two?
The thing I like about BASIC is that PRINT means print, LIST means list, RUN means run, INPUT means input, SETPIN means set pin, but Asr means what exactly ???? Shouldn't need to think about it IMHO


For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 11:02am 21 Sep 2014
Copy link to clipboard 
Print this post

http://en.m.wikipedia.org/wiki/Arithmetic_shift
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 11:14am 21 Sep 2014
Copy link to clipboard 
Print this post

I've never come across that one before - interesting (but personally struggling to find a use for it).

Just noticed at the bottom of the BSF webpage (for page navigation) there is a '<<' sign for the previous page - guess that means 'Shift Left Previous'

I do prefer << and >> instead of 'shortened' named functions such as SHL and SHR. But the number of command indexes remaining for Geoff to utilise has to be considered. So I'm still for SHIFT with a parameter to indicate direction; closely followed by << and >>.
Lets see what he decides as there is quite a bit of debate here with the overall majority favouring << and >>.

<< WW >>
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:21am 21 Sep 2014
Copy link to clipboard 
Print this post

ASR/ASL Argh !!! Where's the carry in MMBasic. ASL/ASR are really vital in doing multiple precision arithmetic in assembler, mod and \ are what I use in MMBasic to do multiple precision arithmetic

Next someone will ask for a DAA instruction followed by a an SBCA, ADCA - Motorola fans may recognise these

Peter
The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:23am 21 Sep 2014
Copy link to clipboard 
Print this post


'
'Returns 1 if X is Odd, 0 otherwise
'
FUNCTION Odd(X)
Odd=X AND &H1
END FUNCTION

'
'Returns 1 if X is even, O otherwise
'
FUNCTION Even(X)
Even=(X AND &H1) XOR &H1
END FUNCTION

'
'Shift X Left by N bits
'
FUNCTION ShiftL(X,N)
ShiftL=X*(2^N)
END FUNCTION

'
'Shift X Right by N Bits
'
FUNCTION ShiftR(X,N)
ShiftR=X\(2^N)
END FUNCTION

'
'Remove leading Spaces from string
'
FUNCTION LTrim$(X$)
LOCAL I,Z$ Length LEN(X$)

'Make copy of caller's string so that we don't damage it
Z$=X$

FOR I=1 TO LEN(Z$)

'Find first NON-Space character
IF MID$(Z$,I,1)<>" " THEN
Z$=MID$(Z$,I)
EXIT FOR
ENDIF

NEXT I

LTrim$=Z$

END FUNCTION

'
'Remove trailing Spaces from string
'
FUNCTION RTrim$(X$)
LOCAL I,Z$ Length LEN(X$)

'Make copy of caller's string so that we don't damage it
Z$=X$


FOR I=LEN(Z$)-1 TO 1 STEP -1

'Find first NON-Space character
IF MID$(Z$,I,1)<>" " THEN
Z$=MID$(Z$,1,I)
EXIT FOR
ENDIF

NEXT I

RTrim$=Z$

END FUNCTION

'
'Remove spaces from LHS and RHS of string
'
FUNCTION Trim$(X$)
LOCAL Y$ length LEN(X$)

'MMBasic doesn't like Trim$=RTrim$(LTrim$(X$))

Y$=LTrim$(X$)
Trim$=RTrim$(Y$)

END FUNCTION

The only Konstant is Change
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 11:30am 21 Sep 2014
Copy link to clipboard 
Print this post

haha substract with borrow from A .
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:31am 21 Sep 2014
Copy link to clipboard 
Print this post

@WW

I think that

ASR and ASL are equivalent to


'Have to assume 16 bit integer
Function ASR(X, Carry)

Carry=X AND &H1

ASR=(X \ 2) AND &HFFFF

End Function

'Have to assume 16 bit integer
Function ASL(X,Carry)

Carry=X AND &H8000
ASL=(X * 2) AND &HFFFF

End Function



Peter
The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:33am 21 Sep 2014
Copy link to clipboard 
Print this post

plasma

Ah, Ah so you must have played with 680X then !!

The '09 was a really clean orthogonal architecture, the last of the 8 bit CPUs.

Peter
The only Konstant is Change
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1141
Posted: 11:36am 21 Sep 2014
Copy link to clipboard 
Print this post

@Peter,

An editor is needed to ensure naming consistency, eliminate namespace collisions, packaging and distribution of the library, documentation standards and so on.

If this idea has legs then we probably need to establish the guidelines, eg naming conventions, documentation headers, error handling/reporting.

Yes! It can also be done in a team. I will collect and rethink my functions and open then a new thread for that. Hopefully you are this editor (I use and like your LCD library) I think this can slowly grow.


@WW
  Quote  The thing I like about BASIC is that PRINT means print, LIST means list ...

It's a matter of self documentation. That's clearly important but not realizable completely in any case. Some functions are very sophisticated (matematical, logic) and some have to have short names, because of the execution speed. In my opinion, programming is always a compromise: Readability, speed and programers laziness.

Regards

Michael

edit:
@Peter

looks good I will check it later. For me it is important, once and for all to have a library that I can rely on. Good work!Edited by twofingers 2014-09-22
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:37am 21 Sep 2014
Copy link to clipboard 
Print this post

I suppose we could do

Function SHIFT(Type, Operand, Number of Bits)

where Type could be
0=>>
1=<<
2=ASR
3=ASL
4=ROR
5=ROL

but what a handful and of very limited use, really only <</SHIFTL >>/SHIFTR are of use in a high-level language IMHO.

Peter


The only Konstant is Change
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:47am 21 Sep 2014
Copy link to clipboard 
Print this post


By Documentation I mean the stuff which describes the Function, eg Purpose, Args in/out, side affects (hopefully none), global vars used (hopefully none), performance characteristics, eg duration of a call to the function at 40MHz, Example usage etc, all of this stuff would be contained in comment lines which get stripped off by MMEdit before download to the target uMite and so would impose NO memory or performance impact but which are vital for usability and maintainability.

With libraries there is always a comprise to be made between robustness, performance, and flexibility. Generally most libraries have several versions. One built for robustness, eg with lots of error/limit/size checking, one built for performance, eg NO/minimal error/limit/size checks, one built for flexibility, eg lots of optional arguments into calls but which often results in larger memory/cpu footprint.

So for example in the few little functions I published earlier, the more robust versions of the TRIM functions would check that the length of the string on entry was at least 1, and the more flexible version of the TRIM functions would have an optional argument specifying which character to throw away rather than just space.

BTW, I use the #define capability of MCPP to reduce long variable/sub/function names to single/dual characters at download time to the uMIte. That way I can keep nice friendly descriptive symbols in my source, but at runtime they all get converted transparently, here's an example from my PIC32 MMBasic based programmer



'Shorten symbols
#define Args A
LOCAL Args(8)

'Shorten symbols
#define H16Out X
#define L16Out Y
LOCAL H16Out,L16Out

'Shorten the Symbols at runtime
#define XferFastData S1
#define XferData32 S2
#define XferData F3
#define SendCommand S4
#define XferInstruction S5
#define Initialise S6
#define SetMode S7
#define ExitProgMode S8
#define Clock S9
#define Send8Bits SA



OK ?

PeterEdited by G8JCF 2014-09-22
The only Konstant is Change
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1141
Posted: 12:06pm 21 Sep 2014
Copy link to clipboard 
Print this post

  Quote  BTW, I use the #define capability of MCPP


but that's C!
Will the compiler not anyway eliminate all names and replace with his own labels?

Michael
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 12:51pm 21 Sep 2014
Copy link to clipboard 
Print this post

@twofingers

MMBasic is NOT compiled.

MCPP does the #define's on the source before download to the uMite, so MMBasic sees the result of the #defines, in this case much shorter variable/sub/function names. AFAIK, MMBasic doesn't really tokenize each line as it is loaded in - I could be wrong there, (I haven't spent any time trying to peek into Memory to find out - Geoff can of course clarify). If my assumption is correct then the MMBasic interpreter has to 'read' and parse each line as it executes the line, so the shorter the line the quicker is the read. If also subs/functions are hashed and held in a separate table then the hashing time will be less for shorter names, finally shorter names reduce the memory impact - it must be for all these reasons and more that Hugh Buckle developed his Crunch program.

The other big thing about #defines is that I can get real constants in MMBasic which occupy no memory. Without #define, one has to write stuff like

Dim PGD
PGD=5
Setpin PGD, DOUT

with #define
#define PGD 5
Setpin PGD, DOUT

which will result in
Setpin 5,DOUT

in the downloaded source

The key difference here is that without #define, PGD is an MMBasic variable occupying memory, and it is actually slower in execution compared to using the constant 5 itself.#

BTW, if MMBasic lines were parsed and tokenized as they were loaded, all numeric values would be converted into their equivalent internal MMBasic representation so that at runtime these values could be operated upon without any conversion time - really important in for/next/do/loop situations. Also if MMBasic lines were parsed/tokenized as they were loaded, syntax errors (even for unreached lines) would be flagged before execution, rather than is the case now where syntax errors are only flagged at execution time, finally if MMBasic lines were parsed/tokenized at load time, variables/subs/functions could be assigned in memory and references to those variables/subs/functions replaced with their actual addresses leading to faster execution. Oh, I forget, if MMBasic lines were parsed/tokenized, then one would see very standard line layout as one sees in VB for example, eg operators with exactly one space before and after, all MMBasic reserved names would have standard casing etc. I'm sure Geoff is fully aware of all of these and more techniques besides and may well have implemented some of them already in MMBasic.

73

Peter


The only Konstant is Change
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 01:20pm 21 Sep 2014
Copy link to clipboard 
Print this post

I prefer the << >> format.
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1141
Posted: 01:22pm 21 Sep 2014
Copy link to clipboard 
Print this post

@Peter

  Quote  MMBasic is NOT compiled.

U are of course right! I was confused. It's late in europa. On the first glance it looks like C.
What's this MCPP? It's it for µMites only?

About speed and loops: Yesterday I checked the execution time of loops. do/loops are much slower as for/next. I had not expected. In my little Game of Life project (for Maximites) I tried all this optimization options.

Michael
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 01:30pm 21 Sep 2014
Copy link to clipboard 
Print this post

No, MCPP is a C preprocessor, just google for MCPP.

To make best use, you should be using MMEdit and then from the advanced menu use "auto run external on load".

You can get MCPP and all the other required stuff to go with it, eg .BAT file to interface to MMEdit, from http://www.g8jcf.dyndns.org/mmbasic/index.html

Peter
The only Konstant is Change
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1085
Posted: 02:59pm 21 Sep 2014
Copy link to clipboard 
Print this post

As someone who uses C, I'm quite happy with << and >>.
However, SHIFT or SHIFTL/SHIFTR would work just as easily.
(Or maybe BSHIFT to mean bit shift, ensuring the 'f' is not lost.)

But I do like the idea of a signed shift amount. I could see cases
of not knowing ahead of time which direction the shift will be.

SHIFT var,num

is much cleaner than

IF num < 0 THEN SHIFTR var, -num
ELSE SHIFTL var, num

Since (for me at least) the main point in bit shifting is to get
the bits that fall out the end, another useful version would be

outbit = SHIFT(var, num)

where outbit gets the value shifted out the end.

ex:
var = 0b01001110
num = 3
SHIFT(var,num) gives 0b010 _AND_ changes var to 0b01110000

Thus, a ROLL function becomes:
outbit = SHIFT(var, num)
var = var OR outbit 'Note this is a bitwise OR

Another interesting thought is longer bit structures. For example,
a graphics LCD screen (128x64 pixels) needs 1024 bytes for a frame buffer.
This could be stored in a string (or string array.) If that string
could then be bitwise shifted appropriately, the entire frame buffer
could be scrolled left, right up or down with a single SHIFT command.
(The shift amount could be quite large, even 128, to scroll a frame buffer
up or down one line, depending on screen pixel layout.)

============
Note, I assume a positive shift value is to the left in order
to behave like exponents.

Visit Vegipete's *Mite Library for cool programs.
 
     Page 2 of 2    
Print this page


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

© JAQ Software 2024