Page 4 of 4
Re: A test program?
Posted: Fri Jun 29, 2018 12:21 am
by dclxvi
The atan2 calculation in line 50 uses X<0, but the sign of TRUE turns out not to matter in that case because the comparison in line 60 is mod pi.
The argument for TRUE = 1 is that it's slightly easier to pack into (and unpack from) a bitfield or an array of bits. The argument for -1 is that it's more useful with bitwise operators (including XOR). I'm more of a fan of -1 myself, but both arguments are reasonable. (Apple I BASIC and Apple "Integer" BASIC also use 1.)
Also, it might be useful to have at least (tested versions of) some of these examples in source code repository and/or possibly a link to this thread. Adding a link to the EhBASIC link in on the homebuilt projects page might also be helpful.
Re: A test program?
Posted: Fri Jun 29, 2018 1:34 am
by BillO
Re: A test program?
Posted: Fri Jun 29, 2018 6:33 am
by BigEd
The argument for TRUE = 1 is that it's slightly easier to pack into (and unpack from) a bitfield or an array of bits. The argument for -1 is that it's more useful with bitwise operators (including XOR).
I always liked the approach taken in BBC Basic. The Boolean value of an expression is the same as testing for non-zero. That is, zero is false and non-zero is true. The builtin FALSE has the value zero, and the builtin TRUE has the value -1. As a consequence of all that, the boolean and bitwise operators are the same things and act in the expected way. It's even the case that NOT TRUE is equal to FALSE and NOT FALSE is equal to TRUE.
Re: A test program?
Posted: Fri Jun 29, 2018 3:26 pm
by Klaus2m5
I always liked the approach taken in BBC Basic. The Boolean value of an expression is the same as testing for non-zero. That is, zero is false and non-zero is true.
I am not aware of any Basic that does not support this. You can replace
Code: Select all
X = 5 : REM any value other than 0
IF X <> 0 THEN
by
Code: Select all
X = 5 : REM any value other than 0
IF X THEN
Re: A test program?
Posted: Sat Jun 30, 2018 7:13 pm
by GaBuZoMeu
3. 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9
You can improve the formatting of this by changing "PRINT Q;" to "PRINT ;Q;".
EhBasic seems to be different on that. "PRINT ;Q;" wouldn't work:
Code: Select all
190 ?;Q;
RUN
3. 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9
Ready
190 ?CHR$(Q+48);
RUN
3.141592653589793238462643383279
Ready
The hard way does

