"Эх вот в школе я такую программулину написал, на Паскале" - бывают такие мысли, особенно у тех кто учился, скажем, в 90е. И даже находятся порой эти старые программы на старом диске. Но если запустить их ещё в DosBox у себя на машине можно - то как показать-похвастаться другим, в интернете?

Возьмём эмулятор js-dos (им старые игры в браузере запускают) - и поколдуем над ним, чтобы можно было своими паскальными-бейсиковыми программулинами делиться всем на радость.

Пользоваться этой поделкой вы сможете не вникая в подробности! Есть страничка для подготовки ссылок с программами - хоть сразу делитесь в комментариях :) А для тех кому захочется по аналогии и другие компиляторы-интерпретаторы подключить - будет немножко пояснений что и как там сделано - чтобы форкнув код на гитхабе вы могли быстро внести нужные изменения.

Как этим пользоваться?

Нам нужна страничка в которой выполняется, например, старый добрый Quick Basic 1.1 или Turbo Pascal 5.5 (до кучи я добавил Matlab 3.05) - притом такая, чтобы ей можно было каким-то образом передать программу для загрузки и выполнения.

А как именно "передать"? Мы же по ссылке делиться будем - ну значит в параметре ссылки передавать либо целиком программу (если она небольшая) - либо урл откуда её можно взять (главное чтобы cross-origin работал).

Если хотите сразу посмотреть на результат, то вот пожалуйста:

Игра "Escape" по мотивам Ж.Арсака

В открывшемся окне вы увидите довольно знакомый интерфейс редактора Турбо-Паскаля - нажмите Ctrl-F9 (как встарь) или Alt-R и Enter - и программа должна запуститься. Есть и возможность автозапуска - дальше увидим.

Зелёное - выход. Синее - игрок. Красно-жёлтое - падающие фрагменты.
Зелёное - выход. Синее - игрок. Красно-жёлтое - падающие фрагменты.

В этой игре нужно (в пошаговом режиме) пробраться через прямоугольный зал к выходу (в левом верхнем углу) - стараясь не попасть под падающие сверху блоки. Поскольку падают они рандомно, особой стратегии тут нет. Главное долго не плутать.

Если хотите попробовать "приготовить" ссылку с собственным кодом - зайдите на центральную страничку https://rodiongork.github.io/dosprog/ - внизу есть поле для ввода программы - скопируйте туда например следующую чепуху (отредактируйте по вкусу):

program demo;

uses crt;

begin
  clrscr;
  gotoxy(33, 13);
  writeln('I am a beautiful message!');
  readln;
end.

После чего убедитесь что выбран нужный язык (паскаль в данном случае) и нажмите кнопку. Под ней появится ссылка - по этой ссылке будет открываться ваша программа, можете попробовать. Если щёлкнете чекбокс "Autorun" - программа не откроется в редакторе а сразу запустится на выполнение.

Поскольку программа может быть длинной, можно также разместить код программы где-нибудь в интернете (например на github pages как с примером выше) - и вместо самого кода использовать ссылку на него. Кроме возможности таким образом сделать большую программу с довольно короткой ссылкой это ещё и позволит редактировать впоследствии код не меняя самой ссылки.

Теперь когда в общих чертах понятно - давайте посмотрим подробности - они понадобятся если вы захотите аналогичным образом какую-то другую среду разработки запустить.

Создадим страницу с компилятором / интерпретатором

Эта часть очень простая. На сайте js-dos.com мы находим раздел Getting Started - и в нём готовый пример. В двух словах идея такая:

  • js-dos в себе содержит эмулятор (DosBox) скомпилированный в JavaScript

  • поэтому на странице вы только создаёте зону где отображать "экран" (например, во всю страницу) и вставляете ссылки на таблицу стилей и на js-файл. Их можно либо использовать либо прямо с сайта js-dos (как в примере), либо скачать себе.

  • создаёте "бандл" с приложением - в общем-то zip-архив, в котором лежит кроме того и конфиг для DosBox

Первые два пункта развернутых пояснений не требуют, на третий взглянем чуть подробнее.

Во-первых, как "приготовить" бандл? Если у вас уже есть zip-архив с нужной досовской программой - останется только добавить конфиг.

Если архива пока нет, удобнее всего (по-моему) DosBox запустить на локальной машине, в него скачать все что надо, установить-настроить нужную программулину - а потом её уже сархивировать в бандл. И опять же добавить конфиг.

