Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Эмуляторы отечественных компьютеров (http://zx-pk.ru/forumdisplay.php?f=61)
-   -   Эмулятор УКНЦ (http://zx-pk.ru/showthread.php?t=6257)

NovaStorm 30th January 2013 20:05

Quote:

Originally Posted by Patron (Post 571775)
Именно безумный стиль

"Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво"
(С) я думаю всё знают чей =)

Patron 30th January 2013 20:12

Quote:

Originally Posted by Titus (Post 571823)
можно писать преобразование типов, скажем, не k = (long)i, а k = long(i).

Насколько я понимаю - в первом случае к объекту i применяется копирование типа long, а во втором случае сначала создаётся новый объект типа long - т.е. вызывается его конструктор, получающий значение объекта i в качестве начального значения, а потом копируется уже вновь созданный объект. Если включена оптимизация - код может получиться одинаковым, а если нет - первый вариант будет короче.

Titus 30th January 2013 20:19

Quote:

Originally Posted by Patron (Post 571830)
Насколько я понимаю - в первом случае к объекту i применяется копирование типа long, а во втором случае сначала создаётся новый объект типа long - т.е. вызывается его конструктор, получающий значение объекта i в качестве начального значения, а потом копируется уже вновь созданный объект. Если включена оптимизация - код может получиться одинаковым, а если нет - первый вариант будет короче.

Не знаю, какие там обьекты, в инструкции про это ничего не сказано) Сказано, что синтаксис может быть и таким, и таким)

hobot 30th January 2013 21:35

Про ООП (но не про Си!)

Скрытый текст


Я не проф. и Си вообще всегда бежал, но вот Паскаль от УК-НЦ потом турбо-паскаль в ДОС - для удовольствия и наконец Delphi под Win. ООП - конструкторы\диструкторы я понял только из объяснений Patrona - слишком заумные мне попадались видимо толкователи до этого.

Но я вот что хотел сказать то - читал учебник (автора не помню), по Delphi, где автор полностью отказался от термина ООП и вообще не использовал его ни разу ни на одной странице (единственный учебник в котором автор на одном со мной языке говорил про ООП паскаль и Delphi), он вводит там такой термин Событийно Ориентированное Программирование.

Мне например "методы" ? Ну то есть переменные объекта, которые через
точку пишутся очень обрадовали! Но потребовалось время что-бы привыкнуть воспринимать и код и результат по новому, если раньше программа была строго линейная (или я такой как рельсы прямой!), то есть автоматом вылетала в монитор
когда доходила до END., то под Win созданное окно так и будет висеть и получать сообщения. В целом это я так - впечатлениями делюсь, но мне например
нелегко было отказаться от циклов и некоторых других вещей которые "не рекомендуются" при СОП, просто потому-что не нужны или не желательны или требуют дополнительного обслуживания (я имею в виду ProcessMessages).

И странное дело, вот объяснения Patrona я понимаю, а код из примеров (сам синтаксис Си для меня всегда был страшен - может потому что я
начинал с Бейсика на БК0010? Но все эти фигурные скобочки - у меня
ассоциация с комментами из паскаля ))) Паскаль - просто больше похож
(Delphi сюда же). на язык человека и наглядней (для меня) для простых
вычислений. Но я не профи.
[свернуть]


