Sunday, April 30, 2017

Release version with working ELSE statement:
MC10_ROM_20.bin

While tests show this to work, it has not been tested as much as I would like, so it should be considered a BETA version.

It is now 11:53 in my time zone so it is as complete as it will get for the retro challenge.

A simple test:

10 FOR I = 1 to 10
20 IF I < 6 THEN PRINT I : ELSE PRINT 10 - I
30 NEXT I

One final note.  Tokens that are to be executed are normally grouped together.  Since ELSE can't be placed with the other tokens, an additional step has to be taken to test it individually and to point to it's location in the jump table.
This means that calling the ELSE token requires a few more clock cycles than the others.
It's ugly but it works.
Documentation:


Changes

V 1.1 optimizes calls to the CHRGET and CHRGOT functions, removes Microsoft and the programmer's unnecessary text, replaces mathematical constants that are incorrect in the original ROM, and calling CLS with numbers greater than 8 simply clears the screen to the standard green background rather than printing "MICROSOFT",
The V 1.1 ROM file is named:  MC10_ROM11.bin

V 2.0 contains all the changes from V 1.1 and adds the ELSE command which is used the same as in Color BASIC.  A brief explanation of it's use can be found in 'Getting Started With Color BASIC', or "Getting Started With Extended Color BASIC", and a brief syntax description is on the Color BASIC Wiki.
"Getting Started With Extended Color BASIC" can be found on the internet archive.
https://archive.org/details/Getting_Started_with_Extended_Color_BASIC_1984_Tandy
The V 2.0 ROM file is named MC10_ROM_20.bin

Using the new ROM in VMC10

In order to use the new ROM with the VMC10 emulator, you should copy the ROM image to the ROM folder located inside the directory where you have installed VMC10.  Then launch VMC10 and load the new ROM by selecting the "Configure" menu, then select the menu item titled "Memory...".
This will display some systems settings.  In the "ROM (Emulator only)" section, click on the "Load 8K BASIC ROM from file" option, then click on the "Browse" button to select the new ROM file.
After you have selected the name of the new ROM file, click "Open" and the file dialog box will close.  Click on the "Ok" button at the bottom of the "Configure" menu to save your settings and reset the emulator.  BASIC should reload and display the new version number.  If BASIC displays V 1.0, you have loaded the original ROM and need to check your settings again.



Using the new ROM in a real MC-10

In order to use the new ROM in a real MC-10, you will need to burn a new 8K EPROM and install it in the computer.  This requires some technical expertise and is beyond the scope of this document.
Most MC-10s have the ROM directly soldered to the board making this a delicate procedure as well.
If that is the case with your machine, I suggest you have someone experienced perform the installation for you.  It requires desoldering the original ROM, installing a socket in it's place, and then plugging in the new EPROM..  You may be able to have this done for you at the same time you have some other upgrade installed.
There are some lucky people out there with a socketed ROM so it may be worth having a look inside your machine.



Technical Details

Microsoft BASIC tokens start at $80.  The reason for this, is that all tokens will have the sign bit set.
When parsing a line of tokenized code, any character with a negative value is easily identified as a keyword token.

In order to add ELSE to Microcolor BASIC, it must be added to the next location in the keyword table.  This will assign the next available token which is $C9.

The token for ELSE in Color BASIC on the CoCo is $84.  The only way we could match tokens to the original color BASIC would be to completely rearrange tables in the Microcolor BASIC ROM and change tokens in the code where it directly tests for them.  That is beyond the scope of this project.

In order to squeeze in the additional code to support the ELSE statement, the address of ROM functions had to change.  Any calls to standard ROM routines must be done using the vectors located at the end of the ROM.  Any function that does not have a vector should not be called from machine language.
Decisions, decisions... what should I put in the final release?
Just a quick scan through the code that has all the optimizations reveals hundreds(?) of lines of code that have been changed.  A couple of those changes break the interpreter and I haven't had time to track down which ones are the problem.  So, I'm going to err on the side of caution, and release a version of the interpreter that adds ELSE to the V1.1 ROM I posted last night.  This will meet the goals I set for the project by the deadline.  The interpreter is faster, and it adds the ELSE command.  But the most important thing is that it will be stable and has the best chance of running everything out there.

A version with a greater speed increase would be nice but it's not going to happen in this time frame.  The first problem is that most of the optimizations only cut a few clock cycles each, so you won't see some massive jump in performance.  For that, the math library needs to be faster, or the interpreter needs significant changes to how it deals with numbers.  There is definitely more speed to be had, but for some massive jump it's going to require more ROM space than I have.

Saturday, April 29, 2017

It appears it's time to start uploading files.
The first file will be assembly source for generating the original ROM.

The biggest change from the disassembly (other than removal of the leftmost columns) is every JSR >CHRGET and JSR >CHRGOT were replaced with a forced extended address version of the JSR instruction.  The assembler Microsoft used clearly didn't take advantage of the direct addressing form of JSR.  This alone would have freed up some space in the ROM and saved some clock cycles.  Every direct version saves 1 clock cycle, and one byte. It's a small optimization, but the interpreter reads a lot of characters through that routine.

To build the original ROM, comment out (add a semicolon in front of) line 40 which says:
#define VERSION   The TASM (Telmark Assembler) is required to build the ROM..

If you leave it in, it will build a ROM displaying V1.1 which uses direct addressing for those calls, uses corrected math constants, removes Microsoft Easter eggs, and removes the programmer's name.
This saves 71 BYTEs and is close to what Microsoft should have produced to begin with.
This is also the file I'm using as a basis for testing other changes.

During testing I encountered one little problem.  I've tried testing this and many other optimizations with Ahl's Benchmark (a simple benchmark in Creative computing) and I cannot duplicate the time listed in the magazine with VMC10, even though the new ROM is faster than the original when compared side by side.  Either the number in the magazine is off, or the emulator is slow.


Source Code
ROM V 1.1

Sunday, April 23, 2017

Status update.

I really haven't spent much time on anything new since the last post.
There is a bug that seems to be part of the original conversion of the disassembly back to assembly code that did not appear in initial tests, but now it has become a show stopper.  This has forced me to go back to my original goal of creating a version of the source code that generates an identical binary to the original ROM.  Then I can test individual changes against that code instead of everything all at once.  Most of that work is complete but I probably have another 25-50 changes to go before it's ready.   It's a couple hours work at the most.

One of the easiest optimizations that came out of this effort was simply using an assembler that properly generates code for direct page references.  I'm actually had to force the assembler to generate the original opcodes using FCB and FDB.  This alone probably saved enough space vs the Easter eggs to implement the ELSE statement.  That's the first change I'll make to the code.
Then I'll insert the ELSE code, followed by a few small optimizations that use D where it's definitely safe.

Two of the optimizations that I want to use involve the CHARGET and storing the pointer to the next line.  They will certainly offer a speedup.  But to fully support the CHARGET changes requires looking at dozens of subroutines to find out what the X register contains for each one.  This is going to take a notebook or whiteboard and several days work.  Given the time constraints of the contest, it will have to be in a later release.  Storing the pointer to the next line is almost complete, but there is still one condition where it is failing and I need to see what is still messing up the FOR NEXT stack.  This optimization may also have to wait.

Everything previously mentioned will certainly offer a small performance increase..  I've also written faster versions of the code that moves strings and made a lot of other modifications that can save clock cycles.  When all those are rolled out, Microcolor BASIC will certainly be more responsive.   Running two copies of the VMC10 emulator side by side running the same program show a small but noticeable difference.

I have not worked on code to speedup the search for line numbers.  I looked at a simple design on paper and I probably need another 50 to 75 bytes for that.  It's just not going to fit in the limited ROM space.  Maybe some future ah-ha moments will free up enough space, but I have my doubts.

This brings us to the real bottleneck which is the math library.  I've made several optimizations but they all have to be retested from scratch thanks to the bug I mentioned.  So that's another thing that may not make the release.  Sadly, the fastest approach on paper to many of these routines is probably going to exceed available space.  It's an 8K ROM, not a Tardis.

Ultimately, I should have a release that supports ELSE and is faster soon.  It won't be as fast as I'd like, but there will certainly be follow up releases as I test the other optimizations.  Hopefully some of the better ones will be ready before the end of the contest.  The fixes to the bad Microsoft math constants can already be used as an option, so that should be in the release as well.

