Собираем Opus
Opus — это кодовое имя, которое разработчики компании Microsoft дали пакету Microsoft Word for Windows v1.1a. Давайте скомпилируем его из исходного кода и посмотрим, удастся ли его запустить!
1. Введение
В этой статье задокументирован процесс получения исходного кода и его превращения в работающее приложение для Windows. Компилятор и инструменты разработки запускаются в операционной системе MS-DOS, потому что в 1989 году ещё не существовало инструментов разработки, работающих в Windows.
Примечание: в этой статье я буду часто упоминать DOS. Под этим обозначением подразумевается Microsoft MS-DOS, хотя бОльшая часть информации также применима к IBM PC-DOS и большинству других разновидностей DOS.
Если вы новичок в пользовании операционной системой DOS, то рекомендую повторять мои действия в копии Microsoft MS-DOS v6.22, версии DOS от июня 1994 года (последней выпущенной версии), содержащей все необходимые нам инструменты (об единственном исключении я расскажу ниже).
2. История вопроса
Разработка текстового процессора под названием Microsoft Word for DOS была начата Ричардом Броди и другими авторами в 1982 году. Ричарда наняли из Xerox Parc, поскольку он был знаком с футуристичным на то время текстовым процессором Bravo.
Впервые Word for DOS был выпущен в 1983 году и поставлялся в комплекте с одной из ранних версий MS-DOS. В нём использовалась графика (примитивная) и поддерживалась работа с мышью, но сама программа получила противоречивые отзывы.
Word v2.0 for DOS был выпущен в 1985 году, он поддерживал EGA-графику и имел функцию проверки правописания.
Word v3.0 for DOS выпустили в 1986 году, приложение поддерживало графику Hercules и расширенный набор принтеров.
Word v4.0 for DOS был выпущен в 1987 году, он поддерживал VGA-графику и имел как тестовый, так и графический режимы.
Word v5.0 for DOS и OS/2 стал 16-битным приложением.
В выпущенном в 1989 году обновлении до Word v5.5 появились окна и меню в стиле Windows/Mac, он стал предшественником Word for Windows, который был выпущен в том же году.
Разработка первого текстового WYSIWYG*-процессора для Microsoft Windows была завершена примерно в 1988-1989 гг, эта версия теперь выложена на сайт Музея компьютерной истории (Computer History Museum, CHM).
*WYSIWYG = What You See Is What You Get
Подробнее прочитать об истории и скачать исходный код из Музея компьютерной истории можно здесь:
https://computerhistory.org/blog/microsoft-word-for-windows-1-1a-source-code/
3. Могу ли я скомпилировать этот код?
Да! Но как? Можно воспользоваться винтажным PC или относительно современным компьютером, который может загружаться в legacy-режиме BIOS, или же сконфигурировать гипервизор для запуска виртуального PC. Все необходимые инструменты находятся в дампе исходного кода по ссылке выше. Все они работают в DOS, поэтому давайте разберёмся, как всё это должно работать.
Для демонстрации я буду использовать VMware Fusion на Mac, но вы можете воспользоваться любым подходящим старым оборудованием или гипервизором, которые способны запускать MS-DOS. После установки DOS необходимо проверить, сколько есть свободной памяти. Для этого
необходимо в общих чертах понимать, как DOS «видит» оборудование. Так как компилятору, похоже, требуется расширенная память (expanded memory), я расскажу, как обеспечивается доступ к этому типу памяти и как сконфигурировать DOS, чтобы эта память была доступна компилятору.
Кроме того, набор файлов довольно объёмен (для DOS-приложения), поэтому рекомендую упростить себе жизнь, создав образ CD-ROM с исходными файлами, чтобы их можно было разом скопировать на DOS-машину. Однако чтобы CD-ROM работал в DOS, также требуются драйверы устройства, поэтому ниже я расскажу и об этом.
Исходный код интересен тем, что проприетарный компилятор требует компьютер с процессором не ниже 386 и 4 МБ ОЗУ. Это превосходит характеристики многих PC того времени и определённо считалось бы «high end», ведь тогда большинство компьютеров имело максимум 1 МБ ОЗУ и всего 640 КБ из них были доступны для типичных DOS-приложений. Из этого объёма приличный объём занимает сама DOS, а приложения используют то, что осталось. Итак, сколько же памяти есть у нашей машины? Как добавить ей ещё памяти? Подробнее об этом ниже.
4. История процессоров Intel
Причина, по которой DOS требует управления памятью, тесно связана с историей процессора, на которой эта ОС должна была работать. Так как многие из ранних программ создавались на ассемблере, операционная система DOS была очень тесно интегрирована с процессором, на котором она работала. В результате она унаследовала ограничения этих процессоров, а они накладывали странные требования, ведь каждое новое поколение процессоров должно было поддерживать кодовую базу всех предшествующих.
В 1979 году 8-битные процессоры Intel 8086/8088 могли адресовать 1024 КБ, или 1 МБ ОЗУ (8-битная шина данных, 16-битные регистры памяти).
В 1982 году 16-битный процессор Intel 80286 мог адресовать до 16 МБ ОЗУ (16-битная шина данных, 24-битное адресное пространство*).
В 1985 году 32-битный Intel 80386 (и более поздний 486) мог (теоретически) адресовать до 4096 МБ, или 4 ГБ ОЗУ**
Современные 64-битные процессоры имеют 40-битные, 52-битные и 64-битные архитектуры адресуемой памяти, поэтому могут поддерживать от 1 ТБ до 4 ПБ ОЗУ!
Примечание*: 24-битное адресное пространство эквивалентно 2 в степени 24 × 1 байт = 16 777 216 байт, или 16 МБ.
Примечание**: 32-битное адресное пространство — это 2 в степени 32 x 1 байт = 4 294 967 296 байт, или 4 ГБ, но в PC с процессорами 386 из-за ограничений материнских плат и огромной стоимости ОЗУ в то время обычно устанавливали гораздо меньше 1 ГБ.
История DOS и Windows переполнена проблемами, созданными обратной совместимостью и ограничениями управления памятью, на которые влияла архитектура первых процессоров Intel.
5. Типы памяти DOS
Существует пять областей памяти, адресуемых операционной системой DOS. Каждая из них адресуется при помощи одного или двух драйверов устройств, вызываемых в CONFIG.SYS во время загрузки. HIMEM.SYS обеспечивает доступ к Extended Memory, а EMM386.EXE — к Expanded Memory. Вот краткое описание этих типов памяти.
Conventional Memory (основная память): память от 0 до 640 КБ (или 651 264 байт), также называемая Lower Memory Area (LMA)
Upper Memory Area (верхняя память): UMA — это память от 640 КБ до 1024 КБ (1 МБ), также называемая Upper Memory Blocks (UMB)
Extended Memory Specification (дополнительная память): XMS — это адреса памяти от 1 МБ до 64 МБ, но эта спецификация также описывает UMA, потому что DOS не имеет доступа к UMA без поддержки от HIMEM.SYS
Expanded Memory Specification (расширенная память): EMS использует кадр страницы в 64 КБ, определённый в Upper Memory, для предоставления доступа к памяти выше 1 МБ. DOS может использовать одновременно XMS и EMS, когда задан параметр AUTO, или отключить её, если EMM386.EXE загружается с параметром NOEMS. EMM386 и другие менеджеры памяти эмулируют expanded memory в области extended memory — всё совершенно понятно и ни капли не запутанно!
High Memory Area: HMA — это 64 КБ, расположенные сразу выше 1 МБ, в которые DOS может загружать себя во время загрузки при помощи параметра DOS=HIGH файла CONFIG.SYS.
В основной памяти (Conventional memory) располагаются олдскульные DOS-приложения. Они могут использовать память только из 0-640 КБ, и поскольку часть этого объёма занимает сама DOS, во время исполнения они могут иметь доступ к менее чем 500 КБ ОЗУ. Часто это ограничивает приложения, запускаемые в так называемом «real mode», иными словами, 16-битные приложения, ограниченные основной памятью (conventional memory). Real mode (реальный режим) называется так, потому что в приложении адресуемой памяти сопоставляются реальные адреса памяти.
Это было вполне нормальным только в течение нескольких лет, а позже 640 КБ превратились в ограничивающий фактор для более сложных приложений, то есть игр! Больше памяти требовалось и для новых Windows-приложений, поэтому появилась Extended Memory Specification (XMS). Память выше 1 МБ стала адресуемой 16-битными программами. Эта спецификация появилась в процессорах 286, которые реализовали protected mode (защищённый режим) для получения доступа к памяти выше этих ограничений DOS, но также поддерживали доступ к основной памяти в real mode, при необходимости переключаясь между режимами.
6. Установка DOS
Мы можем использовать настоящие гибкие диски и USB-привод гибких дисков, создать образы гибких дисков из физических гибких дисков или скачать образы гибких дисков с сайтов наподобие WinWorld.
Физическая или виртуальная машина должна иметь не менее 4 МБ и не более 32 МБ ОЗУ, а также жёсткий диск объёмом не более 512 МБ с единственным разделом FAT16. Если жёсткий диск физически больше 512 МБ, ограничьте первый раздел максимальным размером, который может адресовать ваша версия DOS. Ради совместимости ограничьте этот первый раздел 512 МБ или меньшим объёмом.
Если машина имеет описанные выше минимальные характеристики, загрузитесь с первой дискеты DOS. В версиях выше 5.0 запустится установщик. Следуйте его инструкциям и пока выберите все значения по умолчанию. В следующей статье мы поэкспериментируем с опциями установки. Если вы не увидели диалога с предложением установки, то на первой дискете часто можно найти файл INSTALL.EXE или настроить всё самостоятельно, разбив жёсткий диск вручную. См. ниже раздел «Делаем жёсткий диск загрузочным».
7. Делаем жёсткий диск загрузочным
Если на предыдущем этапе вы загрузились с гибкого диска, но у вас ещё нет жёсткого диска с возможностью доступа или копия DOS не содержит установщика, то можно установить её вручную.
Запустите с гибкого диска FDISK и просмотрите существующую структуру разделов, выбрав пункт 4 и нажав Enter.
Если раздел существует, то дам должно быть написано, что в файловой системе FAT16 есть до 511 МБ, а в столбце состояния должно быть указано, что раздел активен (символ «A» в столбце Status).
Если это не так, то создадим раздел; вернитесь в основное меню, нажав Escape.
Выберите пункт 1 и нажмите Enter. Введите 1 и снова нажмите Enter для создания нового основного раздела (Primary Partition). Программа пожалуется, что там уже есть существующий раздел. Если вы достаточно смелы, то можете удалить его и создать новый, или просто использовать уже имеющийся.
После этого вернитесь в основное меню, выберите пункт 2 и сделайте новый раздел активным, а затем выйдите из FDISK. В командной строке DOS нам нужно отформатировать диск, чтобы сделать этот новый раздел читаемым, а также перенесли систему загрузки DOS на диск при помощи ключа "/s" команды format
command. Ключ "/v" запросит имя нового тома.
format c: /s /v
Следуйте подсказкам и дайте тому допустимое имя из 11 символов. При этому создастся загрузочный диск, но перед перезагрузкой создайте папку DOS
md C:DOS
… а затем скопируйте все файлы с гибкого диска в C:DOS…
copy A:. C:DOS.
Перед перезапуском создайте стандартные CONFIG.SYS и AUTOEXEC.BAT. Нет редактора файлов? Не проблема, введите следующие команды, чтобы скопировать текст из консоли в файл под названием config.sys:
C:
CD
copy con CONFIG.SYS
files=30
buffers=10
Затем нажмите Ctrl-Z, чтобы выйти и сохранить выводимые данные. Данные команды скопируют содержимое консоли (CON) на диск. Теперь у нас есть файл CONFIG.SYS, находящийся в корневом каталоге диска C:.
Проделаем то же самое для создания файла AUTOEXEC.BAT:
copy con AUTOEXEC.BAT
@echo off
prompt $p$g
ver
И нажмите Ctrl-Z. Отлично, теперь можно перезагрузиться.
8. Конфигурируем DOS
Обычно MS-DOS конфигурируется при помощи двух файлов, считываемых DOS во время загрузки (если не считать самого COMMAND.COM). Это следующие файлы (в порядке, в котором к ним выполняется доступ):
CONFIG.SYS содержит список драйверов устройств и опций конфигурации, загружаемых во время загрузки; он находится в корневом каталоге загрузочного диска.
AUTOEXEC.BAT запускается после загрузки машины и после загрузки драйверов устройств в CONFIG.SYS. Оба этих файла конфигурации должны находиться в корневом каталоге загрузочного диска; A: в случае, когда система загружается с гибкого диска, или C: для систем с жёстким диском.
DOS вполне может нормально загружаться без этих файлов, но большинство приложений добавляет в них опции конфигурации, чтобы они могли работать или чтобы оптимизировать их выполнение. Последние версии DOS также пытаются конфигурировать себя самостоятельно, внося изменения в эти файлы в процессе установки.
Запуска HIMEM.SYS во время загрузки недостаточно, нам нужно сконфигурировать EMM386.EXE или сторонний менеджер расширенной памяти (Expanded Memory Manager). Подробнее мы расскажем об этом позже. История архитектур процессоров Intel связана с управлением памятью, поэтому нам нужно в этом разобраться.
Чтобы сконфигурировать доступ к дополнительной памяти (extended memory), мы отредактируем C:CONFIG.SYS при помощи редактора DOS:
DOSEDIT CONFIG.SYS
Если файл не найден, то просто сохраните новый файл под именем C:CONFIG.SYS. Добавьте
в первую строку следующий текст:
DEVICE=C:DOSHIMEM.SYS
В CONFIG.SYS уже могут быть и другие записи, но добавьте это именно в первую строку. Закончив, нажмите Alt-F, чтобы перейти в меню File, и нажмите S, чтобы сохранить, а затем снова нажмите Alt-F и X, чтобы выйти. Перезагрузитесь, вы должны увидеть тест памяти, а затем командную строку DOS: «C>».
Введите в командную строку команду MEM, чтобы увидеть, сколько памяти теперь доступно DOS-приложениям:
Как видите, у DOS есть для приложений всего 571 КБ основной памяти (conventional memory), однако почти 30 МБ дополнительной памяти (Extended Memory, XMS) и нет расширенной памяти (Expanded Memory, EMS).
Причина в том, что я выделил этой виртуальной машине 32 МБ ОЗУ, и на вашем оборудовании/ВМ ситуация может быть другой.
Похоже, для запуска компилятора нам нужен доступ к Expanded Memory (EMS), но как его реализовать? Именно здесь нам пригодится EMM386.EXE; этот драйвер памяти поставляется с поздними версиями DOS для поддержки Microsoft Windows и других DOS-приложений, требующих большого объёма памяти, в том числе и некоторых игр под DOS.
9. Управление памятью в DOS
Если мы загружаем драйвер управления памятью через CONFIG.SYS, то можем посмотреть, сколько ОЗУ он выделяет. В начале файла config.sys есть две следующих строки. Там могут быть и другие записи, но эти первые две строки должны находиться в начале файла и быть именно в таком порядке.
DEVICE=C:DOSHIMEM.SYS
DEVICE=C:DOSEMM386.EXE
DOS=HIGH
FILES=30
Перезагрузитесь и снова запустите MEM.
Сравнив этот скриншот с предыдущим, мы видим, что обнаружена такая же основная память, но максимальный размер программы, которую мы можем запустить, составляет теперь 612 КБ (больше 571 КБ), потому что мы загрузили DOS в верхнюю память (upper memory) командой DOS=HIGH. Также мы эмулировали Expanded Memory (EMS) в диапазоне Extended Memory (XMS).
Если запустить DOS-команду MSD, то получим следующую схему распределения памяти:
На ней показана смежная область памяти, занятая расширенной памятью (Expanded Memory). Каждый из символов P обозначает 1 килобайт, поэтому каждая строка обозначает 16 КБ пространства, которое можно распределить. Границы, не равные 16 КБ, не нужно распределять, потому что они не являются смежными.
Для компиляции Word мне было достаточно основной памяти (conventional memory) и EMS, однако у вас показатели свободной памяти могут быть другими, это зависит от используемой версии DOS и её конфигурации.
Если вам нужно больше основной и/или расширенной памяти, то попробуйте использовать сторонние менеджеры расширенной памяти наподобие QEMM, JEMM или UMBPCI, которые используют меньше основной памяти, в то же время обеспечивая совместимую расширенную память.
Завершаем конфигурацию
Некоторым приложениям требуется временное пространство для хранения файлов, дампа памяти и т.п., поэтому давайте создадим командой MD (make directory) папку для временных файлов, а затем при помощи команды SET укажем на неё переменной окружения TEMP.
MD C:TEMP
Затем сделаем так, чтобы она задавалась во время загрузки, добавив её в autoexec.bat. Введите:
DOSEDIT AUTOEXEC.BAT
И добавьте в конец файла следующее:
SET TEMP=C:TEMP
Нажмите Alt-F, S для сохранения и Alt-F, X для выхода из редактора.
10. Компилируем OPUS
OPUS — это кодовое имя Microsoft Word for Windows v1.1a. Предоставленный исходный код содержит код на C и ассемблере, проприетарный компилятор, компоновщик, проприетарные инструменты патчинга, примечания разработчиков и документацию. В этих файлах есть всё необходимое для создания 16-битного исполняемого файла, который без модификации сможет запускаться в Windows v2.x, Windows v3.x и OS/2 v2.x.
Для компилирования этого программного обеспечения нам понадобится не менее 612 КБ основной памяти, а также не менее 4 МБ Expanded Memory, поэтому вам может потребоваться изучение DOS Configuration Guide для конфигурирования DOS под эти условия.
Я создал guest в VMware Fusion с MS-DOS v6.22 в качестве гостевой операционной системы, а также сконфигурировал DOS VDM под Windows XP; всё это заработало в обоих окружениях.
Этап 1: скачивание
Исходный код доступен на сайте Музея компьютерной истории:
https://computerhistory.org/blog/microsoft-word-for-windows-1-1a-source-code/
Он позволит вам скомпилировать Microsoft Word v1.1a, но у компоновщика часто происходят сбои, если только не запускать отдельно op1.bat из папки сборки. Я пока не разобрался, почему это происходит под DOS… однако под Windows XP мы можем эмулировать не только командную строку DOS, но также расширенную и дополнительную память, и всё работает! Но как это сделать?
Этап 2: распаковка файлов zip
Хост-машина может работать под Windows, Linux или MacOS. Я использовал Mac, но это неважно. Распакуйте файлы zip и создайте файл образа CD-ROM ISO, содержащий все файлы.
См. руководство по созданию ISO.
Этап 3: копирование файлов
Переносим исходный код, компилятор, компоновщик и документацию на DOS-машину/ВМ через CD-ROM.
Компилятор должен запускаться с загрузочного диска, так что поместим всё это в C:SRC. Так как объём данных значительно больше, чем один или два гибких диска, я создал образ CD-ROM, который смонтировал в ВМ. Если у вас есть физическое оборудование, то вы можете сделать то же самое или изучить DOS Configuration Guide, чтобы узнать, как получить доступ к CD-ROM из DOS или через физический диск, или через файл образа ISO.
Этап 4: создание папки BUILD
Примечание: часть этих шагов взята из комметариев на форумах Beta Archive (https://www.betaarchive.com/forum/).
Создадим новую папку BUILD для каждой сборки и изменим fast.ini, чтобы он указывал на эту новую сборку.
MD SRCOPUSBUILD1
Этап 5: изменения в конфигурации компилятора
Прежде чем приложение скомпилируется, нужно изменить два файла, чтобы они соответствовали вашему окружению. БОльшую часть этих параметров я взял из поста на форуме betaarchive. Перейдите в папку инструментов:
CD SRCOPUSTOOLS
Создайте резервную копию fast.ini
COPY FAST.INI FASTOLD.INI
Откройте FAST.INI следующим образом:
DOSEDIT SRCOPUSTOOLSFAST.INI
Затем измените содержимое, чтобы оно выглядело так:
OPFL=+ls
NAM=WINWORD
EXE_DIR=C:SRCOPUSPROGRAM
BUILD=C:SRCOPUSBUILD1
OPUS=C:SRCOPUS
WORDTECH=C:SRCOPUSWORDTECH
USER=Richard Lewis or Your Name
MMEM=
NOAPPLOADER=
Сохраните файл с помощью Alt-F, S и выйдите с помощью Alt-F, X.
Откройте mo1.bat, чтобы он указывал на вашу структуру папок, а не на сетевые диски, которые были указаны в исходном коде:
DOSEDIT SRCOPUSTOOLSMO1.BAT
И измените следующие строки, чтобы они соответствовали путям к файлам:
set PATH=C:SRCOPUSTOOLStoolsdos;C:SRCOPUSTOOLStools
set LIB=C:SRCOPUSTOOLSlib
set INCLUDE=C:SRCOPUSTOOLS;=C:SRCOPUSTOOLSwordtech;=C:SRCOPUSTOOLSlib;=C:SRCOPUSTOOLSasm
Измените все остальные пути, чтобы они соответствовали вашему пути, они могут иметь имена дисков, отличающиеся от C:; поэтому измените их, чтобы они начинались с =C:SRCOPUS
Этап 6: компиляция!
Измените папку инструментов, если ещё этого не сделали:
CD SRCOPUSTOOLS
Скомпилируйте BUILD1 с помощью изменённого файла конфигурации INI:
MAKEOPUS @FAST.INI
Нет ошибок!? Объектные файлы будут помещены в C:SRCOPUSBUILD1 и при удачной компоновке файлы EXE будут находиться в C:SRCOPUSPROGRAM.
Если вы выполняли компиляцию при помощи DOS, то всё должно выглядеть так:
CSL Compiler — успешная компиляция кода и патчинг
Если вы использовали XP (инструкции по конфигурированию будут в следующем посте), то успешное завершение будет выглядеть так:
Если возникают ошибки памяти, то, возможно, не хватает основной или расширенной памяти, вы пропустили этап присвоения TEMP= в AUTOEXEC.BAT, или этап присвоения FILES= в CONFIG.SYS, или в FAST2.INI присутствуют синтаксические ошибки. Проверьте ещё раз эти параметры.
Если вам не удаётся устранить ошибки памяти, то есть два решения.
- Попробовать запустить mo1.bat из папки BUILD. Если это сработает, то проблема может заключаться в достаточной основной памяти, но недостаточной непрерывной расширенной памяти.
- Попробуйте выполнить тот же процесс сборки в DOS VDM под Windows XP — похоже, для каждого типа памяти ОЗУ выделяется правильно, однако получаемый EXE невозможно запустить под Windows XP; он запустится на машине с Windows v2 или v3. См. Windows XP configuration Guide.
Примечание: после выполнения компиляции файл mo1.bat сбросит переменную окружения PATH и в неё больше не будет входить папка DOS. Это означает, что некоторые команды DOS больше не смогут работать, если вы не будете указывать полный путь к папке DOS для каждой команды. Или добавьте C:DOS в переменную PATH в файле mo1.bat, или просто перезагрузитесь для восстановления предыдущих параметров.
11. Запускаем Opus
Если вкратце, то просто скопируйте все файлы из C:SRCOPUSPROGRAM на машину с Windows v2.x или v3.x, а затем запустите WINWORD.EXE. Вот и всё!
В дальнейшем я соберу набор дискет, который будет выполнять правильную установку на основе этого кода, но пока для тестирования этого достаточно.
Под Windows 2.x программа должна выглядеть так
…и тот же код, запущенный в Windows 3.x:
На правах рекламы
Наша компания предлагает серверы с предустановленным Windows. Не экономим на железе — только брендовое оборудование и одни из лучших дата-центров в России и ЕС. Поспешите проверить.
Автор: Mikhail