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 : Webmite FLASH VAR SAVE n function?
Author | Message | ||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Hi all I am writing a sequencer program for the webmite. I am about 75% there. The rest of my work is tidying the program up, and making the sequence presets that will boot with the software. I really need to do these two things in parallel. Sequence data are stored as strings using VAR SAVE. Problem is, when I make a change to the software, a new AUTOSAVE erases the data. It may take me hours to compose one sequence. Much inspiration is being wasted. I am about to create a subroutine that on quit, exports all of the data as text formatted in BASIC (' DATA" " ' lines) and prints it to the modem, where I can then select it, copy it, erase the program memory, paste it in and LIBRARY SAVE it, then update the program memory. the library saved routine can themn restore all of the VAR SAVED variables. Obviously this is very clunky. Does anyone know a better way? Am I missing something? A FLASH VAR SAVE n if you like? Or a sneaky way to overwrite the program without overwriting the VAR SAVEd variables? (I use VSC as my editor as the sequencer program is big and I need to display multiple parts of the code simultaneously to get my head around it. Therefore I have to AUTOSAVE every time I make a change) Thanks Joe |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
Create a file on A: or B: for APPEND within the program to hold the data. Near the start of the program read that file. You may wish to precede that with On Error Skip as it won't exist for the first RUN. |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6783 |
If you open a file as OUTPUT it will overwrite any existing file of the same name. If you open it as APPEND it simply adds the new data to an existing file. In both cases a new file will be created automatically if there isn't one of that name. No need for ON ERROR. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Great info thanks Phil/Mick - I'm giving it a crack |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6783 |
When you want to read the file back you will get an error if it doesn't exist. A neat way to do it, avoiding the use of ON ERROR, is to use something like A = MM.INFO(FILESIZE filename$) This returns the length of the file or -1 if not found or -2 if it's a directory. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Hi all Thanks for your help. I'm looking for the banging my head on a brick wall emoji! Using the above suggested method, I have some double precision variables to print to the A: drive. However when I convert them to strings and back, they lose a ton of precision. I need all 64 bits to come back in tact. If I use str2bin, bin2str$, sometimes it comes back. I first have to pad the string out to 8 characters length using chr$(0) or I get an error. Then it works... 95% of the time. Until one of the characters in the string happens to be line feed, carriage return or quotation marks. Then the data gets corrupted. I wrote a routine to debug the issue see below. I feel like I must be doing something wrong. Can it really be so hard to save and recall a variable?? An OPTION VAR SAVE PROTECT would be amazing. Or a VAR SAVE n, where n is the flash slot would be amazing. In the meantime, here is the code I created to try and save and recall (randomised) double precision variables to A:\. Note some recall correctly, some don't. open "a:\arraydata.txt" for OUTPUT as 1 for a=1 to 8 b=int(rnd*2^50) arr(a)=right$(chr$(0)+chr$(0)+chr$(0)+chr$(0)+chr$(0)+chr$(0)+bin2str$(double,b),8) print #1, arr(a) print arr(a)" "b next a close #1 ?"---------------------" open "a:\arraydata.txt" for INPUT as 1 for a=1 to 8 input #1, arr(a) c$=right$(chr$(0)+chr$(0)+chr$(0)+chr$(0)+chr$(0)+chr$(0)+arr(a),8) ? c$" "str2bin(double,c$) next a close #1 end > run `bπP-UÁB 2.052367994e+14 ¿…Q.∏¯‘B 9.223388642e+13 .ˇ~A]Æ.C 1.079495607e+15 ∞Ú'T.\.C 5.756090091e+14 êow=›u C 1.036545926e+15 p‹0ÏíV.C 7.155860703e+14 ®ÈÛr«).C 5.686920289e+14 @—Å˘ˆÔ.C 9.829585498e+14 --------------------- `bπP-UÁB 2.052367994e+14 ¿…Q.∏¯‘B 9.223388642e+13 .ˇ~A]Æ.C 1.079495607e+15 .∞Ú'T.\C 3.164539044e+16 .êow=›uC 9.846768924e+16 p‹0ÏíV.C 7.155860703e+14 .®ÈÛr«)C 3.628085475e+15 @—Å˘ˆÔ.C 9.829585498e+14 Am I barking up the wrong tree? Thanks Joe |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9110 |
a=Pi Print Str$(a,1,15) Open "test.txt" For output As #1 Print #1,Bin2str$(double,a); 'note the semicolon Print #1,Bin2str$(double,Pi/2); 'note the semicolon Print #1,Bin2str$(double,Pi/4); 'note the semicolon Print #1,Bin2str$(double,Pi*2); 'note the semicolon Close #1 Open "test.txt" For input As #1 Print Str$(Str2bin(double,Input$(8,1)),1,15) Print Str$(Str2bin(double,Input$(8,1)),1,15) Print Str$(Str2bin(double,Input$(8,1)),1,15) Print Str$(Str2bin(double,Input$(8,1)),1,15) Close 1 |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Sorry about the delay getting back. Thanks for your response Matherp. I've tested it out, it still doesn't save a double precision variable in all its glory, and recall it. I think I will have to forget saving my data as a variable. Disappointing that and str2bin and bin2str$ doesn't always recall a string-converted-variable correctly, it suggests in the manual that this is precisely what those commands are for. In my program I have taken lots of small parameter values, converted them to binary, and concatenated as a 64bit string, precisely so it will save conveniently in one variable using only 8 bytes of RAM. But if I can't save and recall that variable, whilst developing other aspects of the code, that method is as useful as an ice cream van in the arctic. I'll try another way... Cheers J |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6098 |
If your data is small and < 256, store each as a single character ' compresseddata$ = CHR$(old(1))+CHR$(old(2))+CHR$(old(3))+CHR$(old(4)) PRINT #1, compresseddata$; ..... retrieveddata$ = INPUT$(4,#1) FOR n = 1 TO 4 NEW(n) = ASC(MID$(retrieveddata$,n,1)) NEXT n Jim VK7JH MMedit MMBasic Help |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Thanks Jim It's double precision floating point variables that I want to save, with full precision. |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9110 |
My example code shows that it does. It saves the 8 bytes that are the floating point data as-is. In your code you were corrupting the readback. You must use the function input$ and read 8 bytes. Anything else will interpret the data as an ascii string |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Well, I'm confused. I ran it and got the following: > run 3.141592653589793 3.141592653589793 1.570796326794897 0.785398163397448 6.283185307179587 > first thing I tried was changing 'a' to int(rnd*2^63) (instead of pi) didn't work... perhaps it would be better if I put it like this... I'm trying to write 2 subroutines: sub STORE x and sub RECALL x so that the following code returns a null: a=int(rnd*2^63) STORE a RECALL b if a-b=0 then print "Finally, I've successfully stored and then recalled a double precision integer on the A: drive!" else print "Not again." end if It's trickier than I'd like... |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9110 |
int(rnd*2^63) makes no sense for double precision when you only have 53 (52) bits of precision (see here } Also testing for equality of floating point numbers is always fraught. Despite all that substitute a=int(rnd*2^63) in my program and you will see you get the same answer back |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
This variation on Peter's program also seems to work. > Open "test.txt" For output As #1 > for n=1 to 4: a% = rnd*2^63:? a% :Print #1,Bin2str$(INT64,a%); :next -8116504444829043712 -2946682655146533888 -9044135987353172992 -784030004272851840 > close #1 : open "test.txt" for input as #1 > FOR n = 1 TO 4:Print int(Str2bin(INT64,Input$(8,#1))):next -8116504444829043712 -2946682655146533888 -9044135987353172992 -784030004272851840 > |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
yes you are right about int(rnd*63) thing is, I don't really care what value the variable is, I am simply using it to store and hopefully recall 64 individual bits which I am setting at will in my main program have you run your code? what are all the references to pi and how do I get the variable 'a' back? |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
> close #1 : open "test.txt" for input as #1 > FOR n = 1 TO 4:a% = int(Str2bin(INT64,Input$(8,#1))): ? a% :next -8116504444829043712 -2946682655146533888 -9044135987353172992 -784030004272851840 > or > option base 1 : dim a%(4) > close #1 : open "test.txt" for input as #1 > FOR n = 1 TO 4 : a%(n) = int(Str2bin(INT64,Input$(8,#1))): ? a%(n) :next -8116504444829043712 -2946682655146533888 -9044135987353172992 -784030004272851840 > Edited 2024-04-24 23:31 by phil99 |
||||
jovian Regular Member Joined: 16/04/2017 Location: AustraliaPosts: 62 |
Oh my goodness! That's it! INT64! So simple! Huge thanks to both of you. Hopefully that'll be me done for a while... Thanks J |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3800 |
matherp's approach looks fine - unless changed in some way when the changed version may not work. If his code doesn't work ... why not? (Bug or what) John |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9110 |
If you are saving individual bits then use STR2BIN(uint64 etc. |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
Using individual bits and UINT64. > clear > > option base 0 : dim integer A(3), B(3) > FOR n=0 TO 3:A(n)=0:FOR m=0 TO 63:Inc A(n),cint(rnd)<<m :next:?hex$(A(n)):next F13BE4C3E71BF2B2 CD170A89296CCDA1 75FE153AB1812D0A 941BACD1FFF5BB53 > > Open "test.txt" For output As #1 > FOR n=0 to 3: Print #1, Bin2str$(UINT64,A(n)); :next :close #1 > > open "test.txt" for input as #1 > FOR n = 0 TO 3 :B(n) = Str2bin(UINT64,Input$(8,#1)) :? hex$(B(n)) :next :close #1 F13BE4C3E71BF2B2 CD170A89296CCDA1 75FE153AB1812D0A 941BACD1FFF5BB53 > Edited 2024-04-26 08:58 by phil99 |
||||
Print this page |