Monday, April 10, 2017

And now I messed up the FOR NEXT stack frame when I moved some stuff related to the next line pointer around.  This should be fun to track down.  <sigh>


Another speed optimization I'm working on involves parsing every character via the CHRGET subroutine.  CHRGET is a piece of self modifying code that is copied from ROM to the direct page at startup.  The function looks like this:

;*
;* Byte parser subroutine utilizing self-modifying code.
;* This routine is copied to RAM at CHRGET ($00EB) during cold start.
;*
          fcb       INIDAT-PARSER       ; number of bytes to copy
PARSER    inc       CHRPTR+1            ; increment LSB of parse location
          bne       LF7D8               ; branch if no carry
          inc       CHRPTR              ; increment MSB of parse location
LF7D8
;     ldaa      $0000              ; load byte from parse location into ACCA
fcb $B6,$00,$00
          jmp       BPARSE              ; call back-end of parser routine in ROM

If we can place CHRPTR in X, we can move this to ROM right in front of BPARSE and reduce it from 22(?) clock cycles to 7(?) clock cycles.  If we don't have to update CHRPTR until we exit BPARSE, we save even more clock cycles since BPARSE loops back to CHARGET.
This also only resulted in a 1 byte increase in code size thanks to removal of a couple STX CHPTR instructions elsewhere.  Sadly, only 2 out of 20+ calls can use this optimization without major changes, and neither will speed up program execution.


CHRGET2
inx
stx CHRPTR
ldaa ,X ; get the next character

If someone builds an MC-10 clone using a 68HC11 based microcontroller (as has been suggested in the MC-10 yahoo group), the code could easily be optimized my placing CHRPTR in the Y register.  Then every update to CHRPTR just involves loading Y or incrementing Y, and CHRGET becomes INY LDAA ,Y.
This should speed up the interpreter significantly.
I asked the MC-10 yahoo group what other changes to add if there is sufficient ROM space after ELSE support.  The only requested change so far is for correction of the SIN coefficients.  Microsoft apparently used the wrong values in many (all?) versions of BASIC.

Here are the changes.  The commented out data ontains the original values, and it is followed by the replacement table thanks to Neil.
SINCOF    fcb       6-1                 ; six coefficients in the table
;          fcb       $84,$E6,$1A,$2D,$1B ; -14.38139067 -(2*Pi)^11/11!
;          fcb       $86,$28,$07,$FB,$F8 ;  42.00779712  (2*Pi)^9 / 9!
;          fcb       $87,$99,$68,$89,$01 ; -76.70417026 -(2*Pi)^7 / 7!
;          fcb       $87,$23,$35,$DF,$E1 ;  81.60522369  (2*Pi)^5 / 5!
;          fcb       $86,$A5,$5D,$E7,$28 ; -41.34170210 -(2*Pi)^3 / 3!
;          fcb       $83,$49,$0F,$DA,$A2 ;   6.28318531  (2*Pi)^1 / 1!
fcb $84,$F1,$83,$A7,$EF ; -15.094642578 -(2*Pi)^11/11
fcb $86,$28,$3C,$1A,$44 ;  42.058693944  (2*Pi)^9 / 9
fcb $87,$99,$69,$66,$73 ; -76.705859753 -(2*Pi)^7 / 7
fcb $87,$23,$35,$E3,$3C ;  81.605249276  (2*Pi)^5 / 5
fcb $86,$A5,$5D,$E7,$31 ; -41.341702240 -(2*Pi)^3 / 3
fcb $83,$49,$0F,$DA,$A2 ;   6.283185307  (2*Pi)^1 / 1

Friday, April 7, 2017

Most of the math library depends on maintaining the value of A or B registers.
This makes it difficult to rewrite most of the functions to use D without rewriting a significant portion of the math library.  Since the Retro Challenge only runs for a month and I'm only doing this in my spare time, it is unlikely I will be able to implement all changes required for a significant speed improvement, but it is definitely a little faster already.

Wednesday, April 5, 2017

Another thing I've noticed about the way the interpreter was written, is that it doesn't take advantage of Motorola's indexed addressing to optimize some code.
It is common for the interpreter to do something like this:

* End of command or program line
 LE52A 
           inx                           ; advance past the end-of-line terminator
           ldaa      ,X                  ; get MSB of 'next line' link
           inx                           ; advacne to LSB
           oraa      ,X                  ; OR in the LSB of the 'next line' link
           staa      ENDFLG              ; clear ENDFLG if end of program
           beq       LE589               ; goto END if no more program lines
 * Start next program line
           inx                           ; advance to LSB of line number
           inx                           ; point X to new line number
           ldd       ,X                  ; get new line number..
           std       CURLIN              ; ..and store in CURLIN
           stx       CHRPTR              ; set parser position to start of line -1

The author does not seem to realize that
    LDAA   ,X
is the same as
    LDAA   0,X

If there are several INX instructions used together like this, then the following code is faster and smaller.  Note that the code at LE589 doesn't care that X has not been updated..
;* End of command or program line
LE52A
         ldaa 1,X
          oraa      2,X                  ; OR in the LSB of the 'next line' link
          staa      ENDFLG              ; clear ENDFLG if end of program
          beq       LE589               ; goto END if no more program lines
;* Start next program line
          ldd       3,X                 ; get new line number..
          std       CURLIN              ; ..and store in CURLIN
          ldab #4                   ; advance to LSB of line number
         abx
          stx       CHRPTR              ; set parser position to start of line -1

The 4 INX instructions in the original code require 12 clock cycles.  LDAB ABX requires 5 clock cycles.

The final code also saves the pointer to the next line since it only takes 5 more clock cycles to load the extra byte and save the pointer.  The end result is that the new code actually takes a fewer number of clock cycles than the old code even though it saves the pointer to the next line, and the new code only requires one additional byte. 

Tuesday, April 4, 2017

April 4, 1997 Update

Microcolor BASIC does some things slowly to conserve space in the ROM and memory.
A perfect example of this has to do with how the program skips over the remainder of a line.
The interpreter reads a byte at a time until if finds the 0 (zero) line terminator, then it increments the current position by 1 to point to the next line.  
This happens for REM, ON GOTO, ON GOSUB, IF THEN, etc... so obviously it will also happen on lines that use IF THEN ELSE.
So how do we speed this up?

The interpreter stores program lines in the following format:
16 bit word pointing to next line
16 bit word holding the current line number
tokenized BASIC code for the line
0 line terminator

Even thought the interpreter has access to a pointer to the next line, it does not use it except when searching for a line number.

A faster way to deal with this is to save the pointer to the next line when BASIC starts interpreting a new line, and then load that pointer instead of searching for the end of the line.
This change adds an extra 4 clock cycles at the start of each line, but calling the search for an end of line marker might take a hundred clock cycles, and removal of a related opcode in the search function reduces each call by 2 clock cycles.  If the interpreter has to search for ":" multiple times, it's even faster.  The longer the lines and more complex the code, the greater the improvement in speed.

There is a drawback to this.  It requires two more bytes on the direct page to store the pointer to the next line.  But BASIC doesn't directly allow access to that, and modern RAM expansions provide more direct page space anyway, so it shouldn't prove to be too much of an inconvenience.

Saturday, April 1, 2017

The new ROM is crashing do to incorrect code being created for the CHARGET code in ROM.
I forced it to create the correct LDAA instruction using FCB.

Some testing will be required before I know everything works, but I can enter and run a simple hello world program.

The assembler is is optimizing all calls to CHARGET as direct addressing, where the ROM uses extended addressing calls.  This saves a byte and clock cycle for every JSR call to the routine, so rather than force extended addressing with FCB, if tests don't reveal any issues, I'll call the first milestone met.  There are a lot of calls to this routine and my time would be better spent on something other than removing an easy optimization.

There are already 71 bytes free with the existing IF handler in place.  There should already be enough space for the new code to handle ELSE, and hopefully, to implement some more radical speed optimizations to the code.

Just a little clarification.

The Color Computer version of the IF THEN ELSE code is about 60 bytes.

But I failed to mention that the current MC-10 version takes up a good part of that, so we are actually within a few bytes of having enough space for ELSE, but I won't know how close until I finish writing the new code.

RetroChallenge Update

One of the things I'll try to do in my blog posts is explain the code changes as well as update overall status..

The initial version of the ROM assembles and boots, but it crashes when you enter a live of code.
There are some differences from the original ROM, probably due to the disassembly having some minor errors and I threw in a few optimizations.  So I'll have to remove optimizations and get it working first.  I actually tried this before writing the project page so I'm not really trying to skip a step.  This is where the initial milestone came from.

I am using TASM to assemble the code and syntax changes were required,so that could also be a problem.  None of the commands in the token table were terminated properly.  The interpreter expects the last character of the strings to be logically ORed with $80  (%1000000).  That lets the code test for a negative number instead of having to use an additional byte to terminate each string.  It works quite well since $80 is above the ASCII characters we have to use.

Here are the Easter eggs and programmer's name in the ROM.  This is from the disassembly located in the files area of the MC-10 Yahoo group.: Most of the space savings  we'll use to add ELSE comes from removing these..

Easter egg #1.  If you pass an invalid color to CLS, it clears the screen to green and prints MICROSOFT.  My change clears the screen turn green.  The code to be changed starts at $FBB8

4998   FB92             ;***
4999   FB92             ;*** CLS [color]
5000   FB92             ;***
5001   FB92 27 13       CLS       beq       LFBD4               ; branch if no parameter provided
5002   FB94 BD EE F1              jsr       LEF0D               ; Evaulate unsigned 8 bit integer expression into ACCB
5003   FB97 C1 08                 cmpb      #8                  ; if color number > 8 then..
5004   FB99             ;          bhi       LFBE5               ; ..go clear with default color and print 'MICROSOFT'
5005   FB99 22 0C                 bhi       LFBD4               ; ..go clear with default color
5006   FB9B 5D                    tstb                          ; check for color code if 0
5007   FB9C 27 06                 beq       LFBD1               ; branch if CLS 0
5008   FB9E 5A                    decb                          ; convert the color number..
5009   FB9F 86 10                 ldaa      #16                 ; ..to a SemiGraphics 4 VDG code..
5010   FBA1 3D                    mul                           ; ..using the formula:
5011   FBA2 CA 0F                 orab      #$0F                ; .. (colorNum - 1) * 16 | $0F
5012   FBA4 CA 80       LFBD1     orab      #$80                ; ..and set the graphics bit (bit 7)
5013   FBA6 8C                    fcb       SKP2                ; skip next instruction
5014   FBA7 C6 60       LFBD4     ldab      #$60                ; default color blank character
5015   FBA9 CE 40 00              ldx       #VIDRAM             ; point X to start of video RAM
5016   FBAC FF 42 80    LFBD9     stx       CRSPTR              ; set new cursor location
5017   FBAF E7 00       LFBDC     stab      ,X                  ; clear screen location with color code
5018   FBB1 08                    inx                           ; bump pointer
5019   FBB2 8C 42 00              cpx       #VIDRAM+$200        ; end of video RAM?
5020   FBB5 26 F8                 bne       LFBDC               ; loop if more to do
5021   FBB7 39                    rts                           ; return
5022   FBB8          
5023   FBB8             ;* Clear screen using default color and then print 'MICROSOFT'
5024   FBB8             ;LFBE5     bsr       LFBD4               ; clear screen
5025   FBB8             ;          ldx       #MS_STR-1           ; point X to 'MICROSOFT' string (-1)
5026   FBB8             ;          jmp       STROUT              ; output string
5027   FBB8     
Here is the new version.  Notice it just jumps to a different address and uses existing code.
This saves 9 bytes.

;***
;*** CLS [color]
;***
CLS       beq       LFBD4               ; branch if no parameter provided
          jsr       LEF0D               ; Evaulate unsigned 8 bit integer expression into ACCB
          cmpb      #8                  ; if color number > 8 then..
;          bhi       LFBE5               ; ..go clear with default color and print 'MICROSOFT'
          bhi       LFBD4               ; ..go clear with default color
          tstb                          ; check for color code if 0
          beq       LFBD1               ; branch if CLS 0
          decb                          ; convert the color number..
          ldaa      #16                 ; ..to a SemiGraphics 4 VDG code..
          mul                           ; ..using the formula:
          orab      #$0F                ; .. (colorNum - 1) * 16 | $0F
