samstyle / Xpeccy

Multiplatform emulator of retro computers
MIT License
71 stars 13 forks source link

+3/+3e запись на диск #72

Closed ammehet closed 4 years ago

ammehet commented 4 years ago

На 3 разных ромах, разные образы dsk. Не пишет, и на крыжики ему плевать.

image

samstyle commented 4 years ago

Потому что uPD765 ещё не научился писать. Чукча не писатель, чукча читатель. В качестве заглушки все диски считаются защищенными от записи.

samstyle commented 4 years ago

как отформатировать 2-стороннюю дискету? format "a:" размечает только 1 сторону, после cat пишет, что свободно 173Кб. и ещё, если есть возможность подсобить с образом только что отформатированной дискеты. Потому что у меня что-то не то выходит - попытка что-то записать на только что отформатированную дискету выдаёт Directory full. При этом по логам читаются с 1 по 4 сектора на дорожке 1 - по результатам форматирования они по 256 байт и заполнены нулями.

ammehet commented 4 years ago

Стандартным бейсиком – никак. Он только один формат умеет: 1 сторона, 40 дорожек, 9 секторов по 512 байт. Причём нулевая дорожка системная, туда пишется часть XDPB для нестандартных/двусторонних дисков.

Вот набросал для себя генератор образов разных dsk.zip

samstyle commented 4 years ago

есть контакт Screenshot_20200117_232354

samstyle commented 4 years ago

Проверяем. У меня почти нет опыта с +3 досом, поэтому не могу проверить все варианты. В этой сборке uPD765 умеет писать на дискеты (формат дорожки, запись обычных и удалённых секторов) и есть сохранение диска в DSK (число дорожек и сторон будет соответствовать настройкам) xpeccy_0.6.20200118_x86_64.dmg.zip

ammehet commented 4 years ago

Портит образ. 1) В заголовке образа в track offset table пишет 2-байтовые значения. Надо так. 2) Начиная с 1 дорожки дублируется блок Track-info, причём в первом дубле пустой sector information list.

samstyle commented 4 years ago

В заголовке образа в track offset table пишет 2-байтовые значения.

fpos = ftell(file); fseek(file, cpos, SEEK_SET); fputc((isize >> 8) & 0xff, file); fseek(file, fpos, SEEK_SET); cpos++;

isize тут - число байт, занятых образом дорожки (от текущего Track-Info до следующего). fputc ложит 1 байт, cpos - позиция в заголовке (начиная от 0x34 и дальше). Начиная с 1 дорожки дублируется блок Track-info, причём в первом дубле пустой sector information list лучше выложи нормальный образ и то, что создаётся эмулятором. Заодно посмотри настройки флопа в опциях. Если там 2 стороны, то и писаться будет по 2 блока Track-Info на дорожку. А т.к. одна сторона не отформатирована (наверное), то она пустая.

ammehet commented 4 years ago

Да, при совпадении настроек с форматом образа пишет корректно. Но тогда проблема в другом. Образы меняются как перчатки, и при загрузке каждого надо в соответствии с его форматом галочки ставить, иначе запорет данные. Это некошерно, надо автоматом определять формат образа и писать в него соответственно. Тем более, что количество сторон и дорожек прямо в заголовке на видном месте лежит.

samstyle commented 4 years ago

Как "автоматически определять формат образа", если это новый файл? Если ты хочешь просто переписать уже существующий файл новыми данными, не совпадающими по параметрам со старым? PS: именно данные портятся или просто появляются лишние неотформатированные дорожки, которые как бы и не нужны?

ammehet commented 4 years ago

Если образ «отформатирован», в нём есть информация о геометрии, знаем сколько сторон, дорожек и прочего. Если неформатирован, то сохранять как бы и нечего.

Когда в настройках указано 2 стороны, а образ вставлен односторонний, куда будет записываться? Добавится дорожка со 2 стороны? А существующие данные так и останутся на одной стороне? И как это отразится в фате, который оперирует 1-4 килобайтными логическими блоками и ничего не знает о сторонах, дорожках и секторах?

По моему мнению настройки количества дорожек и сторон должны применяться к «дисководу», а не к «дискете». Реальный 2-сторонний дисковод прекрасно читает и пишет односторонние дискеты без перепайки джамперов.

К TR-DOS это тоже относится, кстати. Сейчас он независимо от галочек форматирует 80T/DS, а при сохранении ругается на Wrong disk structure for TRD file.

