The PRINT
command in Commodore BASIC V2.0 (the one that runs on the Commodore 64) prints each character to the screen address (which is set by the byte in address 648) as well as putting the current color (stored in byte at address 646) in the respective color RAM address. Is it possible to modify the system with some pokes or similar so that the color RAM is not updated?
-
I don't know any way to change that behavior in BASIC. You might consider a simple ML print routine and calling it from BASIC with USR(M$).– Brian HFeb 2, 2020 at 19:40
-
What are you trying to do here? You can change the color of the PRINT statement in the string printed, if that's what you want.– ZenzizenzizenzicFeb 3, 2020 at 12:53
4 Answers
One approach would be to mirror the BASIC ROM into RAM where it can easily be modified, and then simply NOP the instructions that perform the color change.
I outline the technique used to mirror the ROMS into RAM in this post
Mapping the 64 seems to indicate the BASIC PRINT routing is located at $AAA0, and eventually calls the Kernal CHROUT. I would start by disassembling the PRINT logic at $AAA0 with an eye toward where the color is output, and then override as desired.
-
-
1Looking here: pagetable.com/c64disasm - if you mirror Kernal ROM into RAM and switch to the RAM version, I think a POKE 59937, 234:POKE 59938, 234 will patch out the code that writes to color RAM when outputting characters. You will need to execute these together with no PRINT inbetween or anything that writes to the screen to avoid issues (e.g. don't enter just one POKE in immediate mode). Feb 5, 2020 at 18:40
The "problem" with a screen text rendering routine that also sets the color of each character cell it outputs is performance. It requires two writes for each character, but only one is required if you want to keep whatever color(s) are already assigned.
If you are looking to improve the performance of the PRINT used in BASIC by foregoing unnecessary writes to the color RAM, then there are at least two approaches that should work.
- You can copy BASIC to RAM and then modify the PRINT routine in place, as recommended by @Geo... This will not survive a cold start.
- You can adapt your basic program to call a bespoke print routine, written in ML, which only sets the character and leaves the color unchanged. Such a routine can be loaded via your BASIC program, access with the BASIC USR() function, and naturally unaffected by system restarts.
NOTE: You could also build the process of patching BASIC into your BASIC program so that just running it re-creates the environment after a restart. I think my preference for #2 is just based on adding new ML code is more straightforward than patching.
Maybe you could peek the color at the specified address before you print it. Else, if color ram has different colors at each character location where you want to print, the next idea would be to poke the characters at screenmem (which does not affect colorram). I also think that you can define a function using DEF FN() that peeks and pokes characters (i.e. emulating PRINT) and not change the colorram. That would be an exercise for the reader to find out.
See DEF FN
Of course the drawback is that this is very very slow.
How about intercepting CHROUT print routine and fixing the color value:
C000 LDA #$0C
C002 STA $0326
C005 LDA #$C0
C008 STA $0327
C00B RTS
C00C PHA
C00D LDA #$01 ; SET COLOR HERE
C00F STA $0286
C012 PLA
C013 JMP $F1CA
SYS49152
-
I tried the routine, but it just prints everything in white color, which is different from printing no color. Modifiying the CHROUT routine is an interesting approach though. The address of PHA is wrong by the way, since
C007 STA $327
requires three bytes, the address of the routine is C00B, not C00A.– Peter B.Feb 4, 2020 at 22:34