LFBD1     orab      #$80                ; ..and set the graphics bit (bit 7)
          fcb       SKP2                ; skip next instruction
LFBD4     ldab      #$60                ; default color blank character
          ldx       #VIDRAM             ; point X to start of video RAM
LFBD9     stx       CRSPTR              ; set new cursor location
LFBDC     stab      ,X                  ; clear screen location with color code
          inx                           ; bump pointer
          cpx       #VIDRAM+$200        ; end of video RAM?
          bne       LFBDC               ; loop if more to do
          rts                           ; return



Easter egg #2.  This is actually a remnent from the 6502 code. Microsoft hid their name at the end of a math table in a manner that people would just think it's part of the table.
Removing this saves 10 bytes.
4227 F701 ;* The text 'MICROSOFT!' obfuscated and reversed. Some versions
4228 F701 ;* of Microsoft Basic include a routine to print this message to the
4229 F701 ;* console, but MicroColor Basic does not.
4230 F701 ; fcb $80+'!'
4231 F701 ; fcb $00+'T'
4232 F701 ; fcb $00+'F'
4233 F701 ; fcb $40+'O'
4234 F701 ; fcb $1F&'S'
4235 F701 ; fcb $40+'O'
4236 F701 ; fcb $00+'R'
4237 F701 ; fcb $00+'C'
4238 F701 ; fcb $40+'I'
4239 F701 ; fcb $80+'M'
4240 F701
And here we have the programmer's name in reverse.
Removing this saves 8 bytes.
We are half way to our goal.

5655   FF97          
5656   FF97             ;* Mark Chamberlin co-wrote the 6800 version of Microsoft Basic.
5657   FF97             ;* Perhaps he also worked on the MC-10 version?
5658   FF97             ;          fcc       'nilrebmahC'        ; 'Chamberlin' spelled backwards
5659   FF97             


Sorry if the quoted test isn't properly formatted.
I can spend time making the blog look pretty or spend time on the code.

2017 RetroChallenge Entry


Introduction


My entry into the 2017 RetroChallenge is to update the Tandy MC-10 BASIC ROM to include the ELSE keyword and to improve compatibility with Color BASIC from Tandy's Color Computer, and to provide some performance optimizations.  A ROM image and documentation will be provided at the end of the project.


Backround

Tandy introduced the MC-10 in 1983 as a competitor to a series of very inexpensive entry level 8 bit computers.  This includes the Sinclair ZX-80, ZX-81, TS-1000, TS-1500, etc... that had a lot of sales simply because they were the least expensive computers on the market at the time.  The MC-10 was marketed a starter computer.  Something a person could learn on before moving to a more advanced computer.  Advertising usually involved kids.  So the kids could learn on this while mom and dad used the more powerful Color Computer or other Tandy computer I presume.

The MC-10 has some similarities to the Tandy Color Computer.  It uses a Motorola 6803 microcontroller as the CPU which is partially source compatible with the Color Computer's 6809 CPU, a 6847 Video Display Generator, and a compatible cassette tape storage format.  The MC-10's BASIC is also almost identical to Color BASIC on the Color Computer, with the exception of the ELSE keyword which is absent from the MC-10.

One of the key cost saving measures of the MC-10 was limiting the BASIC ROM to 8K.  Anything that wouldn't fit in 8K had to be left out.  The ELSE keyword was probably omitted because it was also left out of 6502 versions of Microsoft BASIC made prior to 1983.  Programs written in Color BASIC could be typed into the MC-10 and run without change as long as they didn't use ELSE, didn't directly access hardware, didn't include embedded machine code, and did not exceed the size of RAM.  Of all of those conditions, ELSE is the most likely to be a problem.

The ELSE keyword is also important to conserve memory and improve the speed of programs.  It lets you place additional code on a single line that otherwise would require several lines to accomplish.  One of the most time consuming tasks carried out by the BASIC interpreter is searching for line numbers.  The fewer line numbers you have, the quicker the interpreter can find a line of code.  It saves space because you don't need the additional overhead additional lines of code require such as line numbers, line terminators, etc...

