Closed ammehet closed 4 years ago
Ок, сокращу К слову, u765 ещё плохо отлажен, некоторые диски могут открываться, но не читаться.
Ок, сокращу
Пропатчил, пересобрал, интересно же проверить. Выяснилось, что сократить мало, ещё и Disk-Info\r\n
искать не надо вообще: вследствие произвола основной сигнатуры у Disk-Info
нет фиксированной позиции внутри образа. Собственно, его может вообще не быть, и так иногда случается (есть пример). В документации по формату это часть большой сигнатуры, в которой значимы только первые 8 байт. В отличие от Track-Info\r\n
, который обязателен и всегда по смещению 0x100, и это проверять надо ок, всё правильно сделано.
К слову, u765 ещё плохо отлажен, некоторые диски могут открываться, но не читаться.
Да, не читаются вообще все 80-дорожечные и некоторые 40-дорожечные. У меня под рукой есть образы, работающие везде там, но не здесь. Некоторые (40 дорожек) даже бодро начинают, читают загрузчик, меняют цвета бордюра и экрана, но затем устают независимо от крыжика турбо, даже бордюрный LED с дискеткой перестаёт.
Ещё один момент. Если в диске B не примонтировано ничего, то при ресете +3 даже не определяет, что дисководов двое. А если перед ресетом примонтировать образ, то таки да, видит двоих, но читать B отказывается, даже родной формат.
Ну и чтобы два раза не вставать, при сборке под макось (High Sierra 10.13.6) такая неприятность:
Make Error at CMakeLists.txt:199 (find_package):
By not providing "FindQt5Widgets.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"Qt5Widgets", but CMake did not find one.
Чтобы победить, пришлось нагуглить и поменять в CMakeLists.txt
find_package(Qt5Widgets REQUIRED) на find_package(Qt5 COMPONENTS REQUIRED Widgets)
find_package(Qt5Network REQUIRED) на find_package(Qt5 COMPONENTS REQUIRED Network)
Ну и при по ходу паровоза нашлось немножко тоже (возможно, из-за того, что у меня SDL 1 и 2 одновременно, или хз. Для сборки приводил указатели к long, чтобы хоть как-то собралось для теста):
Xpeccy-master/src/xcore/sound.cpp:126:10: error: ordered comparison between pointer and zero ('SDL_TimerID'
(aka '_SDL_TimerID *') and 'int')
if (tid < 0) {
~~~ ^ ~
1 error generated.
Xpeccy-master/src/xgui/options/setupwin.cpp:449:39: error: no matching function for call to 'SDL_JoystickName'
ui.lePadName->setText(conf.joy.joy ? SDL_JoystickName(conf.joy.joy) : "none");
^~~~~~~~~~~~~~~~
/Library/Frameworks/SDL.framework/Headers/SDL_joystick.h:61:38: note: candidate function not viable: cannot convert argument of incomplete
type 'SDL_Joystick *' (aka '_SDL_Joystick *') to 'int' for 1st argument
extern DECLSPEC const char * SDLCALL SDL_JoystickName(int device_index);
1 error generated.
Конкретно по SDL есть ключик для cmake: -DSDL1BUILD=0 или 1, чтобы он не мешал одно с другим. У меня в debian тоже обе версии, но собирается без проблем что с одной, что с другой. Команду в CMakeLists поправил
Насчет DSK. Есть ли возможность "развернуть" загруженный образ (там, где он работает) в udi, чтобы были видны дорожки целиком, с пробелами и заголовками. сравним с тем, что получается у меня, и определим - в загрузке dsk проблема или всё же в u765.
Есть ли возможность "развернуть" загруженный образ (там, где он работает) в udi
Боюсь, такой возможности я не знаю. Если научите, сделаем. DSK и так сам по себе не совсем плоский формат с дорожками и хитровыпендренными последовательностями секторов. Я недавно весной собаку надкусил по этому поводу по взрослому, могу рассказать подробно с примерами, но надо предметно, иначе многабукаф.
Внутри своего эмулятора я разворачиваю загруженные диски в полные образы дорожек - по 6250 байт - с пробелами, маркерами дорожки/заголовка/данных и полями данных заголовка/сектора. Если где-то делается что-то подобное, то для меня самый простой выхлоп для анализа (даже не udi) - сохранить эти развернутые образы в файл по порядку (дорожка 0 голова 0, дорожка 0 голова 1, дорожка 1 голова 0, итд). А сам dsk не так и сложен.
С помощью некой магии удалось сделать udi. Не знаю, насколько он работоспособный, открыть ничем не получилось. А также слегка настораживает размер файла – он получился меньше оригинального dsk.
Там действительно какая-то магия. На корректный udi по содержанию не похоже. Для 80-дорожечных 2-сторонних дисков он должен быть 1125620 байт ЗЫ:я больше склонен винить эмуляцию u765, чем загрузку dsk
Там действительно какая-то магия.
Магии нет =( UDI только на TR-DOS придуман. Лайфхак с запуском виндового fuse в wine под макосью позволил сохранить неизвестно что, нативный такое не позволяет.
Внутри своего эмулятора я разворачиваю загруженные диски в полные образы дорожек - по 6250 байт - с пробелами, маркерами
Вот же я тупица сразу не сообразил, я же всю весну собаку ел на эту тему. Возможно, сейчас я открою англию, но DSK и есть UDI, образ с маркерами дорожки/сектора. Интересное в том, что все пробелы между секторами и прочие железные характеристики определяются неким набором констант, который не хранится на диске/образе, а прибит гвоздями к рому/биосу – так CP/M плодится и размножается на всё, где увидит 8 бит. Это безобразие называется XDPB и выглядит так:
typedef struct
{
WORD SPT; // Number of 128-byte records per track
BYTE BSH; // Block shift. 3 = 1k, 4 = 2k, 5 = 4k, etc (blocksize = 2^BSH * 128)
BYTE BLM; // Block mask. 7 = 1k, #0F = 2k, #1F => 4k, etc (BLM = blocksize / 128 - 1)
BYTE EXM; // Extent mask
WORD DSM; // (no. of blocks on the disc) - 1
WORD DRM; // (no. of directory entries) - 1
BYTE AL0; // Directory allocation bitmap, first byte
BYTE AL1; // Directory allocation bitmap, second byte
WORD CKS; // Checksum vector size, 0 or #8000 for a fixed disc, else No. directory entries/4, rounded up
WORD OFF; // Offset, number of reserved tracks
BYTE PSH; // Physical sector shift, 0 = 128-byte sectors, 1 = 256-byte sectors, 2 = 512-byte sectors etc (sector size = 2^PSH * 128)
BYTE PHM; // Physical sector shift, 0 = 128-byte sectors, 1 = 256-byte sectors, 3 = 512-byte sectors etc (= sector size / 128 - 1)
BYTE Sides;
BYTE TracksPerSide;
BYTE SectorsPerTrack;
BYTE FirstPhysicalSector;
WORD SectorSize;
BYTE ReadGap; // uPD765A read/write gap
BYTE FormatGap; // uPD765A format gap
BYTE MFM; // Bit 7 set = Multitrack else Single track
// Bit 6 set = MFM mode else FM mode
// Bit 5 set = Skip deleted data address mark
// Usually #60 (96) = MFM + Skip deleted data address mark
BYTE Freeze; // Set to nonzero value to force this format to be used - otherwise, attempt to determine format when a disc is logged in
} DskXDPB;
К спектруму +3 гвоздями прибиты три набора констант вот здесь. Но есть ещё некий гвоздодёр, который изредка может храниться прямо на диске/в образе и оверрайдить зашитые константы.
Расковырял половину рома от +3 и реализовал алгоритм определения форматов DSK, чтение каталога и выдёргивание файлов с метаданными от +3 или голый CP/M. Если будет полезно, с удовольствием поделюсь говнокодом на сях без плюсов.
DSK не UDI, а скорее FDI - заголовки секторов отдельно, данные отдельно, маркеров и пробелов нет
Другими словами, да, из тапки tzx не сделать. Но этого и не требуется, всё предефайнено константами в роме, их всего 3 разновидности. И (иногда, сам не встречал) нулевой дорожке. Этого достаточно, чтобы поступать как +3, а дальше он сам разберётся, нам только этого и надо.
Так, стоп. Или не разберётся, а надо наоборот научить? Я что-то упускаю
Для разворачивания дорожки мне достаточно списка заголовков секторов и их данных. Величины пробелов рассчитываются автоматом. Все байты с развёрнутых дорожек CPU получает через u765 (пока грешу на его эмуляцию). А вот какими способами и что с этими данными потом происходит, эмулятор волновать не должно.
Вернулся из отпуска и приступов лени. Немного покопал uPD765. Как минимум, нашёл, почему были ошибки при чтении со 2 стороны диска. Если есть возможность собрать из исходников, просьба потестировать. Баги всё ещё возможны
Собирается кривовато (в дебаггере при вводе адреса цифры задваиваются, а энтер и стрелки ведут себя вообще неприлично). И хоткеи – выход вместо ⌘Q почему-то по Alt-F4.
Но да, 80-дорожечные читаются, ура! Хоть и скорость совсем не турбо. Буду ждать релиз, спасибо!
Насчет глюков с клавиатурой - возможно, стоит пересобрать полностью (make clean && make), потому как я такого не наблюдаю.
Собираю так (с чистого листа): по традиции правлю
Xpeccy-master/src/xcore/sound.cpp:126:10: error: ordered comparison between pointer and zero ('SDL_TimerID'
(aka '_SDL_TimerID *') and 'int')
if (tid < 0) {
~~~ ^ ~
1 error generated.
на
if (tid == NULL) {
и
Xpeccy-master/src/xgui/options/setupwin.cpp:448:39: error: no matching function for call to 'SDL_JoystickName'
ui.lePadName->setText(conf.joy.joy ? SDL_JoystickName(conf.joy.joy) : "none");
^~~~~~~~~~~~~~~~
/Library/Frameworks/SDL.framework/Headers/SDL_joystick.h:61:38: note: candidate function not viable: cannot convert argument of incomplete
type 'SDL_Joystick *' (aka '_SDL_Joystick *') to 'int' for 1st argument
extern DECLSPEC const char * SDLCALL SDL_JoystickName(int device_index);
1 error generated.
на
//#ifdef HAVESDL2
// ui.lePadName->setText(conf.joy.joy ? SDL_JoystickName(conf.joy.joy) : "none");
//#elif HAVESDL1
ui.lePadName->setText(conf.joy.joy ? SDL_JoystickName(0) : "none");
//#endif
затем
mkdir build
cd build
cmake -DSDL1BUILD=0 -DQt5_DIR=$(brew --prefix qt5)/lib/cmake/Qt5 -L/usr/local/lib ..
make
cmake version 3.15.3 AppleClang 10.0.0.10001145 Qt 5.13.1
Ну и внешне интерфейс выглядит не так, как в официальных билдах. Видимо, версии Qt и компилятора и cmake и макоси не совпадают, как по очереди, так и все хором.
Ну и КДПВ
хоть это к теме уже не относится, но хз... нет у меня дублирования ввода
ПыСы: надо вообще это поле заблокировать для ввода
ПыСыСы: подозрение падает только на шланг. Я у себя gcc собираю.
Вот верю! У меня в официальных релизах тоже всё красивее, чем в самосборном. Видимо, где-то у нас инструменты различаются. Ну и пусть их, я подожду релиза. А если что не так, я знаю в какое спортлото жаловаться =)
Спасибо за качественный продукт и оперативную реакцию! Приятно прикоснуться к живому проекту и хоть как-то принять участие в улучшении.
ПыСы: не надо блокировать поле, иногда проще скопипастить втудой полный путь, чем шарахаться по папочкам мышкой ПыСыСы: скорее Qt, потому что интерфейс и кнопки в интерфейсе же (⌘Q vs Alt-F4). В самом эмуляторе ничего не двоится, и кнопки ок, и пиксели не разьезжаются 0 OK, 10:1 =)
Пока что закрывать не буду, вдруг по работе uPD765 ещё какие-то баги вылезут. А они вылезут...
Похоже, таки что-то вылезло. Пробовал разные ромы, в том числе те же самые, что и в fuse, пробовал с турбой и без турбы. Результат один:
(кстати, экран заметно потемнел по сравнению с прошлыми релизами. это где-то настраивается?)
Сейчас стандартный образ DSK определяется по сигнатуре
MV - CPCEMU Disk-File\r\n
Однако, на практике встречаются и другие сигнатуры, в частности,
MV - CPCEMU +3 Disk Image
,MV - CPC format Disk Image
В описании формата DSK есть пояснение:
Такая же история и с расширенным форматом. Сейчас проверяется сигнатура
EXTENDED CPC DSK File\r\n
Про это в том же источнике тоже есть пояснение:
Из-за такой мелочи некоторые образы не открываются, обидно.