Перекомпилировал маленький терминал на LCD c v.3.21 на v.3.30 и перестало работать перекодирование win1251->"русская кодировка LCD".
См. код, после ======= как можно обойти. *** помечены нужные места
Использую максимальную оптимизацию по скорости с выключеной "Code motion". С другими видами оптимизации (по скорости, по объему) ошибка остается при уровнях оптимизации High, Medium.
Код
\ In segment CODE, align 2
178 int putchar( int c )
\ putchar:
179 {
\ 000000 0A12 PUSH.W R10
\ 000002 0B12 PUSH.W R11
\ 000004 0812 PUSH.W R8
\ 000006 0A4C MOV.W R12, R10
180 static const char perecod[] = // перекодировка русских букв из таблицы win1251 в таблицу, применяемую в ЖКИ
181 { 'A' , 0xa0, 'B' , 0xa1, 0xe0, 'E' , 0xa3, 0xa4, 0xa5, 0xa6, 'K' , 0xa7, 'M' , 'H' , 'O' , 0xa8, // 0xc0..0xcf
182 'P' , 'C' , 'T' , 0xa9, 0xaa, 'X' , 0xe1, 0xab, 0xac, 0xe2, 0xad, 0xae, 'b' , 0xaf, 0xb0, 0xb1, // 0xd0..0xdf
183 'a' , 0xb2, 0xb3, 0xb4, 0xe3, 'e' , 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 'o' , 0xbe, // 0xe0..0xef
184 'p' , 'c' , 0xbf, 'y' , 0xe4, 'x' , 0xe5, 0xc0, 0xc1, 0xe6, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 // 0xf0..0xff
185 };
186 static const char n_line[] = { LCD_ONE, LCD_TWO, LCD_THREE, LCD_FOUR, LCD_ONE };
187 static int lcd_pos;
188 static int previos;
189 int c_old = c;
\ 000008 0B4C MOV.W R12, R11
190 // int a = c - 'А'; // пришлось ввести переменную и вынести ее расчет сюда, ато "крутой" оптимизатор от v3.30 заоптимизировывает...
191 //
192 // if ( c )
193 // { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251
194 // c = perecod[a]; // русские буквы в кодировке win1251
195 // else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd
196 // c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0
197
198 if ( c )
\ 00000A 0C93 CMP.W #0x0, R12
\ 00000C D924 JEQ ??putchar_2
199 { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251
\ 00000E 3C90C000 CMP.W #0xc0, R12
\ 000012 0238 JL ??putchar_3
200 c = perecod[c - 'А']; // русские буквы в кодировке win1251
\ 000014 7AF3 AND.B #0xff, R10 // *** ЭТО НЕ ПРАВИЛЬНО
\ 000016 053C JMP ??putchar_4
201 else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd
\ ??putchar_3:
\ 000018 3C908000 CMP.W #0x80, R12
\ 00001C 0238 JL ??putchar_4
202 c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0
\ 00001E 3A504000 ADD.W #0x40, R10
203
204
205 switch ( c )
\ ??putchar_4:
================================================================================
==================================================
178 int putchar( int c )
\ putchar:
179 {
\ 000000 0A12 PUSH.W R10
\ 000002 0B12 PUSH.W R11
\ 000004 0812 PUSH.W R8
\ 000006 0A4C MOV.W R12, R10
180 static const char perecod[] = // перекодировка русских букв из таблицы win1251 в таблицу, применяемую в ЖКИ
181 { 'A' , 0xa0, 'B' , 0xa1, 0xe0, 'E' , 0xa3, 0xa4, 0xa5, 0xa6, 'K' , 0xa7, 'M' , 'H' , 'O' , 0xa8, // 0xc0..0xcf
182 'P' , 'C' , 'T' , 0xa9, 0xaa, 'X' , 0xe1, 0xab, 0xac, 0xe2, 0xad, 0xae, 'b' , 0xaf, 0xb0, 0xb1, // 0xd0..0xdf
183 'a' , 0xb2, 0xb3, 0xb4, 0xe3, 'e' , 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 'o' , 0xbe, // 0xe0..0xef
184 'p' , 'c' , 0xbf, 'y' , 0xe4, 'x' , 0xe5, 0xc0, 0xc1, 0xe6, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 // 0xf0..0xff
185 };
186 static const char n_line[] = { LCD_ONE, LCD_TWO, LCD_THREE, LCD_FOUR, LCD_ONE };
187 static int lcd_pos;
188 static int previos;
189 int c_old = c;
\ 000008 0B4C MOV.W R12, R11
190 int a = c - 'А'; // *** пришлось ввести переменную и вынести ее расчет сюда, ато "крутой" оптимизатор от v3.30 заоптимизировывает...
\ 00000A 0F4C MOV.W R12, R15
\ 00000C 3F5040FF ADD.W #0xff40, R15
191
192 if ( c )
\ 000010 0C93 CMP.W #0x0, R12
\ 000012 DA24 JEQ ??putchar_2
193 { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251
\ 000014 3C90C000 CMP.W #0xc0, R12
\ 000018 0338 JL ??putchar_3
194 c = perecod[a]; // русские буквы в кодировке win1251
\ 00001A 5A4F.... MOV.B ??perecod(R15), R10 // *** ТАК ПРАВИЛЬНО!
\ 00001E 053C JMP ??putchar_4
195 else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd
\ ??putchar_3:
\ 000020 3C908000 CMP.W #0x80, R12
\ 000024 0238 JL ??putchar_4
196 c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0
\ 000026 3A504000 ADD.W #0x40, R10
197
198