Что там за конфиг? Обычный конфиг для DosBox - для начала можно взять тот что в примере (с диггером). В целом всевозможные настройки понятно описаны - самая важная для нас часть - в конце. Там перечислены несколько команд (на манер autoexec) для того чтобы загрузить нужную нам программу после старта.

Конфиг укладывается в подкаталог .jsdos с именем dosbox.conf - типичное его окончание может выглядеть так:

[autoexec]
mount c .
c:
c:\tp\turbo.exe

Сам код для запуска бандла в странице выглядит тоже достаточно понятно - имеет смысл только добавить параметр автозапуска (иначе отображается шестерёнка которую нужно кликнуть чтобы DosBox запустился):

    Dos(document.getElementById("dos"), {
        url: "./my_bundle.zip",
        autoStart: true,
    });

Подразумевая что бандл с именем my_bundle.zip лежит в той же директории что и сама страница - и что элемент для отображения рабочего окна программы имеет id="dos".

Если вы это проделаете - и запустите хотя бы локально (нужно использовать хоть простейший локальный сервер, типа busybox - или python3 -m http.server) - то скорее всего с радостью убедитесь что программа запускается (ну, если все сделано правильно). И выдаёт картинку, например как в заголовке статьи. Или вот с матлабом вариант:

в матлабе всё работает только графика в досбоксе почему-то плохо отображается
в матлабе всё работает только графика в досбоксе почему-то плохо отображается

Но как подгрузить текст программы?

Вот здесь и начинаются пляски с бубном.

То что код программы мы в простейшем случае кодируем в base64 и добавляем к ссылке как значение параметра ?p=... - это уже наверное понятно. Написать кусочек javascript чтобы взять урл текущей страницы и вытащить оттуда этот код - несложно:

  let ppos = location.href.indexOf('?p=');
  let data = atob(location.href.substring(ppos+3));

Это конечно упрощённый способ - мы не парсим параметры всерьёз, а просто находим нужный фрагмент с названием параметра (p), считая что параметр только один. Если вам понадобится больше - поправьте эту часть. После этого atob расшифровывает base64 кодировку - и в общем текст нашей программы в переменной data.

Здесь сразу добавим возможность вытащить программу из интернета, если вместо неё оказался урл:

  if (data.substring(0, 5) == 'https') {
      let req = new XMLHttpRequest();
      req.open('GET', data, false);
      req.send(null);
      data = (req.status === 200) ? req.responseText : '{error loading file}';
  }

Здесь мы используем синхронный XMLHttpRequest - это не лучший вариант, но для минимизации примера пусть так останется. Как видите, в случае ошибки мы вместо результата запроса хотим показать что сообщение о неуспешной загрузке.

Важный момент - конечно сервер с которого вы грузите программу должен отдавать её с соответствующим заголовком, позволяющим загрузку в другие страницы, например:
Access-Control-Allow-Origin: *

В частности github-pages так делают, а gist.github.com нет. Если вы захотите подгружать код с гист-гитхаб или с pastebin - скорее всего вам придётся что-то химичить.

Но это лишь пол-дела, даже наверное треть. Надо загрузить программу в наш DosBox.

Тут проблема. Конфигурация js-dos (в джаваскрипте, не в конфиге dosbox-а) позволяет указать например параметр initFs и dosboxConf - первый из них позволяет добавить файлы в файловую систему, второй помогает скорректировать например строку запуска нашей программы. К сожалению оба они не работают если используется "бандл".

На эту тему даже заведён issue в гитхабе js-dos-а. Там есть мелкие технические сложности, но возможно когда-то это будет улучшено. Пока же приходится мудрить.

В параметре onEvent можно указать функцию которая будет вызвана когда эмулятор уже загружен и в неё будет передан параметр - объект CommandInterface - у него в частности есть методы для работы с файловой системой.

К сожалению когда эмулятор уже загружен, вроде бы уже поздно что-то грузить в файловую систему :) Во-первых наша "IDE" уже будет запущена - да и DosBox не видит новых файлов пока не выполнишь команду rescan. Однако давайте есть слона по частям. Здесь оставим кусочек джаваскриптового кода который "забросит" нашу программу в файловую систему - а в следующем разделе разберемся как её использовать.

Dos(document.getElementById("dos"), {
    url: "./my_bundle.zip",
    autoStart: true,
    onEvent: (event, ci) => {
        if (event === "ci-ready") {
              // здесь подготовим переменную "data" как показано выше
              // и теперь грузим:
              ci.fsWriteFile(dosprog.fname, new TextEncoder().encode(data));
        }
    }
});

