Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
About constants
#1
Defining constants with CONST Constant as UByte=0 is not the ideal way, because they can be easy mistaken for variables, and can interfer with variables. So my proposal is to change it to similar way, PureBasic does:
#Constant as UByte=0, and all constants are marked with "#" sign in the front. In PureBasic it is a little different, as the constant and variable types are defined this way: #constant.ub=0 (ub=short for unsigned byte, has to be defined only one time).
apart from this I propose to include build-in constants with ROM Labels and System variables:
#KSTATE=23552, #LASTK=23560, #REPDEL=23561, #REPPER=23562, ...
#start=$0, #error_1=$8, #print_a_1=$10, #get_char=$18
#test_char=$1C, #next_char=$20, #fp_calc=$28, #bc_spaces=$30, ...
Also constants for some other usages:
#False=0, #True=1, #Zero=0
#Black=0, #Blue=1, #Red=2, #Magenta=3,...

Is this a good idea???
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#2
LCD Wrote:Defining constants with CONST Constant as UByte=0 is not the ideal way, because they can be easy mistaken for variables, and can interfer with variables. So my proposal is to change it to similar way, PureBasic does:
#Constant as UByte=0, and all constants are marked with "#" sign in the front. In PureBasic it is a little different, as the constant and variable types are defined this way: #constant.ub=0 (ub=short for unsigned byte, has to be defined only one time).
apart from this I propose to include build-in constants with ROM Labels and System variables:
#KSTATE=23552, #LASTK=23560, #REPDEL=23561, #REPPER=23562, ...
#start=$0, #error_1=$8, #print_a_1=$10, #get_char=$18
#test_char=$1C, #next_char=$20, #fp_calc=$28, #bc_spaces=$30, ...
Also constants for some other usages:
#False=0, #True=1, #Zero=0
#Black=0, #Blue=1, #Red=2, #Magenta=3,...

Is this a good idea???

Hi, LCD

Well, I'm following the FreeBasic standard. Basically, you can use CONST, or #define. CONST creates a TYPED constant, whilst #define just define a macro (that is, replace a word with another).

The example you give above for PureBasic is a Macro. You can use them if you feel more comfortable with them. This way:
Code:
#define True 1
#define False 0
Notice you always use #define with no equal sign (=). This will give you the same result as PureBasic. You can also elaborate more complex macros:

Code:
#define square(x)  (x * x)
PRINT "Square of 5 is "; square(5) : REM Square is an Inline function.

Note: ZX Basic admits hexadecimal numbers with $-prefix (as you use) or with h-suffix. Eg. 32 (decimal) => $20 or 20h

BTW: Nice retro-site! :!: 8)
Reply
#3
Thank you Boriel. I hope, I can finish some of my Projects from my website using your Compiler...
The Problem was: I never used FreeBasic. so the syntax is a bit strange for me. But now after I know where I can find the references, it will be maybe easier.
The Macros looks like a excellent idea because, if I understand this right, it is faster than calling a function or procedure, but it will surely eat more memory with longer macros. Do ZX Basic support procedures (with shared or local variables)?
Supporting Hex and binary (%0111) natively is a great idea, because it is faster than BIN function. And the InLine ASM is something, I wanted since I was using compilers.
The fact is: HiSoft Basic Calls to additional ASM routines are extremly slow. I had here the fastest PLOT routine ever written (with 1 Kb of tables), but calling it from HiSoft Basic over the ROM USR routine made it slower than the ROM PLOT routine.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#4
LCD Wrote:Thank you Boriel. I hope, I can finish some of my Projects from my website using your Compiler...
The Problem was: I never used FreeBasic. so the syntax is a bit strange for me. But now after I know where I can find the references, it will be maybe easier.
Thank you for your interest. I will fill in the documentation as soon as possible. If you can use subversion (or tortoiseSVN for windows) I encourage you to try de alpha developing version. Just clock on the zxbasic directory with your File Explorer and do a SVN Update. Currently 3 new features are in the alpha version:
  1. If you specify an optimization level like, zxb -O2 program.bas then unused functions won't be compiled Wink
  2. You can start arrays by default with lower bound 1 (the default is 0): DIM a(10) is the same as DIM a(0 TO 10). If you want them like in Sinclair Basic, use zxb --option-base=1
  3. The print, DRAW, PLOT and CIRCLE routines has been slightly optimized (they use attributes in a more efficient way).

