IamRob wrote:
I am wanting to copy a screen to the Virtual Disk, but am scared might accidentally overwrite a screen with important data if wrong number entered.
Welcome to the running with scissors part of Forth. Forth assumes you know what you are asking for and does what you ask it to do right away -- if you want oopsie protection you'll need to build that in yourself. The good news is that Forth lets you build it in yourself. Here are some options for you to consider:
1. Make a backup of your important data before you start your session. That way, you can restore your virtual disk from your "backup" version to undo your mistake.
I like to work on my Forth code on my PC and then copy/paste it over into a terminal window to my single board computer. That way I can get my Forth into a known state and then try something. If it doesn't work out, it's easy for me to restore the Forth to that known state because I saved all of the commands to do that on my PC. I just press reset and copy all of the commands over to get back to that known state. I have a backup of all of the screens in my EEPROM so I can restore them if I do something silly. Then it's *OK* to make mistakes (encouraged even - that's how you learn!).
If I've made awesome sauce in my screens that evening, I might even write a word to print out the Forth needed to recreate those screens (that's a Forth word that outputs runnable Forth to the screen), and then copy/paste that from the terminal back into my editor. I have a word ENTER-SCREEN that prompts me line by line for 16 lines to quickly enter a screen. As long as you have 16 total lines, it's very copy/paste friendly. Here is an example I used while testing blocks (the numbers in parens actually go into the screen so I could make sure the lines were going where they should - the first line is line # 0):
Code:
\ Enter screens for testing LOAD and THRU
1 enter-screen
( Test screen 1 )
( 1 ) variable testvalue
( 2 ) testvalue 5 !
( 3 ) variable blkinscreen
( 4 ) blk @ blkinscreen !
( 5 ) variable blkinstring
( 6 ) s" blk @ blkinstring !" evaluate
( 7 ) variable blkinscreenA
( 8 ) blk @ blkinscreenA !
( 9 )
( 10 )
( 11 )
( 12 )
( 13 )
( 14 )
( 15 )
2. If you want protection, build it into your word. Here's an example of how I might check to see if a block/screen is blank (based on the fact that your blank screens are space filled). Note that this assumes 1024 byte blocks, which you might not have on an older Forth
Code:
: blkblank? ( blk# -- f ) BLOCK 1024 -TRAILING SAWP DROP 0= ;
This loads the block, puts 1024 after it (assuming DECIMAL) to make it a 1024 byte string, and then calls -TRAILING which adjusts the size (only on the stack) of a string to remove trailing spaces. If the entire block is spaces, it will change the 1024 to a 0. It then gets rid of the address (not needed anymore) and checks the resulting size for 0, leaving a flag on the stack. You can now check that flag with IF and copy only if blank (or perhaps prompt the user if it's not blank). Note that this word consumes it's block #, so you'll probably want to DUP that before calling this word. If using an older Forth that has smaller blocks, you'll need to check all the blocks in the screen.
I personally don't like being prompted with ARE YOU SURE? type prompts unless what I am doing is very dangerous. It breaks the copy/paste scriptability if that prompt only comes up sometimes and not others. I'm a big fan of working from one known state to another target state, and then saving that new state by whatever means.