## Формат файла .MSF версии 1.3 (Memory state file)
для эмулятора БК 0010(01) и БК 0011(М)

Файлы данного формата обычно хранят в себе полный слепок всей памяти БК на момент сохранения, состояние регистров, уменьшенную копию экрана, а также любую другую необходимую для последующего восстановления информацию. Формат является бинарным, и представляет собой теговую структуру. Каждый тег представляет собой заголовок, и данные некоторого типа. Теги могут располагаться в любом порядке (кроме первого заголовочного тега MSF_FILE_HEADER), а также быть вложенными один в другой. Теоретически любой из тегов может быть пропущен, а также могут присутствовать теги, которые незнакомы эмулятору данной версии, и будут без проблем пропущены. Таким образом теоретически осуществляется совместимость форматов разных версий в обе стороны.

### Формат заголовочного тега:

struct MSF_FILE_HEADER

{

| DWORD | type; | - тип файла всегда равен (STATE_ID == 65536)
| DWORD | version; | - версия файла: 10 – 1.0, 15 – 1.5, 20 – 2.0, и т.д. В настоящее время версия файла 1.3 (13) и более ранние версии не поддерживаются.
| DWORD | configuration; | - конфигурация компьютера:

1. БК 0010(01) с БЕЙСИКом “Вильнюс 1986”
2. БК 0010(01) с блоком МСТД
3. БК 0010(01) с дополнительным блоком ОЗУ 32Кб
4. БК 0010(01) с контроллером НГМД
5. БК 0011М
6. БК 0011М с контроллером НГМД
7. БК 0011
8. БК 0011М с контроллером НГМД

};

Далее следуют теги для конкретной конфигурации.

### Формат тега:

struct MSF_BLOCK_HEADER

{

| DWORD | type; | - тип тега
| DWORD | length; | - длина в файле, занимаемая им вместе с заголовком

};

За тегом сразу следуют данные. Теги бывают следующих типов:

Имя | Тип | Длина (байт) | Комментарий
--- | --- | --- | ---
MSF_BLOCKTYPE_UNKNOWN | -1 | 8 и более | неизвестный блок. Просто пустая болванка, сделан на всякий случай
MSF_BLOCKTYPE_BASEMEMORY | 0 | 8 + 64 Кб | блок памяти основного 64 Кбайтного пространства. Вся память с 0 – 0200000, то, что в ней находится в текущий момент. В версии 1.0 вместе с системными регистрами, в версии 1.1 системные регистры сохраняются в отдельном блоке
MSF_BLOCKTYPE_CPU_REGISTERS | 1 | 8 + 18 | Регистры процессора: R0 – R5, SP, PC, PSW
MSF_BLOCKTYPE_PREVIEW | 2 |  | Малая копия экрана. См. описание ниже
MSF_BLOCKTYPE_10EXT16 | 3 | 8 + 24Кб | Блок расширенной памяти КНГМД А16М 16К ОЗУ + 8К ПЗУ.
MSF_BLOCKTYPE_10EXT32 | 4 | 8 + 32Кб | Страницы расширенной памяти 32К. Располагается с адресов 0120000 – 140000
MSF_BLOCKTYPE_11EXT64 | 5 |  | Страницы расширенной памяти 64К для БК11М. Формат не определён. Устарел. Зарезервирован.
MSF_BLOCKTYPE_PORT_REGS | 6 | 8 + 30 | (Начиная с версии 1.1) Блок размещения системных регистров 177660, 177662, 177664, 177700-177716
MSF_BLOCKTYPE_MEMMAP | 7 | 8 + 16*20 + 16 | (Начиная с версии 1.1) Карта памяти, в которой обозначено, какие страницы и банки памяти куда подключены.
MSF_BLOCKTYPE_BASEMEMORY11M | 8 | 8 + 0700000 | (Начиная с версии 1.1) Весь блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ
MSF_BLOCKTYPE_MEMORY_SMK512 | 9 | 8 + (512-16)*1024 | (Начиная с версии 1.1) Блок памяти ОЗУ контроллера СМК-512. Т.к. 16 Кб уже сохраняется в блоках №3 и №8, то здесь сохраняется 512 Кб-16 Кб
MSF_BLOCKTYPE_CONFIG | 10 | 8 + заранее не известно | (Начиная с версии 1.2) Структура g_config. (Начиная с версии 1.3) текстовый файл конфигурации со всеми текущими настройками.
MSF_BLOCKTYPE_WAVE | 200 | 8 + заранее не известно | Используется в tap файлах для хранения контента.

### Формат тега MSF_BLOCKTYPE_BASEMEMORY (Тип 0) “Блок памяти основного 64 Кбайтного пространства”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Далее следуют 64 Кбайта основной памяти в диапазоне адресов 0 – 200000.

### Формат тега MSF_BLOCKTYPE_CPU_REGISTERS (Тип 1) “Регистры процессора”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

struct MSF_CPU_REGISTERS

{

| WORD | r0; | - регистр общего назначения R0
| WORD | r1; | - регистр общего назначения R1
| WORD | r2; | - регистр общего назначения R2
| WORD | r3; | - регистр общего назначения R3
| WORD | r4; | - регистр общего назначения R4
| WORD | r5; | - регистр общего назначения R5
| WORD | sp; | - регистр стека SP
| WORD | pc; | - регистр команд PC
| WORD | psw; | - слово состояния процессора PSW

};

### Формат тега MSF_BLOCKTYPE_PREVIEW (Тип 2) “Малая копия экрана”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

struct BITMAPINFOHEADER

{

| DWORD | biSize = 40; | - размер структуры BITMAPINFOHEADER
| DWORD | biWidth = 200; | - всегда 200
| DWORD | biHeight = 200; | - всегда 200
| WORD | biPlanes = 1; | - всегда 1 (1 плоскость);
| WORD | biBitCount = 32; | - кол-во бит на пиксель (любое допустимое кол-во бит)
| DWORD | biCompression = 0; | - всегда 0 (без компрессии)
| DWORD | biSizeImage = 0; | - не используется
| DWORD | biXPelsPerMeter = 0; | - не используется
| DWORD | biYPelsPerMeter = 0; | - не используется
| DWORD | biClrUsed = 0; | - не используется
| DWORD | biClrImportant = 0; | - не используется

};

Далее следует непосредственно массив бит картинки. Картинка записывается в перевёрнутом по вертикали виде, где каждая строка выровнена на границу 4-х байт.

### Формат тега MSF_BLOCKTYPE_10EXT16 (Тип 3) “Блок расширенной памяти КНГМД А16М 16К ОЗУ + 8К ПЗУ”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Для версии 1.0:

DWORD bBasic - флаг, включено ли ПЗУ (0 – нет, 1 – да)

Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 1 (обычно ПЗУ 24К бейсика)

Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 0 (обычно ДОЗУ 16К + ПЗУ НГМД 8К)

Начиная с версии 1.1:

Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 0 (обычно ДОЗУ 16К + ПЗУ НГМД 8К)

### Формат тега MSF_BLOCKTYPE_10EXT32 (Тип 4) “Страницы расширенной памяти 32К”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

DWORD nPage - номер подключенной страницы 0 – 3

Далее следуют 32 Кбайта дополнительной памяти

### Формат тега MSF_BLOCKTYPE_PORT_REGS (Тип 6) “Системные регистры”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

struct MSF_PORT_REGS

{

| WORD | p0177660; | - регистр состояния клавиатуры
| WORD | p0177662_in; | - регистр данных клавиатуры
| WORD | p0177662_out; | - регистр палитр, буфера экрана и таймер по вектору 100 (только на БК11(М))
| WORD | p0177664; | - регистр смещения
| WORD | p0177700; | - регистр режима
| WORD | p0177702; | - регистр адреса прерывания
| WORD | p0177704; | - регистр ошибки
| WORD | p0177706; | - регистр установки таймера
| WORD | p0177710; | - регистр счётчика таймера
| WORD | p0177712; | - регистр управления таймером
| WORD | p0177714_in; | - входной регистр порта ввода вывода
| WORD | p0177714_out; | - выходной регистр порта ввода вывода
| WORD | p0177716_in; | - регистр порта по чтению (чтение с МФ или с линии)
| WORD | p0177716_out_tap; | - регистр порта по записи (запись на МФ или в линию)
| WORD | p0177716_out_mem; | - регистр порта по записи (установка страниц памяти, на БК11(М))

};

