Jestli tim trikem myslis nepouzivat skok a umistit rutina za sebe tak jsem to zkousel jeste krome komentare ze ty rutiny jsou "slepene" :
; fall to print_hex_digit
osetrit pres nejaky
if ($ != print_hex_digit)
.error Blabla
endif
ale to pasmo nezvladne protoze print_hex_digit pry jeste nezna i kdyz lezi pod tim a nekdy se sam prepne do vic pruchodu.
Tak jsem se to snazil obejit pres
omg equ print_hex_digit
if ($ != omg)
.error Blabla
endif
ale to selze stejne uz u omg. Mozna to jde jinym trikem, ale nevim jak.
PS: Tu bfloat, danagy a binary16 floating-point knihovnu jsem psal. Na FB existovala (mozna jeste existuje) skupina lidi z celeho sveta stale programujici pro ZX. A krome ruznych soutezi tam ukazoval Daniel Nagy i Ray tracing pro ZX. Chtel jsem jen vedet zda to nebude lepsi kdyz pouziji jiny format, ale stale 16 bitovy. On zvolil 8 bitu mantisu ja testoval jak 9 bitu tak 7 bitu. Drzel jsem se jeho navrhu "api" a drzel vstupy a vystupy ce stejnych registrech. Delal jsem to zamerene na rychlost, ale snazil se zaroven, aby pokud to jde po operaci byly vzdy vsechny bity mantisy i ten nejnizsi spravne zaokrouhlene. Co on nemel, takze jsem nakonec prepsal i jeho kod. Pak jsem to zpomalil uz jen tim, ze jsem vracel pri preteceni nebo podteceni priznaky.
Psal jsem to cely rok, nez se mi podarilo konecne vygenerovat ten obrazek. Byla tam spousta triku jak to delat pres male tabulky. Zjistil jsem ze napriklad nasobeni je snazsi nez scitani a odcitaniu FP. Deleni je problem, ale jde to pres 1/mantisa tabulku s tim, ze nekdy nejnizsi bit neni dobre. LN je silenost. Delat to nejakym vzorcem pomoci uz vytvorenych operaci jen ztracis bity a bude to pomale. Takze pouzit tabulku s mezivysledky a nejaka interpolace? Je tam i zavislost na exponentu. U nekterych vstupnich hodnot bylo nakonec vic bitu spatne na vystupu.
Z toho githubu se da spoustu veci odvodit, ale neni tam vsechno. Treba nektere tabulky jsem vytvarel pomoci spatlaneho programu v C co me to pocital iteracne (nahodne jsem drobne menil hodnoty tabulky a opravoval zbytek pro nejmensi chyby, mel vic variant a pak nejlepsi ponechal a opakoval) a snazil se mit pro vsechny vstupy minimalni chybu nebo zadnou na vystupu. Aby probehlo vsude spravne zaokrouhleni. Zkousel jsem ruzne verze tabulek. Pocital to kolikrat hodiny co byl v praci na modernim CPU. Proste neco co by pred 40 lety neslo udelat.
Ale uz jsou to 3 roky, moc si toho nepamatuji. Jen ze danagyho format to vyhral. binary16 melo vubec problem to vykreslit, tam uz temer nevyslo pro rozsah exponentu. A byl pomaly a i kdyz nejpresnejsi rozbrazeni stale mel chyby oproti bezchybne basic verzi. Bfloat nepresny a stejne rychly jak Danagy. Ale mensi tabulky, kdyz je mensi mantisa.
1 BORDER 0: PAPER 0: INK 9: BRIGHT 1: CLS: POKE 23672,0: POKE 23673,0: POKE 23674,0 10 LET spheres=2: IF spheres THEN DIM c(spheres,3): DIM r(spheres): DIM q(spheres) 20 FOR k=1 TO spheres: READ c(k,1),c(k,2),c(k,3),r: LET r(k)=r: LET q(k)=r*r: NEXT k 30 DATA -0.3,-0.8,3,0.6 40 DATA 0.9,-1.1,2,0.2 50 FOR i=0 TO 175: FOR j=0 TO 255 60 LET x=0.3: LET y=-0.5: LET z=0 70 LET dx=j-128: LET dy=88-i: LET dz=300: LET dd=dx*dx+dy*dy+dz*dz 80 GO SUB 100: NEXT j: NEXT i 90 PAUSE 1: LET s=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET s=s/50: LET m=INT (INT s/60): LET h=INT (m/60): PRINT "Time: ";h;"h ";m-60*h;"min ";INT((s-60*m)*100)/100;"s ";PAUSE 0:STOP 100 LET n=-(y>=0 OR dy<=0): IF NOT n THEN LET s=-y/dy 110 FOR k=1 TO spheres 120 LET px=c(k,1)-x: LET py=c(k,2)-y: LET pz=c(k,3)-z 130 LET pp=px*px+py*py+pz*pz 140 LET sc=px*dx+py*dy+pz*dz 150 IF sc<=0 THEN GO TO 200 160 LET bb=sc*sc/dd 170 LET aa=q(k)-pp+bb 180 IF aa<=0 THEN GO TO 200 190 LET sc=(SQR bb-SQR aa)/SQR dd: IF sc<s OR n<0 THEN LET n=k: LET s=sc 200 NEXT k 210 IF n<0 THEN RETURN 220 LET dx=dx*s: LET dy=dy*s: LET dz=dz*s: LET dd=dd*s*s 230 LET x=x+dx: LET y=y+dy: LET z=z+dz 240 IF n=0 THEN GO TO 300 250 LET nx=x-c(n,1): LET ny=y-c(n,2): LET nz=z-c(n,3) 260 LET nn=nx*nx+ny*ny+nz*nz 270 LET l=2*(dx*nx+dy*ny+dz*nz)/nn 280 LET dx=dx-nx*l: LET dy=dy-ny*l: LET dz=dz-nz*l 290 GO TO 100 300 FOR k=1 TO spheres 310 LET u=c(k,1)-x: LET v=c(k,3)-z: IF u*u+v*v<=q(k) THEN RETURN 320 NEXT k 330 IF (x-INT x>.5)<>(z-INT z>.5) THEN PLOT j,i 340 RETURN
Ta trva vic jak 8 hodin a 46 minut.