[Coco] CoCo 128-column text mode
William Astle
lost at l-w.ca
Wed Jan 7 16:37:56 EST 2015
On 15-01-07 01:49 PM, Allen Huffman wrote:
> Without attributes would be nice -- scrolling would hopefully be twice as fast. I forgot how sluggish PRINT is in 40/80 column mode. I did some tricks in my MiniBanners (1990) program to make it display instantly like an assembly program, and now I remember why I did that.
The reason the 40/80 column test display is to painfully slow on the
CoCo3 isn't because of the attributes or scrolling. It's painfully slow
because the code for displaying a character on the hires screens is
<bleeeeeeeeeeeeeeeeeeeeeeeeeeep> terrible.
Would you believe, it sets ALL 16 MMU registers one on the way in in
preparation (to map the text screen into CPU space). Then it displays
the character. Then it sets ALL 16 MMU registers *again* on the way out
to restore the memory map. Not only does it set all 16 MMU registers
*twice*, it does it in the least efficient manner possible. And it does
that for each character printed.
I made a modification to the ROM which set only one MMU register on the
way in and reset only one MMU register on the way out. Suddenly, the
hires text screen output was almost the same speed as the 32 column
screen, with no other changes. It's a relatively simple change to make.
It only requires appropriating a few bytes of memory somewhere (say, the
routine that does the inefficient mappings in the first place) and
changing an LBSR call. The patch is as follows:
10 DATA 19,E0B5
20 DATA 34,02,86,36,B7,FF,A1,35
30 DATA 82,34,02,B6,E0,E2,B7,FF
40 DATA A1,35,82
50 DATA 3,F778
60 DATA BD,E0,BE
70 DATA -1
80 READ N:IF N=-1 THEN END
90 READ A$:A = VAL("&H"+A$)
100 FOR N=N TO 1 STEP -1
110 READ A$:B = VAL("&H"+A$)
120 POKE A,B
130 A=A+1
140 NEXT
150 GOTO 80
NOTE: this will be wiped out when you press "RESET" because the ROM will
be recopied then.
The above program is not the most efficient way of doing it but it but
you can see what it does.
It replaces the routine at E0B5 ("SELTEXT") with two smaller routines
what are much more efficient:
SELTEXT PSHS A
LDA #$36
STA $FFA1
PULS A,PC
UNSEL PSHS A
LDA $E0E2
STA $FFA1
PULS A,PC
Then it replaces the call at F778 which in the ROM is "LBSR SETMMU" with
"JSR UNSEL". The UNSEL routine takes the value in the "MMU image" and
restores it to the MMU (that's the E0E2 reference).
The above patch is also completely compatible with the existing
"official" interface which includes "SELTEXT".
Using a short program that saves the TIMER value, prints out 450 As on
the screen, and then shows the number of TIMER ticks elapsed, I was able
to demonstrate that without the patch, the hires screen is about 15%
slower than the 32 column screen when scrolling does not occur.
Obviously scrolling an 80 column screen with attributes will take longer
than scrolling a 32 column screen with none.
With the patch, the hires screen is only about 1.5% slower, much of
which can be attributed to the overhead in SECB just getting to the
screen display, and some can be attributed to inefficient code in the
actual display routine (there is some less than good code in there but
it's not as bad as what the patch above fixes).
I have a hand written routine somewhere that basically replaces the crud
in SECB for handling the hires screen which runs even faster than SECB
patched as above, but it's not easy to shoehorn in.
Before you ask, getting SECB to handle a 64 column screen isn't easy
either because while it looks like the display routines and data
structres were intended to handle arbitrary screen sizes, they were
implemented by idiots (a bit harsh, probably) and, alas, do not handle
it properly. You would think it would be as simple as setting up the
GIME correctly, setting the screen width and size variables, and being
done with it. Except that doesn't work. Scrolling has a check for 40
columns and if found, it uses an 40 column specific scroll loop, and
otherwise uses an 80 column specific scroll loop. It is, of course,
possible to patch around, but it gets fiddly.
More information about the Coco
mailing list