BAT-файл для подгрузки программы

Итак, забросить файл в файловую систему эмулятора мы смогли, однако:

  • он её не видит пока не сделаем rescan

  • поскольку всё работает асинхронно, в эмуляторе редактор может запуститься раньше чем программа будет загружена

Чтобы не дожидаться пока какую-то фичу для этого запилят в js-dos (а может и есть какой-то ход до которого я не додумался) - можно просто написать старый-добрый досовский BAT-файл (аналог юниксовых shell-скриптов, только проще).

Мы будем запускать этот файл из autoexec-секции в конце dosbox.conf - а что же будет в самом файле?

Будем делать rescan, проверять, появилась ли программа на диске, и если появилась то запускаем IDE - а иначе повторяем операцию в цикле.

Один нюанс - нам нужна и возможность загружаться "начисто" - если никакой программы не передано. Ну что ж, будем в этом случае сигнализировать "добрасывая" в файловую систему пустой файл с именем, например, nofile.pas - в общем, BAT-файл получится такой:

:repeat
rescan
if exist prg.pas goto withfile
if exist nofile.pas goto nofile
goto repeat

:withfile
\tp\turbo.exe prg.pas
goto done

:nofile
\tp\turbo.exe

:done

Как видите, циклы, goto и переходы по меткам - логика простая. Если появился файл prg.pas - выскакиваем из цикла и переходим к запуску с файлом. Если появился файл nofile.pas - тоже выскакиваем и переходим к запуску без файла.

В javascript есть отдельная строчка чтобы этот nofile передать - но не будем на этом сейчас останавливаться, просто посмотрите в коде по необходимости.

Автозапуск

В качестве приятной фичи желательно добавить возможность автозапуска. В случае с бейсиком это осуществляется добавлением ключа /run в командную строку. С турбо-паскалём я такого ключа не припомню, поэтому надо запустить компилятор tp.exe а потом запустить скомпилированную программу. В случае матлаба файл и так запускается интерпретатором (отдельный вопрос - может это неудобно).

В общем всё это легко добавить в BAT-файл. Осталось только придумать как передать что мы хотим "автозапустить" программу. Я не придумал ничего лучше кроме как использовать ещё одно отдельное имя файла программы (например auto.pas) и по нему выбирать какой именно режим запуска требуется.

Ну а чтобы на стороне джаваскрипта выбрать нужен ли автозапуск, условимся что это сигнализируется именем параметра в ссылке. Если это буква P большая - значит нужен. Если p маленькая - значит нет. Конечно это вы можете переделать на свой вкус.

На упомянутой "главной" страничке форма для создания ссылок имеет чекбокс чтобы отметить автозапуск.

Заключение

Код выложен на гитхаб - можно пользоваться как есть, можно склонировать себе и добавить любимые компиляторы и т.п.

Для удобства общий джаваскриптовый код отвечающий за запуск вынесен в файл dosprog.js - так что если захотите добавить например Turbo C 2.0, то вам нужны следующие шаги:

  • форкаем или клонируем репозиторий

  • копируем файл tp55.html например в tc20.html - и в нём редактируем заголовок, названия файлов (вместо prg.pas например prg.c и так далее) - а также имя бандла

  • создаём бандл с таким именем как задали выше, в него положим кроме Turbo C также поправленный конфиг dosbox.conf и модифицированный BAT-файл (в общем-то тоже меняются имена файлов и все).

Можно было бы сделать удобнее если использовать серверную часть для хранения пользовательских программ (собственный "pastebin"), сделать пользовательские аккаунты и так далее. Но неясно насколько эта смешная поделка актуальна - кроме того тогда уже не будет так легко добавить собственные компиляторы и т.п.

Хорошо бы иметь возможность экспортировать отредактированный файл. Ведь из досбокса с экрана ничего не скопируешь. Такая возможность добавлена - если открыть консоль разработчика (Developer Console) в браузере и выполнить во вкладке console функцию в духе:

getFile("PRG.PAS")

то в консоль же будет выдана наша программа, уже закодированная в base64. Можно было бы сделать какой-то всплывающий диалог - но пока не придумал куда прилепить кнопку для его вызова. Главное - заметьте что здесь регистр имени файла различается - а в досе нет. Чаще всего файлы будут созданы с большими буквами в имени.

Переводы строк. Это больная тема - по умолчанию нередко может оказаться что они не "досовские" - и приложения типа турбо-паскаля отобразят все в одну строку. Для этого в код загрузки добавлена небольшая "автоподстановка":

