1. На самом деле кодировка указывается в переменной LANG (например, ru_RU.UTF-8, ru_RU.KOI8-R) и не обязательно может быть UTF-8. (Если LANG не определена или LANG=C, то подразумевается кодировка ASCII).
Эта кодировка используется для ввода/вывода на консоль, в именах файлов, в переменных окружения и т.д.
Много кто использует кодировку, отличную от UTF-8. В России под Linux/FreeBSD часто используют KOI8-R. В Японии -- SJIS и т.д, в Китае -- GB2312 и т.д. Много кто (в Европе и т.д.) пользуется кодировками ISO8859-*
У меня кодировка всегда была KOI8-R.
2. У нас преобразования ARRAY OF CHAR <-> ARRAY OF SHORTCHAR нужны, как минимум, в HostFiles, в HostConsole, после Libc.getenv.
Кроме того, преобразования кодировок могут понадобиться при написании программ, в которых осуществляется взаимодействие с внешним миром, например, по сети.
3. Для преобразования кодировок можно написать подсистему на КП, а можно воспользоваться существующей библиотекой libiconv. Список поддерживаемых кодировок libiconv можно посмотреть, выполнив "iconv -l". В Linux также работают mbtowcs (используется, кодировка определённая в LANG).
Некоторые кодировки определены здесь: 
http://www.unicode.org/Public/MAPPINGS/ (все основные, не CJK (не китайские-японские-корейские)).
Если писать свою подсистему, то она будет менее эффективной, чем libiconv. Но не так существенно. Кое-что есть в подсистеме Unicode, но там много того, что не нужно, и не всё из того, что нужно.
4. Поэтому можно сделать абстрактный модуль EncCodecs:
Код:
MODULE EncCodecs;
        TYPE
                Encoding* = ARRAY 32 OF CHAR;
                Directory* = POINTER TO ABSTRACT RECORD END;
                Encoder* = POINTER TO ABSTRACT RECORD END;
                Decoder* = POINTER TO ABSTRACT RECORD END;
        VAR
                dir-: Directory;
        (* Directory *)
        PROCEDURE (dir: Directory) NewEncoder* (enc: Encoding): Encoder, NEW, ABSTRACT;
        PROCEDURE (dir: Directory) NewDecoder* (enc: Encoding): Decoder, NEW, ABSTRACT;
        (* Encoder *)
        PROCEDURE (e: Encoder) Encode* (IN f: ARRAY OF CHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF SHORTCHAR; VAR tW: INTEGER), NEW, ABSTRACT;
        (* у энкодера нет состояния, сброс не нужен *)
        (* Decoder *)
        PROCEDURE (d: Decoder) Decode* (IN f: ARRAY OF SHORTCHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF CHAR; VAR tW: INTEGER; OUT state: BOOLEAN), NEW, ABSTRACT;
        PROCEDURE (d: Decoder) Reset*, NEW, ABSTRACT; (* сброс состояния декодера *)
        PROCEDURE SetDir* (d: Directory);
        BEGIN
                dir := d
        END SetDir;
END EncCodecs.
И конкретную реализацию на основе libiconv (для OpenBSD) или mbtowc (для Linux) -- в HostEncCodecs.
А в будущем сделать реализацию на КП: EncStdCodecs:
Код:
MODULE EncStdCodecs;
        IMPORT Meta, Codecs := EncCodecs, Aliases := EncStdAliases;
        TYPE
                Directory* = POINTER TO RECORD (Codecs.Directory) END;
        (* Directory *)
        PROCEDURE (dir: Directory) NewEncoder* (enc: Codecs.Encoding): Codecs.Encoder;
                VAR modName: ARRAY LEN(Codecs.Encoding) + 16 OF CHAR;
                        item: Meta.Item; ok: BOOLEAN;
                        item0: RECORD (Meta.Value)
                                fun: PROCEDURE (): Codecs.Encoder
                        END;
                        e: Codecs.Encoder;
        BEGIN
                e := NIL;
                Aliases.GetModName(enc, modName, ok);
                IF ok THEN
                        Meta.Lookup(modName, item);
                        IF item.obj = Meta.modObj THEN
                                item.Lookup("NewEncoder", item);
                                IF item.obj = Meta.procObj THEN
                                        item.GetVal(item0, ok);
                                        IF ok THEN
                                                e := item0.fun()
                                        END
                                END
                        END
                END;
                RETURN e
        END NewEncoder;
        PROCEDURE (dir: Directory) NewDecoder* (enc: Codecs.Encoding): Codecs.Decoder;
                VAR modName: ARRAY LEN(Codecs.Encoding) + 16 OF CHAR;
                        item: Meta.Item; ok: BOOLEAN;
                        item0: RECORD (Meta.Value)
                                fun: PROCEDURE (): Codecs.Decoder
                        END;
                        d: Codecs.Decoder;
        BEGIN
                d := NIL;
                Aliases.GetModName(enc, modName, ok);
                IF ok THEN
                        Meta.Lookup(modName, item);
                        IF item.obj = Meta.modObj THEN
                                item.Lookup("NewDecoder", item);
                                IF item.obj = Meta.procObj THEN
                                        item.GetVal(item0, ok);
                                        IF ok THEN
                                                d := item0.fun()
                                        END
                                END
                        END
                END;
                RETURN d
        END NewDecoder;
        PROCEDURE Init;
                VAR dir: Directory;
        BEGIN
                NEW(dir); Codecs.SetDir(dir)
        END Init;
