А смысла вообще ни в чем и ни где нет :)
Вид для печати
Добавил возможность сохранения скриншота в формате PNG (4-битный нежатый, 94011 байт), в диалоге сохранения скриншота поставил этот формат по умолчанию, также можно выбрать BMP (4-битный нежатый, 92278 байт) из списка типов.
Предваряя вопрос "зачем?" -- как-нибудь думаю сделать сохранение анимации в формате APNG.
Теперь есть три команды сохранения скриншотов:
- Screenshot -- делает PNG скриншот ничего не спрашивая, в текущей папке с именем в виде даты и времени
- Save Screenshot as -- показывает диалог сохранения, с возможностью выбора формата PNG либо BMP
- Save Animation -- показывает диалог сохранения в формат APNG, создаёт файл и включает режим сохранения скриншотов после каждого фрейма (25 раз в секунду по времени УКНЦ). Режим выключается повторным выбором той же команды, при этом закрывается файл.
Все три команды вынесены на панель инструментов (toolbar).
В APNG сохраняется без сжатия, поэтому файл быстро растёт. Формат APNG могут просматривать некоторые браузеры (Opera например), есть инструменты оптимизации и конвертации в GIF: http://littlesvr.ca/apng/
Алексей, получается что драйв без дискеты в РСН всегда возвращает установленный бит 7? с такой поправкой у меня PAF Commander загрузился, но хотелось бы точно знать -- что вообще должен возвращать драйв без дискеты в статусе.
Кроме того, есть две ситуации: 1) привод есть, не вставлена дискета 2) привода нет. Интересует что содержит РСН для этих двух случаев.
Ух ты... оказывается, этот бит влияет на подвисание в тех случаях про которые раньше говорилось -- та же третья заливка в JEK например.
И ещё вопрос по PAF Commander. При выборе устройства показывается табличка -- MZ0..7, SD0..7, HD0..7, LD0..7 -- почему по восемь устройств MZ, вроде как максимум 4? что за устройства SD, HD, LD?
- На тулбаре кнопку Screenshot сделал простой кнопкой, убрал меню -- когда нужны две остальные команды можно в меню File залезть
- Добавил фикс с флагом MOREDATA для флоппи-драйвов без дискеты -- заработал PAF Commander и другие несколько мест где подвисало
http://ukncbtl.googlecode.com/files/...beta31-exe.zip
Никита, извиняюсь за поздний ответ.
Во-первых, надо разделить понятия контроллера и дисководов. На контроллер приходит одна линия данных на чтение, на основе поступающих данных и формируется вся считываемая информация и соответственно, в зависимости от ситуации, формируются все флаги регистра состояния. А уже к этой линии на чтение может подключаться любой драйв, или вообще ничего не подключаться. Сам контроллер не знает подключен к нему дисковод или нет, не его это функция. Аналогично и со всеми входящими и выходящими линиями.
Во-вторых - при сбросе, включении питания или сбросе через бит 8 контроллер переходит в режим чтения с поиском адресного маркера. В этом режиме все поступающие на контроллер данные анализируются на поиск пропуска синхроимпульса и чтобы прочитанные данные были равны 0xA1. При этом бит готовности находится в сброшенном состоянии и никакие данные в регистр данных чтения не передаются (остаются старые данные). После того, как был найден адресный маркер, ставится бит готовности, в регистр данных передаются первые прочитанные данные (0xA1A1). И вот здесь контроллер уже входит в режим чтения данных, поступающие на его вход данные аккуратно нарезаются словами каждые 64 мкс (точнее два раза по 32 мкс, т.к. сдвиговый регистр байтовый). Естественно, реальные данные будут, если выдержаны следующие условия:
1. Выбран драйв (установлен бит 10 в регистре 177130)
2. Дисковод реально подключен (в UKNCBTL всегда).
3. Дискета находится в дисководе.
4. Включен мотор.
По этим условиям также должен осуществиться и поиск адресного маркера. Если контроллер уже находится в режиме формирования данных (нарезка), а хоть какое-то условие не выполнено, то тогда нарезка данных не прекращается, а в регистр данных поступает нуль. Т.е. после того как успешно был найден адресный маркер контроллер аккуратно формирует данные каждые 64 мкс, с установкой флага готовности.
Есть у контроллера еще одна особенность. После включения (а может и сброса) контроллер входит в режим поиска маркера, но флаг готовности все время стоит, а регистр данных чтения не меняется. В этом состоянии он находится, пока не начнут поступать данные на его вход чтения. Как только данные начнут поступать, то флаг готовности сбрасывается. начинается процесс поиска маркера.
Здесь мне кажется очень удобно сделать функцию чтения данных с дисковода. Если не выполнено одно из условий, то прочитывается ноль, а в ином случае берутся данные из соответствующего буфера дорожки. Но это данные только для сдвигового регистра. Если контроллер уже находится в режиме реального чтения данных, то тогда данные со сдвигового регистра поступают в регистр данных чтения.
Здесь все просто - в RT-11 все устройства делятся на символьные и блочные. Соответственно PAF Commander сканирует все установленные драйвера в системе и выбирает из них только блочные. А RT-11 до версии 5.6 поддерживала до восьми устройств на драйвер, при этом сколько реально устройство поддерживает - один, два или восемь - узнать невозможно. Потому и выводится все - 0 до 7.
SD - это квазидиск (по команде SET SD INFORM), что такое HD - не знаю. А LD - драйвер логических дисков, это когда на физическом диске или внутри другого логического диска можно создать файл (обычно с расширением DSK) и назначить его диском. Для этого в RT-11 есть команды MOUNT и DISMOUNT.
http://ukncbtl.googlecode.com/files/...32-Windows.zip
В этом релизе добавлена первичная поддержка скриптинга. Командой File > Run Script выбирается .JS-файл и запускается на выполнение. Язык файла -- ECMAScript, по сути это JavaScript. В тексте программы может использоваться объект emulator, имеющий методы:
emulator.reset(); -- сброс машины
emulator.run(100); -- работа эмулятора в течение 100 фреймов, каждый фрейм это 1/25 секунды
emulator.saveScreenshot("test.png"); -- сохранение скриншота в формате PNG
Пример скрипта:
Справочник по ECMAScript: http://qt-project.org/doc/qt-4.8/ecmascript.htmlКод:emulator.reset();
for (i = 0; i < 10; i++)
{
emulator.run(10);
emulator.saveScreenshot('test' + i + '.png');
}
В дальнейшем набор методов объекта emulator будет расширятся.
Тоже хотел нечто подобное добавить в свой эмуль, но меня опередили :)
Но savestate никогда никто не добавит. Зато свистелок уже тыщу внедрили. Анимацию сохранять в apng это конечно важнее.
PS: Ну да, надоел уже всем, я в курсе.
http://ukncbtl.googlecode.com/files/...33-Windows.zip
Ещё одна порция свистелок и перделок.
Собственно в этом релизе скриптовое API несколько доработано.
Напомню, было всего три метода:
emulator.reset(); -- сброс машины
emulator.run(100); -- работа эмулятора в течение 100 фреймов, каждый фрейм это 1/25 секунды
emulator.saveScreenshot("test.png"); -- сохранение скриншота в формате PNG
Дальше что добавилось:
emulator.attachCartridge(1, 'romctr_basic.bin'); -- подключение картриджа
emulator.detachCartridge(1); -- отключение картриджа
emulator.attachFloppy(0, 'sys1002.dsk'); -- подключение диска
emulator.detachFloppy(0); -- отключение диска
emulator.attachHard(1, 'WDC170inv.img'); -- подключение харда, работает только если уже подключена прошивка через emulator.attachCartridge
emulator.detachHard(1);
emulator.getUptime(); либо свойство emulator.uptime -- возвращает number количество секунд работы эмулируемой машины, по emulator.reset() сбрасывается в 0
emulator.keyScan(0153); -- нажимает клавишу (задаётся скан-код), прогон 3 фрейма, отпускает, прогон 3 фрейма
emulator.keyScan(0153, 6); -- то же но задаётся интервал (фреймов) от нажатия до отжатия
emulator.keyScanShift(0013); -- нажатие SHIFT, 2 фрейма, нажатие клавиши, 3 фрейма, отжатие клавиши, 2 фрейма, отжатие SHIFT, 3 фрейма -- т.е. комбинация для ввода символа в другом регистре
emulator.keyString('1\n'); -- ввод серии символов; для каждого ASCII-символа ищется скан-код, если нужно используется нажатие SHIFT
emulator.getCPU() либо emulator.cpu -- получение объекта для ЦП
emulator.getPPU() либо emulator.ppu -- получение объекта для ПП
Дальше описываю в примерах для ПП, для ЦП то же самое:
emulator.ppu.getName() либо emulator.ppu.name -- название процессора, "CPU" либо "PPU"
emulator.ppu.getReg(0) либо emulator.ppu.r(0) -- значение в регистре 0..7
emulator.ppu.getPC() либо emulator.ppu.pc -- значение в регистре 7
emulator.ppu.getSP() либо emulator.ppu.sp -- значение в регистре 6
emulator.ppu.getPSW() либо emulator.ppu.psw -- значение в PSW
emulator.ppu.isHalt() либо emulator.ppu.halt -- признак HALT/USER режима
emulator.ppu.readWord(0160304) -- прочитать слово из памяти процессора
emulator.ppu.disassemble(0160304) -- дизассемблирует одну инструкцию по заданному адресу, возвращает массив из четырёх элементов: { address, instruction, arguments, instruction length }
Актуальный справочник по скриптовому API лежит здесь: http://code.google.com/p/ukncbtl/wiki/Scripting
Под Qt скриптинг прикручивается довольно легко -- движок есть в самом фреймворке.
Меня тоже интересует как бы его попроще прикрутить к Win32-программе. JavaScript движков много но все какие-то сложные: http://en.wikipedia.org/wiki/List_of_ECMAScript_engines
Ещё видимо популярно использовать скриптинг на Lua:
http://code.google.com/p/psxjin/wiki...ptingFunctions
http://code.google.com/p/snes9x-rr/w...ptingFunctions
еще довольно часто питон прикручивают
На самом деле сейвстейтами я занимался, но успехов особых не было.
Во вложении первая версия в которой сейвы хоть как-то заработали -- по крайней мере, простейший Save/Load на загрузочном меню работает, в сложных случаях пока не тестировал.
Сейвы от предыдущих версий НЕ будут работать точно.
Информация от флоппи НЕ сохраняется, поэтому не рекомендую делать сейвы в моменты обмена с дисками.
В сейве (пока) НЕ сохраняется информация о подключенных картриджах/дисках -- предполагается что они не менялись.
В Qt-версию сейвстейты тоже добавил, будут со следующим релизом, причём формат сейвов совпадает с Win32-версией.
Можно я отвечу?
Скриптинг это способ автоматизации рутинных операций. Часто бывает что одни и те же действия нужно сто раз повторять -- например, дойти куда-то до места где отлаживаться надо.
Плюс функциональное тестирование можно на этом построить -- написать серию скриптов, в которых в ключевых моментах сравниваются показатели с эталонными (например, берём скриншот и сравниваем с эталоном).
Если для всех пунктов меню есть соответствующие команды -- можем делать "запись макроса" -- писать скрипт в ответ на выбор команд.
SDL-версия эмулятора в full screen на моём рабочем мониторе:
http://img-fotki.yandex.ru/get/6507/...b00baab1_L.jpg
---------- Post added at 18:11 ---------- Previous post was at 17:48 ----------
http://ukncbtl.googlecode.com/files/...35-Windows.zip
Эта версия почти не управляется из интерфейса, все настройки задаются через INI-файл UkncBtlSdl.ini -- обычный INI-файл с секциями SDL, VIDEO, UKNCBTL.
Секция SDL -- все ключи начинаются с "SDL_", все пары ключ-значение без изменений передаются в SDL, полный набор опций описан в http://www.libsdl.org/docs/html/sdlenvvars.html
В частности, можно указать размещение окна на экране и выбрать видеодрайвер:
SDL_VIDEO_WINDOW_POS=300,200
SDL_VIDEODRIVER=directx
Секция VIDEO:
Width и Height -- ширина и высота окна, по умолчанию 800 x 600.
BitsPerPixel -- количество бит на пиксел, обычно 0 т.е. родное, можно поставить 32 или 16, но обычно не нужно.
FullScreen -- флаг показа на полный экран; при установленном флаге (1, yes, true) в Width и Height лучше ставить родное разрешение монитора.
ScreenMode -- число от 0 до 4, режим скалирования экрана УКНЦ, те же режимы что в win32-версии.
Секция UKNCBTL:
Cartridge1=romctr_basic.bin -- подключение картриджа
Floppy0=RT11A5.dsk -- подключение флоппи
Hard1=harddisk.img -- подключение харда
Пример INI-файла -- показ в полный экран на FullHD мониторе:
Клавиатура размаплена, но не до конца.Код:[UKNCBTL]
Cartridge1=romctr_basic.bin
Floppy0=RT11A5.dsk
[SDL]
SDL_DEBUG=1
SDL_VIDEO_WINDOW_POS=300,200
SDL_VIDEODRIVER=directx
[VIDEO]
Width=1920
Height=1080
BitsPerPixel=0
FullScreen=1
ScreenMode=4
Выход по клавише Esc.
Погонял Win32-версию UKNCBTL под профайлером VS2012. Результаты неутешительные.
Основное на что уходит время:
Emulator_PrepareScreenRGB32() -- около 40%
CMotherboard::SystemFrame() -- около 38%, в том числе
- CProcessor::CommandExecution() -- ~3%
- CProcessor::InterruptProcessing() -- ~6%
Сам рендеринг экрана средствами VFW занимает доли процента, поэтому не так важно чем образ экрана отправляется на видеокарту. Посмотрел код PrepareScreen -- оптимизировать там особо нечего.
Вы бы (оба ) не язвили друг на лруга, а усилия объединили. Всё равно проекты некоммерческие.
Мы совершенно не язвим. Во всяком случае nzeemin. Я тоже стараюсь подталкивать в конструктивные направления.
А усилия в некоторой степени и так обьединены. Когда я вижу у них ошибку, говорю. Они тоже мне много интересного рассказали.
А в плане самого эмулятора - концепции и построение очень разное, там даже отдельные функциональные блоки не перенесешь, т.е. каждый делает по-своему, как считает правильным. Я упираю на одно, они на другое. И кто хочет, может вполне заимствовать друг у друга чего-то.
Например, у них появились сканлайны и масштабирование в пропорциях, как у меня. У меня дополнительные палитры, как у них. Это, если смотреть на интерфейсные стороны. И т.д.
было:
стало:Код:for (int s = 0; s < scale; s++)
*pBits++ = valueRGB;
охеренный прирост производительности, процентов на 20-30Код:switch (scale)
{
case 8:
*pBits++ = valueRGB;
*pBits++ = valueRGB;
*pBits++ = valueRGB;
*pBits++ = valueRGB;
case 4:
*pBits++ = valueRGB;
*pBits++ = valueRGB;
case 2:
*pBits++ = valueRGB;
case 1:
*pBits++ = valueRGB;
default:
break;
}
я-то думал 2-3% было бы классно здесь выжать
На моём ноуте с выключенным звуком эмулятор выдавал 500% от оригинала, теперь 700%.
Занимался сегодня ещё оптимизацией.
В итоге, теперь пятёрка лидеров по затратам времени:
CMotherboard::SystemFrame() -- 40.90%
Emulator_PrepareScreenRGB32() -- 24.39%
CProcessor::InterruptProcessing() -- 9.52%
CMemoryController::GetWord() -- 5.64%
CProcessor::CommandExecution() -- 4.52%
На ноуте уже примерно 750% от оригинала.
Спасибо за новую бету! Очень полезная и удобная кнопка "скриншот",
остальное будем гонять, на картинке видно какой на моём ноуте % "без звука",
но ноут греться стал сильнее к сожалению.
Скрытый текст
в архиве прилепленном дискета со "скриншота"
загрузчик + игрушки
OС-85 в бете 37 UKNCBTL
http://savepic.net/3376989.png
Этой интересной дискетой поделился [anasana]
Образ для UKNCBTL в прилепленном архиве.
Поправил !
Ещё разок самые свежие и актуальные ссылки по теме:
http://zx.pk.ru/attachment.php?attac...6&d=1346948690 -ukncbtl beta37
http://zx.pk.ru/attachment.php?attac...9&d=1347143289 -дискета с играми и системой
http://pdp-11.org.ru/~hobot_lmb/EMULATORS/UKNCBTL_HDD/ -образы ЖД для UKNCBTL (инструкции и описания там)
http://www.old-games.ru/forum/showth...719#post828719 -ещё игрушки для UKNCBTL
Для интереса попробовал сделать реализацию эмулятора в виде C++/CLI модуля плюс интерфейс на C#, в общем и целом получилось.
Visual Studio 2005, .NET Framework 2.0
http://img-fotki.yandex.ru/get/6610/..._38589bcf_orig
А как на счет улучшения качества?
Точная эмуляция времянок процессора, памяти и т.д.
Рано или поздно будет (я думаю) очередная бета для Win, у меня такая просьба-предложение: может путь для сохранения скриншотов жестко в ini файле завести?
Просто сейчас картина такая - путь для сохранения скриншота читается(подставляется) из переменной - а это сбивает с толку иногда.
:redface:
Не совсем так! Устраивает, если бы было так, но это не так ! )))
Попробуйте в процессе уже после запуска воткнуть какой нибудь образ, и папка
с образом становится текущей и скрин пишется уже в неё (вот я что имел в виду,
когда писал про переменную), а если я ОН_ЛАЙН образ из архива подцеплю? Куда
скрин улетит - неведомо )))
Спасибо за ответ!