Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
not sure what it is bug/feature/me
#1
First something easy I spotted in DRAW.ASM, there are two EQU's that point to the same address
Code:
LOCAL __PIXEL_ADDR
__PIXEL_ADDR EQU 22ACh
    call __PIXEL_ADDR

and
    
PIXEL_ADDR    EQU 22ACh


one of those two can be removed.

The program I work on I typed in long ago (needless to say it contains typo's in the data) you can find a copy in WOS it's called PIANOLA.
http://www.worldofspectrum.org/infoseeki...id=0008549


In trying to speed up this program i ran into some problems. The program plays music by machine code, the information is transferred by means of reading data into a string. Compiling the hole program is not my intention,
but some drawing and printing to the screen can surly be sped up by compiling that part.

There is a difference in ZX Basic and the Compiler in handling float's in the PLOT and DRAW statements.
It draws 2 figure's with the help of following code
Code:
2030 FOR i=8 TO 215 STEP 207
         LET p=30
         LET q=0
         LET c=COS (14*PI/p)
         LET s=SIN (14*PI/p)
         PLOT i,132
         FOR b=1 TO 30
           DRAW INK 1;p,q
           LET p=p*c-s*q
           LET q=(p*s+q)/c
         NEXT b
       NEXT i

    I converted it into
    
       dim p,q,c,s as float ' need to use float, fixed screws up totally
       dim b as byte
       dim i as integer

  2030 FOR i=8 TO 215 STEP 207
         LET p=30
         LET q=0
         LET c=COS(14*PI/p)
         LET s=SIN(14*PI/p)
         PLOT i,132+16     ' +16 to get the same position
         FOR b=1 TO 30
           DRAW INK 1;p,q
           LET p=(p*c)-(s*q)
           LET q=(p*s+q)/c
         NEXT b
       NEXT i
Both give a different figure. It took me some days before I figured out that the calculations in the compiled version where correct, converting the float into a integer screwed things up.

1. first add .5 (round off the number)
2. INT must work like in ZX Basic (3.9 gives 3, -3.9 must give -4)
Code:
       dim p,q,c,s as float
       dim b as byte
       dim x,y,i as integer

  2030 FOR i=8 TO 215 STEP 207
         LET p=30
         LET q=0
         LET c=COS(14*PI/p)
         LET s=SIN(14*PI/p)
         PLOT i,132+16     ' +16 to get the same position
         FOR b=1 TO 30
           LET x = INT(p+.5-(p<0)) ' must use strict-bool, works correct in this case because there is never a number+.5 that equals a integer
           LET y = INT(q+.5-(q<0))
           DRAW INK 1;x,y
           LET p=(p*c)-(s*q)
           LET q=(p*s+q)/c
         NEXT b
       NEXT i

This code will give the same figure as ZX Basic.
I think a closer look into how ZX Basic works using float's in PLOT and DRAW and how the are converted to integers is needed

Now my code compiled without error and it's output looked like the normal basic version. The final piece of code.
Code:
dim p,q,c,s as float
dim melo,b as byte
dim x,y,i,t as integer
const p1 as byte = 8

border 5
paper 6
2020 CLS
melo = peek (byte,50900) 'if haven't worked out a better place for this yet
PRINT AT 2,7; BRIGHT 1;"WE PROUDLY PRESENT"
PLOT 55,151+16
DRAW 145,0
DRAW 0,9
DRAW -145,0
DRAW 0,-9
DRAW 2,-2
DRAW 145,0
DRAW 0,9
DRAW -2,2
2025 FOR i=7 TO 18
PRINT PAPER 0;AT i,0;"      ";AT i,26;"      "
NEXT i
PRINT PAPER 0;AT 19,0,,,,,,
2030 FOR i=8 TO 216 STEP 208
LET p=30
LET q=0
LET c=COS(14*PI/p)
LET s=SIN(14*PI/p)
PLOT i,132+16+1
FOR b=1 TO 30

let x = int(p+.5-(p<0))
let y = int(q+.5-(q<0))

DRAW INK 1;x,y
LET p=(p*c)-(s*q)
LET q=(p*s+q)/c
NEXT b
NEXT i
2040 rem LET p=8 'rename p to p1 and made it a constant
PRINT OVER 1;AT 18,6;"\..\..\..";AT 18,23;"\..\..\.."; INK 2;AT 6,0;"\..\..\..\..\..\..";AT 6,26;"\..\..\..\..\..\..";AT 15,0;"\::\::\::\::\::\::";AT 15,26;"\::\::\::\::\::\::";AT 18,9;"\..\..\..\..\..\..\..\..\..\..\..\..\..\.."
2045 FOR i=1 TO 5
let h$="    "
let f$="    "
if i=3 then let h$="BACH" : let f$="BEAT" : end If
if i=5 then let h$="  " : let f$="  " : end if
PRINT OVER 1; BRIGHT 1; INK p1; PAPER 4;AT i,1+(i=5);h$;AT i,27+(i=5);f$
next i
2050 PLOT 204,28+16
DRAW 0,104
PLOT 207,28+16
DRAW 0,104
DRAW -80,0,.3
DRAW -79,0,.3
DRAW 0,-104
PLOT 51,28+16
DRAW 0,104
PLOT INK p1;127,28+16
DRAW INK p1;0,104
2055 FOR i=9 TO 15 STEP 2
PRINT AT i,p1;"\e\g  \h\g";AT i+1,p1;"\f \g\h \h";AT i,18;"\e \h\h \h";AT i+1,18;"\f\g  \g \h"
NEXT i
2060 FOR i=61 TO 141 STEP 80
FOR b=98 TO 50 STEP -16
FOR t=0 TO -p1 STEP -2
PLOT i,b+t+16
DRAW 58,0
NEXT t
DRAW 0,p1
PLOT i,b-p1+16
DRAW 0,p1
NEXT b
NEXT i
2070 PRINT AT 17,9;"= ";melo-1;" =";AT 17,18;"= ";melo-1;" =";AT 20,10; BRIGHT 1; INK 7; PAPER 1;"SPECTRUM&SONS"
2080 PRINT AT 22,0;paper 5;bright 1;"\d \d\d \d\d\d \d\d \d\d\d \d\d \d\d\d \d\d \d\d\d \d\d"; ink 7 ;"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";


The compiled piece of code worked but it corrupted something so the running of the normal basic part was not what it should be.
First I load the program, RUN, the program loads the two piece of machine code and runs normal until it returns from the first time it used the compiled code, it then needs to print the title of the music piece on the screen, but here go things wrong, instead it prints what looks likes a piece of listing from the basic program, it seems that some where something is corrupted.
But now comes the weird part, if I BREAK the program and let it RUN without loading the two pieces of machine code, it works as it should with out a problem. :?:

I have tried out something, and found at last the line that causes the problem.

If I REM this line out

PRINT OVER 1; BRIGHT 1; INK p1; PAPER 4;AT i,1+(i=5);h$;AT i,27+(i=5);f$

there is no problem, or replacing f$ and h$ with " " will also work.

The problem seems to be with f$ and h$ or I am doing something wrong. (I rewrite the code, now I know what will work)

Sorry for the somewhat long posting.

Regards
Frisian.
Reply
#2
Your code runs OK in my emulator. I don't see any corruption.

If you are adding extra machine code during runtime (por POKES or UDG), you might be corrupting the heap (used mainly for string -alphanumeric- variables). To use UDG use --spectrum, or better ask here the other (best) way to do it.

If you need to load machine code at any location, there are other methods, like using a malloc for reserving such space, or using asm directives with DEFB.
Can you upload a screenshot of the corruption?
Reply
#3
frisian Wrote:Both give a different figure. It took me some days before I figured out that the calculations in the compiled version where correct, converting the float into a integer screwed things up.

1. first add .5 (round off the number)
2. INT must work like in ZX Basic (3.9 gives 3, -3.9 must give -4)
Frisian.
This bug is marked for correction. INT will behave as Sinclair BASIC, since CAST(Integer, <float value>) will also perform the truncation. So we'll have both choices. Better comment this issue in the bug thread (your first post).
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)