BEGIN
        Init
END EncStdCodecs.
Enc/Mod: Codecs, StdAliases, StdCodecs, StdMap_ascii, StdMap_utf_8, StdMap_utf_16be, StdMap_utf_16le и генерируемые автоматичеки из таблиц на сайте unicode.org и csets:
StdMap_iso8859_1, StdMap_iso8859_2, StdMap_iso8859_3, StdMap_iso8859_4, StdMap_iso8859_5, StdMap_iso8859_6, StdMap_iso8859_7, StdMap_iso8859_8, StdMap_iso8859_9, StdMap_iso8859_10, StdMap_iso8859_11, StdMap_iso8859_13, StdMap_iso8859_14, StdMap_iso8859_15, StdMap_iso8859_16,
StdMap_cp037, StdMap_cp1026, StdMap_cp1140.txt
StdMap_cp1250, StdMap_cp1251, StdMap_cp1252, StdMap_cp1253, StdMap_cp1254, StdMap_cp1255, StdMap_cp1256, StdMap_cp1257, StdMap_cp1258, StdMap_cp424, StdMap_cp437, StdMap_cp500, StdMap_cp720, StdMap_cp737, StdMap_cp775, StdMap_cp850, StdMap_cp852, StdMap_cp855, StdMap_cp856, StdMap_cp857, StdMap_cp858, StdMap_cp860, StdMap_cp861, StdMap_cp862, StdMap_cp863, StdMap_cp864, StdMap_cp865, StdMap_cp866, StdMap_cp869, StdMap_cp874, StdMap_cp936, StdMap_cp949,
StdMap_mac_centraleurope, StdMap_mac_cyrillic, StdMap_mac_greek, StdMap_mac_iceland, StdMap_viscii, StdMap_mac_roman,  StdMap_mac_turkish,
StdMap_koi8_r, StdMap_koi8_u,
StdMap_georgian_academy, StdMap_georgian_ps,
StdMap_atarist, StdMap_hp_roman8,
StdMap_kps9566, StdMap_kz1048, StdMap_ptcp154
( Не указаны модули CJK (в том числе CP932, CP950) )
Модуль StdAliases также должен генерироваться автоматически.
Модули StdMap_ascii, StdMap_utf_* -- реализовывать вручную.
Пример автоматически сгенерированного модуля:
Код:
MODULE EncStdMap_cp1251;
        (* This file was generated automatically *)
        (* Source: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT *)
        IMPORT Codecs := EncCodecs;
        TYPE
                Encoder = POINTER TO RECORD (Codecs.Encoder) END;
                Decoder = POINTER TO RECORD (Codecs.Decoder) END;
        (* Encoder *)
        PROCEDURE (e: Encoder) Encode (IN f: ARRAY OF CHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF SHORTCHAR; VAR tW: INTEGER);
                VAR x, y: INTEGER;
        BEGIN
                WHILE fLen > 0 DO
                        x := ORD(f[fR]);
                        CASE x OF
                        | 00H..7FH: y := x
                        | 0A0H: y := 0A0H
                        | 0A4H: y := 0A4H
                        | 0A6H..0A7H: y := x
                        | 0A9H: y := 0A9H
                        | 0ABH..0AEH: y := x
                        | 0B0H..0B1H: y := x
                        | 0B5H..0B7H: y := x
                        | 0BBH: y := 0BBH
                        | 0401H: y := 0A8H
                        | 0402H..0403H: y := x - 0382H
                        | 0404H: y := 0AAH
                        | 0405H: y := 0BDH
                        | 0406H: y := 0B2H
                        | 0407H: y := 0AFH
                        | 0408H: y := 0A3H
                        | 0409H: y := 8AH
                        | 040AH: y := 8CH
                        | 040BH: y := 8EH
                        | 040CH: y := 8DH
                        | 040EH: y := 0A1H
                        | 040FH: y := 8FH
                        | 0410H..044FH: y := x - 0350H
                        | 0451H: y := 0B8H
                        | 0452H: y := 90H
                        | 0453H: y := 83H
                        | 0454H: y := 0BAH
                        | 0455H: y := 0BEH
                        | 0456H: y := 0B3H
                        | 0457H: y := 0BFH
                        | 0458H: y := 0BCH
                        | 0459H: y := 9AH
                        | 045AH: y := 9CH
                        | 045BH: y := 9EH
                        | 045CH: y := 9DH
                        | 045EH: y := 0A2H
                        | 045FH: y := 9FH
                        | 0490H: y := 0A5H
                        | 0491H: y := 0B4H
                        | 2013H..2014H: y := x - 1F7DH
                        | 2018H..2019H: y := x - 1F87H
                        | 201AH: y := 82H
                        | 201CH..201DH: y := x - 1F89H
                        | 201EH: y := 84H
                        | 2020H..2021H: y := x - 1F9AH
                        | 2022H: y := 95H
                        | 2026H: y := 85H
                        | 2030H: y := 89H
                        | 2039H: y := 8BH
                        | 203AH: y := 9BH
                        | 20ACH: y := 88H
                        | 2116H: y := 0B9H
                        | 2122H: y := 99H
                        ELSE
                                RETURN
                        END;
                        t[tW] := SHORT(CHR(y)); INC(tW);
                        INC(fR);
                        DEC(fLen)
                END
        END Encode;
        PROCEDURE NewEncoder* (): Codecs.Encoder;
                VAR e: Encoder;
        BEGIN
                NEW(e); RETURN e
        END NewEncoder;
        (* Decoder *)
        PROCEDURE (d: Decoder) Decode (IN f: ARRAY OF SHORTCHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF CHAR; VAR tW: INTEGER; OUT state: BOOLEAN);
        BEGIN
                HALT(126) (* not implemented *)
        END Decode;
        PROCEDURE (d: Decoder) Reset;
        BEGIN
                HALT(126) (* not implemented *)
        END Reset;
        PROCEDURE NewDecoder* (): Codecs.Decoder;
                VAR d: Decoder;
        BEGIN
                NEW(d); RETURN d
        END NewDecoder;
