Monday, March 26, 2018

What good is a new MC-10 ROM? (reply to CoCo Crew Podcasts)

My replacement for Microcolor BASIC has had a some mentions on the CoCo Crew Podcast in recent episodes.  This nay answer a couple questions they had.

Why did I start this?  The project arose for a couple reasons, and no it's not nostalgia, I did't own an MC-10 until a few years ago.  I wanted to enter the retro challenge (why I started this blog), and I had claimed on a forum that the MC-10 is more powerful than people give it credit for CPU wise... or something like that.  Someone mocked me for that.  Challenge accepted!  Plus this sort of thing is fun for me, I created a commented disassembly of the Amiga exec back in the 90s. 

Why would you want it?  If you want to run BASIC games on the MC-10, or you want to program the MC-10 in BASIC, programs will run faster.  It also adds the ELSE statement which makes it easier to port programs from other machines including from CoCo Color BASIC. Since a lot of programs never appeared on the MC-10, you can be the first to port them.

Okay, so there's a new ROM, how can we use it?
1)  The most obvious is that you can use it in an emulator.  This is how I test the ROM.  Just tell the emulator to load the ROM image instead of the original.  This is also the best way to write BASIC programs for the MC-10.  If you don't have to type them in on that little keyboard things become a lot easier.
2) The MC-10 hardware was designed so that external hardware can disable the internal CPU address decoding, including the ROM.  You can put the new ROM onto an expansion board that includes a socket for one, or replace internal ROM with RAM where supported to load the ROM image into RAM.
3) You can replace the system ROM inside the machine.  Most MC-10s have the ROM soldered to the motherboard, but there are a few (like mine) that have the ROM socketed.  You can desolder the ROM and install a socket if it doesn't already have one, then plug in a new ROM. 
You could have the ROM desoldered for you at CoCo Fest. 
At the same time, you could also have the CPU socketed for a future 6303 upgrade.  The 6303 upgrade requires a new ROM.  Getting the shielding removed to access the ROM and CPU also makes it easier to upgrade the internal RAM to take advantage of the highest resolution 6847 graphics modes.

FWIW, the optimizations I've made are mostly machine or Motorola specific.  You can't speed up the 6502 or Z80 versions of Microsoft BASIC the same way.  Microcolor BASIC on the MC-10, and Color BASIC on the CoCo weren't optimized much over the 6800 version they seem to be derived from.

Why the MC-10 ROM and not the CoCo ROM?   There's less software to break, and the MC-10 needs some love.

Thursday, March 15, 2018

MAME MC-10 HD6303 support is on hold

It seems the MAME crew is rewriting a lot of stuff again and it makes no sense to fix any code that is just going to to broken by the rewrite.  The design of the system is still a bit C oriented anyway.  The HD6303 object should be able to inherit from the MC6801/3 object which should be able to inherit from the 6800 object... and then just overload things that have changed.  The 6800/6801/6303 stuff hasn't quite made that transition yet.  The built in I/O and RAM isn't even in the 6801/6303 objects, it part of the code for each machine.

I'll hack together a version of MAME using the timing table of the 6303 in place of the 6803 so I can perform some benchmarks and make a video or two, but until I see what changes are being made to MAME, there isn't much point in doing anything more.  

Thursday, March 8, 2018

MAME MC-10 support update part 2