Вот кстати говоря вопрос такой - если Си родился из макро-11 (а судя
по данным многие профессионалы сразу начинали с той самой версии,
минуя ассемблер, где Паскаль впервые в виде транслятора появился,
так же на PDP? (наверное это легко нагуглить, но всё же).

---------- Post added at 20:35 ---------- Previous post was at 20:34 ----------

Quote:

Originally Posted by Titus (Post 571833)
Если включена оптимизация - код может получиться одинаковым, а если нет - первый вариант будет короче.

Главное - какой будет быстрее работать?

Patron 30th January 2013 21:46

Quote:

Originally Posted by hobot (Post 571847)
Главное - какой будет быстрее работать?

Сейчас оптимизаторы достигли такой крутизны, что при включённой глобальной оптимизации - вызов целого вороха вложенных функций может скомпилироваться в одну-две ассемблерных команды вообще без всяких вызовов подпрограмм.

Когда я впервые в жизни включил глобальную оптимизацию и посмотрел ассемблерный листинг компиляции - то очень удивился. Из функций исчезли прологи и эпилоги, а аргументы стали передаваться в регистрах вместо стека. Если функция не числится глобальной (а значит не должна быть доступна в OBJ-файле в виде глобального имени) - оптимизатор может иногда вообще не компилировать её, а подставлять в точках вызовов как макрос.

nzeemin 30th January 2013 21:58

Patron, Vamos -- спасибо за критику и вклад в проект.
Сейчас станции уже начинают пытаться переговариваться, но сбиваются.

http://img-fotki.yandex.ru/get/4119/..._3d220139_orig

При этом на принимающей станции выпадает в СТОП.

Загрузчик из сети в ПЗУ (спасибо Alex_K):
Code:

; Загрузчик из сети
164160$:MTPS        #340                ; Запретить прерывания
        MOVB        @#176561,R5        ; Выделение в R5 номера сетевой станции
        MOV        R5,R0
        BIC        #177760,R5
        ASR        R0
        BIC        #177717,R0
        BIS        R0,R5
        MOVB        R5,164556$        ; Сохранение номера сетевой станции
        MOVB        164572$,R0        ; R0 = 173(8)
        XOR        R5,R0                ; R0 = 173(8) XOR номер_сетевой_станции
        MOVB        R0,164572$
        MOV        #30,R0                ; R0 = 30 (адрес вектора команды EMT)
        MOV        #164500$-164160$+1000,(R0)+ ; Установка вектора прерывания EMT
        CLR        (R0)+                ; Установка ССП при вызове EMT
        MOV        #164512$-164160$+1000,(R0)+ ; Установка вектора прерывания TRAP
        CLR        (R0)+                ; Установка ССП при вызове TRAP
164244$:MOV        #10000,SP        ; Установка указателя стека
        MOV        #164526$-164160$+1000,@#100 ; Устан. вект. прер. сет. таймера
        CLR        @#102
        MTPS        #0                ; Разрешить прерывания
        CLR        164534$                ; Очистка счетчика ожидания
164272$:TRAP        0                ; Чтение пришедшего байта
        CMP        164534$,#5        ; Счетчик ожидания больше пяти
        BLO        164272$                ; Нет
164304$:EMT        0                ; Посылка и чтение очередного байта
        CMPB        #376,R0                ; Пришедший байт равен 376(8)
        BNE        164304$                ; Нет
        MOV        #164554$-164160$+1000,R1 ; R1 = адрес блока передачи
164320$:MOVB        (R1)+,R0        ; R0 = очередной байт из блока передачи
        CMPB        #376,R0                ; Он равен 376(8) ?
        BEQ        164334$                ; Да
        EMT        0                ; Посылка и чтение очередного байта
        BR        164320$
164334$:EMT        0                ; Посылка и чтение очередного байта
        CMPB        #377,R0                ; Прочитанный байт равен 377(8) ?
        BNE        164334$                ; Нет
        EMT        0                ; Посылка и чтение очередного байта
        CMPB        R5,R0                ; Полученный байт равен номеру станции ?
        BNE        164334$                ; Нет
        MOV        #377,R4                ; R4 = 377(8) (контрольная сумма)
        XOR        R0,R4                ; R4 = 377(8) XOR номер_сетевой_станции
        MOV        #50000,R1        ; R1 = адрес расположения загрузчика
        EMT        0                ; Посылка и чтение очередного байта
        MOV        R0,R3                ; R3 = считанный байт
        XOR        R0,R4                ; Подсчет контрольной суммы
164372$:EMT        0                ; Посылка и чтение очередного байта
        CMPB        #373,R0                ; Считанный байт равен 373(8) ?
        BLOS        164410$                ; Выше или равен 373(8)
        XOR        R0,R4                ; Подсчет контрольной суммы
        MOVB        R0,(R1)+        ; Передача принятого байта в память
        BR        164372$
164410$:BNE        164426$                ; Принятый байт равен не равен 373(8)
        EMT        0                ; Посылка и чтение очередного байта
        COM        R0                ; Инверсия принятого байта
        XOR        R0,R4                ; Подсчет контрольной суммы
        MOVB        R0,(R1)+        ; Передача принятого байта в память
        COM        R0                ; Инверсия для передачи
        BR        164372$
164426$:CMPB        #374,R0                ; Принятый байт равен 374(8)
        BNE        164244$                ; Нет
        EMT        0                ; Посылка и передача байта
        CMPB        R0,R4                ; Он равен контрольной сумме ?
        BNE        164244$                ; Нет
        EMT        0                ; Посылка и передача байта
        BISB        #10,R0                ; R0 = R0 OR 10(8)
        EMT        0                ; Посылка и передача байта
        CMPB        #377,R0                ; Принятый байт равен 377(8)
        BNE        164244$                ; Нет
        EMT        0                ; Посылка и передача байта
        MOV        #4,@#176560        ; Включение кольцевой сети
        MTPS        #340                ; Запретить прерывания
        JMP        @#50000                ; Переход на исполнение загрузчика
; Подпрограмма передачи байта в локальную сеть (исполнение команды EMT)
164500$:TSTB        @#176564        ; Передатчик СА готов ?
        BPL        164500$                ; Нет
        MOVB        R0,@#176566        ; Передача байта в сеть
; Подпрограмма чтения байта, пришедшего по сети (исполнение команды TRAP)
164512$:TSTB        @#176560        ; Приемник СА готов ?
        BPL        164512$                ; Нет
        MOVB        @#176562,R0        ; Прием байта из сети
        RTI
; Подпрограмма исполнения прерываний таймера
164526$:CLR        @#176560        ; Включение режима загрузки
        INC        (PC)+                ; Инкремент счетчика ожидания
164534$:.WORD        0
        CMP        164534$,#1000        ; Счетчик ожидания превысил лимит времени ?
        BHI        164550$                ; Да
        RTI
164550$:JMP        164244$
; Блок передачи в сеть
164554$:.BYTE        377,0,0,204,0,0,0,0,0,0,0,0,0,374,173,60,377,376,0,0


Patron 30th January 2013 22:05

Quote:

Originally Posted by nzeemin (Post 571855)
Сейчас станции уже начинают пытаться переговариваться, но сбиваются.

Это происходит из-за того, что в эмулируемом порту (почему-то) эмулируется overrun.
Можно вставить в эмулятор слежение за битом 012 в регистре состояния приёмника и убедиться.

Vamos 30th January 2013 22:08

Так вот он какой 1801ВП-065, там оказывается есть бит 0 и бит 2 в регистре состояния приемника.
Бит 2 это вывод ST, программное управление вкл./выкл. станции из кольцевой сети.
Бит 0 ??? , разрыв линии

Получается это те самые DTR/DSR которые и должны были быть 107, 108 на стыке С2

Alex_K 30th January 2013 22:28

Quote:

Originally Posted by Vamos (Post 571859)
Так вот он какой 1801ВП-065, там оказывается есть бит 0 и бит 2 в регистре состояния приемника.
Бит 2 это вывод ST, программное управление вкл./выкл. станции из кольцевой сети.
Бит 0 ??? , разрыв линии

Получается это те самые DTR/DSR которые и должны были быть 107, 108 на стыке С2

Уже писалось, что линии квитирования ни на какие биты не выводятся, квитирование делается полностью аппаратно самим 1801ВП1-065.
Бит 0 - разрыв линии - это посылка BREAK.
А вывод ST - это не бит 2, а сигнал "свой адрес". Благодаря этому можно на неиспользуемые биты 1801ВП1-065 вешать свою обвязку без необходимости дешифрации адреса. В этом случае достаточно запомнить только младшие биты (различать приемник, передатчик, регистры данных) и реагировать на сигналы DIN, DOUT. Сигнал RPLY выставит сама 1801ВП1-065. Вот в этой обвязке есть номер станции и управление электронным коммутатором сети.

Vamos 31st January 2013 01:26

Quote:

Originally Posted by Patron (Post 571858)
Это происходит из-за того, что в эмулируемом порту (почему-то) эмулируется overrun.

А подскажите пожалуйста как в НХ сервере сделана работа с СОМ портом, что переполнения не происходит.

Patron 31st January 2013 03:18

Quote:

Originally Posted by Vamos (Post 571907)
А подскажите пожалуйста как в НХ сервере сделана работа с СОМ портом, что переполнения не происходит.

Так и там тоже были переполнения

http://zx-pk.ru/attachment.php?attac...1&d=1358979832

поэтому, проверить на счёт переполнений всегда есть смысл первым делом.

Vamos 31st January 2013 03:30

Quote:

Originally Posted by Patron (Post 571923)
Так и там тоже были переполнения

НО переполнения возникали уже в загрузчике НХ сервера, а все остальные программы вызывают переполнение в загрузчике УКНЦ, почти сразу.
Есть ли смысл рассматривать фукцию CreateFile() с параметром FILE_FLAG_OVERLAPPED или результат будет такой же?

Patron 31st January 2013 04:25

Quote:

Originally Posted by Vamos (Post 571925)
Есть ли смысл рассматривать фукцию CreateFile() с параметром FILE_FLAG_OVERLAPPED или результат будет такой же?

Т.е. чтение виртуального порта в Windows возвращается с ошибкой?
Но ведь в порту com0com включена бесконечная буферизация и переполнения быть не может..

Vamos 31st January 2013 04:38

Как я понял, запись в буфер происходит слишком быстро и код эмулятора не успевает.

Vamos 31st January 2013 04:51

1 Attachment(s)
Ну вот чего ему не хватает :mad:

http://zx-pk.ru/attachment.php?attac...1&d=1359589855

если кому попадался этот тест с пунктом 6 (стык С2) поделитесь пожалуйста.

Patron 31st January 2013 04:54

Quote:

Originally Posted by Vamos (Post 571928)
Как я понял, запись в буфер происходит слишком быстро и код эмулятора не успевает.

Речь пока не о диагнозе, а об анамнезе - т.е. действительно ли какая-то из функций Windows ( чтение порта, запись порта ) возвращает ошибку или WaitCommEvent рапортует о EV_ERR ?

Vamos 31st January 2013 05:16

Patron, на этот вопрос у меня ответа нет, но вот код, может там чего
Code:

                if (m_SerialInCallback != NULL && frameticks % 416 == 0)
        {
            CFirstMemoryController* pMemCtl = (CFirstMemoryController*) m_pFirstMemCtl;
            if ((pMemCtl->m_Port176574 & 004) == 0)  // Not loopback?
            {
                BYTE b;
                if (m_SerialInCallback(&b))
                                {
                                        if ((pMemCtl->m_Port176570 & 0200) == 0)  // Ready?
                                        {
                                                pMemCtl->m_Port176572 = b;
                                        }
                                        else
                                                {
                                                        pMemCtl->m_Port176570 |= 010000;  // Set Overflow flag
                                                }
                                        pMemCtl->m_Port176570 |= 0200;  // Set Ready flag
                                }
                        }
                }

        if (m_SerialOutCallback != NULL && frameticks % serialOutTicks == 0)
        {
            CFirstMemoryController* pMemCtl = (CFirstMemoryController*) m_pFirstMemCtl;
            if (serialTxCount > 0)
            {
                serialTxCount--;
                if (serialTxCount == 0)  // Translation countdown finished - the byte translated
                {
                    if ((pMemCtl->m_Port176574 & 004) == 0)  // Not loopback?
                                        {
                                                (*m_SerialOutCallback)((BYTE)(pMemCtl->m_Port176576 & 0xff));
                                        }
                                        else  // Loopback
                    {
                        pMemCtl->m_Port176572 = pMemCtl->m_Port176576 & 0xff;
                                                pMemCtl->m_Port176570 |= 0200;  // Set Ready flag
                    }
                    pMemCtl->m_Port176574 |= 0200;  // Set Ready flag
                }
            }
            else if ((pMemCtl->m_Port176574 & 0200) == 0)  // Ready is 0?
            {
                serialTxCount = 8;  // Start translation countdown
            }
        }


nzeemin 31st January 2013 10:27

У меня пока основная гипотеза -- что передача байт из эмулятора происходит без проверки того готов ли к этому COM-порт. Поэтому вероятно мы и видим overrun. Вообще общение с COM-портом у меня построено не на overlapped и не на событиях, а по более простой схеме -- чисто байтовое чтение и запись. При чтении если очередной байт не готов -- он не отдаётся. Но при записи пишется всё не взирая на возможные переполнения.

hobot 31st January 2013 12:44

1 Attachment(s)
Quote:

Originally Posted by Vamos (Post 571930)
если кому попадался этот тест с пунктом 6 (стык С2) поделитесь пожалуйста.

Эта версия TUK.SAV от СЭМЗА, я сейчас потыкался - другой версии не нашёл,
попробуй TS.SAV - просто ради эксперимента?

http://savepic.org/2745756.png

http://savepic.org/2736540.png


и вот ещё отдельный для СА "TSA.SAV"
http://savepic.org/2697628.png

hobot 31st January 2013 12:46

Кажется где-то под С2 было что-то отдельно написано, если откопаю-вспомню выложу сразу.

Patron 31st January 2013 13:41

Quote:

Originally Posted by nzeemin (Post 571950)
Поэтому вероятно мы и видим overrun.

А мы таки видим именно overrun ?

Мы видим именно бит 010000 в регистре статуса приёмника ?

Если да - это неправильная эмуляция.

Вот такой код в принципе ошибочен:
Code:

if (m_SerialInCallback(&b))
{
        if ((pMemCtl->m_Port176570 & 0200) == 0)  // Ready?
        {
                pMemCtl->m_Port176572 = b;
        }
        else
        {
                pMemCtl->m_Port176570 |= 010000;  // Set Overflow flag
        }
        pMemCtl->m_Port176570 |= 0200;  // Set Ready flag
}

Quote:

Вообще общение с COM-портом у меня построено не на overlapped и не на событиях, а по более простой схеме -- чисто байтовое чтение и запись. При чтении если очередной байт не готов -- он не отдаётся. Но при записи пишется всё не взирая на возможные переполнения.
Так и надо.

Но ещё надо учитывать, что драйвер com0com - пакетный. Он не следит за промежутком времени между байтами ( в Windows вообще ни одна программа этого не делает ), поэтому, если эмулятор допускает формирование признака overrun - при работе в Windows этот признак обязательно будет формироваться.

---------- Post added at 11:38 ---------- Previous post was at 11:35 ----------

Здесь даже промежутки времени не столь важны.

Ведь в реальном порту действует квитирование, т.е. байт не может быть принят, если порт не готов. А в эмуляторе может! И даже признак overrun формируется!

---------- Post added at 11:41 ---------- Previous post was at 11:38 ----------

Поэтому - в нынешнем состоянии эмулятор эмулирует работу 1801ВП1-065 по кабелю без линий квитирования. А по такому кабелю ни TU58, ни сеть УКНЦ работать не могут.

Alex_K 31st January 2013 15:39

Quote:

Originally Posted by Patron (Post 571977)
Если да - это неправильная эмуляция.

Вот такой код в принципе ошибочен:
Code:

if (m_SerialInCallback(&b))
{
        if ((pMemCtl->m_Port176570 & 0200) == 0)  // Ready?
        {
                pMemCtl->m_Port176572 = b;
        }
        else
        {
                pMemCtl->m_Port176570 |= 010000;  // Set Overflow flag
        }
        pMemCtl->m_Port176570 |= 0200;  // Set Ready flag
}


А в чем ошибочность кода? Если стоит признак готовности, то данные с приемника не считаны, и при приходе других данных ставится бит переполнения, а принятая посылка теряется.
Quote:

Originally Posted by Patron (Post 571977)
Ведь в реальном порту действует квитирование, т.е. байт не может быть принят, если порт не готов. А в эмуляторе может! И даже признак overrun формируется!
Поэтому - в нынешнем состоянии эмулятор эмулирует работу 1801ВП1-065 по кабелю без линий квитирования. А по такому кабелю ни TU58, ни сеть УКНЦ работать не могут.

А как это так, что байт не может быть принят, если порт не готов? Может, еще как может. Ведь для приема другая сторона его передает, а если она не следит за состояниями линии квитирования, то она может его передать и возможно переполнение. Единственное 1801ВП1-065 не сможет передать байт, если на линии BSYD нет готовности от приемника той стороны.
И кстати в сетевом адаптере линии квитирования не используются, там только прием, передача и земля.

Patron 31st January 2013 15:47

Quote:

Originally Posted by Alex_K (Post 572022)
А в чем ошибочность кода? Если стоит признак готовности, то данные с приемника не считаны, и при приходе других данных ставится бит переполнения, а принятая посылка теряется.

Ошибочность в том, что Windows не исключает приход в программу любого количества байтов без задержки вообще. Это же мы не с аппаратным портом по прерываниям работаем, а опрашиваем входной буфер Windows ёмкостью 3К. Пока Windows занимается своими делами - в этом буфере копятся байты, а когда процесс исполняющейся программы эмулятора получает свой квант - ему вываливаются из буфера все накопившиеся там байты разом.

Quote:

кстати в сетевом адаптере линии квитирования не используются, там только прием, передача и земля.
И это на скорости 57600.. Круто! Быстро же должны работать программы сетевого обмена, чтобы не потерять ни одного байта.

Alex_K 31st January 2013 16:03

Quote:

Originally Posted by Patron (Post 572026)
Ошибочность в том, что Windows не исключает приход в программу любого количества байтов без задержки вообще. Это же мы не с аппаратным портом по прерываниям работаем, а опрашиваем входной буфер Windows ёмкостью 3К. Пока Windows занимается своими делами - в этом буфере копятся байты, а когда процесс исполняющейся программы эмулятора получает свой квант - ему вываливаются из буфера все накопившиеся там байты разом.

Это же с какой скоростью по COM-порту идти данные? Да и как же редко программ должна получать кванты времени?
Проблема может быть в другом. UKNCBTL работает по фреймам, 25 фреймов в секунду. Т.е. быстренько эмулируется 1/25 секунды, обновляется экран, а потом спит в ожидании завершения 1/25 секунды на реальном PC. Вот во время этой спячки и могут придти реальные данные. Но однако же в эмуляторе данные с очереди снимаются со скоростью порта внутри фрейма, поэтому между снятиями данных эмулируемая программа должна успеть прочесть приемник. Если успевает, то и переполнения не будет.
Quote:

Originally Posted by Patron (Post 572026)
И это на скорости 57600.. Круто! Быстро же должны работать программы сетевого обмена, чтобы не потерять ни одного байта.

Быстро. Загрузчик из ПЗУ без прерываний. А в RT-11 драйвер MC.SYS работает в режиме прерываний. Но драйвер MC.SYS не является самим драйвером, а скорее резидентной программой, сидящей на обработке и отправке пакетов по сети.

Titus 31st January 2013 16:07

Quote:

Originally Posted by Alex_K (Post 572027)
UKNCBTL работает по фреймам, 25 фреймов в секунду. Т.е. быстренько эмулируется 1/25 секунды, обновляется экран, а потом спит в ожидании завершения 1/25 секунды на реальном PC.

А чего не 1/50? Почему выбрали каждый второй фрейм?

Patron 31st January 2013 16:34

Quote:

Originally Posted by Alex_K (Post 572027)
между снятиями данных эмулируемая программа должна успеть прочесть приемник. Если успевает, то и переполнения не будет.

Именно так. И проведённые испытания показывают, что как раз и не успевает.

В настройках COM-порта можно сделать дополнительную опцию: Эмулировать OVERRUN - при включении которой чтение из буфера Windows будет работать как сейчас, а при выключении - как надо.

---------- Post added at 14:11 ---------- Previous post was at 14:08 ----------

Quote:

Originally Posted by Titus (Post 572031)
А чего не 1/50?

Даже за 1/50 секунды com0com на скорости 9600 насыпет во входной буфер 20 байтов.

---------- Post added at 14:19 ---------- Previous post was at 14:11 ----------

Хочется же иметь возможность эмулировать как работу по кабелю без квитирования, так и работу по кабелю с квитированием.

Вот выбор этих режимов и надо добавить в окно настроек COM-порта.

Alex_K 31st January 2013 16:35

Quote:

Originally Posted by Patron (Post 572032)
Именно так. И проведённые испытания показывают, что как раз и не успевает.

В эмуляторе еще не сделана корректно эмуляция последовательного порта, вот дождемся нормальной эмуляции, тогда уже можно говорить о переполнении, есть или нет.
Quote:

Originally Posted by Patron (Post 572032)
Ведь нужно же иметь возможность эмулировать как работу по кабелю без квитирования, так работу и по кабелю с квитированием.

Выбор этих режимов и надо добавить в окно настроек COM-порта.

Эмулятор работает рывками по фреймам, так что довольно сложновато это сделать.

Patron 31st January 2013 17:07

Quote:

Originally Posted by Alex_K (Post 572051)
В эмуляторе еще не сделана корректно эмуляция последовательного порта, вот дождемся нормальной эмуляции, тогда уже можно говорить о переполнении, есть или нет.

Т.е. до сих пор неизвестно, устанавливается ли бит переполнения в ходе работы..
А если добавить в это самое место отладочную печать и всё узнать ?

Alex_K 31st January 2013 17:27

Quote:

Originally Posted by Patron (Post 572062)
Т.е. до сих пор неизвестно, устанавливается ли бит переполнения в ходе работы..
А если добавить в это самое место отладочную печать и всё узнать ?

В эмуляторе есть такая функция для вывода сообщения в консоль вроде DebugPrint. Так что можно в интересующие места программы вставлять вывод на консоль.

Patron 31st January 2013 17:27

Если с выключенной эмуляцией оверрана всё заработает - значит оверран эмулируется плохо. Если же и тогда ничего не заработает - значит качество эмуляции оверрана не при чём.

alone 31st January 2013 17:42

Quote:

Originally Posted by Patron (Post 571852)
Сейчас оптимизаторы достигли такой крутизны, что при включённой глобальной оптимизации - вызов целого вороха вложенных функций может скомпилироваться в одну-две ассемблерных команды вообще без всяких вызовов подпрограмм.

Удивительно, почему тогда программы пухнут год от года.

Patron 31st January 2013 18:14

Если загрузчик TU58 использует сигнал BREAK, то он не начнёт нормально работать до тех пор, пока в нужные места эмулятора не будут вставлены вызовы SetCommBreak и ClearCommBreak.

Patron 1st February 2013 18:05

Эксперимент по запуску эмулятора TU58 с "Эмулятором ДВК" показал, что эмуляция сигнала BREAK для работы с эмулятором TU58 через com0com не обязательна.

После запуска - TU58.exe предлагает нажать клавишу [Esc] и пропустить ожидание сигнала BREAK. После чего начинает обрабатывать пакеты в заданном порту, позволяя результативно выполнить в эмуляторе ДВК команды DIR DD: и BOOT DD:

---------- Post added at 16:05 ---------- Previous post was at 14:48 ----------

Выяснилось, что эксперимент по работе с эмулятором TU58 без сигнала BREAK был не вполне корректным - оказывается, и эмулятор последовательного порта в "Эмуляторе ДВК", и адаптер COM-порта в модульном API поддерживают передачу сигнала BREAK. В описании com0com тоже указано, что передача сигнала BREAK не просто поддерживается, а многократно улучшалась.

Однако, эмулятор TU58 начал нормально работать только после отключения ожидания сигнала BREAK нажатием клавиши [Esc].

Так что пока вся эта история с сигналом BREAK выглядит довольно непонятно.

Vamos 1st February 2013 19:26

1 Attachment(s)
как бы вот, после нажатия ESC
http://zx-pk.ru/attachment.php?attac...1&d=1359728766

Patron 1st February 2013 22:59

Quote:

Originally Posted by Vamos (Post 572333)
как бы вот, после нажатия ESC

Когда я отключил в эмуляторе ДВК посылку сигнала BREAK - стало так же, поэтому без посылки BREAK TU58.exe работать не будет.

Посылку BREAK добавить нетрудно - когда программа устанавливает бит 00 в статусе передатчика - нужно вызвать SetCommBreak( hComPort ) ( и ещё можно сделать Sleep(15) - тогда Windows успевает отреагировать до сброса этого бита эмулятором ), а когда программа обнуляет установленный бит 00 - нужно вызвать ClearCommBreak( hComPort ) ( здесь Sleep уже не нужен ).

---------- Post added at 20:45 ---------- Previous post was at 19:45 ----------

Хотя, если внимательнее присмотреться к сообщениям TU58.exe:
Code:

command 2 count 800 block 2
получается, что эмулятор опознал и выполнил команду чтения вторичного загрузчика.

Поэтому, ситуация с сигналом BREAK в данном конкретном случае не вполне ясна - если TU58.exe и без сигнала BREAK передал загрузчик, то на чём всё потом остановилось..

Однако, когда я отключил BREAK в эмуляторе ДВК и дал DIR DD: - эффект был нулевой, а с посылкой BREAK - всё работало как надо.

---------- Post added at 20:49 ---------- Previous post was at 20:45 ----------

Возможно, в последнем случае дело было не в самом сигнале BREAK, а в том, что при подаче BREAK эмулятор делал Sleep(15) - вот TU58.exe и успевал ответить до отвала драйвера DD.SYS по таймауту.

Сейчас проверю эту гипотезу..

---------- Post added at 20:59 ---------- Previous post was at 20:49 ----------

ДА! TU58.exe нормально работает без BREAK !!!

Если вместо сигнала BREAK просто делать Sleep(15) - TU58.exe без проблем обслуживает любые запросы драйвера DD.SYS

Только что загрузил RT-11 c DD: с отключенной посылкой BREAK.

Vamos 1st February 2013 23:01

1 Attachment(s)
Quote:

Originally Posted by Patron (Post 572356)
то на чём всё потом остановилось..

вот на этом

http://zx-pk.ru/attachment.php?attac...1&d=1359741657

Patron 1st February 2013 23:29

Quote:

Originally Posted by Vamos (Post 572388)
вот на этом

Т.е. загрузчик успешно прочитался, успешно запустился и довольно много чего читает.

Есть уже отладочная печать в том месте, где бит переполнения устанавливается ?
Из-за переполнения проблема или нет ?

Vamos 1st February 2013 23:48

1 Attachment(s)
Quote:

Originally Posted by Patron (Post 572400)
Есть уже отладочная печать в том месте, где бит переполнения устанавливается ?

У меня нет.

Quote:

Originally Posted by Patron (Post 572400)
Из-за переполнения проблема или нет ?

видимо нет. видимо BREAK
http://zx-pk.ru/attachment.php?attac...1&d=1359744341

Подскажите куда втыкать SetCommBreak, там где порт инициализируется или там где бит 00 обрабатывается.

Patron 2nd February 2013 00:29

Quote:

Originally Posted by Vamos (Post 572403)
куда втыкать SetCommBreak

Вот сюда:
Code:

void CFirstMemoryController::SetPortByte(WORD address, BYTE byte)
{
    WORD word = (address&1)?((WORD)byte) << 8:(WORD)byte;
    switch (address) {
        case 0176574:  // Стык С2: Регистр состояния передатчика
        case 0176575:
            if (((m_Port176574 & 0300) == 0200) && (word & 0100))
                m_pProcessor->InterruptVIRQ(8, 0374);
            if (word & 01)
            {
                if (!(m_Port176574 & 01))
                { // BREAK
                    SetCommBreak( m_hEmulatorComPort );
                    Sleep(15);
                }
            }
            else
            if (m_Port176574 & 01)
                ClearCommBreak( m_hEmulatorComPort );

            m_Port176574 = (m_Port176574 & ~0105) | (word & 0105);
            break;
    }
}

void CFirstMemoryController::SetPortWord(WORD address, WORD word)
{
    switch (address) {
        case 0176574:  // Стык С2: Регистр состояния передатчика
        case 0176575:
            if (((m_Port176574 & 0300) == 0200) && (word & 0100))
                m_pProcessor->InterruptVIRQ(8, 0374);
            if (word & 01)
            {
                if (!(m_Port176574 & 01))
                { // BREAK
                    SetCommBreak( m_hEmulatorComPort );
                    Sleep(15);
                }
            }
            else
            if( m_Port176574 & 01 )
                ClearCommBreak( m_hEmulatorComPort );

            m_Port176574 = (m_Port176574 & ~0105) | (word & 0105);
            break;
    }
}


nzeemin 2nd February 2013 18:10

Я вот думаю -- не проще ли сразу после SystemFrame() вызвать SetCommBreak(), а непосредственно перед SystemFrame() сделать ClearCommBreak().
Если проблема действительно в паузе между фреймами, это может помочь.

---------- Post added at 17:10 ---------- Previous post was at 17:00 ----------

Попробовал -- не помогает.
Кроме того, я пробовал запускать загрузку по сети когда оба эмулятора работают на полной скорости (без звука) -- загрузка тоже падает с ошибкой.


All times are GMT +4. The time now is 02:55.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.