Page 8 of 10
Re: <2kbyte 6502 Tiny Basic?
Posted: Mon Oct 23, 2023 9:34 am
by Chromatix
It might, if I need it - but there are more important things to deal with first.
Re: <2kbyte 6502 Tiny Basic?
Posted: Mon Oct 23, 2023 11:33 am
by drogon
One thing I have considered (still am, somewhat) is an optional "library" of code with the intention of it being called by poking input values into a fixed location, calling the routine then peeking the result - rather than extend the interpreter (which is costly in terms of time in TinyBasic) so e.g.
Code: Select all
10 !&500 = A : !&502=B : !&504 = C : CALL &9000 : M = !&500 : REM MulDiv:- M=A*B/C
Same for maybe some scaled trig, etc. Feels a bit cheaty, but stranger things have been done in the past...
-Gordon
Re: <2kbyte 6502 Tiny Basic?
Posted: Mon Oct 23, 2023 1:41 pm
by Chromatix
Good news: while implementing an absolutely minimalist PRINT statement and working through the resultantly exposed bugs, the code actually got slightly smaller. Most of this was from finding some code I'd prepared for implementing PRINT later, which performed a conditional negate without using the more recent DoNegate subroutine. Cutting out the duplicate code and using the subroutine as intended saved more space than adding the partial PRINT statement used up.
The interpreter is now able to run simple programs involving variables, expressions, comparisons, and printing out single integers. Not everything has been thoroughly tested yet, but I did check most of the basic functionality and some important corner cases.
Next step is to complete the feature set of PRINT. My goal here is string literals and more than one integer per statement, divided by semicolons (no space) or commas (one space), with a final semicolon or comma suppressing the newline. How much change will I have from the present 56-byte margin? (NB: this is not a hard limit, as I can go to 3.5KB of code before running into the configured I/O area, but I'll be looking to cut excess beyond 2KB for the sake of bragging rights.)
Re: <2kbyte 6502 Tiny Basic?
Posted: Mon Oct 23, 2023 3:47 pm
by barrym95838
I don't think that you explicitly stated it, but I saw something a few pages back hinting that you were using the Kowalski simulator for your development. Its I/O is rather simplified and flexible, but it also has some annoying quirks with linefeeds if you want to copy and paste BASIC source into it. Klaus2m5 figured it out for me, but you may already know all of this.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 4:45 am
by Chromatix
I did notice it went weird when I pasted a program in, yes. I suspect it's pasting LF characters after each CR, whereas pressing Return just sends CR. If that's what it is, I can work around it without too much difficulty.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 9:22 am
by Chromatix
As you can see here, the FizzBuzz program I wrote earlier is now running. It takes about 2.5 million cycles, which isn't
too bad considering this really isn't a performance-oriented interpreter.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 10:28 am
by drogon
Excellent!
Here it is in my TinyBasic:
With an interesting note... In the old TinyBasic documents I had, the NOT operation was defined as Ones Compliment... So that's what I implemented... And it made my initial version of this fail... Because at (e.g.) X=3 :-
(Y OR Z) returnes
(1 OR 0) which is
1 and
NOT 1 is
-2.
True/False is defined as Non-zero/Zero, so
NOT (1 OR 0) is
NOT 1 which is
-2 which is
TRUE.
Which is correct, but not the expected result...
I changed my implementation of NOT to make 0 -> 1 and anything non-zero return 0 and it worked.
Or did it - which was right? It's an interesting conjecture...
I also fear we're losing the art of translating programs from different dialects - which many of us did back in the 70's/80's when typing into our plethora of little micros, all different at the time...
-Gordon
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 10:35 am
by Chromatix
I adopted the BBC BASIC convention of making "true" results from comparison operators be -1. This means that bitwise operators can also be used for logical operations, including NOT. I don't think it requires significantly more code than producing a 1 result, as for both "false" and "true" a single byte value is replicated to all four result positions.
C doesn't do this - it has separate operators for bitwise and logical operations. So bitwise complement is ~ and logical complement is !.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 10:43 am
by drogon
I adopted the BBC BASIC convention of making "true" results from comparison operators be -1. This means that bitwise operators can also be used for logical operations, including NOT. I don't think it requires significantly more code than producing a 1 result, as for both "false" and "true" a single byte value is replicated to all four result positions.
C doesn't do this - it has separate operators for bitwise and logical operations. So bitwise complement is ~ and logical complement is !.
If only there was a standard... but wait, there is....
https://xkcd.com/927/
-Gordon
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 12:31 pm
by Chromatix
Another program showing off interesting features of the interpreter. Note that the code is not presented in execution order, but when pasted in it will effectively be sorted by line number. This takes approximately 1.2 million cycles to complete, and then executing the program takes several million more.
Code: Select all
5000 PRINT D,"|",(18432*100)/(D*16);
5010 F=(18432*10000/(D*16))-(18432*100/(D*16))*100
5011 GOSUB 4000
5020 PRINT " |",(24576*100)/(D*16);
5030 F=(24576*10000/(D*16))-(24576*100/(D*16))*100
5031 GOSUB 4000
5040 PRINT " |",(18432*200)/(D*16);
5050 F=(18432*20000/(D*16))-(18432*200/(D*16))*100
5051 GOSUB 4000
5060 PRINT
5070 RETURN
4000 IF F PRINT ".";F/10;F-(F/10*10);
4010 RETURN
10 D=1
20 D=2
30 D=3
40 D=4
50 D=6
60 D=8
70 D=12
80 D=16
90 D=24
100 D=32
110 D=48
120 D=64
130 D=96
140 D=128
150 D=192
160 D=256
170 D=384
180 D=512
190 D=576
200 D=768
210 D=856
220 D=1047
230 D=1142
240 D=1396
250 D=1536
260 D=1713
270 D=2048
280 D=2095
290 D=2304
300 D=2534
310 D=3072
320 D=3379
15 GOSUB 5000
25 GOSUB 5000
35 GOSUB 5000
45 GOSUB 5000
55 GOSUB 5000
65 GOSUB 5000
75 GOSUB 5000
85 GOSUB 5000
95 GOSUB 5000
105 GOSUB 5000
115 GOSUB 5000
125 GOSUB 5000
135 GOSUB 5000
145 GOSUB 5000
155 GOSUB 5000
165 GOSUB 5000
175 GOSUB 5000
185 GOSUB 5000
195 GOSUB 5000
205 GOSUB 5000
215 GOSUB 5000
225 GOSUB 5000
235 GOSUB 5000
245 GOSUB 5000
255 GOSUB 5000
265 GOSUB 5000
275 GOSUB 5000
285 GOSUB 5000
295 GOSUB 5000
305 GOSUB 5000
315 GOSUB 5000
325 GOSUB 5000
330 GOTO 65535
The main features thus demonstrated/exercised are the memory management for program code, the use of 32-bit internal arithmetic to support fixed-point, and nested subroutine calls. In a more complete and conventional BASIC interpreter, this would be a natural place to use DATA and READ, which I don't have - nor is there an END or STOP, but a contrived GOTO past the end of the program also works.
The output is a table of the baud rates for my "improved ACIA" proposal:
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 3:51 pm
by Chromatix
And, what I'm sure you've all been waiting for:
Code: Select all
0 S=2048
10 A=S*-21/10
20 B=S*3/2
30 C=S*3/2
40 D=S*-3/2
50 E=200
60 F=(B-A)/128
70 G=(C-D)/48
80 L=C
90 REPEAT
100 K=A
110 REPEAT
120 V=0
130 U=0
150 O=0
160 REPEAT
170 X=U*U/S
180 Y=V*V/S
190 V=U*V/(S/2)+L
200 U=X-Y+K
210 O=O+1
220 UNTIL O >= E OR X+Y > 4*S
230 IF O<E AND O>9 VDU 64
240 IF O<10 VDU O+48
250 IF O=E VDU 32
260 K=K+F
270 UNTIL K >= B
280 PRINT
290 L=L-G
300 UNTIL L < D
I haven't got a timing for this, but it does run and produce reasonable results. I did have to correct a serious oversight in the division routine, related to the handling of negative argumentsā¦
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 5:04 pm
by gfoot
Hooray! There are some overflows though, I think, e.g. the noise in the top and bottom right corners, and between zones 3 and 4. I'd guess U*U/S or V*V/S is overflowing before the division, so you might need to do range checks on U and V as well, perhaps, and decide how to act if they're already above a threshold.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 5:32 pm
by Chromatix
I have a suspicion that those aren't really overflows, but might be due to a subtle bug in the interpreter which would only show up with large-magnitude numbers. The near-threshold iterates in those regions should not be overflowing 32 bits with the scale factor I've selected, but might overflow 24 bits. I'll investigateā¦
EDIT: Well, there's no problem in the intermediate values, but it's more likely that the stored variables are overflowing. With some extra bailout tests on the inner loop, I can successfully hide these, though the shape of the exterior gradient changes.
Re: <2kbyte 6502 Tiny Basic?
Posted: Tue Oct 24, 2023 9:27 pm
by Chromatix
This is much better:
Code: Select all
0 S=4096
5 T=S*4
10 A=S*-21/10
20 B=S*3/2
30 C=S*3/2
40 D=S*-3/2
50 E=200
60 F=(B-A)/128
70 G=(C-D)/48
80 L=C
90 REPEAT
100 K=A
110 REPEAT
120 V=L
130 U=K
150 O=-1
160 REPEAT
170 Z=(U*U-V*V)/S
190 V=U*V/(S/2)+L
200 U=Z+K
210 O=O+1
220 UNTIL O >= E OR U*U+V*V > T*S
230 IF O<E AND O>9 VDU 64
240 IF O<10 VDU O+48
250 IF O=E VDU 32
260 K=K+F
270 UNTIL K >= B
280 PRINT
290 L=L-G
300 UNTIL L < D
Re: <2kbyte 6502 Tiny Basic?
Posted: Sun Jan 21, 2024 7:10 am
by barrym95838
A fellow by the name of Will Stevens has recently implemented a 1012 byte tiny BASIC, with signed 16-bit arithmetic, tokenization, a single numeric array, FOR/NEXT/STEP, ABS(), USR() and RND(). The only trouble (at least for me) is that it's
for the 8080, and I quickly developed a headache trying to grok his assembly code. All of those LXI, SHLD, DCX, RST, XTHL, XCHG, SPHL, PCHL instructions certainly pack a punch, but I've never heard of a non-trivial 8080 program being half the size of an equivalent 6502 program, so it's quite possible that some valuable insights could be gained from Will's code related to the subject at hand, for someone brave enough to take the dive. I haven't given up entirely, but I also haven't gathered sufficient courage yet ...