samstyle commented 4 years ago

Внутри эмулятора нет понятия "образ dsk". там есть дисковод, который может двигать голову до 40 или до 80 дорожки и имеет 1 или 2 читающих головы. Именно эти настройки выставляются в опциях. Эмулятору глубоко пофиг, что записано в секторах - он тупо передаёт эту информацию с дисковода в контроллер дисков, а оттуда в CPU. Сторону меняет софт, который обращается к контроллеру. Соответственно, обращение к 2й голове при отсутствии оной не принесёт плодов. Любой загруженный образ дискеты разворачивается в полный образ дорожек - вместе с пробелами, синхробайтами и прочим. Если образ односторонний - он разворачивается на 1 сторону. Если 40-дорожечный - только на 40 дорожек. Параметры флоповода от этого не меняются.

ammehet commented 4 years ago

А почему бы в таком случае как раз и не менять параметры флоповода в зависимости от загруженного образа? Вот прям количество голов и дорожек из образа (42 дорожки по 10 секторов тоже достаточно популярный формат). Тогда геометрия образа точно не сломается при записи. А при создании нового образа запрашивать головы/дорожки и создавать его сразу форматированным (как RVM делает). Либо неформатированным, тогда уже по умолчанию в зависимости от эмулируемой машины + галочек в интерфейсе.

samstyle commented 4 years ago

Ну, при загрузке dsk можно менять парметры флопа под его формат. Создание чистой дискеты внутри эмулятора делает пустую, неформатированную. Сохранение в dsk и так учитывает дорожность-головастость флоповода. Только сейчас 40 дорожек, а не 42...

ammehet commented 4 years ago

Можно заложиться на то, что +3 стандартными средствами не умеет форматировать ничего, кроме 40T/SS. Но бывают и самописные нестандартные форматтеры, вот на этой дискете есть один. И RVM их корректно сохраняет. Видимо, потому что в реальном времени файл пишет.

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

samstyle commented 4 years ago

Почему бы просто не сохранять 80DS. "Как бэээ лишняя" информация в файле ведь не мешает пользоваться диском как 40SS. Потому что мне придумалось, что никто не мешает загрузить диск как 40SS, а потом отформатировать ему вторую сторону или с 40 до 80 дорожки.

ammehet commented 4 years ago

Ну какбэ одностороннюю дискету на реале тоже можно попытаться на 2 стороны отформатировать. Но так почему-то никто не делает, а все берут для этого другую двухстороннюю. Предлагаю эмулировать именно такое поведение.

Зато дискета с игрушкой или редактором каким, где есть отгрузки, например, будет попорчена и другой эмулятор, а может и сам хрессу её не прожуёт. А если дискета с защитой хитрым форматом с переменным количеством/размером/порядком следования секторов? А если оригинальный образ был 42/82 дорожки на сторону, ему отрежут лишнее при сохранении?

Если мы хотим эмулировать реальные твёрдые штуки, надо учитывать их неизменяемость. Когда дискета односторонняя, она такая и останется как ни крути. А если дисковод не дотягивает до 84 дорожки, он её не сотрёт. Не переформатировал дискету – сохраняй образ с оригинальной геометрией. Отформатировал -> новая дискета, сохраняйте как хочете.

И да, образ – это не просто контейнер для перемешанной кучки секторов, которые находятся по ID. В нём хранится инфа о геометрии, в соответствии с которой софт читает/пишет логические кластеры, ничего не зная о секторах. В стандартном формате 9х512 байт секторов на дорожку, при этом система (и фат) оперирует 1-килобайтными кластерами. То есть на дорожке не целое количество блоков информации, и в определённый момент один логический кластер (2 последовательных физических сектора), оказывается на двух разных дорожках одновременно. И если мы пришьём вторую сторону после записи такого кластера, то она неаккуратно порвёт его напополам.

P.S. +3Dos умеет в фрагментацию

samstyle commented 4 years ago

Софт знает про сектора, потому что про кластеры ничего не знает FDC. Для FDC дискета - это набор секторов с заголовками и данными. Ты обращаешься к дискете посредством прослойки в виде +3DOS (которая объединяет сектора в кластеры и обрабатывает всю информацию с диска). PS: Существуют односторонние дискеты? Именно односторонние, без доступа ко второй стороне. С отверстием для чтения только с одной стороны. PSS: Вот ты говоришь, что информация о геометрии записана на дискете. В секторах? Так она там и остаётся. Если не в секторах - софт её не прочитает. PSSS: Я эмулирую именно железяку. FDC uPD765. Посредством которого можно разметить диск до 86 дорожки и на обе стороны, если это позволяют параметры флопа. А как это будет использовать эфемерный софт - мне должно быть побоку.