END EncStdMap_cp1251.
Черновик StdMap_utf_8:
Код:
MODULE EncMap_utf_8;
        IMPORT Codecs := EncCodecs;
        TYPE
                Encoder = POINTER TO RECORD (Codecs.Encoder) END;
                Decoder = POINTER TO RECORD (Codecs.Decoder) END;
        (* Encoder *)
        PROCEDURE (e: Encoder) Encode (IN f: ARRAY OF CHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF SHORTCHAR; VAR tW: INTEGER);
                VAR x: INTEGER;
        BEGIN
                WHILE fLen > 0 DO
                        x := ORD(f[fR]);
(* http://www.lemoda.net/c/ucs2-to-utf8/index.html *)
                        CASE x OF 00H..7FH:
                                t[tW] := SHORT(CHR(x)); INC(tW)
                        | 80H..7FFH:
                                t[tW] := SHORT(CHR(x DIV 64 + 192));
                                t[tW+1] := SHORT(CHR(x MOD 64 + 128));
                                INC(tW, 2)
                        | 800H..0FFFFH:
                                t[tW] := SHORT(CHR(x DIV 4096 + 224));
                                t[tW+1] := SHORT(CHR((x DIV 64) MOD 64 + 128));
                                t[tW+2] := SHORT(CHR(x MOD 64 + 128));
                                INC(tW, 3)
                        ELSE
                                RETURN
                        END;
                        INC(fR);
                        DEC(fLen)
                END
        END Encode;
        PROCEDURE NewEncoder* (): Codecs.Encoder;
                VAR e: Encoder;
        BEGIN
                NEW(e); RETURN e
        END NewEncoder;
        (* Decoder *)
        PROCEDURE (d: Decoder) Decode (IN f: ARRAY OF SHORTCHAR; VAR fR, fLen: INTEGER; VAR t: ARRAY OF CHAR; VAR tW: INTEGER; OUT state: BOOLEAN);
        BEGIN
                HALT(126) (* not implemented *)
        END Decode;
        PROCEDURE (d: Decoder) Reset;
        BEGIN
                HALT(126) (* not implemented *)
        END Reset;
        PROCEDURE NewDecoder* (): Codecs.Decoder;
                VAR d: Decoder;
        BEGIN
                NEW(d); RETURN d
        END NewDecoder; 
END EncMap_utf_8.