Welcome, Guest |
You have to register before you can post on our site.
|
Online Users |
There are currently 626 online users. » 0 Member(s) | 625 Guest(s) Bing
|
Latest Threads |
Includes in ASM
Forum: How-To & Tutorials
Last Post: bracckets
04-04-2024, 12:17 AM
» Replies: 2
» Views: 463
|
Intermittent errors
Forum: Help & Support
Last Post: zarsoft
03-12-2024, 12:39 PM
» Replies: 0
» Views: 270
|
Store array information i...
Forum: Help & Support
Last Post: rbiondi
03-10-2024, 09:42 PM
» Replies: 0
» Views: 346
|
ScrollLeft function scrol...
Forum: Bug Reports
Last Post: rbiondi
03-07-2024, 03:57 PM
» Replies: 2
» Views: 701
|
string.bas errors when co...
Forum: Bug Reports
Last Post: rbiondi
03-01-2024, 10:10 AM
» Replies: 2
» Views: 622
|
Using Beepola with ZX BAS...
Forum: How-To & Tutorials
Last Post: edtoo
02-29-2024, 09:47 AM
» Replies: 15
» Views: 32,182
|
Johnny Bravo
Forum: Gallery
Last Post: zarsoft
02-11-2024, 11:20 PM
» Replies: 0
» Views: 425
|
Compiling +D G+DOS progra...
Forum: ZX Basic Compiler
Last Post: boriel
01-22-2024, 08:32 AM
» Replies: 4
» Views: 8,488
|
VAL = ? (solved)
Forum: Bug Reports
Last Post: zarsoft
01-03-2024, 11:44 PM
» Replies: 8
» Views: 2,913
|
Wrong math (solved)
Forum: Bug Reports
Last Post: zarsoft
01-03-2024, 11:38 PM
» Replies: 4
» Views: 1,572
|
|
|
Feature: Italics! |
Posted by: britlion - 04-29-2009, 12:09 PM - Forum: Wishlist
- Replies (9)
|
|
I was rummaging through the .asm code, and I note it's pretty well optimized - though I can see places that could be neater. But that's for another time.
I noticed one of the runtime code blocks was labelled Italics..
So, curious, I tried compiling:
PRINT ITALIC 1; "Italics?"
And it worked perfectly! This isn't documented anywhere! What an awesome little addition to the language.
(It prints the text with the top a pixel to the right and the bottom a pixel to the left, and the middle left alone)
This should probably be added to the reserved words list.
|
|
|
Faster multiply? |
Posted by: britlion - 04-28-2009, 09:34 PM - Forum: ZX Basic Compiler
- Replies (8)
|
|
Okay, I confess: I'm not an assembler user. This is why I need a compiler.
That said, I love to nosey into things I don't understand. I often learn from that.
I was looking at an old piece of assembler code I found, when trying (fairly unsuccessfully) to learn Z80 code:
8 Bit number multiply
Rotates Num 1 round to examine it. Rotates Num2 up. Adds HL and DE if the bit is set.
Result is Num1 * Num2 in HL.
LD HL,0
LD DE, (NUM2)
LD A, (NUM1)
LOOP RR A (Divide A by 2 - copying the 1's column bit into the carry flag.)
JR NC, JP1 (Jump over the add if we have to)
ADD HL,DE
JP1 RET Z (Leave when we finish - A has gone to zero)
SLA E }
RL D } Multiply DE*2
JR LOOP
naturally, when I found this again, I couldn't resist comparing it to the 8 bit multiply assembler in the library. I'm not sure which is faster (Boriel's code is a little unclear in the fastcall case which registers are set with parameters; I think it's A and HL tho. I have a suspicion this code is faster, if only because it doesn't loop for a whole 8 bits if A is small - it quits as soon as A hits zero, which might optimize a few loops out.
Anyway, just for your perusal. Like I said, I'm a little beyond my depth on this one; but I love to optimize where I can!
I'm glad LCD mentioned the HISOFT compiler - because I think it does an awesome job. The limitation with it is that it's ON the spectrum, so you need room for basic + compiler + compiled code [though it can be clever and delete the basic as it goes to make more room]. I'm hoping Boriel's compiler will eventually Exceed the speed of Hisoft's - because it can be much cleverer outside the Spectrum than one locked into it!
|
|
|
String Slicing (*solved*) |
Posted by: britlion - 04-27-2009, 07:32 PM - Forum: Bug Reports
- Replies (3)
|
|
Not sure whether this is as intended, but it's not quite compatible with Sinclair Basic:
LET K$="1234567890"
PRINT K$(TO 3)
PRINT K$( 3 TO)
All seems to compile - though strings are numbered from 0, whereas Sinclair basic numbers them from 1.
So ZX Basic gives the output:
1234, where Sinclair basic would give the output 123
If the aim is to be able to compile Sinclair Basic, we're not there with that one. (Perhaps a switch, or configurable option?)
Also:
Print K$(3) fails. We would need to use k$(3 TO 3). Is this a bug?
PRINT K$( TO ) also fails, and ZX Basic allows it. It's an unusual corner case, though - it means the same thing as just K$. If it was to be supported for compatibility, a preprocessor tweak ought to be able to optimize it to disappear before the compiler saw it.
|
|
|
Optimisation level 3 Bug (*solved*) |
Posted by: LCD - 04-10-2009, 06:22 PM - Forum: Bug Reports
- Replies (5)
|
|
Hi Boriel,
I wrote the following little game (which is supposed to become a "Jewel Quest" clone one day :-):
Code: dim a as uinteger
dim x as ubyte
dim y as ubyte
dim solv as ubyte
dim posx as uinteger
dim posy as uinteger
sub field(x as uinteger,y as uinteger,obj as ubyte)
dim adr as uinteger
dim adr1 as uinteger
dim col as ubyte
adr=22528+x*3+y*96
adr1=50064+x+y*8
col=56
if obj=0 then col=2:end if
if obj=1 then col=3:end if
if obj=2 then col=4:end if
if obj=3 then col=5:end if
if obj=4 then col=6:end if
if obj=5 then col=7:end if
if obj=64 then col=48:end if
if peek adr1 then col=col+8:end if
poke adr,col:poke adr+1,col:poke adr+2,col
poke adr+32,col:poke adr+33,col:poke adr+34,col
poke adr+64,col:poke adr+65,col:poke adr+66,col
end sub
sub DisplayField()
adr=50000
for y=0 to 7
for x=0 to 7
a=peek(adr)
adr=adr+1
field(x,y,a)
next x
next y
end sub
sub ClearField(x as uinteger,y as uinteger)
poke 50000+x+y*8,64
poke 50064+x+y*8,1
end sub
function GetFieldObj(x as uinteger,y as uinteger) as ubyte
return peek (50000+x+y*8)
end function
sub SetFieldObj(x as uinteger,y as uinteger,obj as ubyte)
poke 50000+x+y*8,obj
end sub
function CheckBoard(x as integer,y as integer)
solved=0
dim current as ubyte
dim c1 as ubyte
dim c2 as ubyte
current=GetFieldObj(x,y)
c1=GetFieldObj(x-1,y)
c2=GetFieldObj(x-2,y)
if x>3 then
if c1=current and c2=current and GetFieldObj(x-3,y)=current and GetFieldObj(x-4,y)=current then for a=0 to 4:ClearField(x-a,y):next a:solved=solved+1:end if
end if
if x>2 then
if c1=current and c2=current and GetFieldObj(x-3,y)=current then for a=0 to 3:ClearField(x-a,y):next a:solved=solved+1:end if
end if
if x>1 then
if c1=current and c2=current then for a=0 to 2:ClearField(x-a,y):solved=solved+1:next a:end if
end if
c1=GetFieldObj(x,y-1)
c2=GetFieldObj(x,y-2)
if y>3 then
if c1=current and c2=current and GetFieldObj(x,y-3)=current and GetFieldObj(x,y-4)=current then for a=0 to 4:ClearField(x,y-a):next a:solved=solved+1:end if
end if
if y>2 then
if c1=current and c2=current and GetFieldObj(x,y-3)=current then for a=0 to 3:ClearField(x,y-a):next a:solved=solved+1:end if
end if
if y>1 then
if c1=current and c2=current then for a=0 to 2:ClearField(x,y-a):solved=solved+1:next a:end if
end if
return solved
end function
sub fieldupdate()
for x=0 to 7
for y=0 to 7
if GetFieldObj(x,y)=64 then
ypos=y
while ypos>0
SetFieldObj(x,ypos,GetFieldObj(x,ypos-1))
ypos=ypos-1
end while
SetFieldObj(x,0,rnd*5)
end if
next y
next x
end sub
function SolveField() as ubyte
solv=0
for y=0 to 7
for x=0 to 7
solv=solv+CheckBoard(x,y)
next x
next y
return solv
end function
sub PutCoin(x as uinteger,y as uinteger)
print at y,x;"\ \..\ "
print at y+1,x;"\ :\::\: "
print at y+2,x;"\ \''\ "
end sub
sub DisplayCursor(x as integer,y as integer,mode as byte)
dim adr as uinteger
dim newcol as ubyte
adr=22528+x*3+y*96
poke 65535,peek adr
asm
ld a,(65535)
and 7
ld (65535),a
end asm
if mode then
poke 65535,(peek 65535)+56
else
adr1=50064+x+y*8
if peek adr1 then
poke 65535,peek 65535+8
end if
end if
newcol=peek 65535
poke adr,newcol
poke adr+1,newcol
poke adr+2,newcol
poke adr+32,newcol
poke adr+33,newcol
poke adr+34,newcol
poke adr+64,newcol
poke adr+65,newcol
poke adr+66,newcol
end sub
randomize
for a=0 to 63
poke 50000+a,rnd*5
poke 50064+a,0
next a
asm
ld hl,50000
ld de,50128
ld bc,64
ldir
end asm
paper 0:ink 7:border 0:cls
'poke 23607,127
'poke 23606,16
print at 2,0;"Controls"
print at 4,0;"1) Keyboard"
print at 5,0;"2) Sinclair Joystick"
controls1:
if inkey$="1" then
up$="q"
dw$="a"
le$="o"
ri$="p"
fi$="m"
goto controls2
end if
if inkey$="2" then
up$="9"
dw$="8"
le$="6"
ri$="7"
fi$="0"
goto controls2
end if
goto controls1
controls2:
cls
for y=0 to 7
for x=0 to 7
PutCoin(x*3,y*3)
next x
next y
posx=4
posy=4
solveboard:
solv=SolveField()
DisplayField()
fieldupdate()
if solv then goto solveboard:end if
controlloop0:
DisplayCursor(posx,posy,1)
for a=0 to 5:pause 1:next a
controlloop1:
if inkey$=up$ and posy>0 then DisplayCursor(posx,posy,0):posy=posy-1:DisplayCursor(posx,posy,1):goto controlloop0:end if
if inkey$=dw$ and posy<7 then DisplayCursor(posx,posy,0):posy=posy+1:DisplayCursor(posx,posy,1):goto controlloop0:end if
if inkey$=le$ and posx>0 then DisplayCursor(posx,posy,0):posx=posx-1:DisplayCursor(posx,posy,1):goto controlloop0:end if
if inkey$=ri$ and posx<7 then DisplayCursor(posx,posy,0):posx=posx+1:DisplayCursor(posx,posy,1):goto controlloop0:end if
if inkey$=fi$ then gosub activate:end if
goto controlloop1
activate:
asm
ld hl,50000
ld de,50128
ld bc,64
ldir
end asm
if inkey$=up$ and posy>0 then
adr=50000+posx+posy*8
a=peek adr
b=peek (adr-8)
poke adr,b
poke adr-8,a
gosub check
return
end if
if inkey$=dw$ and posy<7 then
adr=50000+posx+posy*8
a=peek adr
b=peek (adr+8)
poke adr,b
poke adr+8,a
gosub check
return
end if
if inkey$=le$ and posx>0 then
adr=50000+posx+posy*8
a=peek adr
b=peek (adr-1)
poke adr,b
poke adr-1,a
gosub check
return
end if
if inkey$=ri$ and posx>0 then
adr=50000+posx+posy*8
a=peek adr
b=peek (adr+1)
poke adr,b
poke adr+1,a
gosub check
return
end if
complete=0
for a=0 to 63
if peek(50064+a) then complete=complete+1:end if
next a
if complete=64 then
goto won
end if
goto activate
check:
solv=SolveField()
if solv then
DisplayField()
goto solveboard
else
asm
ld hl,50128
ld de,50000
ld bc,64
ldir
end asm
goto controlloop0
end if
return
won:
cls
print "Congratulations"
The Problem is:
It works with Optimisation Level 2, but on Optimisation level 3 it throws "Unexpected tokem IX [IX] at line 1208"
|
|
|
Version 1.1.4 released! |
Posted by: boriel - 03-30-2009, 06:46 AM - Forum: ZX Basic Compiler
- No Replies
|
|
Changes from Version 1.1.2 to 1.1.4 - + The peephole optimizer has been enabled and seems to be working
reasonabily well (use -O3 for higher optimization).
- ! When a DIV BY ZERO error occurs with floating point numbers the program
crashes and resets the computer. This behaviour has been fixed
and now returns 0 value and sets the error code 6 (Numbert Too big)
in the ERR_NR system variable.
- * Refactorization of the assembler and compiler so they now
shared the OPTIONS in a better way (still to be finished). This
makes easier to program future compiler options. Now also --debug
flag is additive, showing more verbosity the more it is used.
- + Memory optimization: The PRINT routine (which is about 1K) is not
included if not USED.
- ! Fixed a bug in negative constant integer typecasting (Thanks to LCD
at WOS for reporting it! ;-)). It was causing decremental FOR..NEXT
to fail.
- ! Scientific notation numbers (e.g. 2e10) were not correctly parsed.
Fixed. Thanks again to LCD. ;-)
- + Added TAB compatibility for the PRINT command (both as a command
and as a CHR$ control character).
- * PRINT code optimized for size, maintaining speed.
====
TODO:- Some little more peephole optimizations.
- Implementation of SAVE/LOAD/VERIFY with DATA/CODE/SCREENS (And maybe even the BASIC zone)
- 8 bits AND/OR/NOT/XOR instructions
- READ/DATA/RESTORE (mostly for compatibility)
- CLEAR for filling memory zones.
- USR n and USR n$ function (mostly for compatibilty)
|
|
|
Version 1.1.1 released! |
Posted by: boriel - 03-16-2009, 08:10 AM - Forum: ZX Basic Compiler
- No Replies
|
|
This version fixed some issues and introduces interesting improvements:
Changes from Version 1.1.0 to 1.1.1
- !Fixed a bug in CONTINUE DO which was not being correctly compiled
- +PRINT routines were included even when neither PRINT nor
drawing primitives were used. Optimized.[/*]
- ! Fixed a lot of syntax error checkings with array operations.
- ! Fixed array dimension checking
- + Expanded syntax: Direct array assignation a = b (being a and b
arrays of thes same type an size)[/*]
- ! Fixes an error exception on syntax error for array subscripting.
- * Changed alloc functions to match the FreeBasic names.
- * Using a wrong sigil in array declaration is now forbidden.
- * Better sigils (suffixes) types managements at DIM declarations.
- * Lot of internal source code refactoring
- + DIM r AT @a(k0, k1, ...) is allowed (k0, k1, ... constants)
- ! Fixed a bug for local variables and parameters when the offset is
very large (> 128)
- + Enabled the --sinclair flag for automatic sinclair libraries inclusion
- + Added SetAttr routine whichs changes the attribute of
screen coordinate (I, J) with the given color attr
value.
- ! Fixed a buggy modu16 modi16 implementation that was not compiling
correctly
- * Output asm code is now slightly optimized (for speed an memory)
- ! Fixed a bug in intenger parameters (16 and 32 bits)
- ! Fixed a compiler crash when using arrays of Fixed Point numbers
|
|
|
Negative STEP does not work (*solved*) |
Posted by: LCD - 03-15-2009, 07:03 PM - Forum: Bug Reports
- Replies (12)
|
|
Hi Boriel, I just trying to write some stuff in ZX Basic compiler 1.1.0, but I ran into some problems:
Code: x=0
if x=1 then
print "1"
else if x=0 then
print "0"
end if
I got the message "Unexpected end of file", so if it is a part of FOR NEXT Loop, I got the message "Unexpected Token 'NEXT' <NEXT>". ELSE alone works, but I was sure, ELSE IF should work too, Or maybe I'm wrong?
Another one: the program does not accept Exponents: 2e4 (=2000) or similar.
And finally:
Negative STEP does not work with integers or long, only with floats or byte:
Code: dim x as integer
for x=7 to 1 step -1
print x
next x
The compiler is otherwise fantastic! Please continue your great work!
|
|
|
Version 1.1.0 released! |
Posted by: boriel - 03-11-2009, 08:35 AM - Forum: ZX Basic Compiler
- No Replies
|
|
This version fixed some issues and introduces interesting improvements:
Changes from Version 1.0.9 to 1.1.0 - SCREEN$ coordinated were swapped. Fixed.
- DIM .. AT was not correctly working with local vars nor params. Fixed.
- Added BOLD "attribute".
Code: PRINT BOLD 1; "Hello"
- Added ITALIC "attribute".
Code: PRINT ITALIC 1; "Hello"
- Added malloc, free and realloc functions to work with the heap
- Some code rearrangement
- The IFDEF directive was not working in the preprocessor. Fixed.
================================================================
Changes from Version 1.0.8 to 1.0.9
- Fixed a bug which could crash the program if no memory
- Added better error handler for parameter declaration
- Added UCase function
- Added Lcase and fixed ucase to be case insensitive
- Added MultiKeys Function (similar to FREEBASIC) so multiple keys can be checked at once
- Added GetKeyScanCodes
- Added HEX and HEX16 functions to return HEXadecimal string representation of numbers
- Fixed a bug when a$(n TO) was specified
- Optimization: Remove unnecessary jumps at function returns.
- STORE16 now generates a more efficient backend (Z80 ASM) code.
- Added alias for arrays. Now you can declare:
Code: DIM a(10)
DIM c at @a
- Better code generation for STORE32 and STOREF backend
- Optimized constant array assignation as a direct store.
- Added constant array Read access optimizations
|
|
|
Version 1.0.8 released! |
Posted by: boriel - 03-01-2009, 12:34 AM - Forum: ZX Basic Compiler
- No Replies
|
|
This release includes new fixes and improvements: - Fixed a bug in the PRINT command when printing floating point numbers due to a Spectrum ROM Bug. The temporary attributer were not being used.
- Fixed a bug in the STR$ function that made the program to freeze and also clears the temporary attributes (related to the ROM bug as above).
- Fixed a bug in the assembler which, sometimes won't assemble if #init directives were used. Also some code clean up.
- Now you can enter ink/paper codes and graphic characters ala BASIN (read below)
- Added shift bit instructions (SHL, SHR)
About the spectrum ROM bug. The original STR$ Basic function clean up the temporary attributes. Try this in your ZX Spectrum:
Code: 10 PRINT PAPER 2; STR$(0)
The bug causes that PAPER 2 has no effect (you should see a "0" over a red background). ZX Basic workaround this bug now.
To enter an UDG character like "A" type \A. For example:
Code: PRINT "\a": REM This will print UDG "A"
The numeric graphics characters can be obtained using the backslash (as above) followed by two punctuation characters. These ones are: [ ] ['] [:] and [.] characters. Each dot represents a square in the graphic character. Try this:
Code: 10 PRINT "\ \::\:'\:.\..\'."
|
|
|
Version 1.0.7 released! |
Posted by: boriel - 02-22-2009, 10:58 AM - Forum: ZX Basic Compiler
- No Replies
|
|
This release includes new fixes and improvements: - Fixes a bug in the DRAW command. The draw implementation was buggy. The new DRAW implementation works ok, and is faster and smaller.
- Support for DRAW with 3 arguments. Now you can DRAW arcs as in Sinclair BASIC. The routine works exactly as the ZX Spectrum ROM, but also allows drawing in the lower 16 scan lines
- Optimization: If a function is not called, and you use -O1 (or a higher number), it won't be compiled, allowing saving space
- Optimization: If a global variable is not used, and you use -O2 (or a higher number), it won't be compiled, allowing saving space
- Optimization: The code generated for temporary atributes is now smaller and faster
New compiler options:- Use --array-base=1 to start arrays at subscript 1 (default is 0)
- Use -On to enable optimizations. Higher n number leads to higher optimizations
|
|
|
|