Quote:The Macros looks like a excellent idea because, if I understand this right, it is faster than calling a function or procedure, but it will surely eat more memory with longer macros. Do ZX Basic support procedures (with shared or local variables)?
Yes, a macro is faster than a procedure/function, but takes more memory. Use it only for very simple functions (like the square example above). Macros can have more than one line. Look in library/retrace.bas

ZX BASIC supports FUNCTIONS and procedures (SUB). Declared variables (with DIM) in them are local. In fact SCREEN$, POINT and ATTR are implemented this way. Function calls uses the STD_CALL convention (used in most compilers today). You can see the library of high-level functions in the library/ directory to see how functions are implemented (some of them use inline ASM).

To use a function from the library (e.g. SCREEN$), use #include directive:
Code:
#include <screen.bas>

For functions/subs that use only 1 or none parameters you can use the FASTCALL convention (parameteres are passed in the registers). This is VERY internal Wink so please, ask me more if interested.

Quote:Supporting Hex and binary (%0111) natively is a great idea, because it is faster than BIN function. And the InLine ASM is something, I wanted since I was using compilers.
Binary numbers here are written either %0111 or 0111b Wink

Quote:The fact is: HiSoft Basic Calls to additional ASM routines are extremly slow. I had here the fastest PLOT routine ever written (with 1 Kb of tables), but calling it from HiSoft Basic over the ROM USR routine made it slower than the ROM PLOT routine.
Is HiSoft BASIC available today for FREE? I would like to try it.

You can embed your PLOT routine this way:
Code:
SUB FASTCALL myplot(x AS UBYTE, y AS UBYTE)
    ASM
    pop hl ' HL gets the return address
    ex (sp),hl ' HL now contains the X parameter (in H register)
    ' Now A register contains Y
    ' and H register contains X
    ' ASM includes must be included within asm scope
#include "myplot.asm"
     END ASM
END SUB
Note: ZX BASIC is (by now), case sensitive. This means that for your function and variables, MYVARIABLE and myvariable refers to diferent variables.
Reply
#5
boriel Wrote:Thank you for your interest. I will fill in the documentation as soon as possible. If you can use subversion (or tortoiseSVN for windows) I encourage you to try de alpha developing version. Just clock on the zxbasic directory with your File Explorer and do a SVN Update. Currently 3 new features are in the alpha version:
  1. If you specify an optimization level like, zxb -O2 program.bas then unused functions won't be compiled Wink
  2. You can start arrays by default with lower bound 1 (the default is 0): DIM a(10) is the same as DIM a(0 TO 10). If you want them like in Sinclair Basic, use zxb --option-base=1
  3. The print, DRAW, PLOT and CIRCLE routines has been slightly optimized (they use attributes in a more efficient way).
I did not used tortoiseSVN yet, but will try this, currently started the download. The new features sounds great. Not using ROM Routines for DRAW, PLOT and CIRCLE means the Coordinate range for Y 0 to 191, excellent! I pointed Website Watcher to the directory of ZX Basic, so I will be informed if anything changes, as I run it every day. But it would be nice to have a changelog to see what was changed from previous version.

Quote:Yes, a macro is faster than a procedure/function, but takes more memory. Use it only for very simple functions (like the square example above). Macros can have more than one line. Look in library/retrace.bas

ZX BASIC supports FUNCTIONS and procedures (SUB). Declared variables (with DIM) in them are local. In fact SCREEN$, POINT and ATTR are implemented this way. Function calls uses the STD_CALL convention (used in most compilers today). You can see the library of high-level functions in the library/ directory to see how functions are implemented (some of them use inline ASM).

To use a function from the library (e.g. SCREEN$), use #include directive:
Code:
#include <screen.bas>

For functions/subs that use only 1 or none parameters you can use the FASTCALL convention (parameteres are passed in the registers). This is VERY internal Wink so please, ask me more if interested.
Aha, include them... good to know. I guess, it is possible to include any other ZXBasic programm too. I was about to ask it... It sounds well developed. I'm now much more encouraged to use your program often.


Quote:Binary numbers here are written either %0111 or 0111b Wink
Sounds logical after all. Good to know, even if I prefer to use % and $ for binary and Hex.

Quote:Is HiSoft BASIC available today for FREE? I would like to try it.
Yes, you can download it with the instruction from here:
<!-- m --><a class="postlink" href="http://www.worldofspectrum.org/infoseekid.cgi?id=0008249">http://www.worldofspectrum.org/infoseek ... id=0008249</a><!-- m -->
I'm using the debugged version in 48K Basic running on real Hardware.
Also Uschi is a very good compiler (german): <!-- m --><a class="postlink" href="http://www.worldofspectrum.org/infoseekid.cgi?id=0008927">http://www.worldofspectrum.org/infoseek ... id=0008927</a><!-- m -->, even if limited to integer and not accepting strings, but very fast.
Other compilers are not that good because they include the complete compiler runtimes.

Quote:You can embed your PLOT routine this way:
Code:
SUB FASTCALL myplot(x AS UBYTE, y AS UBYTE)
    ASM
    pop hl ' HL gets the return address
    ex (sp),hl ' HL now contains the X parameter (in H register)
    ' Now A register contains Y
    ' and H register contains X
    ' ASM includes must be included within asm scope
#include "myplot.asm"
     END ASM
END SUB

Aha, I think, I now know how it works, very clever!!! Thank you.
Quote:Note: ZX BASIC is (by now), case sensitive. This means that for your function and variables, MYVARIABLE and myvariable refers to diferent variables.
I did not noticed that yet, because all my variables are lower case, but thank you for the warning :-).
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#6
I just tried to use the inline ASM:
Code:
dim source as uinteger
dim dest as uinteger
dim a as ubyte

for a=0 to 191
  source=a*32
  dest=16384+a*32
  asm
  ld hl,(_source)
  ld de,(_dest)
  ld bc,32
  ldir
  end asm
next a
I got two warnings:
dest and source are never used (?) and undefined label "_source" (surely also undefined label "_dest") was critized.
The fact is, these variables are used. I wonder also why the _source and _dest are undefined labels, even if I try to use source=0 and dest=0 in the source. I checked the asm output, but only _a was defined with defb. Btw: PRINT was not used, but it was included in the asm source.
I'm using the version 1.1.0 by the way.
Maybe you know the reason?
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#7
LCD Wrote:I just tried to use the inline ASM:
Code:
dim source as uinteger
dim dest as uinteger
dim a as ubyte

for a=0 to 191
  source=a*32
  dest=16384+a*32
  asm
  ld hl,(_source)
  ld de,(_dest)
  ld bc,32
  ldir
  end asm
next a
I got two warnings:
dest and source are never used (?) and undefined label "_source" (surely also undefined label "_dest") was critized.
The fact is, these variables are used. I wonder also why the _source and _dest are undefined labels, even if I try to use source=0 and dest=0 in the source. I checked the asm output, but only _a was defined with defb. Btw: PRINT was not used, but it was included in the asm source.
I'm using the version 1.1.0 by the way.
Maybe you know the reason?
Are you using the -o2 optimization level? -o2 removed unused variables. Use -o1. See explanation:
The problem here is that the compiler does not know anything about the assembler level. So 'ld hl,(_source)' is taken as is. It is not intelligent enough to understand you're accesing a variable from the assembler layer directly.

For example, if you create a program like this:
Code:
a = 1
b = 1
print a
You can see the 'b' variable is useless: You don't use if for anything. If you use -o2 it will be removed.
In your listing you're having the same problem because the compiler does not know anything about the asm level. This problem also exists in other compilers and it's usually fixed with a directive.
You can avoid this by using -o1 compiler option, or just do something like:
Code:
REM this code will be optimized and removed
dummy = source
dummy = dest
Which will prevent "source" and "dest" to be removed.

I'm also studying the PRINT library inclusion (this is due to a reorder of the attributes routines for higher speed). Will fix it in 1.1.1.
Reply
#8
boriel Wrote:You can see the 'b' variable is useless: You don't use if for anything. If you use -o2 it will be removed.
In your listing you're having the same problem because the compiler does not know anything about the asm level. This problem also exists in other compilers and it's usually fixed with a directive.
You can avoid this by using -o1 compiler option, or just do something like:
Code:
REM this code will be optimized and removed
dummy = source
dummy = dest
Which will prevent "source" and "dest" to be removed.

I'm also studying the PRINT library inclusion (this is due to a reorder of the attributes routines for higher speed). Will fix it in 1.1.1.

Yes, its true, I was using -o 2, you arguments are absolutly correct, but I was not expecting that if I use these Variables with ASM, they will be stripped away (they are used ad least in ASM). Maybe this problem could be adressed in one of the future releases. If the variables are used in ASM code, the optimisation must not strip the variables. It will be very useful to have optimisation level 2 together with the possibility to use the variables directly in ASM of a SUB.
The workaround works, thank you.

By the way, I wrote a very positive article about the Compiler for a german fanzine
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#9
LCD Wrote:
boriel Wrote:You can see the 'b' variable is useless: You don't use if for anything. If you use -o2 it will be removed.
In your listing you're having the same problem because the compiler does not know anything about the asm level. This problem also exists in other compilers and it's usually fixed with a directive.
You can avoid this by using -o1 compiler option, or just do something like:
Code:
REM this code will be optimized and removed
dummy = source
dummy = dest
Which will prevent "source" and "dest" to be removed.

I'm also studying the PRINT library inclusion (this is due to a reorder of the attributes routines for higher speed). Will fix it in 1.1.1.

Yes, its true, I was using -o 2, you arguments are absolutly correct, but I was not expecting that if I use these Variables with ASM, they will be stripped away (they are used ad least in ASM). Maybe this problem could be adressed in one of the future releases. If the variables are used in ASM code, the optimisation must not strip the variables. It will be very useful to have optimisation level 2 together with the possibility to use the variables directly in ASM of a SUB.
The workaround works, thank you.
By now -o2 only stripes variables! Tongue so you can delay using it.
Parsing accessed labels from the asm layer back to the compiler is a really really hard task! :?
What I've seen with GNU C an others is to declare variables in a way that tell the compiler no to optimize them (for example, "volatile" in C or something like that).

See here an example for the GNU C compiler, and some problems (warning, too technical, it's just an example). So it's not a trivial task. :?

Quote:By the way, I wrote a very positive article about the Compiler for a german fanzine
Thanks a lot! Do you have the URL?
Reply
#10
boriel Wrote:By now -o2 only stripes variables! Tongue so you can delay using it.
Parsing accessed labels from the asm layer back to the compiler is a really really hard task! :?
What I've seen with GNU C an others is to declare variables in a way that tell the compiler no to optimize them (for example, "volatile" in C or something like that).

See here an example for the GNU C compiler, and some problems (warning, too technical, it's just an example). So it's not a trivial task. :?

It is not trivial, but leaving declaration to the user may be a good way
Code:
DeclareL _source

Quote:
Quote:By the way, I wrote a very positive article about the Compiler for a german fanzine
Thanks a lot! Do you have the URL?
The first new issue of "SPC Ressurection" is not yet out (because the previuus editor was unable to continue his work for one year), so there is a new editor to continue the work (me). The magazine is in german, but I will tell you the link when it is out. Planet release date: 1.7.2009, but the currently the editing is faster than I expected, so it will be probably be out much earlier. 50% of the current issue is already finished.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)