![]() |
Forum Index : Microcontroller and PC projects : CM2: DIM bit
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
oppps! I didn't expect that! ![]() With pleasure! Bit Manipulation Functions for CMM2 'New SUB FlagSet(bit AS INTEGER) FLAGS=FLAGS or (1<<63) END SUB 'New SUB FlagRes(bit AS INTEGER) FLAGS=FLAGS AND inv (1<<63) END SUB SUB FlagEq(bit As Integer,v as integer) IF v=0 THEN FlagRes(bit) ELSE FlagSet(bit) ENDIF END SUB 'New FUNCTION FlagTest(bit AS INTEGER) AS INTEGER FlagTest=(FLAGS AND(1<<bit))<>0 END FUNCTION Demo: bittest.zip causality ≠correlation ≠coincidence |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
Well, a minute ago you were off on an irrelevant tangent about Walmart. You can just use integers or strings and some simple functions to do huge bit arrays instead of fouling up the core interpreter. John |
||||
bar1010 Senior Member ![]() Joined: 10/08/2020 Location: United StatesPosts: 197 |
MMBasic has three datatypes: strings, 64-bit integers, and double precision floats - end of discussion. It is extremely frustrating when people who know nothing of the history of MMBasic and how long it took Geoff to integrate integers and how many bugs and difficulties that caused blithely suggest, bytes, booleans or whatever. If MMBasic as-is doesn't work for you feel free to use something else. The core basic interpreter isn't going to change. Please also understand the licencing of the source. You can do what you like with it for your own personal use but you may not incorporate any of my or Geoff's code in anything to be released in any way without our permission which in my case will not be forthcoming. I haven't got the time or energy to answer every new forum user who wants to modify the concept in his or her own image so please lets stop these endless requests for changes or a different version. I will always try and help new users who have problems with understanding and my greatest pleasure is to see new users like epsilon today whose first posts have been to contribute great new code using the firmware as-is rather than immediately wanting changes [/rant] Are there any future plans for a Color Maximite 3? If so, would like to see a Boolean datatype available for it. Edited 2020-09-19 10:13 by bar1010 |
||||
Turbo46![]() Guru ![]() Joined: 24/12/2017 Location: AustraliaPosts: 1642 |
The bit manipulation functions would be also useful for adventure games and the like in keeping collectable items in one word for locations and inventory. Invert function for Micromite 170. Inv64 function is obvious. inv32 = a xor &hFFFFFFFF end function Bill Keep safe. Live long and prosper. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
I bow to your superior knowledge of programming languages but I understand that with SQL, internally, the BOOLEAN type is stored as a single-byte integer that can take only the values 0 and 1. So no saving of memory there. Other languages I do have some limited knowledge of also use a full byte for their BOOL types. You seems to have an application which requires 40+Mbits. I suggest that the CMM2 is not the platform to use. If your requirements were more realistic, bit manipulation of string arrays using PEEK and POKE is trivial with the existing commands. Jim VK7JH MMedit |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1134 |
Or use a display page as the buffer, and peek and poke in that. Offers the advantage of blit commands for bulk copying, cls for filling values and maybe other graphics commands could be useful too. Visit Vegipete's *Mite Library for cool programs. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
CLS DIM test$(137,137,136) LENGTH 1 PRINT "Remaining Heap using 'test$(137,137,136)': ";MM.INFO(heap) MEMORY ERASE test$() DIM test$(137,137*137) LENGTH 1 PRINT "Remaining Heap using 'test$(137,137*137)': ";MM.INFO(heap) MEMORY ERASE test$() DIM test$(137*137*137) LENGTH 1 PRINT "Remaining Heap using 'test$(137*137*137)': ";MM.INFO(heap) MEMORY ERASE test$() DIM test$(137*137*137/255) PRINT "Remaining Heap using 'test$(137*137*137/255)': ";MM.INFO(heap) MEMORY ERASE test$() DIM test%(137*137*137/8) PRINT "Remaining Heap using 'test%(137*137*137/8)': ";MM.INFO(heap) MEMORY Output: Remaining Heap using 'test$(137,137,136)': 24064 Program: 1K ( 0%) Program (25 lines) 515K (100%) Free Data: 5096K (98%) 1 Variable 0K ( 0%) General 88K ( 2%) Free Remaining Heap using 'test$(137,137*137)': 61696 Program: 1K ( 0%) Program (25 lines) 515K (100%) Free Data: 5059K (97%) 1 Variable 0K ( 0%) General 125K ( 3%) Free Remaining Heap using 'test$(137*137*137)': 99584 Program: 1K ( 0%) Program (25 lines) 515K (100%) Free Data: 5022K (96%) 1 Variable 0K ( 0%) General 162K ( 4%) Free Remaining Heap using 'test$(137*137*137/255)': 2660608 Program: 1K ( 0%) Program (25 lines) 515K (100%) Free Data: 2521K (48%) 1 Variable 0K ( 0%) General 2663K (52%) Free Remaining Heap using 'test%(137*137*137/8)': 2670848 Program: 1K ( 0%) Program (25 lines) 515K (100%) Free Data: 2511K (48%) 1 Variable 0K ( 0%) General 2673K (52%) Free > Moral of the story: Single dimension arrays save a small amount of memory but not enough to be worthwhile for normal use. Using normal length strings give a dramatic improvement due to the overheads with single length strings. Using arrays of integers saves a bit more memory by getting rid of the length bytes. Jim VK7JH MMedit |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1134 |
Weird windows thing - ignore this post. Edited 2020-09-19 14:06 by vegipete Visit Vegipete's *Mite Library for cool programs. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
No: but in any case you misunderstand how an interpreter works. When you create a variable it results in a data structure being created that includes the name (32 bytes), data-type, array of dimensions, and level. One 8 byte field is then overloaded as either the data itself or a pointer to the memory location for a string or an array. This structure is 64-bytes long. A byte or boolean datatype would use the same structure and so be the same size - saving NOTHING. Interpreters are not compilers struct s_vartbl { // structure of the variable table char name[MAXVARLEN]; // variable's name char type; // its type (T_NUM, T_INT or T_STR) char level; // its subroutine or function level (used to track local variables) unsigned char size; // the number of chars to allocate for each element in a string array char dummy; int __attribute__ ((aligned (4))) dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero union u_val{ MMFLOAT f; // the value if it is a float long long int i; // the value if it is an integer MMFLOAT *fa; // pointer to the allocated memory if it is an array of floats long long int *ia; // pointer to the allocated memory if it is an array of integers char *s; // pointer to the allocated memory if it is a string } __attribute__ ((aligned (8))) val; } __attribute__ ((aligned (8))) val; Edited 2020-09-19 17:17 by matherp |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7938 |
How do these work? 'New SUB FlagSet(bit AS INTEGER) FLAGS=FLAGS or (1<<63) END SUB 'New SUB FlagRes(bit AS INTEGER) FLAGS=FLAGS AND inv (1<<63) END SUB Is it something magical about the version of MMBasic for the CMM2 (which I don't have), I wondered? The "bit" argument passed to the sub is only used by telepathy. I tried them just for giggles on the DOS version: FlagSet does nothing. May be useful to change it to FLAGS=bit or (1<<63) in which case FLAGS is replaced by a zero word with a single bit set on every call. FlagRes, in its current form, merely zeroes FLAGS on every call. The correct format is, of course, (1<<bit) I came up with something else of more concern if you are looking for a lot of bit storage. Using original or new versions of these routines I can't reset bits from bit 53 upwards, even though all variables are integers. They will set and test but not reset. Here's my little test prog. Input command,bit_number e.g. s,0 will set bit 0 bits01.zip Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
'New SUB FlagSet(bit AS INTEGER) ... SUB FlagRes(bit AS INTEGER) . Is it something magical about the version of MMBasic for the CMM2 (which I don't have), I wondered? The "bit" argument passed to the sub is only used by telepathy. Don't get hung up on the <<63 - it was just to illustrate a method. In anger it should read <<bit Check here for the complete (correct) code |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
[...] FlagSet does nothing. May be useful to change it to FLAGS=bit or (1<<63) Hi Mixtel90, you are correct! This should work: Bit Manipulation Functions for CMM2 (for CBs Wiki) 'New SUB FlagSet(bit AS INTEGER) FLAGS=FLAGS or (1<<bit) END SUB 'New SUB FlagRes(bit AS INTEGER) FLAGS=FLAGS AND inv (1<<bit) END SUB SUB FlagEq(bit As Integer,v as integer) IF v=0 THEN FlagRes(bit) ELSE FlagSet(bit) ENDIF END SUB 'New FUNCTION FlagTest(bit AS INTEGER) AS INTEGER FlagTest=(FLAGS AND(1<<bit))<>0 END FUNCTION Regards causality ≠correlation ≠coincidence |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Don't get hung up on the <<63 - it was just to illustrate a method. In anger it should read <<bit Check here for the complete (correct) code Thanks CB! ![]() Michael causality ≠correlation ≠coincidence |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
actually, this code is now broken. Anyone any ideas why using << breaks the OR function? Admittedly I am using an old version (5.04.08) on a micromite but I imagine this particular bit of the firmware is old as the hills - take a look at the following. the original code: dim integer flag SUB FlagSet(bit AS INTEGER) FLAG=FLAG OR (2^bit) END SUB SUB FlagRes(bit AS INTEGER) FLAG=(FLAG OR (2^bit)) XOR (2^bit) END SUB FUNCTION FlagTest(bit AS INTEGER) AS INTEGER FlagTest=ABS(SGN(FLAG AND (2^bit))) END FUNCTION gives the expected output: > flagset 2:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000100 > flagset 63:?bin$(flag,64) 1000000000000000000000000000000000000000000000000000000000000100 > flagset 62:?bin$(flag,64) 1100000000000000000000000000000000000000000000000000000000000100 > flagset 31:?bin$(flag,64) 1100000000000000000000000000000010000000000000000000000000000100 > But the new code using 1<<bit instead of 2^bit, 'Set a Flag Sub FlagSet(bit As Integer) FLAG=FLAG Or 1<<bit End Sub gives this. > flagset 2:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000100 > flagset 63:?bin$(flag,64) 1000000000000000000000000000000000000000000000000000000000000000 > flag=0 > flagset 2:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000100 > flagset 62:?bin$(flag,64) 0100000000000000000000000000000000000000000000000000000000000000 > flagset 2:?bin$(flag,64) 0100000000000000000000000000000000000000000000000000000000000000 > flagres 62:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000000 > flagset 2:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000100 > flagset 0:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000101 > flagset 31:?bin$(flag,64) 0000000000000000000000000000000010000000000000000000000000000000 > bits get cleared as if ANDed can anyone verify this? (any platform) Edited 2020-09-20 21:20 by CaptainBoing |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
The new code probably needs brackets around the 1<<bit to make the precedence work the way you want Jim VK7JH MMedit |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Here's my little test prog. Input command,bit_number e.g. s,0 will set bit 0 bits01.zip This should work: Function inv64(b As integer) AS INTEGER inv64 = b Xor &hFFFFFFFFFFFFFFFF End Function causality ≠correlation ≠coincidence |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
@CB Sub FlagSet(bit As INTEGER) flags=flags Or 1<<bit End Sub works on my CMM2, even without the brackets. ![]() Strange. causality ≠correlation ≠coincidence |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
that was a tricky one to figure out! try this version of the code, only requiring flagset: Dim integer flag Sub FlagSet(bit As INTEGER) FLAG=FLAG Or (2^bit) Print Bin$(FLAG, 64) Print FLAG End Sub save and RUN with f2 now type the following at the prompt: > flagset(1) 0000000000000000000000000000000000000000000000000000000000000010 2 > flagset(63) 1000000000000000000000000000000000000000000000000000000000000010 -9223372036854775806 > > clear > > flagset(1) 0000000000000000000000000000000000000000000000000000000000000010 2 > flagset(63) 1000000000000000000000000000000000000000000000000000000000000000 -9.22337e+18 > not the difference between the behaviour BEFORE and AFTER typing 'clear'? the first two calls to flagset occur after FLAG has been defined (because of the save and RUN) as a 64-bit integer. but after the 'clear' FLAG reverts to being the default type the first time it is used by a call to flagset, ie, as a 32-bit float. 32-bit floats can only represent EXACTLY a range covering 24 bits. seethe diagram here: https://en.wikipedia.org/wiki/Single-precision_floating-point_format while higher numbered bits can be set, doing so causes lower bits to drop off the end. the moral: implicitly define the type of FLAG by using FLAG%. cheers, rob :-) addendum: the CMM2 uses 63-bit floats, where the exact range of storing integers is 53 bits. see: https://en.wikipedia.org/wiki/Double-precision_floating-point_format Edited 2020-09-20 22:01 by robert.rozee |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
try giving this a spin: Sub flagSET(bit) FLAG%=FLAG% Or (1<<bit) Print Bin$(FLAG%, 64) Print FLAG% End Sub Sub flagCLR(bit) FLAG%=FLAG% And (-1 Xor (1<<bit)) Print Bin$(FLAG%, 64) Print FLAG% End Sub Function flagTST(bit) FlagTST=((FLAG% And (1<<bit))<>0) End Function End cheers, rob :-) Edited 2020-09-20 22:28 by robert.rozee |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
Hi Jim, I did it both ways, still get that weird behaviour where the bit gets cleared. the moral: implicitly define the type of FLAG by using FLAG%. if working from a command prompt yes but as part of the running code, the Dim takes care of this. something is not right and I can't put my finger on it. In the below test, I progressively set the flags (after a run) and as soon as I get to bit 23, it zeroes all the earlier bits. This is an OR, it absolutely cannot reset bits! ![]() > list all 'preamble 'Dim Integer Flag 'Set a Flag Sub FlagSet(bit As Integer) FLAG=FLAG Or (1<<bit) End Sub 'Clear a flag Sub FlagRes(bit As Integer) Local Integer x x=1<<bit FLAG=(FLAG Or x) Xor x End Sub 'Equate a flag to a value Sub FlagEq(bit As Integer,v As Integer) If v Then FlagSet(bit) Else FlagRes(bit) EndIf End Sub 'Test a flag Function FlagTest(bit As Integer) As Integer FlagTest=Abs(Sgn(FLAG And (1<<bit))) End Function 'Bitise Invert a value 'For MMBasics without native Inv() Function Function Inv(a As Integer) Inv=a Xor &hFFFFFFFFFFFFFFFF End Function > >run > > flagset 0 :?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000001 > flagset 1:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000011 > flagset 2:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000000111 > flagset 3:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000001111 > flagset 4:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000011111 > flagset 5:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000000111111 > flagset 6:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000001111111 > flagset 7:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000011111111 > flagset 8:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000000111111111 > flagset 9:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000001111111111 > flagset 10:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000011111111111 > flagset 11:?bin$(flag,64) 0000000000000000000000000000000000000000000000000000111111111111 > flagset 12:?bin$(flag,64) 0000000000000000000000000000000000000000000000000001111111111111 > flagset 13:?bin$(flag,64) 0000000000000000000000000000000000000000000000000011111111111111 > flagset 14:?bin$(flag,64) 0000000000000000000000000000000000000000000000000111111111111111 > flagset 15:?bin$(flag,64) 0000000000000000000000000000000000000000000000001111111111111111 > flagset 16:?bin$(flag,64) 0000000000000000000000000000000000000000000000011111111111111111 > flagset 17:?bin$(flag,64) 0000000000000000000000000000000000000000000000111111111111111111 > flagset 18:?bin$(flag,64) 0000000000000000000000000000000000000000000001111111111111111111 > flagset 19:?bin$(flag,64) 0000000000000000000000000000000000000000000011111111111111111111 > flagset 20:?bin$(flag,64) 0000000000000000000000000000000000000000000111111111111111111111 > flagset 21:?bin$(flag,64) 0000000000000000000000000000000000000000001111111111111111111111 > flagset 22:?bin$(flag,64) 0000000000000000000000000000000000000000011111111111111111111111 > flagset 23:?bin$(flag,64) 0000000000000000000000000000000000000001000000000000000000000000 > it skips setting bit 23, sets bit 24 and clears 0-22 ![]() I am going to try this on another MicroMite just to see if there is something freaky with the firmware. Edited 2020-09-20 22:27 by CaptainBoing |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |