Sunday, April 1, 2018

Patching the CoCo ROM Part 1

The TRS-80 Color Computer's Color BASIC ROM is quite similar to the MC-10's Microcolor BASIC.  The major flaws found in the latter, also seem to be in the former.

(this has been revised since the first posting)
The parser uses the same CHRGET/CHRGOT functions to step through programs.  The CHRGET code is stored in the ROM at $A10D, right after a series of other bytes that are copied to direct page RAM at the same time.  The code is copied to address $9F, and CHRGOT simply skips incrementing the address so the interpreter can reload the current byte being examined by the parser.  After reading a character, it jumps to the ROM code at $AA19 to test the character and decide how to process it.

CHRGET
;increment the BASIC parser's pointer
INC CHARAD+1
BNE LA123
INC CHARAD
CHRGOT
; load the current character
LA123 LDA >0000
JMP >BROMHK



ROM portion at $AA19

BROMHK
CMPA #'9+1 ; IS THIS CHARACTER >=(ASCII 9)+1?
BHS LAA28 ; BRANCH IF > 9; Z SET IF = COLON
CMPA #SPACE ; SPACE?
BNE LAA24 ; NO - SET CARRY IF NUMERIC
JMP GETNCH ; IF SPACE, GET NEXT CHAR (IGNORE SPACES)
LAA24 SUBA #'0 ; * SET CARRY IF
SUBA #-'0 ; * CHARACTER > ASCII 0
LAA28 RTS



Patching the code to reduce or eliminate jumps back and forth between CHRGET and ROM simply requires overwriting the JMP opcode with part or all of the ROM code, but adapted for the short branch back to CHRGET.  This also overwrites whatever is on the direct page until the end of the patch.  Anything that uses those addresses including BASIC, Extended BASIC, and Super Extended BASIC is likely to cause the computer to crash.  There is no guarantee either of these patches will work.

First approach, the entire function is in RAM:

org $9F
CHRGET
org $a8

CMPA #'9+1 ; IS THIS CHARACTER >=(ASCII 9)+1?
BHS EXIT ; BRANCH IF > 9; Z SET IF = COLON (BCC)
CMPA #SPACE ; SPACE?
BNE ASCII ; NO - SET CARRY IF NUMERIC
BRA CHRGET ; IGNORE SPACES
ASCII SUBA #'0 ; * SET CARRY IF
SUBA #-'0 ; * CHARACTER > ASCII 0
EXIT RTS



Second approach, returns on most likely condition, only uses 3 additional bytes:

org $9F
CHRGET
org $a8

cmpa #'9+1 ; IS THIS CHARACTER >=(ASCII 9)+1?
bcs PARSER2 ; (BHS is the same as BCC, reverse is BCS)
rts ; return if character >= (ASCII 9) +1
PARSER2
jmp >BROMHK+4 ;a9-ac

No comments:

Post a Comment