Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 18:45 25 Nov 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 : Webmite FLASH VAR SAVE n function?

Author Message
jovian
Regular Member

Joined: 16/04/2017
Location: Australia
Posts: 62
Posted: 02:25am 11 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 2135
Posted: 03:04am 11 Apr 2024
Copy link to clipboard 
Print this post

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.
  Manual said  OPEN fname$ FOR mode AS [#]fnbr
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6783
Posted: 07:07am 11 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 62
Posted: 07:26am 11 Apr 2024
Copy link to clipboard 
Print this post

Great info thanks Phil/Mick - I'm giving it a crack
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6783
Posted: 07:40am 11 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 62
Posted: 06:36am 18 Apr 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9110
Posted: 07:21am 18 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 62
Posted: 09:43am 24 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 6098
Posted: 10:06am 24 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 62
Posted: 10:08am 24 Apr 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9110
Posted: 10:52am 24 Apr 2024
Copy link to clipboard 
Print this post

  Quote  Thanks for your response Matherp. I've tested it out, it still doesn't save a double precision variable in all its glory,


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: Australia
Posts: 62
Posted: 12:35pm 24 Apr 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9110
Posted: 01:10pm 24 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 2135
Posted: 01:17pm 24 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 62
Posted: 01:17pm 24 Apr 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 2135
Posted: 01:24pm 24 Apr 2024
Copy link to clipboard 
Print this post

> 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: Australia
Posts: 62
Posted: 01:31pm 24 Apr 2024
Copy link to clipboard 
Print this post

  phil99 said  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
>


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 Kingdom
Posts: 3800
Posted: 02:08pm 24 Apr 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9110
Posted: 02:20pm 24 Apr 2024
Copy link to clipboard 
Print this post

If you are saving individual bits then use STR2BIN(uint64 etc.
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2135
Posted: 01:07am 25 Apr 2024
Copy link to clipboard 
Print this post

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


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

© JAQ Software 2024