Semi-Automatic SAVE

Discuss all aspects of programming here. From 8-bit through to modern architectures.
Post Reply
julie_m
Posts: 68
Joined: Wed Jul 24, 2019 8:53 pm
Location: Derby, UK
Contact:

Semi-Automatic SAVE

Post by julie_m » Sat Nov 09, 2019 2:33 pm

If you put a line like this in a BASIC program:

Code: Select all

10 *KEY1REP.U.A<>A|MSA."MYPROG"|MA=1|M
then once you are back at the BASIC prompt, pressing F1 will either save your program if it has been edited, or get caught in an infinite loop requiring you to press ESCAPE if it has not been edited since it was last saved.

It uses the fact that BBC BASIC -- unlike ZX Spectrum BASIC -- wipes out all variables (except the permanent ones A%-Z%) on making any change to the program. If A has a value, then the UNTIL condition will never satisfy (barring a precisely-timed and located memory corruption event) requiring an ESCAPE to exit, which will also discard the rest of the keyboard buffer. Otherwise, this will produce "No such variable", continue with a SAVE command and finally assign a value to A, so the next press of F1 will catch itself.

User avatar
jgharston
Posts: 3722
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Semi-Automatic SAVE

Post by jgharston » Sat Nov 09, 2019 5:52 pm

Hmmm. That challenges me to write a version that doesn't need Escape. ;)

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
jgharston
Posts: 3722
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Semi-Automatic SAVE

Post by jgharston » Sat Nov 09, 2019 6:03 pm

jgharston wrote:
Sat Nov 09, 2019 5:52 pm
Hmmm. That challenges me to write a version that doesn't need Escape. ;)
Ah ha!

Code: Select all

*KEY 1 DIM A%-1:IF A%<>LOMEM:*FX 216|MSAVE"MYPROG"|M
:)

DIM numvar max reserves a block of memory at the top of the heap. DIM numvar -1 reserves a block zero bytes long (as DIM numvar max reserves a block of a size to go from numvar?0 to numvar?max). DIM A% max reserves a block without taking any heap space for the variable name. Consequently, DIM A% -1 assigns A% with the value of the top of the heap.

If the top of the heap is not the same as the bottom of the heap (LOMEM) because variables are present, then *FX 216 clears the current soft key expansion. If the top of the heap is the same as the bottom of the heap, because the program has been editied, then the *FX216 is skipped, and the SAVE is executed.

Later versions of BBC BASIC have =END which returns the top of the heap.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

julie_m
Posts: 68
Joined: Wed Jul 24, 2019 8:53 pm
Location: Derby, UK
Contact:

Re: Semi-Automatic SAVE

Post by julie_m » Wed Nov 13, 2019 9:11 pm

For the purpose of avoiding a "catch groove", *FX15 (which clears the remainder of the input buffer) is as good as *FX216 (which stops reading the rest of the function key definition). It's also a byte shorter, which probably only really matters if you like having lots of function key definitions on the go.

The one thing I was never fully happy about with this was the fact that LOADing, *EXECing or typing in a new program without clearing the function key definition risks overwriting the original program with the new one. OK, so the new program will redefine the key anyway with the correct filename; but there are always those few seconds, before you type RUN for the first time .....

So, for those (all too long .....) moments, how about this?

Code: Select all

10REMPRG1
20OSCLI"KEY1IF!&"+STR$~(PAGE+5)+"<>&"+STR$~!(PAGE+5)+":*FX15|MIFA=A:*FX15|MSAVE""PRG1""|MA=1|M"
This checks the first 4 characters after the verb in the first line of the program (which you will have to make different in each of your files) have not changed; if they have, it clears the input buffer with *FX15 (or you could use *FX216 as per JGH above) and therefore does nothing else (so it won't overwrite anything). If the first 4 characters are what it is expecting, it carries on to the next command and checks to see if the variable A exists (change this to match a variable set in your program). If the variable does exist, it clears the input buffer with *FX15 and does nothing else. If the input buffer has not been cleared (either because the first line of the program has changed, or because the variable still exists and therefore the program has not been edited) then the program will be saved and A will be given a value, so subsequent presses of f1 will not cause the program to be saved again.

This guards against overwriting a source file, if you load a new source file without changing the f1 function key definition, while still ensuring that the program will be saved if any line but the first is changed. Even if the key definition was on the first line, that's no use if you accidentally press f1 before running the freshly-loaded program.

You can probably guess what motivated this .....

Post Reply