Menu
JAQForum Ver 19.10.27

Forum Index : Microcontroller and PC projects : Webmite FLASH VAR SAVE n function?

Posted: 02:25am
11 Apr 2024
Copy link to clipboard
jovian
Regular Member

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
 
Posted: 03:04am
11 Apr 2024
Copy link to clipboard
phil99
Guru


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
 
Posted: 07:07am
11 Apr 2024
Copy link to clipboard
Mixtel90
Guru


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. :)
 
Posted: 07:26am
11 Apr 2024
Copy link to clipboard
jovian
Regular Member

Great info thanks Phil/Mick - I'm giving it a crack
 
Posted: 07:40am
11 Apr 2024
Copy link to clipboard
Mixtel90
Guru


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.
 
Posted: 06:36am
18 Apr 2024
Copy link to clipboard
jovian
Regular Member

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
 
Posted: 07:21am
18 Apr 2024
Copy link to clipboard
matherp
Guru

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
 
Posted: 09:43am
24 Apr 2024
Copy link to clipboard
jovian
Regular Member

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
 
Posted: 10:06am
24 Apr 2024
Copy link to clipboard
TassyJim
Guru


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
 
Posted: 10:08am
24 Apr 2024
Copy link to clipboard
jovian
Regular Member

Thanks Jim

It's double precision floating point variables that I want to save, with full precision.
 
Posted: 10:52am
24 Apr 2024
Copy link to clipboard
matherp
Guru

  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
 
Posted: 12:35pm
24 Apr 2024
Copy link to clipboard
jovian
Regular Member

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...
 
Posted: 01:10pm
24 Apr 2024
Copy link to clipboard
matherp
Guru

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
 
Posted: 01:17pm
24 Apr 2024
Copy link to clipboard
phil99
Guru


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
>
 
Posted: 01:17pm
24 Apr 2024
Copy link to clipboard
jovian
Regular Member

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?
 
Posted: 01:24pm
24 Apr 2024
Copy link to clipboard
phil99
Guru


> 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
 
Posted: 01:31pm
24 Apr 2024
Copy link to clipboard
jovian
Regular Member

  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
 
Posted: 02:08pm
24 Apr 2024
Copy link to clipboard
JohnS
Guru

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
 
Posted: 02:20pm
24 Apr 2024
Copy link to clipboard
matherp
Guru

If you are saving individual bits then use STR2BIN(uint64 etc.
 
Posted: 01:07am
25 Apr 2024
Copy link to clipboard
phil99
Guru


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
 


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

© JAQ Software 2024