Sunday, May 28, 2017

This post is to address why so many patches were required to get ELSE working and why I was not expecting it.  I've looked at the internals of other versions of Microsoft BASIC before, so why the surprise?  It has to do with the size of the Microcolor BASIC ROM.

Valid keyword tokens are all negative numbers.  That means there are up to 128 tokens without using multiple bytes to represent keywords.  A jump table filled with the address of every possible function those tokens might represent would require 2 bytes per address, times 128 tokens, for a total of 256 bytes.  In 8K, 256 bytes is a lot, and reducing the size of the jump table is an easy way to save space.
Simply group all the valid tokens together starting with the lowest token value, and any token greater than the highest one in the group is a syntax error.  

The other version of Microsoft BASIC I worked with used a 256 byte jump table and did not require the range check.  Any tokens that would be a syntax error simply have the address of the syntax error routine at their location in the table.  This is faster because no range check is required before making the table call, but it does require around 60 more bytes than the code using the range check on the token.  

Microsoft made a trade off, they sacrificing a few clock cycles in exchange for a few bytes.  Sadly, it creates another problem.  In addition to a few clock cycles, it also makes it difficult to add additional commands while maintaining the original tokens.  There were two possible solutions to the problem once I encountered it.  Either patch the functions performing a range check so they perform an additional check for the ELSE token, or switch to larger table.  Given the time and ROM space I had, I chose the first approach.  Now that I have time, I may see if I can switch to the table.  A full 256 byte table isn't mandatory, but it means the interpreter will crash if an unknown token is encountered.

Saturday, May 27, 2017

Here are a few programs I've been using to benchmark the math changes.
I didn't write most of it, so if it does something stupid it's not my fault.  :)


10 W=500:DIM F(W):P=1:A=3:F(P)=A
20 FOR P=2 TO W
30 A=A+2:X=1
40 S=A/F(X):IF S=INT(S) THEN 30
50 X=X+1:IF X<P AND F(X)*F(X)<=A THEN 40
60 F(P)=A
70 NEXT P


10 REM PRIME NUMBER GENERATOR
20 FOR X=1 TO 1000
30 FOR Y=2 TO X-1
40 IF X/Y=INT(X/Y) THEN 70
50 NEXT Y
60 PRINT X
70 NEXT X



This simple BASIC mandelbrot generator required some porting, but it mostly works now.
The original used a MOD function in line 110 which has been replaced, but it has some issues with negative numbers.  The IF THEN was enough to get it running but it's not a proper fix.
The step rate has been cut in half to adjust for 40 columns, but for a benchmark it might be better to use 80 columns, and build a string array with the results instead of just printing them.  That would test some string functions as well as math, and the results could be compared for differences.
It does the job for now.

You could use this as the basis for a graphic version if you adjust the step rate to match the graphics resolution, replace the print with SET() or equivalent function, replace the string with an integer array containing the color numbers you want to use, and replace 5 with the number of colors in your graphics mode.


10 REM SIMPLE MANDELBROT GENERATOR USING TEXT
20 X0=-2: X1=0.5: Y0=-1: Y1=1: I1=20
30 X2=0.06: Y2=0.2: D$=" .-=#"
40 FOR Y=Y0 TO Y1 STEP Y2
50 FOR X=X0 TO X1 STEP X2
60 Z0=0: Z1=0
70 FOR I=1 TO 11
80 Z2=Z0*Z0-Z1*Z1: Z3=2*Z0*Z1
90 Z0=Z2+X: Z1=Z3+Y: IF Z0*Z0+Z1&gt;4 THEN GOTO 110
100 NEXT I
110 IF Z0 AND Z1 &gt; 0 THEN PA=SQR(Z0*Z0+Z1):A=(PA-(5*INT(PA/5)))+1:C$=MID$(D$,A,1):PRINT C$;
120 NEXT X: PRINT
130 NEXT Y

Friday, May 26, 2017

The results of the Retro Challenge are up.  I did not win anything but it was fun.
First of all, thanks to John Linvillle for running the retro challenge this year.
The pay isn't exactly great, and I'm sure everyone involved was already busy.

As for the results... someone who built a Win98 gaming machine finished ahead of me.
Well, that's depressing.


John's comments on my entry:

"James cleverly picked a project platform close to my heart -- the MC-10, a cousin of my retro favorite, the Tandy Color Computer. James sets-out to improve the comptibility between the CoCo and MC-10 BASIC implementations. There is a fair amount of "2 steps forward, 1 step back", as many changes caused somewhat unpredictable breakage in other areas. Having done similar projects before, I suspect that the MC-10 ROM disassembly is a bit imprefect. Nevertheless, he completed the project. Jim Gerrie and other MC-10 BASIC aficionados of the world may now rejoice!"

No clever about it... just trying to back up a claim I made on a forum.
John's "2 steps forward..." comment pretty much sums up the project though.
The disassembly isn't perfect, but it was more than sufficient.  It is far more detailed than other projects I've worked with.

Monday, May 22, 2017

After spending several hours implementing a faster SQR function, there isn't enough space left in the ROM for it. :(

Friday, May 19, 2017

There were two unused bytes on the direct page between Floating Point Accumulator 1 and the current execution line number.  MATHTEMP (added to speed up the math library) has been moved there so that all direct page variables are now at the same location as the original ROM.  As long as a program doesn't try to use the two MATHTEMP addresses, there shouldn't be any incompatibilities on the direct page.
That was going to hold the next line pointer, but that's going to be a new revision so this one might as well be as compatible as possible.
Here's an updated list of BASIC tokens for the MC-10 including the new ELSE statement.


Microcolor BASIC Tokens
Hex Dec Token meaning
80128FOR
81129GOTO
82130GOSUB
83131REM
84132IF
85133DATA
86134PRINT
87135ON
88136INPUT
89137END
8A138NEXT
8B139DIM
8C140READ
8D141LET
8E142RUN
8F143RESTORE
90144RETURN
91145STOP
92146POKE
93147CONT
94148LIST
95149CLEAR
96150NEW
97151CLOAD
98152CSAVE
99153LLIST
9A154LPRINT
9B155SET
9C156RESET
9D157CLS
9E158SOUND
9F159EXEC
A0160SKIPF
A1161TAB(
A2162TO
A3163THEN
A4164NOT
A5165STEP
A6166OFF
A7167+
A8168-
A9169*
AA170/
AB171^
AC172AND
AD173OR
AE174>
AF175=
B0176<
B1177SGN
B2178INT
B3179ABS
B4180USR
B5181RND
B6182SQR
B7183LOG
B8184EXP
B9185SIN
BA186COS
BB187TAN
BC188PEEK
BD189LEN
BE190STR$
BF191VAL
C0192ASC
C1193CHR$
C2194LEFT$
C3195RIGHT$
C4196MID$
C5197POINT
C6198VARPTR
C7199INKEY$
C8200MEM
C9201ELSE