Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 258
» Latest member: manuelzo75
» Forum threads: 1,074
» Forum posts: 6,434

Full Statistics

Online Users
There are currently 376 online users.
» 0 Member(s) | 374 Guest(s)
Bing, Google

Latest Threads
.tap file code not execut...
Forum: Help & Support
Last Post: Zoran
04-28-2025, 10:59 AM
» Replies: 4
» Views: 189
Exit from more than one l...
Forum: Wishlist
Last Post: Duefectu
04-23-2025, 10:06 PM
» Replies: 3
» Views: 258
put small ASM programs li...
Forum: How-To & Tutorials
Last Post: Zoran
04-18-2025, 02:02 PM
» Replies: 6
» Views: 1,521
Creating +3 Menus - Loadi...
Forum: Help & Support
Last Post: merlinkv
04-16-2025, 02:08 PM
» Replies: 6
» Views: 512
Randomize not very random...
Forum: Help & Support
Last Post: Zoran
04-08-2025, 10:40 AM
» Replies: 4
» Views: 414
Scope rules
Forum: Bug Reports
Last Post: Zoran
04-04-2025, 09:46 AM
» Replies: 2
» Views: 287
Using constants not allow...
Forum: Bug Reports
Last Post: baltasarq
03-19-2025, 10:00 PM
» Replies: 8
» Views: 1,014
404 page not found
Forum: Documentation
Last Post: boriel
03-08-2025, 07:16 PM
» Replies: 5
» Views: 2,852
Spectrum keywords codes
Forum: Bug Reports
Last Post: boriel
03-08-2025, 11:00 AM
» Replies: 1
» Views: 395
ZXodus][Engine
Forum: ZX Basic Compiler
Last Post: boriel
02-19-2025, 11:43 PM
» Replies: 69
» Views: 213,483

 
  leer de un archivo txt
Posted by: omontero - 02-18-2010, 01:50 PM - Forum: Off-Topic - No Replies

Saludos amigos,
necesito saber como consultar la informacion de un archivo txt y colocarla en mi sitio drupal en cualquier pagina web, si alguien me puede ayudar se lo agradecere. Drupal se desarrollo con PHO por lo que muchas de las funciones de PHP corren en Drupal.
Saludos a todos y gracias de antemano.
Osbel

Print this item

  read from a txt file
Posted by: omontero - 02-18-2010, 01:47 PM - Forum: Off-Topic - Replies (1)

Hi,
I am developed a web site with drupal, and need some help. I need to read a txt file to view information and then put it in a web page.
Thanks anyway.
bye

Print this item

  Function calls
Posted by: britlion - 02-17-2010, 01:15 PM - Forum: ZX Basic Compiler - Replies (3)

When doing assembler based function calls, there's something that confuses me about the stack.

Code:
FUNCTION thing (num1 as uByte, num2 as uByte) as uByte
asm
DI
HALT
end asm
END FUNCTION

When the virtual computer crashes, you can look at the registers and the stack and find out what it's doing.

The stack seems to have
uinteger <something>
uinteger <return address>
uinteger <44,num1>
uinteger <44,num2>

A is set to num1

First question: What's the <something> ? I end up popping it off the stack and dumping it. This worries me.
Second question: If I can trust A to be num1 already, why do I have to go through num1 to get to num2?
Third question: Why the 44's strapped to each byte parameter?

So right now I end up:
Code:
POP BC  ; throw this away
POP HL  ; return address
POP AF  ; num 1 -> A
POP DE  ; num2 -> D.

And since that's less than helpful:
LD E,D
LD D,0

To make DE the value of num2.

Question 1 worries me most. What IS that extra value on the stack?

Is there a better way of handling parameters - with IX+offset, say?
Does the compiler set it to clean up the stack afterwards, and I shouldn't POP it at all?

Sorry to whine, but this isn't documented, and I'm trying to reverse engineer it! I've got the hang of fastcall, but soemtimes I want more than one parameter.

Print this item

  Memory corruption (Bugs 1.25 Beta) (*solved*)
Posted by: britlion - 02-16-2010, 01:43 AM - Forum: Bug Reports - Replies (8)

* Local array issues:
I noticed that a table I had in a subroutine wasn't returning the correct values. Finally pinned down a short program that demonstrates this:
(Both printed lines should be the same)

Code:
SUB failing(a as ubyte,b as ubyte, c as byte, d as byte, text as string)
DIM table2(25) as uByte => {18,24,16,14,14,12,20,12,12,16,14,6,12,10,18,14,26,18,24,8,12,24,12,26,18,10}
print table2(0);" ";table2(1)
end sub

sub working()
DIM table(25) as uByte => {18,24,16,14,14,12,20,12,12,16,14,6,12,10,18,14,26,18,24,8,12,24,12,26,18,10}
print table(0);" ";table(1)
end sub

cls
working()
failing(1,2,3,4,"A")

Interestingly if you swap the order that the two subs are in, which one breaks swaps too - it's the first one defined that breaks each time.

Print this item

  Wishlist
Posted by: britlion - 02-13-2010, 11:44 AM - Forum: Wishlist - Replies (8)

  • * Faster Printing routine
    * Ability to print anywhere on the 256*192 grid, with optional attributes
    * Different sized printing (I'll probably tackle 64 Char printing as well as that 42 character one eventually)
    * Interrupt driven routines
    * Automated 128K support

    *More people adding to function and subroutine libraries

Print this item

  Faster Square Roots
Posted by: britlion - 02-13-2010, 01:16 AM - Forum: How-To & Tutorials - Replies (12)

I've got a version that does LONG as well as uInteger later in this thread.

I note that the compiler uses the Spectrum ROM square root routine. This routine is hideously slow. It actually calculates x^(0.5) instead, and takes ages about it. The Newton-Raphson method would be a lot faster, and pretty easy to put in.

If you are willing to sacrifice accuracy, an integer square root would be faster still. For a lot of situations, an integer root would be just fine - for example, if I had to calculate the nearest of two objects on screen, I'm going to have to use pythagoras' theorum to calculate distances. [ A^2 = B^2 + C^2 ] that needs square roots to make a distance. But probably the nearest whole pixel would be a perfectly good enough result!

So, here are two functions, and some code to demonstrate them. One is a perfect replacement for sqr.asm in the library, actually - it's full floating point compatible, 100% accurate, and about 3-6 times faster. It actually uses the FP-Calculator in the rom. It just doesn't use the SQR command. [Note: It comes back with something instead of an error in case of a negative square root request. Boriel - you might want to change that behavor. Not sure.] The integer version... well - look for yourself! I reckon it's about 40 times faster than the fast version.

Also: Should be able to do a something similar for a 32 bit LONG integer.

Copy and compile this program. I hope you like it:

Code:
FUNCTION FASTCALL SQRT (radicand as FLOAT) as FLOAT
ASM
; FLOATS arrive in A ED CB
;A is the exponent.
          
          AND   A               ; Test for zero argument
          RET   Z               ; Return with zero.
          
          ;Strictly we should test the number for being negative and quit if it is.
          ;But let's assume we like imaginary numbers, hmm?
          ; If you'd rather break it change to a jump to an error below.
          ;BIT   7,(HL)          ; Test the bit.
          ;JR    NZ,REPORT       ; back to REPORT_A
                                ; 'Invalid argument'
          RES 7,E               ; Now it's a positive number, no matter what.
          
          call __FPSTACK_PUSH   ; Okay, We put it on the calc stack. Stack contains ABS(x)
                    
          ;   Halve the exponent to achieve a good guess.(accurate with .25 16 64 etc.)

                                ; Remember, A is the exponent.
          XOR   $80             ; toggle sign of exponent
          SRA   A               ; shift right, bit 7 unchanged.
          INC   A               ;
          JR    Z,ASIS          ; forward with say .25 -> .5
          JP    P,ASIS          ; leave increment if value > .5
          DEC   A               ; restore to shift only.
ASIS:     XOR   $80             ; restore sign.
          
          call __FPSTACK_PUSH   ; Okay, NOW we put the guess on the stack
          rst  28h    ; ROM CALC    ;;guess,x
          DEFB $C3              ;;st-mem-3              x,guess
          DEFB $02              ;;delete                x

SLOOP:    DEFB  $31             ;;duplicate             x,x.
          DEFB  $E3             ;;get-mem-3             x,x,guess
          DEFB  $C4             ;;st-mem-4              x,x,guess
          DEFB  $05             ;;div                   x,x/guess.
          DEFB  $E3             ;;get-mem-3             x,x/guess,guess          
          DEFB  $0F             ;;addition              x,x/guess+guess          
          DEFB  $A2             ;;stk-half              x,x/guess+guess,.5
          DEFB  $04             ;;multiply              x,(x/guess+guess)*.5
          DEFB  $C3             ;;st-mem-3              x,newguess
          DEFB  $E4             ;;get-mem-4             x,newguess,oldguess
          DEFB  $03             ;;subtract              x,newguess-oldguess
          DEFB  $2A             ;;abs                   x,difference.
          DEFB  $37             ;;greater-0             x,(0/1).
          DEFB  $00             ;;jump-true             x.

          DEFB  SLOOP - $       ;;to sloop              x.

          DEFB  $02             ;;delete                .
          DEFB  $E3             ;;get-mem-3             retrieve final guess.
          DEFB  $38             ;;end-calc              sqr x.

          jp __FPSTACK_POP
          
END ASM
END FUNCTION


FUNCTION FASTCALL SQRT16(radicand as uInteger) as uByte
asm
    XOR A
    AND A
    
    ld  a,l
    ld  l,h
    ld    de,0040h    ; 40h appends "01" to D
    ld    h,d

    ld b,7
sqrt16loop:
    sbc    hl,de        ; IF speed is critical, and you don't mind spending the extra bytes, you could unroll this loop 7 times instead of DJNZ.
    jr    nc,$+3    
    add    hl,de        
    ccf            
    rl    d        
    rla            
    adc    hl,hl        
    rla            
    adc    hl,hl        
    DJNZ sqrt16loop
    
    sbc    hl,de        ; optimised last iteration
    ccf
    rl    d

    ld a,d
end asm
END FUNCTION


FUNCTION t AS ULONG
   RETURN INT((65536 * PEEK (23674) + 256 * PEEK(23673) + PEEK (23672)))
END FUNCTION

CLS

DIM a,b as float
DIM i as uInteger
DIM time as long

PRINT "ROM","FAST"

REM show it's as accurate
for i=1 to 15
    LET a=rnd * 32768
    PRINT SQR(a),SQRT(a)
next i

PRINT
PRINT "Over 500 Cycles:"
PRINT

REM ROM version 500 times.
LET time=t()
for i=1 to 500
    b=SQR(a)
next i
PRINT "Rom routine: ";t()-time;" Frames."

REM MY version 500 times.
LET time=t()
for i=1 to 500
    b=SQRT(a)
next i
PRINT "Fast routine: ";t()-time;" Frames."

PRINT
PRINT "PRESS A KEY"

PAUSE 1: PAUSE 0

CLS

PRINT "NUM   FAST      INTEGER"

REM show it's as accurate
for i=1 to 15
    LET a=INT(rnd * 32768)
    PRINT a;TAB 6;SQRT(a);TAB 16;SQRT16(a)
next i

PRINT
PRINT "Over 500 Cycles:"
PRINT

REM MY version 500 times.
LET time=t()
for i=1 to 500
    b=SQRT(a)
next i
PRINT "Fast routine: ";t()-time;" Frames."

REM MY Integer version 500 times.
LET time=t()
for i=1 to 500
    b=SQRT16(a)
next i
PRINT "Integer routine: ";t()-time;" Frames."

Print this item

  How to make your code faster
Posted by: britlion - 02-11-2010, 12:20 AM - Forum: How-To & Tutorials - Replies (5)

One of the reasons you are probably looking at this is that you have some idea how to program in Sinclair Basic, and no idea how to code in machine code (or z80 assembler as it's sometimes called). You want to go play with the old spectrum stuff, and want faster programs - and it must be easier these days, right?

Well, with Boriel's compiler, it is. Most programs can be put into the compiler in a form almost identical to an original sinclair basic program, and it will work. It will be faster. But you want to make it as fast as you can, right?

First thing then: variable types. (see http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Types for details on what variable types the compiler supports.)

Nothing you can do to your program will make as big a speed increase as making sure you use the smallest variable type possible in every case. A byte is better than an integer is better than a long and all those are better than using floating point numbers if you can avoid them.

Have a look at this program:

Code:
FUNCTION t AS ULONG
    RETURN INT((65536 * PEEK (23674) + 256 * PEEK(23673) + PEEK (23672)))
END FUNCTION

DIM i,j,k,fake as <insert type here>
DIM time as uLong
let fake=0

CLS

PRINT "Loop Start"
LET TIME=t()
for k=1 to 20    
    for j=1 to 125
        for i = 1 to 125
        LET fake=fake+1-(fake/2)
        next i
    next j
next k

PRINT "loop End"

print t()-TIME

If we set the type of variable for i,j,k,fake as FLOAT up there at the top, this program will disappear for ages before it reports that it took 119,551 frames to come back. That's almost 40 minutes! If you change the type of variable there to UBYTE it comes back in 839 frames. That's under 17 seconds. To put it another way, the code runs over 142 times faster. Variable types make a BIG difference!

NOTE: The nearest Sinclair BASIC equivalent of this program runs in 235,726 frames, or just over 78 minutes to do the same thing. Even using the same variable types as Sinclair BASIC (Which always uses five byte FLOAT types), a compiled program is quite a lot faster!

For the above program, here are the times, in frames (a frame is 1/50th of a second. Divide by 50 to get a time in seconds if you want - I left it this way to make a speed comparison)

Code:
uByte =     839
Byte  =     861
uinteger=  1126
integer =  1178
uLong =   31792
Long  =   32895
Fixed =   36711
Float =  119551

The rule is use the smaller one every time you can, especially in loops! If you're only going round a for/next loop about 10 times, use uByte.

If you can get away with positive numbers, unsigned types (uByte, uIntger and uLong) are a little bit faster than signed ones.

You may also be able to eliminate floating point numbers by multiplying up - for example store $3.02 as 302 pennies.

[Note: In computing terms generally (not just on the spectrum) there are good reasons not to store money in floating point numbers anyway - floating point numbers are NOT perfectly accurate and you may get rounding errors that could cause problems later on. Just as in decimal you can't write 1/3 without an infinitely long 0.33333333->forever happening, you can't store something like 0.1 in binary without an infinitely long binary number. So, far better to store currency as the smaller unit in an integer or long type. A long would allow you to keep track of up to +/- 2,147,483,647 pennies - or about 21 million currency units. If you want to track more than that you can definitely afford a more powerful computer than a Spectrum!]

Print this item

  Forum problems fixed / Problema resueltos en el foro
Posted by: boriel - 02-09-2010, 08:01 PM - Forum: ZX Basic Compiler - Replies (11)

There has been several forum technical problems regarding to cache and template issues. All of them seems to be fixed now.
Please read here for more info: <!-- l --><a class="postlink-local" href="http://www.boriel.com/forum/viewtopic.php?f=9&t=375">viewtopic.php?f=9&t=375</a><!-- l -->

Sorry again, and thanks to Britlion for notifying me. 8)

Print this item

  Forum problems fixed / Problema resueltos en el foro
Posted by: boriel - 02-09-2010, 07:57 PM - Forum: News - No Replies

=== English ===

There has been several problems regarding to this site styles and template caches, all of them has been fixed now:

  • New users could not register, because Captcha code was failing! Sad (Fixed)
  • Private mensajes and Forum email notifications were not working so I was not aware about new users questions! Sorry. Thes has been fixed!
  • Template glitches and misbehaviour (Fixed)
I hope everything works as expected now. If you notice any problem, please send mi a private message.

Remember: If you don't like the current theme (Dark, Spectrum-retro like style), you can switch to the previous theme (cyan/lighter backgruound) in your preferences account panel.


=== Español ===

Ha habido varios problemas en el foro relativos a los temas y estilos utilizados, así como las cachés de las plantillas. Todos ellos resueltos ya:
  • No se podían dar de alta nuevos usuarios, porque el código visual de Captcha estaba fallando! Sad (Arreglado)
  • Los mensajes privados y las notificaciones por email no estaban funcionando, así que no me estaba enterando de los nuevos mensajes de los usuarios. Lo siento. Eso está arreglado!
  • Diversos fallos en la plantilla así como comportamientos erráticos. (Arreglado)
Espero que ahora todo vaya bien. Si notas algún problema, envíame un privado por este foro.

Recuerda: Este sitio usa un tema oscuro (al estilo Spectrum/Retro), pero si no te gusta, lo puedes cambiar por uno más claro (fondo azul celeste, etc..) en tu panel de preferencias de tu cuenta de usuario.

Print this item

  Summary of stuff not working [V1.2.4]
Posted by: britlion - 02-06-2010, 12:05 PM - Forum: Bug Reports - Replies (24)

Okay, I've made several posts and it's all getting confusing. Here's what seems to be wrong:

  • * [Tested Fixed in 1.25 Beta r1489]@variablename - Seems to point at one byte BELOW the correct one.

    * [Can't replicate cleanly. Needs proved example of error.] [This was probably caused by the stack erorr which is fixed in r1489 ] CHR / CHR$ - CHR$(variable) seems to crash sometimes. CHR$(number) works fine.

    * [Tested Fixed in 1.25 Beta r1489] BOLD and ITALIC cannot be used as temporary attributes (BOLD 1 works. PRINT BOLD 1;"Hello" does not.) The compiler issues some very cryptic error messages about this.

    * -O2 and -O3 are likely to fail to compile what -O1 and no optimization compiles perfectly. (Seems to fail in 'update_goes_and_comes' in optimizer.pyc on larger files)

    * [Tested Fixed in 1.25 Beta r1489]SHL and SHR don't work for Integers (reported by LCD)

    *[Tested Fixed in 1.25 Beta 1] Comparisons : the Boolean logic for >= for type FIXED is bugged. (it always returns true)

    *[Tested Fixed in 1.25 Beta 1] uByte seem to have something wrong on the comparison front as well:
    Code:
    DIM ub as uByte
    DIM b as byte
    DIM ui as uInteger
    DIM i as integer
    DIM ul as uLong
    DIM l as LONG
    DIM fi as fixed
    DIM fl as float

    print ub,b,ui,i,ul,l,fi,fl

    if 0<=20 then print "0<=20" : END IF
    if ub <= 20 then print "ub <= 20" : END IF
    if b <= 20 then print "b <= 20"   : END IF
    if ui <= 20 then print "ui <= 20" : END IF
    if i <= 20 then print "i <= 20"   : END IF
    if ul <= 20 then print "ul <= 20" : END IF
    if l <= 20 then print "l <= 20"   : END IF
    if fi <= 20 then print "fi <= 20" : END IF
    if fl <= 20 then print "fl <= 20" : END IF

    NOT strictly speaking broken, but serious "Quality of life" issues:

    * The compiler's errors could be a lot more helpful!
    1> Instead of "unexpected end of file" how about "You started a FOR loop on line 30 that never finished" and "You have an IF on line 100 that doesn't have an END IF" - if the compiler could say what statement or parenthesis isn't closed that would help me track down about 90% of my bugs. As it is, I type a line, compile, type a line, compile and so on - otherwise I'd never find the problem! [I'm REALLY bad at forgetting END IF]

    2> Could we get a warning any time a variable is used that hasn't been DIM first? Or just plain not allow it, even? A mistyped variable (vectory instead of vectorY) is very hard to find if the compiler simply creates it without telling me. So the program compiles and runs, but the math isn't working right...

    * The assembler seems to be very slow - zxb --asm program.bas returns to the command prompt within a few seconds. If we ask the assembler to assemble the file as well, it can stay away for several minutes.

Print this item