data = data.replace(/(?<!=r)\n/g, '\r\n');

Не пугайтесь её - но если будут какие-то проблемы с переводами строк - вы теперь знаете где можно поправить.

Вот и всё! Можете пробовать и делиться своими историческими чудо-программами в комментариях :)

P.S. данную статью не следует рассматривать как руководство по JavaScript - автор мало знаком с ним и с фронтенд-разработкой - так что тут наверняка есть что улучшать!

Комментарии (11)


  1. NeoCode
    12.11.2024 06:10

    Насчет полезности запуска в браузере не знаю, а вообще интересно было бы собрать такой dosbox (или может быть virtualbox/vmware?) дистрибутив, включающий в себя множество программ тех времен. Что-то вроде виртуального рабочего места типичного айтишника 90-х. Не только с играми (хотя это наверное было бы интересно большинству) но и с другим софтом, включая средства разработки.


    1. RodionGork Автор
      12.11.2024 06:10

      ну вот это всё вы можете сделать склонировав данную репу :)

      • добавляете нужные вам программулины в каталог example

      • на главной странице делаете список ссылок для запуска этих программулин в эмуляторе

      • и всё :)

      что касается других средств разработки - ну это чуть более телодвижений требует, как описано в статье

      основная-то мысль в том что если "собрать такой досбокс" у себя на компе то шарить его неудобно (rar-архивчиком по почте что ли рассылать)


      1. NeoCode
        12.11.2024 06:10

        У меня компьютер появился в 98 году (и первой системой была win95), я почти не застал ту эпоху, но все равно испытываю к ней некую ностальгию. И софта для dos у меня было немного - Нортон коммандер, Borland C/C++ 3.1 и несколько игрушек. Но первый опыт программирования был именно для dos.

        Поэтому мне было бы интересно именно скачать что-то готовое, некую коллекционную систему, собранную сообществом при участии большого числа людей. А для распространения можно использовать обычный сайт, торренты, можно даже выпускать дистрибутивы с какой-то периодичностью, вносить добавления и улучшения))


        1. RodionGork Автор
          12.11.2024 06:10

          У меня кстати тоже в 98 но это был 386 так что даже win 3.11 я лишь через несколько месяцев донёс на дискетках и с большим любопытством поставил не понимая "зачем оно".

          Про коллекционную систему - мысль понятна. Просто не очень ясно как лучше сделать. В виде здоровенных образов на торрентов - этим мало кто пользоваться будет. А делать что-то объёмное ради нескольких скачиваний в месяц наверное всем лень.

          Мой вариант улучшает доступность - но прям таки единого большого образа тут не создаётся (каждая программулина в общем-то в своём изолированном "бандле") - т.к. иначе пришлось бы этот мега-образ прокачивать при каждой загрузке.

          В общем небольшая дилемма. Ну да хоть с чего-нибудь начнём.


        1. goldexer
          12.11.2024 06:10

          Так же примерно было, в тот же временной период. Каким же крутым тогда казался Visual Basic 6.0 (аж шесть дисков, включая FoxPro, MSDN...), со своим «просто нарисуй кнопку и пиши код в обработчике». Это после игрушечного ТП и длиннющих простыней создания окон для всего и вся на С. Delphi тогда радовал очень, я установил его на школьный комп и доспорился с учителем, что мне разрешили писать в нём. Когда у других на черном экране школьное «введите А, введите Б», тут уже было окошко с текстовыми полями, иконочками, проверкой ввода, подсказками и вообще было переносимым экзешником - кайф вселенского масштаба. Нам всё приелось и сейчас уже мало что из новинок может порадовать, как тогда


          1. RodionGork Автор
            12.11.2024 06:10

            о да, Дельфи это фурор был :) не знаю почему VB6 на его фоне менее заметен был, он как будто даже удобнее был

            а в 2011 году я устроился переписывать кучку разрозненных приложений с дельфи - на одно энтерпрайзовое джаванское - так исплевался от дельфи-то уже :)


  1. AlxndrPakhomov
    12.11.2024 06:10

    Круто ! спасибо автору =))) давно не видел интерфесов таких.


  1. rezdm
    12.11.2024 06:10

    Как тут не вспомнить "Трубо Паскакаль"


    1. weedjy
      12.11.2024 06:10

      Трупопаскаль:)


    1. RodionGork Автор
      12.11.2024 06:10

      Ещё были споры насильников с напаскальниками


      1. hkm2
        12.11.2024 06:10

        С пасквилянтами же. А еще были asmатики...