[I already sent this reply to the list - but it didn't appear.  So sent again]

Hi Marcos,
On 08/06/2014 14:57, Marcos Cruz wrote:
Well, I think there's still an option to get some non-English letters:
overwrite the definition of some ASCII chars not used in the texts of
the program. I suppose Pro-DOS uses its own charset, not the SAM's
charset in ROM. Could it be modified by a CP/M program?
Pro-DOS uses its own charset. Initially it starts life as a standard 8x8 pixel (bit-per-pixel) font, with
the characters being no more than six pixels wide for the 80 (actually 85) 
column screen.  So, character
"A", for example, is designed like this (which will look wrong if you're not 
using a fixed-width font)
........ Row 0
..###...     "  1
.#...#..     "  2
.#...#..     "  3
.#####..     "  4
.#...#..     "  5
.#...#..     "  6
........     "  7
But the characters are actually stored interleaved, so the above character "A" is stored: ........ Row 0
.#...#..    Row 2
.#####..    Row 4
.#...#..    Row 6
........    Row 7
.#...#..    Row 5
.#...#..    Row 3
..###...    Row 1
This charset occupies 768-bytes and contains ASCII characters 32-127 in that order. However, the character set
in this format is not used by Pro-DOS once the program is up and running at the 
space it occupied gets reused for
other stuff.  During initial boot-up Pro-DOS constructs four versions of this 
charset in the spare 8k of space
below the 24k Mode 3 screen.  These versions are expanded bitwise by taking 
each single bit in the initial 768-byte
charset and expanding it to a pair of bits in the constructed (in screen) 
versions to make dumping to the Mode 3
screen faster.  The four expanded versions are stored at the following 
addresses (assuming the screen is paged in
at address &0000):
&6000 - Expanded charset for characters printed on EVEN screen addresses
&6600    -    Expanded charset for characters printed on ODD screen addresses
&6C00    -    Expanded charset for INVERSE characters printed on EVEN screen 
addresses
&7200    -    Expanded charset for INVERSE characters printed on ODD screen 
addresses
The four expanded charsets take up 6k in the spare 8k after the screen. They are also stored in the same row
interleave order shown above.  Also note, the remaining 2k of space is *not* 
free space!  It contains code and
buffers used by the system.  It is *not* safe to write to the area &7800 to 
&7FFF in the screen pages.
Also note, the expanded data for ASCII 32 (space) is not used by Pro-DOS - so there are 16-bytes of "spare"
space at the start of each 1536-byte expanded charset.  Pro-DOS uses a separate 
(faster) routine to print the
space character due to many CP/M programs using the printing of spaces to clear 
areas of the screen.  This gave a
nice (almost free) speed boost to a number of programs!
You asked if it is possible to modify the charset by a CP/M program. The answer is yes, but there are a number
of caveats which must be observed.  Firstly, the screen page(s) differ 
depending on whether Pro-DOS is currently
running on a 256k or 512k SAM.  The base page for the screen on each SAM is:
256k SAM - Screen page(s) = &0E and &0F
512k SAM    -    Screen page(s) = &1E and &1F
Your program is free to page in the screen but you *must* remember to restore the original LMPR (or HMPR) page
when you are finished.  It is easier to page the screen to address &0000 (LMPR) 
as the system uses IM2 interrupts
for keyboard scanning and these are vectored/run in the top 32k (HMPR).  Of 
course, you are free to DI should you
wish to page the screen at address &8000 but remember to EI (and restore the 
original HMPR pages!!) otherwise you
will lose keyboard input.
Once the screen is paged in your code is free to patch/alter any of the bytes within the area used by the charsets,
as detailed above.  Just to reiterate, you should *not* write any bytes to the 
last 2k of the second screen page.
At best strange things will happen and at worse you'll crash the SAM.
An alternative way to expand the character set would be to write a small resident (TSR) program that copies itself
to the area just below the system entry point (&F806) and alters the JP address at 
address &0006 to trap each system
function call.  Then your TSR could trap the functions that output ASCII to the 
screen, test if the ASCII character
has BIT 7 set and if so it could strip BIT 7 and patch the resulting charset 
data to equal the expanded character.
Then pass the character (BIT 7 stripped) to the system, which would then dump 
the patched character.  On return you
would have to restore the original character data over the patched data.  Your 
code would need to scan any strings
passed to the string output function (function 9) for expanded chars too.
The disadvantage here would be performance, as you would have to patch and restore each expanded character in all
four character sets (a total of 64-bytes (or 128 if you copy the original 
character for restoring)) as there is no
simple way to tell if the system is about to dump to an ODD or EVEN screen 
address, or if INVERSE characters are in
play.  Also note, characters 128-160 would not be usable as after stripping BIT 
7 you would end up with the chars
0-32.  The system treats characters 0-31 as control-characters and character 32 
is a special case.
Finally, if your program is in control you can make sure all of your output is via system "CALL &0005". But if you
are planning to expand the character set for other programs then you may well have to 
patch the "BIOS" JP table at
address &FB00 as they might make direct system "calls" via this table rather than the usual 
"CALL &0005"
So it is possible to expand the charset to use ASCII characters > 127 but it's not trivial. Doing it via a TSR is
a more "complete" method but the I think the performance hit would be 
noticeable when dumping expanded characters.
Hope that info gives you something to experiment with? Chris.

Reply via email to