ammehet commented 4 years ago

Односторонние дискеты сам не видел, но формат существует. Приходилось, скорее, обратным заниматься – дыроколить индексные отверстия и симметрично защиту от записи =)

Мне кажется некорректным сохранять одностороннюю дискету в двухстороннем формате. Потому что софт увидит вторую несуществующую сторону и будет пытаться читать пустые дорожки второй головой, тратя время. И писать, скорее всего, тоже попытается (надо проверить).

А также интересно, как такая псевдо-двухсторонняя дискета поведёт себя на одностороннем приводе.

samstyle commented 4 years ago

Софт как-то "увидит" вторую сторону двусторонней дискеты, отформатированной только с одной стороны? Мне так думается, именно в системных секторах записано, что дискета отформатирована на 1 сторону, и именно эту информацию использует софт.

ammehet commented 4 years ago

Эксперимент показал, что в формате EDSK такой образ вполне жизнеспособен. Только всё равно неправильно в заголовке диска длина псевдодорожки пишется: A size of "0" indicates an unformatted track. In this case there is no data, and no track information block for this track in the image file!

А в формате CPCEMU уже такой финт не проходит. Fuse зачем-то принудительно в CPCEMU сохраняет, в результате чего образ уже ничем не открывается, а RVM вообще падает %) Думаю, если заголовки пустых дорожек не писать, и нули в заголовке диска, то всё должно быть ок. Подумаешь, нестандартный образ =)

Скормил ему 42T/SS/10 секторов. При сохранении в 80T/DS получилась адовая мешанина, каталог сьехал, но всё читается и пишется на разных эмулях. И в конце каждой дорожки появился одинаковый мусор 144 байта. Мусор появляется только когда секторов больше 9. А если секторов больше 10, то обрезается до 10. Если бы там были данные... Всё-таки надо при открытии дисковод под образ затачивать.

image

samstyle commented 4 years ago

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

ясно-понятно. так и сделаю. а насчет состава секторов на дорожке - сканируется вся дорожка с самого начала, собираются данные о заголовках секторов. т.е не обязательно сектора пойдут в порядке 1-2-3-4. как наформатировано, в таком порядке и будут. потому что хрен знает с какими извращениями придётся столкнуться - возможно, это будут сектора 200, 202, 204, 173, 111 итд, а не 1,2,3,4...

ammehet commented 4 years ago

Сектора в заголовке дорожки указаны, и количество, и номера, и порядок следования. Но обрезать 16 секторов до 10 нехорошо. И нестандартное количество дорожек тоже. Шикарный пример – дискета из интернетов, думаю, таких полно. 42 дорожки по 10 секторов, и сектора не по порядку. А на амстрад-СРС дискетах сектора нумеруются от 0x41 и 0xC1 в зависимости от типа дискеты – с системной дорожкой или без (есть подозрение, что по нумерации секторов вычисляют XDPB.OFF без системной дорожки). И весь этот зоопарк читается и пишется на +3, надо соответствовать. Отличная идея с подстройкой дисковода под образ =)

samstyle commented 4 years ago

В каком "заголовке дорожки" указано следование секторов на ней? Я говорил про сохранение в dsk, а не про загрузку.

samstyle commented 4 years ago

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

ammehet commented 4 years ago

О! А что, так можно было? =) Это же самый правильный вариант! Видимо, и с определением количества отформатированных сторон тоже сложностей не должно возникнуть?

samstyle commented 4 years ago

Нет :) дорожки проходятся одна за другой, пишутся в файл в это же время. Так что если только определять по 2 стороне 1й дорожки. Но это не 100% вариант, извращений ведь много

samstyle commented 4 years ago

Вот, опробуй. Заодно и #58 проверь. Починил загрузку DSK - с большим GAP3 не все сектора на дорожку влезали :( xpeccy_0.6.20200118_x86_64.dmg.zip

ammehet commented 4 years ago

