-
- ? Дмитрий
- 24.10.2023 22:23
gid, я уже чет ваще подзабыл - в БК как ведут себя регистры состояния/ошибки при отсутствующем винте? Как определяем, что винта нет? Drive Ready отсутствует - это понятно, а Busy выставлен всегда? Или только регистр падает в бесконечный Busy после посылки любой команды? В сырцы глянул, но не нашел - видать к ночи башка плохо варит.
- ? Дмитрий
- 10.04.2023 00:21
1) В одном хэндбуке написано, что бит FER сбрасывается только через LDFPS. В другом (PDP11_Handbook1979.pdf) - еще и с помощью RESET. Так на самом деле только LDFPS или еще и RESET? И раз можно сбросить, то можно и установить? Если можно установить, то не поломает ли это логику работы FPP?
2) Непонятно в описании MULF в разделе interrupts:
¤
>> If overflow or underflow occurs and if the corresponding interrupt is enabled, the trap occurs with the faulty results in AC. The fractional parts are correctly stored.
>> The exponent part is too small by 400(8) for underflow, except for the special case of 0, which is correct.
¤
глянул в simh - там тупо обнуляется, а тут написано, что дробная часть сохраняется. Так где правильно? И как понять: дробная часть сохраняется, а экспонента обнуляется чтоль? Умели тогда писать, что черта с два поймешь.
- ? Дмитрий
- 26.03.2023 12:08
Опять наткнулся на двоякое толкование. https://bitsavers.org/pdf/dec/pdp11/handbooks/PDP11_Handbook1979.pdf
¤
1) стр. 346 в самом низу.
¤
>> The FER bit is set by the FPP if:
>> 1. Division by zero occurs.
>> 2. Illegal OP code occurs.
>> 3. Anyone of the remaining occurs and the corresponding interrupt is enabled.
¤
т.е. получается, если мы заблокировали прерывание, допустим, по переполнению, то бит ошибки не будет выставлен в случае переполнения при вычислениях? Или все же будет выставлен при ЛЮБОЙ описанной ошибке?
¤
идем дальше. 2) стр. 350 вверху
¤
>> The FEC and FEA registers are updated when one of the following occurs:
>> • divide by zero
>> • illegal OP code
>> • any of the other five exceptions with the corresponding interrupt enabled
¤
опять-таки говорится, что FEC и FEA будут обновлены только, если разрешено прерывание
¤
и там же, чуть ниже:
¤
>> The FEC and FEA are not updated if no exception occurs.
¤
что это значит? Что если вычисление не привело, к примеру, к переполнению, то регистры не обновляются? Это понятно. Или же если при заблокированном прерывании произошло переполнение, но прерывания не происходит (заблокировано), то регистры тоже не обновляются?
¤
Из такого описания получается, что заблокируй прерывание по переполнению и хрен ты когда поймешь, что оно произошло. Бит ошибки не выставлен, регистр ошибок не обновлен, регистр адреса тоже.
¤
В догонку.
¤
1) В simh начальное значение FEC/FEA ноль.
2) Там же заметил, что команда CLRF не читает предыдущее значение как CLR(B), а сразу пишет ноль. В исходниках 4.2 бета читает. По идее можно вычисление адреса CalcArgAddrX воткнуть вместо вызова GetXdef.
- ? Дмитрий
- 15.03.2023 20:14
Вопрос по STST. Как я понял из описания и сырцов эмулятора, если метод адресации > 0, то получается адрес и последовательно пишется FEC и FEA. Причем независимо от метода, т.е. STST @(R0)+ получает адрес из R0, потом из этого адреса слово и по полученному пишется два слова. Точно также и STST @#1000 - FEC будет записан в @#1000, а FEA - в @#1002. Еще нашел в описании, что STST SP и STST PC вызывают illegal opcode. И непонятно, что выдаст команда, если не было ошибок - оба слова равны 0 или их значение неопределено после старта машины?
- ? Дмитрий
- 07.03.2023 00:11
>> Есть исходники. Я пару месяцев мучился распознавал эти пдфки
Благодарю. Мельком пока глянул. Погляжу на досуге по-подробнее.
¤
Судя по тому как записаны тестовые константы для проверки, запись double осуществляется big endian. Хотя в вики сказано, что у PDP был свой т.н. "PDP-endian". Я почему-то думал, что у PDP тоже little endian, потому как 16-битное слово пишется как раз LE.
- ? Дмитрий
- 03.03.2023 00:00
>> у меня абсолютно всё - это арифметические выражения, даже единичная числовая константа - это тривиальное арифметическое выражение, которое вычисляется немедленно.
Я аналогично сделал. Но я не стал делать в виде бинарника. Потому как константа "1" - это байт, а 000001 в двоичном занимает в 2 раза больше. А после "100" уже выгоднее бинарником. Спасибо. Обдумаю на досуге этот вариант.
¤
>> будет прочитано 16 разрядное плавающее число и преобразовано в 32 или 64-х разрядное путём добивания нулями хвоста мантиссы.
т.е.
SETD
MULF (PC)+,AC0
.FLT4 2.0
¤
черта с два выполнится? но 16-разрядное - это же половина float, при добивании нулями потеряется точность. про double вообще молчу. Хотя этот вариант вряд ли будет кто-то использовать. Проще
¤
SETD
MULF D2,AC0
...
D2: .FLT4 2.0
¤
>> Она проходит тесты DEC xxdp: dffpa, dffpb, cffpc
Тесты нашел, но в PDF. А исходников их нет?
- ? Дмитрий
- 02.03.2023 20:19
Да и еще в догонку про команды FPU. Если в командах MULF/DIVF/ADDF/SUBF и других в качестве источника будет указано непосредственное значение: MULF #X,AC0, то как себя будет вести проц? Исключение по неправильной команде или все же выполнит? Я что-то не нашел в описаниях команд такого случая.
- ? Дмитрий
- 02.03.2023 20:10
Я про то, как сохраняется такое выражение. Как вырезанное в отдельную строку или запоминается ссылка на его первый символ в исходнике? Я сделал сохранение вырезанного выражения в отдельную таблицу доп. прохода, но при инклюдах приходится сохранять еще имя файла и позицию для вывода возможной ошибки, что громоздко. А могут быть и вложенные инклюды. Ведь адрес метки в выражении на момент разбора нам неизвестен и метка помещается в таблицу меток как неопределенная. А в дополнительном проходе по такой таблице все метки нам должны быть известны и встреча неопределенной метки вызовет ошибку, которую и надо сообщить пользователю. Вот думаю либо переделать на ссылки, чтоб не плодить тонну строк, либо также вырезать выражение, но не могу придумать как с минимальными накладными расходами сохранить все (имя файла, позиция в тексте, позиция ошибки, номер строки и указатель на ошибочный идентификатор выражения) для вывода возможных ошибок.
- ? Дмитрий
- 01.03.2023 23:38
gid, вопрос по Турбо8. Как в нем реализовано вычисление выражений с меткой или метками (типа MOV #LABEL+12,R1), которые пока еще не определены? У себя сделал запись таких выражений в таблицу для повторной обработки после прохода по всему тексту. Плюс такие выражения могут быть и в подключаемых файлах - их тоже надо обрабатывать, а в случае ошибки правильно выдать в каком файле, в какой строке и позиции ошибка, если она возникнет. Так-то все работает, но что-то мне не совсем нравится способ - хочу переделать.
- ? Дмитрий
- 02.12.2022 22:02
Тогда в догонку еще вопрос: бит в слове состояния - режим округления chop/round. Chopping - это, вроде как, просто отбрасывание дробной части, а округление - оно и есть округление, но какое - round to nearest? Up/Down/ToZero?
- ? Дмитрий
- 02.12.2022 20:03
https://bitsavers.org/pdf/dec/pdp11/handbooks/PDP11_Handbook1979.pdf стр. 363 (по нумерации вьювера).
¤
This instruction generates the product of its two floating point operands, separates the product into
integer and fractional parts and then stores one or both parts as floating point numbers.
Let PROD = (AC)*(FSRC) so that in: <------------------------------------------------------------------ тут все понятно
Floating point: ABS(PROD) = (2**K)*f where 1/2.LE.f.LT.1 and EXP(PROD) = (200+K)s <------------------ смутила эта строка
Fixed Point binary: PROD = N + g, with <-------------------------------------------------------------- а тут уже про целую и дробную
N = INT(PROD)=the integer part of PROD and g = PROD - INT(PROD) = the fractional part of PROD with 0<g<1
Both N and g have the same sign as PROD.
¤
И еще. Если я парвильно понял, в операциях FPU, если метод адресации 0, то это не регистр, а аккумулятор. Но не везде.
- ? Дмитрий
- 01.12.2022 21:00
Не подскажет кто - что возвращает команда FPU MODF/MODD после перемножения? Просто разделяет целую и дробную части или раскладывает число как FREXP на 2^x * y? В древних pdf в описании упомянуты оба варианта.
- ? Дмитрий
- 20.07.2021 10:51
http://gid.pdp-11.ru/
утилита BKDE
- ? Дмитрий
- 24.02.2021 00:12
Файл по указанному пути открывается с правами, которые указываются при открытии - на основании этих данных возвращается хэндл. При передаче его функциям чтения/записи права не меняются - кто бы этимм хэндлом не пользовался. Можно повторно открыть открытый файл для чтения/записи, если при первом открытии указывалось, что файл могут читать или писать другие программы. Если таких прав не задано, повторное открытие вернет ошибку, т.е. файл открыт эксклюзивно.
- ? Дмитрий
- 29.12.2020 00:56
>> чтобы две программы открывали один и тот-же файл для записи
А что если в эмуляторе сделать экспортируемые функции R/W с образом? Тогда образ, открытый эмулятором, через них может писать и BKDE. А BKDE при запуске будет искать загруженный эмулятор и воспользуется его функциями, если не находит - открывает файл самостоятельно.
- ? Дмитрий
- 02.11.2020 21:03
Красивая фтучка. А кто писать под нее будет? :)
- ? Дмитрий
- 16.10.2020 14:15
gid, вопрос: что-то не могу найти в стандартах - разве при выборе устройства в регистре DrvHeadReg (1F6) не должны выставляться биты готовности или занятости накопителя + биты в регистре статуса, если накопитель отсутствует? Я что-то не могу найти внятного ответа на вопрос - как детектируются винты через порты контроллера? В одном месте посылают команду диагностики, в другом - soft reset.
- ? Дмитрий
- 29.08.2020 22:59
Почему о разных? Как вычислить смещение курсора особо не играет роли - важен результат. Учитывать нужно накладные расходы. Раз уж все взаимосвязано фреймами, то отвлекаться отдельно на отлов мыши мб нецелесообразным. Подобным образом я сделал таймер - в режиме fullspeed никаких фреймов нет, поэтому приходится вычислять значение счетчика при чтении регистра, а сам счетчик реализован на high precision таймере (QueryPerformanceCounter) - его не надо реализовывать, он не зависит от загруженности проца и пр. Просто пересчет тиков по частоте.
- ? Дмитрий
- 29.08.2020 14:06
Навскидку, можно пойти другим путем. При чтении 177714 (если мышь разрешена в настройках) считать координаты курсора мыши GetCursorPos, преобразовать в координаты формы ScreenToClient, проверить, находится ли курсор над отрисованным "экраном" PtInRect. Если да, то сравнить с предыдущими запомненными координатами, выставить биты смещения и запомнить новые координаты. Никаких доп. обработчиков не надо.
- ? Дмитрий
- 29.08.2020 13:55
Я не Сишник, поэтому моя реализация никак не адаптируется. В Delphi все уже сделано до нас, все сообщения ловятся, кодеру надо лишь вставить в обработчик свой код.
- ? Дмитрий
- 29.08.2020 02:56
>> Проблема в рассинхронизации из-за своей отрисовки формы (фрейма) окна БК.
А какая там рассинхронизация? Отрисовка формы это одно, а посылка сообщения о перемещениях мыши - другое. У меня тоже отрисовывается экран на форме, но сообщение от мыши без проблем поступают.
- ? Дмитрий
- 29.08.2020 02:56
>> Проблема в рассинхронизации из-за своей отрисовки формы (фрейма) окна БК.
А какая там рассинхронизация? Отрисовка формы это одно, а посылка сообщения о перемещениях мыши - другое. У меня тоже отрисовывается экран на форме, но сообщение от мыши без проблем поступают.
- ? Дмитрий
- 25.08.2020 22:28
gid, ловить мышь надо прямо на форме, сообщение WM_MOUSEMOVE. Поскольку экран отрисовывается в определенной точке формы, то если координаты курсора "попали" в экран - сравниваем с предыдущими запомненными и вычисляем, какое смещение надо выдать битами в 177714.
- ? Дмитрий
- 12.07.2020 12:00
Я в свое время несколько раз встречал инфу, что где-то выложены исходники TP6, но ссылки были все битые. Если не сложно - мона ссылочку на сырцы TP6?
- ? Дмитрий
- 05.07.2020 00:14
Бутылочное горло - операции с диском. CreateFile с флагом FILE_FLAG_NO_BUFFERING крайне медленно ведет обмен с диском. Пришлось отказаться и открывать с FILE_FLAG_RANDOM_ACCESS.
- ? Дмитрий
- 05.07.2020 00:11
Я проверял в своей версии - вроде 1 цикл ожидания бита готовности на записи (если не ошибаюсь). Надо будет написать подробный тест (как время появится) и залоггировать кол-во циклов после записи каждого сектора при записи, допустим, 1 мб данных.
- ? Дмитрий
- 19.06.2020 20:19
Нет, это понятно. Я имел в виду как будет себя вести накопитель, который ждет считывания данных или получения данных для записи и которому в этот момент подают команду ну, допустим, рекалибрации или IDLE. Он отменит текущую незавершенную команду или проигнорирует поданную?
- ? Дмитрий
- 05.06.2020 20:20
>> При этом, если вылезли за геометрию, будем пытаться позиционироваться за конец файла, при этом будут читаться нули и не будет выдаваться флагов ошибок.
А проверка на что перед чтением? Если указатель равен размеру файла, то ошибка.
¤
>> Там перед командой надо каждый раз задавать координаты нужного сектора.
Так после подачи команды и происходит единственное позиционирование. Зачем его вызывать перед каждым сектором?
¤
>> Для БК мало 1,5МБ/сек? У неё команд в секунду в пять раз меньше! Хост выдаёт так мало? Ну так это где-то косяк в софте
Для БК10/11 норм, а для моего симулятора 32-битной - мало. Я же писал, что не ...дцатый эмулятор пишу, текущего за глаза хватает, да плюс твой.
¤
>> современные винты выдают порядка 100 МБ/сек
Это в ДМА. PIO такой скорости не даст.
- ? Дмитрий
- 05.06.2020 01:29
В пределах одной операции никаких рандомных операций не может быть. Конманда READ_SECTORS читает указанное число секторов, начиная с указанного.
- ? Дмитрий
- 05.06.2020 01:26
>> И не нашёл, чего там оптимизировать
после поступления команды чтения/записи:
1) спозиционировать в файле указатель, соответствующий LBA/CHS
2) считать сектор
3) выдать следующий сектор в регистры
4) выдать данные в регистр данных
5) если есть еще секторы - goto 2
а в текущей реализации goto 1
- ? Дмитрий
- 04.06.2020 14:44
Потому что у меня, на моей машине, текущая реализация контроллера HDD прогоняет примерно 1,5мб/сек. Было меньше, но после того, как я эмуляцию команд сделал на чистом асме (и получил офигенный буст), скорость увеличилась. Теперь думаю, что придется и контроллер переписать на асм. В дополнение к эмуляции команд прибавится буст от контроллера. В теории всю реализацию надо бы переписать на асм, но я пока перепишу основную часть, где есть бутылочное горло.
- ? Дмитрий
- 04.06.2020 13:48
Я про PIO-чтение/запись - там нет никакого кэширования, вся работа на программисте. На БК ни в одной (емнип) нет никаких кэширований, памяти мало, поэтому есть небольшой буфер для FAT/каталога.
- ? Дмитрий
- 04.06.2020 01:40
>> А там код эмуляции довольно кривоватый, он эмулирует а не симулирует HDD и там много условностей.
Ну скажем так, код там более-менее нормальный. Я доработал его до LBA48 - все работает отлично. Но скорость маленькая. Все из-за того, что эмулятор читает/пишет каждый сектор по мере передачи данных через регистр. Хочу доработать, чтобы эмулятор считывал весь запрошенный объем в буфер, а затем выдавал его пословно в регистр. И запись точно также - передали весь объем в бефур, записываем. Емнип, винт так и работает - при чтении/записи во внутренней памяти выделяется буфер не на один сектор, а макс. возможный размер. Иначе и на РС скорость была бы копеечной. А она на реальном винте гораздо выше той, что достижима этим алгоритмом. Плюс там очень много лишних операций - в частности seek: нет смысла высчитывать указатель на следующий сектор в пределах одной операции, после чтения/записи данных мы уже стоим на следующем секторе. Нужен только первый вызов, затем просто увеличивать счетчик LBA/CHS.
- ? Дмитрий
- 01.06.2020 21:50
>> Сейчас уже не помню нужного числа
у МКДОС 172 файла макс. АНДОС 112.
- ? Дмитрий
- 13.05.2020 01:25
Еще вопрос. В эмуляторе на время отладки отключается прерывание по вектору @#100?
- ? Дмитрий
- 11.05.2020 14:18
Возник еще один вопрос. Команды MTPS/MFPS работают, учитывая биты признаков. А в случае прерывания из второго слова в PS копируются все биты или только старшие 4 бита (приоритет и Т-бит)? Т.е. если в @#32 записано 201(8), то войдя в прерывание по ЕМТ мы увидим в PSW повышенный приоритет и установленный бит С или только приоритет? БКаха у меня завалена в кладовке, самостоятельно проверить нет возможности в данный момент.
- ? Дмитрий
- 04.05.2020 23:43
>> При каждом вызове туда пишется, где продолжать исполнение при возврате, и текущее значение SP.
При JSR R1,PRINT + .ASCII адрес возврата в R1 будет изменен, а внутри PRINT иожно сохранить какое-либо значение в стек (для дальнейшего использования) и поменять местами его и содержимое R1 в стеке (мало ли какие трюки могут быть). В итоге стек будет изменен, R1 изменен и что мы получим? RSB паникует и выбрасывает сохраненное значение R1, раз стек не совпадает? А вариант MOV #100000,-(SP) + RET? RSB не использовался - как быть? Кодоизвращения могут быть разными, все не учтешь.
- ? Дмитрий
- 03.05.2020 21:46
Забыл дописать. Данный прием отлавливать только при нажатии на кнопку "Трассировка без захода" в пошаговом режиме. При выполнении фреймов не проверять.
- ? Дмитрий
- 03.05.2020 21:44
>> постоянно в программировании на БК применяются такие методы
Черт, точно. В описаннных случаях не только не поймает выход, да еще и все трюки учитывать - голову сломаешь.
¤
>> Я не смог придумать правильный алгоритм, который бы учитывал вот это всё и не ломался.
Я тут ломал голову, до того момента, когда написал вопрос. Есть пока один вариант, который учитывает только классический вариант jsr+rts или прерывание+rti/rtt с учетом вложенности. Примерно так:
¤
1) int Recurse,NeedStop = 0;
2) В процедурах ExecuteRTS/RTI/RTT добавить NeedStop = 1; и Recurse -= 1;
3) В процедурах ExecuteJSR и прерываний добавить Recurse += 1;
¤
далее выполняем код до тех пор, пока не выполнится условие Recurse = 0 && NeedStop = 1;
¤
В итоге имеем следующее: при входе в подпрограмму/прерывание увеличиваем счетчик рекурсии, при выходе взводим флаг необходимости останова и уменьшаем счетчик рекурсии. Если у нас была вложенная подпрограмма, то при встрече выхода из нее, счетчик рекурсии будет =2. А нам надо 0. Поэтому останова не будет. NeedStop можно сделать bool.
- ? Дмитрий
- 03.05.2020 18:40
gid, а как в эмуляторе реализовано выполнение jsr/прерывания как одной команды? Сырцы щас ковырять особо нет времени (тонкости гляну в них позже). У меня не лезет в голову ничего, кроме как при отработке RTS/RTI/RTT взводить признак и выполнять код до тех пор, пока признак не будет взведен. Потому как контролить адрес возврата в регистре не вариант, ибо распространенный способ применения позиционно-независимого JSR R1,PRINT + .ASCII так не сработает.
- ? Дмитрий
- 29.03.2020 14:17
http://www.pentacom.jp/pentacom/bitfontmaker2/
Онлайн-редактор. Рисуешь точечный шрифт, а на выходе получаешь ttf. Кто сам хотел сделать БКшный шрифт?
- ? Дмитрий
- 26.02.2020 20:29
Про биты я в курсе - меня интересовало откуда такая константа. Еще в 80-е на БК10 исследовал, но так и не въехал, почему именно это число.
- ? Дмитрий
- 09.02.2020 21:10
Получается, что раз биты 10 и 11 никогда не установлены (нечем устанавливать/сбрасывать), то и в обработчике прерывания все, что проверяет эти биты и выполняет при их =1, бесполезно?
- ? Дмитрий
- 09.02.2020 13:27
gid, я что-то запутался. Каким образом (и зачем) вызывается системное прерывание, если на 160000 у БК ПЗУ контроллера? Да и пультового режима нет.
- ? Дмитрий
- 02.02.2020 16:44
В чем заключается перепроектировка?
- ? Дмитрий
- 02.02.2020 16:39
Кстати, если я правильно понял, то FPU PDP ловит NaN перед вычислениями и, если операнд NaN, то возникает исключение и операция не выполняется. А если в результате операции будет NaN, то не возникает, а возникнет при попытке сделать что-то с этим результатом? Потому как у современного FPU операции с NaN не вызывают ничего - равносильно выполнению FNOP. А вот если попробовать что-либо вычислить из Infinity, то в результате возникает NaN и исключение "Недействительная операция". Получается ли, что нужно ловить перед операцией NaN, а после деление на ноль, overflow и underflow?
- ? Дмитрий
- 01.02.2020 11:22
По поводу бита 11. Проверил. Действительно, в современных процах такого не происходит. При попытке занести с стек число -0 (0x8000000000000000), оно автоматически преобразуется в 0 и никаких исключений не вызывает. Но если занести в стек число 4.94065645841246544176568792868E-324 (0x0000000000000001), то возникает исключение "денормализованный операнд".
- ? Дмитрий
- 31.01.2020 22:34
gid (да и вообще любой кто знает), еще вопросы по FPU.
¤
1) Бит 5 (Floating Chop Mode) округления в слове статуса имеет два значения - Chop (или Truncate) и Round. Truncate понятно - просто отбрасывание дробной части. А вот Round к чему - к ближайшему целому, вверх или вниз? Такой подробности я не нашел.
2) Бит 11 (Interrupt on undefined variable) - перевод какой-то туманный - нифига непонятно. А отсюда вылезает непонятка с каким исключением современных FPU его связать. Денормализованный операнд?
- ? Дмитрий
- 27.01.2020 20:33
Переписал все критичное по скорости на асм, пока кроме диспетчера прерываний, FPU и DIV. В итоге тест заполнения 1Мб 16-битным паттерном (фактически вывод картинки 800*600 = 960000 байт) в простом цикле с 40-41 мс сократилось до 25-27 мс. Даже не ожидал такого резкого ускорения. Плюс есть еще резерв - множество обращений к регистрам БК через [FRON+регистр*4]. Надо вынести адрес массива регистров в отдельный регистр и, тем самым, резко сократить обращения в память.
- ? Дмитрий
- 08.01.2020 14:08
Кстати, диспетчер прерываний из v4.1 неплохо ускорил поток выполнение команд. Заполнение 16-битным паттерном 1Мб памяти сократилось с 47 до 40-41мс.
-
1 | 2 | »
?