Re: A test program?
Posted: Sun Jul 01, 2018 12:33 pm
by Klaus2m5
The string compare is at LAB_1CAE. At LAB_1CE6 the strings are actually compared if they have the same length. FAC1_1 and FAC2_2 is used to hold the indirect pointer to the strings being compared. FAC2_2 was pointing to an invalid location in direct mode. Earlier in the code the string descriptor is pulled
Code: Select all
LDA FAC2_2 ; get descriptor pointer low byte
LDY FAC2_3 ; get descriptor pointer high byte
JSR LAB_22BA ; pop (YA) descriptor off stack or from top of string space
; returns with A = length, X=pointer low byte,
; Y=pointer high byte
STX FAC2_2 ; save string pointer low byte
STY FAC2_3 ; save string pointer high byte
In memory the pointer to the string descriptor is off by +$100. So I went back to LAB_EVEX to see where FAC2_2 is loaded. After some more single stepping I found it is pushed onto the stack from FAC1 and then restored to FAC2. When it is pushed to the stack via LAB_1B5B FAC1 is rounded which causes the high address to be incremented by 1 if FAC1_r is > $7f. FAC1_r is not cleared when FAC1 actually contains a memory pointer. Actually it is never cleared and so I am not so sure wether it could also go wrong in run mode.
Code: Select all
; push sign, round FAC1 and put on stack
LAB_1B5B
PLA ; get return addr low byte
STA ut1_pl ; save it
INC ut1_pl ; increment it (was ret-1 pushed? yes!)
; note! no check is made on the high byte! if the calling
; routine assembles to a page edge then this all goes
; horribly wrong !!!
PLA ; get return addr high byte
STA ut1_ph ; save it
LDA FAC1_s ; get FAC1 sign (b7)
PHA ; push sign
; round FAC1 and put on stack
LAB_1B66
JSR LAB_27BA ; round FAC1
LDA FAC1_3 ; get FAC1 mantissa3
PHA ; push on stack
LDA FAC1_2 ; get FAC1 mantissa2
PHA ; push on stack
LDA FAC1_1 ; get FAC1 mantissa1
PHA ; push on stack
LDA FAC1_e ; get FAC1 exponent
PHA ; push on stack
JMP (ut1_pl) ; return, sort of
Either FAC1_r must be cleared when FAC1 is used as a memory pointer or LAB_27BA should check wether the data type is string or number (without breaking something else of course).
edit: Sorry, I have posted this in the wrong thread. I will repost to the correct one.
Re: A test program?
Posted: Sun Jul 01, 2018 4:18 pm
by JenniferDigital
I wasn't expecting the FAC1 (which I thought to be a floating point accumulator) to be used as a pointer.
Re: A test program?
Posted: Sun Jul 01, 2018 5:33 pm
by barrym95838
I wasn't expecting the FAC1 (which I thought to be a floating point accumulator) to be used as a pointer.
Agreed. If there's a point to that apparent level of complexity, it whizzed past my head.
Mike B.
Re: A test program?
Posted: Sun Mar 08, 2026 8:08 am
by soci
Quick hack I did yesterday for testing. The original was for CBM PET and was adapted to use VT100 control sequences. Might be too fast on some systems with high baud rates. But is usable on my setup (~1.7Mhz and 38400N1).
Code: Select all
0 REM BASED ON ORIGINAL PETRIS (C)2002 CURTIS F KAYLOR
10 E$=CHR$(27)+"[":R$=E$+"C":U$=E$+"A":L$=E$+"D":W$=E$+"B":I$=E$+"7m":J$=E$+"27m"
20 DIMT$(15),B(6,3,3),P(23),I(2):I$(0)=R$:I$(1)="":I$(2)=L$
21 T$(0)=E$+"4C":T$(1)=E$+"3C ":T$(2)=E$+"2C "+R$:T$(3)=E$+"2C "
22 T$(4)=R$+" "+E$+"2C":T$(5)=R$+" "+R$+" ":T$(6)=R$+" "+R$:T$(7)=R$+" "
23 T$(8)=" "+E$+"3C":T$(9)=" "+E$+"2C ":T$(10)=" "+R$+" "+R$:T$(11)=" "+R$+" "
24 T$(12)=" "+E$+"2C":T$(13)=" "+R$+" ":T$(14)=" "+R$:T$(15)=" "
30 S=0:M=0:Z=0
40 B$="DDDD@O@@DDDD@O@@@FDD@GA@@AAC@DG@@FBB@AG@@DDF@GD@@BFB@BG@@BCB@GB@@ACB@FC@"
50 B$=B$+"@ACB@FC@@DFB@CF@@DFB@CF@@FF@@FF@@FF@@FF@":FORI=0TO6:FORJ=0TO3:FORK=0TO3
60 Z=Z+1:B(I,J,K)=ASC(MID$(B$,Z))AND15:NEXT:NEXT:NEXT:FORI=0TO19:P(I)=4097:NEXT
61 P(I)=8191:PRINTE$"H"E$"2J";
70 PRINTE$"H":FORI=0TO20:P=8191-P(I)
71 PRINTT$(P/4096)T$(P/256AND15)T$(P/16AND15)T$(PAND15)
72 P=8191-P:PRINTU$I$T$(P/4096)T$(P/256AND15)T$(P/16AND15)T$(PAND15)J$:NEXT
80 PRINTU$E$"4C"I$"PETRIS"S;
90 X=32:Y=0:B=7*RND(0):C=0:D=2:PRINTE$"H"E$"7C"W$;:R=1
100 IFRTHEND$="":FORI=0TO3:D$=D$+T$(B(B,C,I))+W$+E$+"4D":NEXT:D$=D$+E$+"4A"
110 PRINTI$(M+1)I$D$J$;
115 GETK$:M=(K$="2")-(K$="1"):R=K$=" ":V=M+R=0:IFK$<>""ANDVTHENGOTO115
120 IFMTHENX=X*(2.5+M*1.5)/2:GOSUB160:IFZTHENX=X*(2.5-M*1.5)/2:GOTO115
130 IFRTHENC=C-RAND3:GOSUB160:IFZTHENC=C+RAND3:GOTO115
140 IFVTHENY=Y+1:GOSUB160:IFZTHENY=Y-1:ONSGN(Y)GOTO170:END
150 PRINTD$LEFT$(W$,-V*3);:GOTO100
160 Z=0:FORI=0TO3:Z=ZOR(P(Y+I)ANDB(B,C,I)*X):NEXT:RETURN
170 A=0:FORI=0TO3:P(Y+I)=P(Y+I)ORB(B,C,I)*X:IFP(Y+I)=8191ANDY+I<20THENGOSUB190
180 NEXT:ONDGOTO70,90
190 FORZ=Y+ITO1STEP-1:P(Z)=P(Z-1):NEXT:P(0)=4097:D=1:A=A+10:S=S+A:RETURN