Настройки 80T/DS: 1) На входе пустой форматированный стандарт 40T/SS. После записи «как бы честно» получился 40T/DS с неформатированной 1 стороной. У других эмулей от этого башню сносит: Fuse тупо валится (проверил – от того, что в заголовке 2 стороны. Пропатчил на 1 и всё ок). RVM2 читает/пишет ок, но в заголовке образа почему-то 43 дорожки ставит. RVM1 читает/пишет ок, количество дорожек не правит, но безобидно нагадил после списка дорожек в заголовке диска. Понятно, что это проблемы тех эмулей, но всем не наябедничать, особенно на неподдерживаемые старые версии. 2) На входе пустой форматированный 80T/DS. Если открыть после одностороннего, то сходу не читает (спек виснет или ресетится), после ресета всё красиво ок. Надо при смене образа ресетить дисковод (или контроллер?), чтобы откалибровалось заново. Через полчаса не смог воспроизвести, всё ок. 3) На входе пустой форматированный 40T/SS/10 секторов с интерливом. Всё полностью аналогично 40T/SS.

Настройки 40T/SS: 1) 40T/SS. Всё ок. 2) 80T/DS. Не читает дальше 40 дорожек, причём обе две стороны читает. Странновато, но чтобы 80T/DS полностью читался, достаточно в настройках поставить 80T/SS. 2a) После записи превращается в 80T/SS путём отрезания половины жопы. После этого ни сам xpeccy, ни кто-либо другой уже прочитать образ не может (диагностики разные – Unsuitable media и Missing address mark с переменным успехом). А если заглянуть внутрь образа, то дорожки (80) вроде на месте, а каталог похерен. Ещё больше нехорошо. 3) 42T/SS/10. Всё полностью аналогично 40T/SS.

В общем, несмотря на соответствие стандарту образа, хорошо бы фактическое количество сторон туда в заголовок. И тогда поставил раз и навсегда 80T/DS и забыл. А то очень обломно лазить в настройки на каждый образ. А если не залезть, то не прочитаешь диск или попортишь данные. Особенно весело при копировании на одном дисководе (например, каким-нибудь копировщиком) с одностороннего на двусторонний =)

А #58 починилось, да.

samstyle commented 4 years ago

ок, попытаюсь буферизировать таблицу длин дорожек в заголовке и, если на 2 стороне так ничего и не найдено, помечать образ как односторонний и урезать эту таблицу вдвое. посмотрим, что выйдет А, и ещё. Это, конечно, фиг проверишь с реалом - если читать вторую сторону на одностороннем дисководе (именно дисководе), что прочитается? FF потому что второй головы нет, или с 1 стороны, потому что на 2 нет переключения?

ammehet commented 4 years ago

У меня в 90-х был односторонний 5" дисковод. ТРДОС вторую сторону даже не пытался читать (судя по скорости перемещения головы), хоть диск и определялся как 2-сторонний по 9 сектору. Тупо читал сказанное количество секторов с одной стороны.

В +3досе есть процедура определения типа дисковода, видимо это как-то должно учитываться.

samstyle commented 4 years ago

лол, смотри ситуёвина: есть игра BeachVolley. В dsk указано, что там 0x2A дорожек и 1 сторона, но на деле записано только 0x14 дорожек. Если оставлять остальные неформатированными, Xpeccy запишет в файле, что там 0x14 дорожек. Если форматировать - они продетектятся как существующие и запишутся в dsk в довесок к тем, что были. :)

ammehet commented 4 years ago

Эмм... А в исходном dsk и размер прям обрезан под 20 дорожек или чем-то добито до стандартного размера? Дай образ пощупать =) По моим наблюдениям башни сносить начинает от неправильно указанного количества сторон, а на дорожки вроде пофиг.

samstyle commented 4 years ago

Воть Beach Volley (Erbe).dsk.zip

ammehet commented 4 years ago

Затестил релиз. В настройках 80T/DS, проверил 40T/SS, 40T/DS, 80T/SS, 80T/DS и 42T/SS/10 секторов. Всё идеально!

Один раз словил Unsuitable media при записи, когда без ресета менял образы с разной геометрией туда-сюда. Что-то где-то недоинициализируется при смене диска, видимо. Воспроизвести снова не удалось, как и в прошлый раз.

А образ с волейболом интересный, не встречались ещё такие. Типа с «защитой» =) На нулевом треке сектора не в том порядке, как на остальных, на файлах аттрибуты установлены, поэтому часть файлов только через cat exp видно. Кодовый загрузчик напрямую из секторов, без каталога... Отличный экземпляр для потамагочить свою образную утилитку!