Goals


The first goal is to add support for ELSE keyword to the MC-10 ROM.  There really isn't room to add any other keywords.  Examination of the MC-10 ROM disassembly, and the disassembly of the Color BASIC ROM  reveals there needs to be 60 or more bytes of code for the IF keywords handler, and several bytes for the new keyword.  Some of that space will be gained by removing two "Easter eggs" Microsoft placed in the code, and removal of the programmer's name which is in reverse towards the end of the ROM.  The existing IF handler takes up several more bytes.  However, the total comes up a few bytes short for the new code.  This means some code will need to be optimized for size before the ELSE code can be added.

The second goal is speed optimization of the interpreter and math library.  The BASIC in the MC-10 appears to have been derived from the earlier 6800 Microsoft BASIC.  One of the enhancements the 6803 offers over the 6800, is the ability to combine the A and B registers to for a 16 bit D register.  This can reduce the number of instructions required to perform many operations.  While the interpreter seems to take advantage of the D register, the math library appears to be the same as the 6800 version of Microsoft BASIC.  Replacing some of the 8 bit instructions with 16 bit instructions will make the code faster, and some of it will be smaller which should help with the first goal. Speed improvements are likely to be small.

A bonus goal will be to fix other known bugs in the standard MC-10 ROM if time and space permits.


Limitations

MC-10 BASIC uses different tokens to represent the keywords in MC-10 BASIC, than are used in Color BASIC.  This prevents the MC-10 from loading Color BASIC programs from tape unless they were saved in ASCII.   Due to the amount of BASIC software that has been ported to the MC-10 in recent years, it is no longer practical to change the tokens to match Color BASIC.

Adding the ELSE keyword will require placing it to the end of the existing keyword table.  Whatever the next available token is will be what we are stuck with.  Unless MCX BASIC added ELSE into keyword table in the same spot, the tokenized BASIC code will not be able to run on MCX BASIC unless it doesn't use ELSE.  I cannot change this. However, you will be able to save programs in ASCII format, and then load them into the other BASIC just like with Color BASIC.
Some additional RAM will need to be reserved to accommodate nested ELSE keyword handling, and to free up the B register so that the 16 bit D register can be used instead of just A.

The address of where code reside in the ROM is necessarily going to change.  Any software that makes direct ROM calls could break. There just isn't enough ROM space to preserve exiting ROM call addresses.  The vectors at the end f the ROM will point to the proper locations though.  In the future I may be able to produce a ROM image with some optimizations that still preserve entry points to commonly used functions, it just won't be able to support all optimizations or the ELSE keyword.

Some of the largest speed gains in the math library can only be achieved by use of different algorithms.  However, they will require larger code and are not an option.  Also, one of the biggest gains would be through caching recently called line numbers.  Sadly, there isn't enough space to do this either.

While the interpreter will support all the keywords of Color BASIC once this modification is complete, the changes will not let you type in every program for Color BASIC. The editor in the MC-10 uses a smaller input buffer than the one in Color BASIC, so some lines may be too long to type into the machine.  The interpreter itself can still execute longer lines, once they are entered though.

Testing will be carried out using emulation for convenience, and to make it easier to make a side by side comparison.  And due to the fact that the software for my EPROM burner isn't Windows 10 compatible.   Since no I/O code will be changed, emulation should prove to be sufficient.

Note that most MC-10's have the ROM soldered to the motherboard and you either need to perform electronic surgery, or have to add an external expansion board.  If you are lucky, your MC-10 may have a socketed ROM like I do.


Milestones

A working ROM image built from the existing commented disassembly of the MC-10 ROM.  This will serve as the baseline to add changes to.

Removal of the programmer's name, the Easter egg text and code.  Add the initial ELSE handling code to see how much additional space will be required.

Identify possible optimizations and implement as many as are required to fit else in the ROM.
Generate a working ROM image with the ELSE keyword.  This will only have as many optimizations as are required to fit in the ELSE keyword.  Build the first release.

Identify additional optimizations and generate additional working ROM images for testing as optimizations are completed.  Fix any bugs found in testing.  This will be repeated until the end of the contest or until I can't find any more optimizations and all known bugs are fixed.