Image Map Image Map
Results 1 to 6 of 6

Thread: Model I Upper Case

  1. #1

    Default Model I Upper Case

    Since the standard Model I didn't have lower case, how did text output get converted to upper case?

    If I hit the screen with lower case, it mostly works in emulators because they assume the lower case mod. What happens on a real model I with no lower case HW, presumably garbage (what i get currently in trs80gp -nlc).

    Did the ROM output routines convert to upper case? If so, how did they know to do this?

    In my case, i have my own output routines, so i will need to do something similar.

    thanks for any help.

  2. #2
    Join Date
    Mar 2013
    Chaffee, MO


    OK, It's been XX years but let's see if I can still remember how it worked. First of all, there
    are some Basic Programs that will show you the existing characters in the Character ROM.

    Basic Programs to display:
    1. Special Characters
    2. Text Characters
    3. Graphic Charaters

    1. Special Characters
    10 CLS
    20 FOR I=0 TO 31
    30 POKE, 15360+I*16,I
    40 NEXT
    50 PRINT@ 640,"";
    2. Text Characters
    10 CLS
    20 FOR I=32 TO 127
    30 PRINT@ (I-32)*8,I; CHR$(I);
    40 NEXT
    50 END
    3. Graphic Characters
    10 CLS
    20 FOR I=128 TO 191
    30 PRINT@ (I-128)*8,I; CHR$(I);
    40 NEXT
    50 END
    5  CLS
    10 POKE 16526,105
    20 POKE 16527,0
    30 X=USR(O)
    40 PRINT CHR$(21);
    60 FOR I=192 TO 255
    70 PRINT CHR$(I);
    80 NEXT
    90 PRINT
    110 PRINT CHR$(22);
    130 PRINT CHR$(22); CHR$(21)
    140 END
    You should be able to notice that the "A" = 65(decimal) is the same as the "A" = 97(decimal), because those
    folks saved one display RAM (2102 IC). Bit 6 is missing, and that happens to the the bit that selects
    UPPER or lower Case. It's tied into IC Z30 where NOT Bit 5 is ANDED with NOT Bit 7, to generate Bit 6.

    There were several Lowercase modifications done on the Model 1, and mine happens to be a KGS PCB
    that I bought at the Dayton Hamfest XX Years ago. I've decoded it, along with the Character ROM (really an EPROM)
    and have the bit patterns in Excel, along with a file of the hex bytes.

    If you are interested I've got a document that explains how I read my Character Generator, and decoded the Bit Patterns
    that make up each character.

    The easiest thing to do is find out what Version Motherboard you have, along with the Number from the Character Generator.
    Certain Character Generators have the proper Character set programmed, and by just adding one 2102 IC piggyback
    with U45 you can have Upper and lowercase characters. Or you can use an eprom and roll your own Character set.
    It's just a matter if programming the EPROM with the updated Characters.

    TRS-Ian has a posting on here somewhere about the easiest way to make Lowercase conversion.

    I simplified it this way which has served me well since the 80s.

    If your character generator (Z29) last 4 numbers are 3001 or 6670, then you do the mod Lowercase with Upper from Custom TRS-80

    If your character generator last for numbers are 6673 or 6674, then you do the Radio Shack lowercase mod, from the same book.

    All other LC mods are complicated or unnecessary in this day and age, and in fact when I buy systems with other mods I undo them and set them up as listed, above.

    For the record:
    3001 : early systems, lowercase but no descenders, and a flying 'a' due to Motorola manufacturing fault (so they sold these chips cheap to RS who figured they didn't need LC anyway)
    6670 : mid-production systems, same as above but with no flying 'a'
    6673 : late systems, custom part made especially for the M1 for Radio Shack and included with most late 79 and 1980 machines. By this time RS was selling the LC modification "kit" for $99 but if the computer already had the 6673 then the 1-min job was to cut the trace, install the stacked 2102s into the already fitted socket, and solder two wires. It probably took longer for the soldering iron to warm up than to make the mod.


    PM me with your email address requesting more info.

    Last edited by ldkraemer; September 2nd, 2019 at 04:29 AM. Reason: added TRS-Ian info

  3. #3


    Quote Originally Posted by steaminghacker View Post
    If I hit the screen with lower case, it mostly works in emulators because they assume the lower case mod. What happens on a real model I with no lower case HW, presumably garbage (what i get currently in trs80gp -nlc).
    The upper-case-only Model I can only store character codes 32 to 95. The hardware converts any other 7-bit codes into that range by flipping bit 6. So, 0-31 map to 64-95, and 96-127 become 32-63. What you want is for 96-127 (lower case) to be mapped to 64-95 (upper case) if and only if the system cannot display lower case. You also want 32-95 to map to themselves, and presumably don't care what happens to the ASCII non-printing codes 0-31. The following code will do the trick (once you have the character code in A and the video address in HL).

            LD (HL), A
            XOR (HL)
            XOR (HL)
            LD (HL), A
    That takes 5 bytes, and runs in 32 T cycles. I just wrote it now, and I was thinking it was a slight improvement on the Big Five code George posted here last year:

            LD   (HL),A
            CP   (HL)
            JR   Z,chok
            RES  5,(HL)
    That uses 6 bytes, and takes 36 or 26 T cycles. So my code is better in space and worst-case time, and only a little slower on a lower-case system. However, I now realize that what's probably a more important metric on a Model I is how many times you hit the video RAM, and therefore how many video glitches are caused. Both versions will make four video RAM accesses on an upper-case-only system, but on lower-case systems the Big Five version will cut the number of accesses in half, possibly causing a noticeable improvement in screen clarity. So that's probably the way to go. (I shouldn't have thought I was cleverer than Bill Hogue.)

  4. #4


    Hi! Thanks for your answer, this has been helpful.

    So if i;
    POKE 15360,97

    I get a '!' on the screen, and if i PEEK it back, I get 33, so bit 6 is clobbered.

    And when i;

    PRINT A$

    i get "A", but A$ still has 97 with


    So, how is it on a M1 with no lowercase mod, that PRINT A$ above appears as "A" when poking the screen loses a bit.

    Does the ROM PRINT routine convert? If so, how does it know not to do this if a lcase mod is installed?

    Another way to solve this problem;

    Is there a way i can detect if a lower case mod is installed on a M1?
    Last edited by steaminghacker; September 2nd, 2019 at 07:45 AM.

  5. #5
    Join Date
    Jun 2010
    Vancouver, BC, Canada


    The Model I ROM has no idea if the lower case mod is installed. The code at $468 translates ASCII values into values that work with the 7-bit Model I VRAM. This includes translating lower case to upper case unconditionally. That's why you need a lower case driver loaded to get lower-case output in ROM BASIC.

    The only way to detect if the lower-case mod is installed is to probe the video RAM as described earlier.

    This can be done once at the start of your program but I'd suggest doing it with every character printed or at the very least regularly since some lower-case mods came with a physical switch to turn the lower case mod on and off. Since the user can change the hardware at a whim it'd be best that no messages are scrambled when the switch is flipped and that then can get lower case from the program even though it started out in upper case mode.

  6. #6


    Aha! So the ROMS convert.

    I like the idea of testing the VID RAM, here's my plan:

    20 maps to 84('T') on a Model I without a lcase mod. So whenever a 'T' is printed, I'll write a 20, then read it back to see if it has changed to 84. If it has changed, then a lower case mod is present and uppercasing can be disabled. But the above test will continue for all subsequent 'T's printed.

    like this:

    static void setChar(volatile char* a, char c)
        if (TRSModel <= 2)
            // Each time we see a T, check for lcase mod?
            if (c == 'T')
                // 20 displays the same as T, 20+64=84=T
                *a = 20;
                TRSUppercaseOutput = (*a != 20);
            if (TRSUppercaseOutput) c = toupper(c);
        *a = c;


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts