Формат файла .MSF версии 1.9 (Memory state file)
для эмулятора БК 0010(01)
и БК 0011(М)
Файлы данного формата обычно хранят в себе полный слепок всей памяти БК на момент сохранения, состояние регистров, уменьшенную копию экрана, а также любую другую необходимую для последующего восстановления информацию. Формат является бинарным, и представляет собой теговую структуру. Каждый тег представляет собой заголовок, и данные некоторого типа. Теги могут располагаться в любом порядке (кроме первого заголовочного тега MSF_FILE_HEADER), а также быть вложенными один в другой (но на практике оказалось, что в этом нет необходимости). Теоретически любой из тегов может быть пропущен, а также могут присутствовать теги, которые незнакомы эмулятору данной версии, и будут без проблем пропущены. Таким образом теоретически осуществляется совместимость форматов разных версий в обе стороны.
Но практически - нет. MSF младших версий не поддерживается из-за того, что там нет критически важных блоков, без которых невозможно восстановить состояние эмулятора. И соответственно, невозможна дальнейшая эмуляция.
Формат заголовочного тега:
struct MSF_FILE_HEADER
{
uint32_t | type; | // тип файла всегда равен (STATE_ID == 65536) | |
uint32_t | version; | // версия файла: 10 – 1.0, 15 – 1.5, 20 – 2.0, и т.д. В настоящее время версия файла 1.9 (19) и более ранние версии не поддерживаются. | |
uint32_t | configuration; | // конфигурация компьютера:
|
Далее следуют теги с данными для конкретной конфигурации.
Формат тега:
struct MSF_BLOCK_HEADER
{
uint32_t | type; | // тип тега | |
uint32_t | 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 |
8 + переменное количество |
Малая копия экрана. См. описание ниже |
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*24 + 12 |
(Начиная с версии 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. |
MSF_BLOCKTYPE_FRAMEDATA |
11 |
8 + 4*8 + 8*3 |
В версии 1.9 размер такой. Блок содержит состояние ВЕ-таймера, состояние хода луча ЭЛТ, состояние текущего вычислительного фрейма эмуляции. |
MSF_BLOCKTYPE_WAVE |
200 |
8 + заранее не известно |
Используется в tap файлах для хранения контента. |
Формат тега MSF_BLOCKTYPE_BASEMEMORY (Тип 0) "Блок памяти основного 64 Кбайтного пространства":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Далее следуют 64 Кбайта основной памяти в диапазоне адресов 0 – 200000.
Формат тега MSF_BLOCKTYPE_CPU_REGISTERS (Тип 1) "Регистры процессора":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
struct MSF_CPU_REGISTERS
{
uint16_t | r0; | // регистр общего назначения R0 | |
uint16_t | r1; | // регистр общего назначения R1 | |
uint16_t | r2; | // регистр общего назначения R2 | |
uint16_t | r3; | // регистр общего назначения R3 | |
uint16_t | r4; | // регистр общего назначения R4 | |
uint16_t | r5; | // регистр общего назначения R5 | |
uint16_t | sp; | // регистр стека SP | |
uint16_t | pc; | // регистр команд PC | |
uint16_t | psw; | // слово состояния процессора PSW |
Формат тега MSF_BLOCKTYPE_PREVIEW (Тип 2) "Малая копия экрана":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
struct BITMAPINFOHEADER
{
uint32_t | biSize = 40; | // размер структуры BITMAPINFOHEADER | |
uint32_t | biWidth = 256; | // всегда 256 | |
uint32_t | biHeight = 256; | // всегда 256 | |
uint16_t | biPlanes = 1; | // всегда 1 (1 плоскость); | |
uint16_t | biBitCount = 32; | // кол-во бит на пиксель (любое допустимое кол-во бит) | |
uint32_t | biCompression = 0; | // всегда 0 (без компрессии) | |
uint32_t | biSizeImage = 0; | // не используется | |
uint32_t | biXPelsPerMeter = 0; | // не используется | |
uint32_t | biYPelsPerMeter = 0; | // не используется | |
uint32_t | biClrUsed = 0; | // не используется | |
uint32_t | biClrImportant = 0; | // не используется |
Далее следует непосредственно массив бит картинки. Картинка записывается в перевёрнутом по вертикали виде, где каждая строка выровнена на границу 4-х байт.
Формат тега MSF_BLOCKTYPE_10EXT16 (Тип 3) "Блок расширенной памяти КНГМД А16М 16К ОЗУ + 8К ПЗУ":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Для версии 1.0:
uint32_t bBasic - флаг, включено ли ПЗУ (0 – нет, 1 – да)
Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 1 (обычно ПЗУ 24К бейсика)
Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 0 (обычно ДОЗУ 16К + ПЗУ НГМД 8К)
Начиная с версии 1.1:
Далее следуют 24 Кбайта памяти при установленном флаге bBasic в 0 (обычно ДОЗУ 16К + ПЗУ НГМД 8К), без флага bBasic.
Формат тега MSF_BLOCKTYPE_10EXT32 (Тип 4) "Страницы расширенной памяти 32К":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
uint32_t nPage - номер подключенной страницы 0 – 3
Далее следуют 32 Кбайта дополнительной памяти
Формат тега MSF_BLOCKTYPE_PORT_REGS (Тип 6) "Системные регистры":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
struct MSF_PORT_REGS
{
uint16_t | p0177660; | // регистр состояния клавиатуры | |
uint16_t | p0177662_in; | // регистр данных клавиатуры | |
uint16_t | p0177662_out; | // регистр палитр, буфера экрана и таймер по вектору 100 (только на БК11(М)) | |
uint16_t | p0177664; | // регистр смещения | |
uint16_t | p0177700; | // регистр режима | |
uint16_t | p0177702; | // регистр адреса прерывания | |
uint16_t | p0177704; | // регистр ошибки | |
uint16_t | p0177706; | // регистр установки таймера | |
uint16_t | p0177710; | // регистр счётчика таймера | |
uint16_t | p0177712; | // регистр управления таймером | |
uint16_t | p0177714_in; | // входной регистр порта ввода вывода | |
uint16_t | p0177714_out; | // выходной регистр порта ввода вывода | |
uint16_t | p0177716_in; | // регистр порта по чтению (чтение с МФ или с линии) | |
uint16_t | p0177716_out_tap; | // регистр порта по записи (запись на МФ или в линию) | |
uint16_t | p0177716_out_mem; | // регистр порта по записи (установка страниц памяти, на БК11(М)) |
Формат тега MSF_BLOCKTYPE_MEMMAP (Тип 7) "Карта памяти":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Далее следует массив из 16 элементов следующей структуры, которые отвечают за сегменты адресного пространства размером 4 Кб, последний сегмент служит для хранения режимов работы контроллера АльтПро:
struct BKMEMBank_t
{
BOOL | bReadable; | // флаг, указывающий что память доступна для чтения | |
BOOL | bWritable; | // флаг, указывающий что память доступна для записи | |
uint32_t | nBank; | // номер банка памяти 4 kb | |
uint32_t | nPage; | // страница памяти БК11 == nBank >> 2 | |
uint32_t | nOffset; | // смещение в массиве == nBank << 12 | |
uint32_t | nTimingCorrection; | // значение корректировки тайминга при обращении к памяти, которая не управляется ВП1-037 (ПЗУ или ОЗУ СМК) |
И затем следует один элемент следующей структуры, который сохраняет информацию о типе FDD контроллера и режимах работы контроллеров АльтПро.
struct ConfBKModel_t
{
uint32_t | nAltProMemBank; | // код подключения страницы памяти контроллера для записи | |
uint16_t | nExtCodes; | // доп. коды контроллера, такие как 10 - подключение бейсика и 4 - блокировка регистров 177130 и 177132 по чтению (для простоты ПЗУ бейсика включается только в режиме 020. В остальных режимах не имеет смысла, хотя на реальной железке технически возможно) | |
uint16_t | nROMPresent; | // битовая маска присутствия ПЗУ БК на своих местах. | |
uint32_t | nAltProMode; | // код режима контроллера |
Формат тега MSF_BLOCKTYPE_BASEMEMORY11M (Тип 8) "Блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Далее следует массив размером 0700000 байт содержащий всю указанную память.
Формат тега MSF_BLOCKTYPE_MEMORY_SMK512 (Тип 9) "Блок памяти ОЗУ контроллера СМК-512":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Далее следует массив размером 512 - 16 Кбайт содержащий всю указанную память (первые 16 Кбайт входят в блок MSF_BLOCKTYPE_BASEMEMORY11M).
Формат тега MSF_BLOCKTYPE_CONFIG (Тип 10) "Конфигурация":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Довольно сложный блок. Сперва формируется массив в памяти содержащий содержимое ini файла конфигурации. Определяется его размер, и затем сохраняется в виде бинарного массива. Размер переменный.
Формат тега MSF_BLOCKTYPE_FRAMEDATA (Тип 11) "Параметры фрейма":
struct MSF_BLOCK_HEADER
{
uint32_t | type; | ||
uint32_t | length; |
Далее идёт следующая структура данных.
struct MSF_FRAMEDATA
{
// состояние ВЕ таймера | |||
int | nTimerSpeed; | // текущее значение счётчика ВЕ таймера | |
int | nTimerDiv; | // текущий делитель ВЕ таймера | |
// состояние экрана | |||
int | nVideoAddress; | // видео адрес, младшие 6 бит - счётчик строк внутри строки | |
int | bHgate; | // флаг отсчёта служебных видеоциклов в строке | |
int | bVgate; | // флаг отсчёта служебных строк | |
int | nVGateCounter; | // дополнительный счётчик служебных строк | |
int | nLineCounter; | // счётчик видео строк | |
// состояние фрейма (значения внутренних счётчиков фрейма) | |||
int | nCPUTicks; | ||
double | fMediaTicks; | ||
double | fMemoryTicks; | ||
double | fFDDTicks; |
Последовательности тегов для конфигураций создаваемых эмулятором версии 3.x. Хотя порядок тегов может быть произвольным, в реальных файлах MSF теги идут именно так:
0 – БК 0010(01) с БЕЙСИКом "Вильнюс 1986"
Тип | Название |
---|---|
Hdr |
Заголовочный тег |
2 |
Preview |
10 |
Config |
1 |
Регистры процессора |
6 |
Системные регистры и порты |
7 |
Карта памяти |
0 |
Основная память 64К |
1,17 – БК 0010(01) с блоком МСТД или БК 0010Ш
Тип | Название |
---|---|
Hdr |
Заголовочный тег |
2 |
Preview |
10 |
Config |
1 |
Регистры процессора |
6 |
Системные регистры и порты |
7 |
Карта памяти |
0 |
Основная память 64К |
2 – БК 0010(01) с дополнительным блоком ОЗУ 32Кб
Тип | Название |
---|---|
Hdr |
Заголовочный тег |
2 |
Preview |
10 |
Config |
1 |
Регистры процессора |
6 |
Системные регистры и порты |
7 |
Карта памяти |
0 |
Основная память 64К |
4 |
Страницы расширенной памяти 32К |
3,4,6 – БК 0010(01) со стандартным КНГМД (+16кБ ОЗУ), контроллером A16M с ДОЗУ 16К, контроллером НГМД+HDD Самара (+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 |
7,8,9,11,12,13,14,16 – БК 0011(М) без FDD, со стандартным FDD, с контроллером A16M с ДОЗУ 16К, с контроллером Самара
Тип | Название |
---|---|
Hdr |
Заголовочный тег |
2 |
Preview |
10 |
Config |
1 |
Регистры процессора |
6 |
Системные регистры и порты |
7 |
Карта памяти |
8 |
Весь блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ |
10,15 – БК 0011(М) с контроллером СМК-512 с ДОЗУ 512К
Тип | Название |
---|---|
Hdr |
Заголовочный тег |
2 |
Preview |
10 |
Config |
1 |
Регистры процессора |
6 |
Системные регистры и порты |
7 |
Карта памяти |
8 |
Весь блок памяти БК 11М, включая доп. ПЗУ + ПЗУ контроллера А16М и доп. ОЗУ |
9 |
Блок памяти ОЗУ контроллера СМК-512 |