Basic VAL function
Basic VAL function
Hello!
If I'm not mistaken, the VAL function takes a string containing an expression and returns a number which represents the result of the expression.
I'm reading a Basic listing and I found some constructs that confuse me a little. Some examples:
LET d=VAL "256"
GO SUB VAL "900"
POKE VAL "23658",VAL "8"
Why not simply:
LET d=256
GO SUB 900
POKE 23658,8
Thank you!
If I'm not mistaken, the VAL function takes a string containing an expression and returns a number which represents the result of the expression.
I'm reading a Basic listing and I found some constructs that confuse me a little. Some examples:
LET d=VAL "256"
GO SUB VAL "900"
POKE VAL "23658",VAL "8"
Why not simply:
LET d=256
GO SUB 900
POKE 23658,8
Thank you!
Re: Basic VAL function
In this case VAL's probably being used to save memory. Numbers on the Spectrum are stored with a 5-byte numeric representation accompanying the textual representation, which speeds up the interpreter as it doesn't have to parse each number every time it reads it. The downside is this ends up wasting memory. Although VAL looks like it's making the program larger, it actually saves bytes in most cases: you have three extra bytes for the VAL and the two quote marks, but you no longer have to store the 5-byte number and so you save two bytes overall.
There are also some other tricks you can do, such as BIN for zero, SGN PI for one, and INT PI for 3, but VAL is more general and works in most situations.
Hope this helps!
There are also some other tricks you can do, such as BIN for zero, SGN PI for one, and INT PI for 3, but VAL is more general and works in most situations.
Hope this helps!
Re: Basic VAL function
It's to save memory, since in BASIC representation, VAL "256", takes less bytes to represent the number 256 directly.
This saves memory, if you are really tight on it, but it's slower. So it's a compromise, that can be used on code that does not run often, or is just part of the loader for example.
The less bytes you consume in basic, the more bytes you can LOAD "" CODE, for assembly, for example.
This saves memory, if you are really tight on it, but it's slower. So it's a compromise, that can be used on code that does not run often, or is just part of the loader for example.
The less bytes you consume in basic, the more bytes you can LOAD "" CODE, for assembly, for example.
Re: Basic VAL function
I think this is done more from habit than necessity. VAL and NOT PI are commonly used in short loaders for machine code games where the handful of bytes it saves doesn't make any difference, but then if you can save a few bytes then why not.
Actually how many bytes does NOT PI save?
Actually how many bytes does NOT PI save?
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Basic VAL function
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Basic VAL function
The above is all relevant and correct but it was especially useful in Sinclair Basic on the unexpanded ZX81.
With only 1K for screen and program, every byte was even more important than on the Spectrum.
It may have been that it became habit and as mentioned, if you can save bytes then why not?
With only 1K for screen and program, every byte was even more important than on the Spectrum.
It may have been that it became habit and as mentioned, if you can save bytes then why not?
- Einar Saukas
- Bugaboo
- Posts: 3144
- Joined: Wed Nov 15, 2017 2:48 pm
Re: Basic VAL function
Actually five
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Basic VAL function
Mmm . . . A zero is one byte, plus 5 bytes of the BASIC’s number representation. That’s six bytes. NOT PI is two bytes. Six minus two is four.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
- Einar Saukas
- Bugaboo
- Posts: 3144
- Joined: Wed Nov 15, 2017 2:48 pm
Re: Basic VAL function
Plus one byte for control code 14 that prefixes the number representation IIRC.Ast A. Moore wrote: ↑Thu May 24, 2018 3:07 pmMmm . . . A zero is one byte, plus 5 bytes of the BASIC’s number representation. That’s six bytes. NOT PI is two bytes. Six minus two is four.
- Einar Saukas
- Bugaboo
- Posts: 3144
- Joined: Wed Nov 15, 2017 2:48 pm
Re: Basic VAL function
Text adventures in Sinclair BASIC usually need this trick to fit in 16K.
This is also useful for small tape loaders. Making them smaller allows setting RAMTOP to a lower address, so you can have more available space to load a code block.
Re: Basic VAL function
Good job black works well with every other colour. I wonder if any games chose a Magenta colour scheme purely because they used BORDER PI on loading...
Re: Basic VAL function
It's really a bizarre choice for a 1k machine's basic.
I guess the ZX80 BASIC, being integer only, didn't do this?
Microsoft BASIC leaves this kind of optimization in your hands - put the constant in a variable if it's in a tight loop.
I guess the ZX80 BASIC, being integer only, didn't do this?
Microsoft BASIC leaves this kind of optimization in your hands - put the constant in a variable if it's in a tight loop.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Basic VAL function
D’oh. Right you are!Einar Saukas wrote: ↑Thu May 24, 2018 3:15 pmPlus one byte for control code 14 that prefixes the number representation IIRC.Ast A. Moore wrote: ↑Thu May 24, 2018 3:07 pm Mmm . . . A zero is one byte, plus 5 bytes of the BASIC’s number representation. That’s six bytes. NOT PI is two bytes. Six minus two is four.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Basic VAL function
Hmm, it looks like I was mistaken about BIN using fewer bytes. I just checked the memory of a BASIC program and it turns out that even if you have no digits after the BIN, it still uses 5 extra bytes to store the value and so uses exactly the same amount of memory as the number 0.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Basic VAL function
Yes, NOT PI is the way to go. Honestly, when it comes to loaders, I prefer using machine code inside BASIC.djnzx48 wrote: ↑Fri May 25, 2018 8:46 am Hmm, it looks like I was mistaken about BIN using fewer bytes. I just checked the memory of a BASIC program and it turns out that even if you have no digits after the BIN, it still uses 5 extra bytes to store the value and so uses exactly the same amount of memory as the number 0.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Basic VAL function
You'd have to make sure that the loader is relocatable though, as I'm pretty sure peripherals like the Interface 1 can move BASIC up in memory to make room for their own data.
Another alternative is to find some empty space on the loading screen and stick the loader there. If you go this route, you also get the advantage that it's a lot easier to load into the entire memory without having to worry about what happens when the loader gets overwritten.
Another alternative is to find some empty space on the loading screen and stick the loader there. If you go this route, you also get the advantage that it's a lot easier to load into the entire memory without having to worry about what happens when the loader gets overwritten.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Basic VAL function
Sure. That’s trivial, though, particularly if you’re using a ROM-based loader. A custom loader would have to be relocated to non-contended memory anyway, so if you’re using calls within it, the addresses must be pre-calculated in relation to the execution location. Incidentally, I use both a ROM-based and a custom turbo loader in Yankee. Enable, say, Interface 1 in your emulator, initialize it by typing CAT 1 in BASIC, and then load each version of the game. They’ll both work.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Basic VAL function
I liked the trick of putting all the numbers in as zero and poking the correct values into the 5 bytes so you'd end up with loader programs like:
10 CLEAR 0: POKE 0,0: LOAD "" CODE: RANDOMIZE USR 0
You would still save some memory on the larger numbers, plus it would add some simple obfuscation. Also if the line was edited it would now no longer work as the zeros would really be zeros.
10 CLEAR 0: POKE 0,0: LOAD "" CODE: RANDOMIZE USR 0
You would still save some memory on the larger numbers, plus it would add some simple obfuscation. Also if the line was edited it would now no longer work as the zeros would really be zeros.
Re: Basic VAL function
Necroposting, sorry.
While exploring old utilities, I've found this:
https://spectrumcomputing.co.uk/entry/2 ... Cruncher_2
It's a good alternative to VAL for numbers >4 digits, saving more memory but maintaining the speed.
While exploring old utilities, I've found this:
https://spectrumcomputing.co.uk/entry/2 ... Cruncher_2
It's a good alternative to VAL for numbers >4 digits, saving more memory but maintaining the speed.