### Формат тега MSF_BLOCKTYPE_MEMMAP (Тип 7) “Карта памяти”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Далее следует массив из 16 элементов следующей структуры, которые отвечают за сегменты адресного пространства размером 4 Кб, последний сегмент служит для хранения режимов работы контроллера АльтПро:

struct BKMEMBank_Type

{

| BOOL | bReadable; | - флаг, указывающий что память доступна для чтения
| BOOL | bWritable; | - флаг, указывающий что память доступна для записи
| int | nBank; | - номер банка памяти 4 kb
| int | nPage; | - страница памяти БК11 == nBank >> 2
| int | nOffset; | - смещение в массиве == nBank << 12

};

И затем следует один элемент следующей структуры, который сохраняет информацию о типе FDD контроллера и режимах работы контроллеров АльтПро.

struct ConfBKModel_Type

{

| DWORD | nBKModel; | - модель БК, для конфигуратора
| DWORD | nAltProMemBank; | - код подключения страницы памяти контроллера для записи
| DWORD | nExtCodes; | - доп. коды контроллера, такие как 10 - подключение бейсика и 4 - блокировка регистров 177130 и 177132 по чтению (для простоты ПЗУ бейсика включается только в режиме 020. В остальных режимах не имеет смысла, хотя на реальной железке технически возможно)
| DWORD | nAltProMode; | - код режима контроллера

};

### Формат тега MSF_BLOCKTYPE_BASEMEMORY11M (Тип 8) “Блок памяти БК 11М, включая
доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Далее следует массив размером 0700000 байт содержащий всю указанную память.

### Формат тега MSF_BLOCKTYPE_MEMORY_SMK512 (Тип 9) “Блок памяти ОЗУ контроллера СМК-512”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Далее следует массив размером 512 - 16 Кбайт содержащий всю указанную память (первые 16 Кбайт входят в блок MSF_BLOCKTYPE_BASEMEMORY11M).

### Формат тега MSF_BLOCKTYPE_CONFIG (Тип 10) “Конфигурация”:

struct MSF_BLOCK_HEADER

{

| DWORD | type; |
| DWORD | length; |

};

Довольно сложный блок. Сперва формируется массив в памяти содержащий содержимое ini файла конфигурации. Определяется его размер, и затем сохраняется в виде бинарного массива. Размер переменный.

Последовательности тегов для конфигураций создаваемых эмулятором версии 3.x. Хотя порядок тегов может быть произвольным, в реальных файлах MSF теги идут именно так:

### 1 – БК 0010(01) с БЕЙСИКом “Вильнюс 1986”

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
0 | Основная память 64К

### 2 – БК 0010(01) с блоком МСТД

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
0 | Основная память 64К

### 3 – БК 0010(01) с дополнительным блоком ОЗУ 32Кб

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
0 | Основная память 64К
4 | Страницы расширенной памяти 32К

### 4 – БК 0010(01) со стандартным КНГМД и контроллером A16M с ДОЗУ 16К:

(дело в том, что стандартный КНГМД строится на основе А16М с отключенным функционалом переключения страниц и жёстко закреплённым стандартным режимом. А весь код обработки один.)

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
0 | Основная память 64К
3 | Блок расширенной памяти 16К + 8К КНГМД

### 5 – БК 0010(01) с контроллером СМК-512 с ДОЗУ 512К

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
0 | Основная память 64К
3 | Блок расширенной памяти 16К + 8К КНГМД
9 | Блок памяти ОЗУ контроллера СМК-512

### 6,7,8 – БК 0011М без FDD, со стандартным FDD, с контроллером A16M с ДОЗУ 16К

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
8 | Весь блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ

### 9 – БК 0011М с контроллером СМК-512 с ДОЗУ 512К

Тип | Название
--- | ---
Hdr | Заголовочный тег
2 | Preview
10 | Config
1 | Регистры процессора
6 | Системные регистры и порты
7 | Карта памяти
8 | Весь блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ
9 | Блок памяти ОЗУ контроллера СМК-512