The ROM performs the memory test, copies setup code to RAM (that isn't there), returns and jumps into never never land because the stack pointer was never set due to loading it from page zero.
Turns out the HD6301/3 support in MAME is incomplete, it doesn't include the built in hardware and RAM. 
There were several oversights in my code prior to last night's work, so it would have had problems anyway, but seriously?  Someone couldn't take the time to inherit this from the 6801 emulation?
It's already there.  I'll look at fixing this in the next day or two.

One of the problems with MAME is that they use a lot of macros to "simplify" supporting new systems, but it has the side effect of keeping developers that aren't familiar with them from seeing what is going on, or more appropriately, what is going wrong.  Once I got around that hurdle, it was pretty easy to finish the HD6803 support in the MC-10 code.  I still have to fix an issue with the Alice support this caused, but I'll cross that bridge when I get to it.  Perhaps the most difficult part will be getting the MAME devs to accept these changes. 

Saturday, March 3, 2018

MAME MC-10 support update

I just spent several hours setting up a build environment for the MAME/MESS emulator.
It took a couple times to get it working properly.  Not sure what went wrong with the first install. 
Building it took 3 hours on my Intel i7 quad core laptop.  One thing MAME isn't, is small and I need a faster hard drive.

Adding HD6303 support for the MC-10 took about 2 hours.  Half of that was finding examples to make the changes, and the rest of the time was needed to figure out what was barfing in the build.  I cut and pasted from the 6309 CoCo3h definition and didn't update the tag on the line that replaces the cpu.  Du-Oh!

A real MC-10 with a 6303 will require a different ROM to fix timing differences, to add the extra 6303 interrupt vector, etc... but that shouldn't be a big deal.  Some testing will before I can submit the changes to the MAME project.  I won't be able to start that until tomorrow night.

MAME may not properly support 6803/6303 internal direct page RAM... but I haven't looked through all of the code yet.

Friday, March 2, 2018

Testing 1... 2... 3...

Testing some code formatting so it doesn't look ugly anymore.




Using http://hilite.me to format the html.
; Simple speed up for MC-10 Microcolor BASIC
; (C) 2018  James Diffendaffer
; May be freely redistributed
; Date:  2/28/2018
; code to patch the CHRGET function on the direct page 
; chrget is used to parse through the BASIC code and gets called a lot.
; by checking the most frequent case in RAM, it saves a 3 clock cycle jmp
; to the remainder of the function in ROM.  

; definitions for the TASM cross assembler needed for 6803 syntax
.MSFIRST           ; Most Significant byte first

#define EQU     .EQU
#define ORG     .ORG
#define RMB     .BLOCK
#define FCB     .BYTE
#define FCC     .TEXT
#define FDB     .WORD
#define END  .END
#define FCS  .TEXT

#define equ     .EQU
#define org     .ORG
#define rmb     .BLOCK
#define fcb     .BYTE
#define fcc     .TEXT
#define fdb     .WORD
#define end  .END
#define fcs  .TEXT

;start of code
 org  $434B   ;1st address after a REM on the first line of codeof the program.
       ;this is constant on startup in Microcolor BASIC

 pshx     ;preserve register contents
 psha
 pshb
 ldaa $F6
 cmpa #$7E    ; is it a jmp instruction?
 bne  exit   ; if not we exit
 
 ldd  $F7    ; grab the current address JMP calls
 addd #$0105   ; hopefully this will skip the compare & branch now on the direct page
 subd #$0101   ; - to avoid putting a zero in the code. 
 std  $FC    ; save it at the end of the new code

; ldx  #PATCH   ; get the address of our patch code minus 1 (to avoid using LDD 0,X)
 ;pc relative version of ldx to make code relocatable
 bsr  pcRel+1   ; push PC (avoiding zero byte)
pcRel:
 nop      ; origin for PC-relative indexing
 pulx     ; X = pcRel
 
 ldd  PATCH-pcRel,X    ; get the firs two bytes
 std  $F6    ; save them
 ldd  PATCH-pcRel+2,x    ; get the next two
 std  $F8    ; etc...
 ldd   PATCH-pcRel+4,x
 std  $FA
exit:
 pulb     ; restore registers
 pula
 pulx

 rts      ; return to BASIC

; contains the patch
PATCH:
; FCB $F0     ; dummy byte so LDD doesn't have to use LDD 0,X
; org $00F6    ; the address the patch is meant to run at.  Not really needed due to relative branch.
 cmpa      #':'    ; set Z flag if statement separator
 bcs       AA    ; perform more tests if not
 rts       ; return if >= ':' 
AA jmp $E1CC     ; jump to the parser back end.  The address can be dropped 
        ; - because we copy the current one plus 4 now

 end
 

Thursday, March 1, 2018

Final BASIC code for CHRGET patch.

The relocatable version using a string variable.
RUN it.  It will stop after POKEing the code into the string.
Then delete lines 1, 2, 3, and 5.
Save the program and then every time you load it, the patch will already be in the string.
You won't have to wait for it to be READ from the DATA and POKED into memory, it will just find the address of the string and EXECute the code.

0 Z$="01234567890123456789012345678901234567890123456"
1 DATA 60,54,55,150,246,129,126,38,26,220,247,195,1,5
2 DATA 131,1,1,221,252,141,1,1,56,236,18,221,246,236,20,221
3 DATA 248,236,22,221,250,51,50,56,57,129,58,37,1,57,126
4 Z=PEEK(VARPTR(Z$)+2)*256+PEEK(VARPTR(Z$)+3)
5 FORI=0TO44:READ A:POKE Z+I,A:NEXT:STOP
6 EXEC Z

Position independent code version of MC-10 patch.

Darren from the yahoo MC-10 group suggested this change.
The patch code is relocatable now in case the normal start address of a BASIC program is different on some machine. 

The BASIC code has the new DATA, but the POKE and EXEC are still position dependent.


0 REM01234567890123456789012345678901234567890123456
1 DATA 60,54,55,150,246,129,126,38,26,220,247,195,1,5
2 DATA 131,1,1,221,252,141,1,1,56,236,18,221,246,236,20,221
3 DATA 248,236,22,221,250,51,50,56,57,129,58,37,1,57,126
4 FORI=0TO44:READ A:POKE 17227+I,A:NEXT:STOP
5 EXEC17227



0001   0000             ; Simple speed up for MC-10 Microcolor BASIC
0002   0000             ; (C) 2018  James Diffendaffer
0003   0000             ; May be freely redistributed
0004   0000             ; Date:  2/28/2018
0005   0000             ; code to patch the CHRGET function on the direct page
0006   0000             ; chrget is used to parse through the BASIC code and gets called a lot.
0007   0000             ; by checking the most frequent case in RAM, it saves a 3 clock cycle jmp
0008   0000             ; to the remainder of the function in ROM.  
0009   0000             
0010   0000             ; definitions for the TASM cross assembler needed for 6803 syntax
0011   0000             .MSFIRST        ; Most Significant byte first
0012   0000             
0013   0000             #define EQU     .EQU
0014   0000             #define ORG     .ORG
0015   0000             #define RMB     .BLOCK
0016   0000             #define FCB     .BYTE
0017   0000             #define FCC     .TEXT
0018   0000             #define FDB     .WORD
0019   0000             #define END .END
0020   0000             #define FCS .TEXT
0021   0000             
0022   0000             #define equ     .EQU
0023   0000             #define org     .ORG
0024   0000             #define rmb     .BLOCK
0025   0000             #define fcb     .BYTE
0026   0000             #define fcc     .TEXT
0027   0000             #define fdb     .WORD
0028   0000             #define end .END
0029   0000             #define fcs .TEXT
0030   0000             
0031   0000             ;start of code
0032   434B              org $434B ;1st address after a REM on the first line of codeof the program.
0033   434B              ;this is constant on startup in Microcolor BASIC
0034   434B             
0035   434B 3C          pshx ;preserve register contents
0036   434C 36          psha
0037   434D 37          pshb
0038   434E 96 F6        ldaa $F6
0039   4350 81 7E        cmpa #$7E ; is it a jmp instruction?
0040   4352 26 1A        bne exit ; if not we exit
0041   4354             
0042   4354 DC F7        ldd $F7 ; grab the current address JMP calls
0043   4356 C3 01 05    addd #$0105 ; hopefully this will skip the compare & branch now on the direct page
0044   4359 83 01 01    subd #$0101 ; - to avoid putting a zero in the code. 
0045   435C DD FC        std $FC ; save it at the end of the new code
0046   435E             
0047   435E             ; ldx #PATCH ; get the address of our patch code minus 1 (to avoid using LDD 0,X)
0048   435E              ;pc relative version of ldx to make code relocatable
0049   435E 8D 01        bsr pcRel+1 ; push PC (avoiding zero byte)
0050   4360             pcRel:
0051   4360 01          nop ; origin for PC-relative indexing
0052   4361 38          pulx ; X = pcRel
0053   4362             
0054   4362 EC 12        ldd PATCH-pcRel,X ; get the firs two bytes
0055   4364 DD F6        std $F6 ; save them
0056   4366 EC 14        ldd PATCH-pcRel+2,x ; get the next two
0057   4368 DD F8        std $F8 ; etc...
0058   436A EC 16        ldd PATCH-pcRel+4,x
0059   436C DD FA        std $FA
0060   436E             exit:
0061   436E 33          pulb ; restore registers
0062   436F 32          pula
0063   4370 38          pulx
0064   4371             
0065   4371 39          rts ; return to BASIC
0066   4372             
0067   4372             ; contains the patch
0068   4372             PATCH:
0069   4372             ; FCB $F0 ; dummy byte so LDD doesn't have to use LDD 0,X
0070   4372             ; org $00F6 ; the address the patch is meant to run at.  Not really needed due to relative branch.
0071   4372 81 3A        cmpa      #':' ; set Z flag if statement separator
0072   4374 25 01        bcs       AA ; perform more tests if not
0073   4376 39          rts ; return if >= ':' 
0074   4377 7E E1 CC    AA jmp $E1CC ; jump to the parser back end.  The address can be dropped 
0075   437A              ; - because we copy the current one plus 4 now
0076   437A             
0077   437A              end
0078   437A              tasm: Number of errors = 0