Итоги минувших дней...
Но предварительно хотел бы рассказать, чем же именно я всё-таки занимаюсь.
Пару лет назад, когда я повторял Паскаль, чтобы программирование совсем уж не выветрилось из головы, меня посетила идея сделать маленькую консольную программку, которая могла бы хранить в себе и отображать ANSI-графику, а то уж совсем скучно было решать студенческие математические паскалевские задачи. Тогда я ещё не понимал, куда я в итоге вмазался.
Первым, казалось бы, решением проблемы, на которое я наткнулся, было PingAnsi v1.30:
https://pascal.sources.ru/ansi/ansi_130.htmНа том сайте есть версия постарше (1.33) с дополнительным модулем, но я тогда остановился именно на ранней версии.
Первой проблемкой было уже то, что для успешной компиляции юнитов из комплекта и самой программки PingAnsi требовались модули из библиотеки "Turbo Professional" от компании TurboPower Software, последняя версия которой была выпущена в свет чёрт знает когда (ещё до официальной смерти самого Паскаля). Библиотеку в интернете я нашёл, нужные модули и объекты компилятору скормил.
Второй проблемкой стало то, что на финальном шаге я столкнулся с ошибкой 200 "Division by zero", которая осталась сейчас только на моём старом видео, что я тогда записывал (честно, пытался на днях повторить данную ошибку на виртуалке с Windows XP, и даже задирал в ВМ количество потребляемой оперативы до 2 ГБ - ошибка не повторяется, словно сама по себе куда-то бесследно испарилась, хотя ноут, на котором я всё это провожу, тот же самый).
В интернете тогда нагуглил, что данная ошибка впоследствии стала появляться на всех компьютерах, частота процессора которого превышала 200+ МЕГАГЕРЦ!!!
И что для решения проблемы нужно скачать официальный фикс TPCrt от той же конторы.
Фикс я нашёл, TPCrt перекомпилировал, а вместе с ним и пару юнитов PingAnsi. Программа скомпилировалась и завелась!
Но вот незадача - оригинальный Borland Pascal компилирует программки в 16-битной разрядности, которые максимум могут запуститься в 32-битной системе. А мне бы хотелось, чтобы она запускалась и в 64-битной ОС тоже (для чего весь этот процесс и был начат).
Начался долгий, безумный, бессонный и мучительный перебор всевозможных 32-битных компиляторов Паскаля, большинство из которых останавливали обработку кода на тех же местах, как и в этом случае, что я публиковал на днях:
https://www.emu-land.net/forum/index.php/topic,33894.msg1544016.html#msg1544016Пример такой необработанной процедуры (красным помечен тот участок кода, который большинство 32-битных компиляторов вводил в состояние полнейшего ступора от того, что же за муть ему пытаются скормить):
procedure SetJump(var JumpDest : JumpRecord); inline(
$5F/ {pop di ;di = Ofs(JmpDest)}
$07/ {pop es ;es = Seg(JmpDest)}
$26/$89/$25/ {mov es:[di],sp ;save sp}
$26/$89/$6D/$02/ {mov es:[di+2],bp ;save bp}
$E8/$00/$00/ {call null ;push IP onto stack}
{null:}
$58/ {pop ax ;pop into ax}
$05/$0C/$00/ {add ax,12 ;point to "next:"}
$26/$89/$45/$04/ {mov es:[di+4],ax ;save jump offset}
$26/$8C/$4D/$06); {mov es:[di+6],cs ;save jump segment}
{next:}Как мне ответили 2 года назад на форуме Lazarus, в левой части находится ассемблерный код для древних 8086 процессоров, и чтобы данный участок обработать их Фри Паскалем - нужно правую часть в комментариях правильно для компилятора оформить. Но как я ни пытался вчера всё это оформить...
И так:
И сяк:
Компиляция тупо не идёт.
Я понимаю, что в разделе Interface перед Implementation я много чего не описал, но основная проблема не в этом, а в том, что компилятор в принципе этот ассемблерный код не может обработать. А сам я язык ассемблера не знаю от слова совсем (можно, конечно, в теории и на его обучение потратить пару лет в свободное от работы время, но так же как и с Паскалем я на данный момент не вижу в этом смысла, да и до книг Дональда Кнута "Искусство программирования" в качестве развлечений пока ещё не добрался).
Единственным 32-битным компилятором, который обработал 8086 ассемблерный код, был TMT Pascal:
http://old-dos.ru/files/file_1410.html (по ссылке, к примеру, есть неурезанная Multitarget-версия 2002 года с ключиком)
Но и тот в одном из юнитов сначала ругнулся на неправильно проставленную границу Implementation, а потом ещё на что-то (понятно, ведь юниты писались под 5 версию Borland / Turbo Паскаля, а тогда и синтаксис у языка, судя по всему, был ещё другой).
Тут ещё как-то кто-то писал:
http://freepascal.ru/forum/viewtopic.php?f=1&t=42669#p154385Насколько я помню древнюю историю Паскаля ( :-D ) TurboProfessional принципиально не работал ни в Windows режиме, ни в досовском защищённом.
Там и правда, ассемблера хоть одним местом ешь. И весь этот ассемблер рассчитан на:
- 16 бит;
- адресацию база+смещение.
поэтому что там может понадобиться в сегодняшнем программировании - тайна покрытая мраком. Тем более, что нынешний FPC, по сравнению с TurboPascal, позволяет делать очень много не лазая в какие-то сторонние коды.На самом деле, как я выяснил, в 16-битном оригинальном Borland Pascal всё работало. На 32 битах такая программа работала. Проблема остро встала только при переходе на 64 бита, и, в принципе, она решаема там методом использования каких-либо DOSBox'ов, но всё равно костылями пользоваться неохота, учитывая ещё, что ТЫЖПРОГРАММИСТ!
И вчера я вспомнил, что 2 года назад я в итоге плюнул на это безблагодатное дело и начал искать другие варианты решения из своей внезапно из ниоткуда возникшей проблемы.
На том же сайте, где я в своё время вышел на PingAnsi, скачал решение под названием EmulAnsi:
https://pascal.sources.ru/ansi/index.htmНикакие модули из библиотеки "Turbo Professional" от TurboPower Software для EmulAnsi не требовались, т.е. всё работало со штатными средствами 7-го Борланда Никлаусовича Паскаля. Но им и ANSI-музыку (честно говоря, даже не знаю, что это) нельзя было завести, только графику. Мне, в принципе, только реализация графики в консоле и требовалась.
Единственный косячок там состоит в том, что автор EmulAnsi в своём модуле забыл указать глобальную переменную Coul2, которую впоследствии использовал в коде, но после её указания всё отлично компилируется и работает.
Также всё отлично скомпилировалось и в 32-битном Virtual Pascal (правда после предварительного скармливания ему Crt'хи и ряда запрашиваемых модулей из папок программы "vp21\sourse\rtl" и "vp21\sourse\w32").
После запуска программа на непонятном языке просила указать путь к ANSI-файлу, графику из которого требовалось отобразить.
После небольшой редактуры участка кода:
BEGIN
ClrScr;
Write ('Nom du fichier Ansi … afficher : ');
ReadLn (PathName);
Assign (Fichier, PathName);
{$I-}
Reset (Fichier);
{$I+}
If IOResult = 0 Then
BEGIN
While not Eof (Fichier) do
BEGIN
Read (Fichier, Caract);
PrintChar_Ans (Caract);
END;
Close (Fichier);
END
Else Writeln ('Fichier non trouv‚.');
END.
На (зелёным обозначил изменения)...
BEGIN
ClrScr;
PathName:='C:\vp21\progs\emulansi\LOGO.ANS';Assign (Fichier, PathName);
{$I-}
Reset (Fichier);
{$I+}
If IOResult = 0 Then
BEGIN
While not Eof (Fichier) do
BEGIN
Read (Fichier, Caract);
PrintChar_Ans (Caract);
END;
readln; // чтобы программа не закрывалась сразу же после запуска
Close (Fichier);
END
END.
Итоговая программа сразу же отобразила графику в консоли из указанного файла.
И только вчера до меня дошло, что как EmulAnsi, так и PingAnsi ранее (позже это подтвердилось) отображали графику из внешнего файла, а не из самой себя (типа зашитую графику в саму программку). Поэтому поставленная задача вроде как и была решена, а вроде как и нет (или не совсем).
Посему у меня после написания данного лонгрида осталось 2 острых вопроса:
1. Возможно ли в принципе зашить в саму программу подобного рода графику, используя ANSI-символы (ASCII-гра́фику же народ через те же wrtiteln'ы туда засовывает)?2. Есть ли у кого-нибудь инвайт на Хабру, дабы поделиться там своей кулстори по сабжу?Честно, после вчерашнего дня я вновь встал на черту очередного выгорания любимым делом. Ещё пару таких денёчков и я точно буду готов посвятить свою оставшуюся жизнь уже выпечке пиццы в соседнем ТЦ.
С другой стороны, хочу как можно скорее расквитаться с этим древним злом под названием PASCAL и продвинуться уже куда-нибудь на уровень повыше.
Весь оставшийся код для СВОЕЙ желаемой программы у меня уже написан, даже сделана привязка к системному времени. Осталась вот единственная наполовину нерешённая задача.