Очереди в коде две, т.к. два процессора. В ПП действительно 7 и 9 очередь занята приемниками каналов 1 и 2, но это ПП, а не ЦП.
Patron, извините за оффтоп
Скрытый текст
Это должно быть именно в этой функции кода или можно поместить вот сюдаКод:void CFirstMemoryController::SetPortWord(WORD address, WORD word)
{
switch (address) {
case 0176574: // Стык С2: Регистр состояния источника
case 0176575: // Bits 0,2,6
if(((m_Port176574 & 0300) == 0200) && (word & 0100))
{
m_pCPU->InterruptVIRQ(8, 0374);
}
m_Port176574 = (m_Port176574 & ~0105) | (word & 0105);
break;
case 0176576: // Стык С2: Регистр данных источника
case 0176577: // нижние 8 бит доступны по записи
m_Port176576 = word & 0xff;
m_Port176574 &= ~128; // Reset bit 7 (Ready)
break;
}
}
А то там код и так раскидан по разным местам.Код: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->SerialInput(b) && (pMemCtl->m_Port176570 & 0100))
m_pCPU->InterruptVIRQ(3, 0370);
}
}
}
[свернуть]
Для реализации прерываний портов СА и С2 нужно модифицировать не только функцию void CFirstMemoryController::SetPortWord(WORD address, WORD word), но и void CFirstMemoryController::SetPortByte(WORD address, BYTE byte), которая в данный момент выглядит довольно бледно.
См. ЗДЕСЬ.
Чувствую, что последовательный порт нас ещё удивит..
Вот адаптированный код инициализации TU58 из драйвера DD.SYS:
В большинстве эмуляторов этот код посылает 377, 0, 4, 4. Тогда как на реальном порту он должен посылать 0+FrameError, 4, 4. Порт не может послать в линию отмену FrameError - принимающая сторона снимает признак FrameError после приёма полноценного байта, а признак Break ( в тех портах, где он определяется отдельно ) снимает после приёма первого бита "1" ( перевода линии в состояние IDLE ).Код:MOV #177777, @#TPB
BIS #<CS$INT!CS$BRK>, @#TPS
TSTB @#TPS
BPL .-4.
MOV #177777, @#TPB
TSTB @#TPS
BPL .-4.
BIC #CS$BRK,@#TPS
MOV #4, @#TPB
TSTB @#TPS
BPL .-4.
MOV #4, @#TPB
TSTB @#TPS
BPL .-4.
BIC #CS$INT,@#TPS
Только вчера я понял, почему код инициализации TU58 из DD.SYS в реальности должен посылать ( есть смысл это проверить ) не 4, а лишь 3 байта ( 0+FrameError, 4, 4 ) - BREAK снимается во время передачи стартового бита второго байта 377, поэтому весь последующий байт распознаётся принимающим портом не как байт, а как перевод линии в состояние IDLE, предшествующее стартовому биту очередной посылки.
Кстати, если во втором байте передать хотя бы один 0-й бит, то он (скорее всего) будет распознан как стартовый с весьма оригинальными последствиями в зависимости от его позиции ( если установленный в 1 бит посылки байта 04 придётся на место стопового - будут переданы два фиктивных байта, иначе возникнет переходящая ошибка FrameErrror и только последний байт 04 будет нормально принят, хотя и с фиктивным значением ).
Если я правильно понимаю суть работы последовательного порта, то при работе без бита паритета возможна передача байтов без FrameError при несовпадающих скоростях передачи и приёма.
Если принимать на скорости 9600, то при передаче байта 0377 ( 11111111 ) будет принято (в зависимости от скорости передачи) следующее:
1. 9600 - 11111111 ( 0377 )
2. 4800 - 11111110 ( 0376 )
3. 2400 - 11111000 ( 0370 )
4. 1200 - 10000000 ( 0200 )
Так как стартовый бит при меньших скоростях передачи будет "длиннее", а передаваемые единицы сыграют роль недостающих битов байта и стопового бита.
Нарисовал небольшую темплату для написания тестов с регистрами терминала, работающих как в однотерминальном так и в многотерминальном мониторе.
Здесь нет переключения в кернел режим, но в данном примере он и не нужен.
Код:.TITLE MTATT
.IDENT /V01.00/
TKS == 176500 ;CSR ТЕСТИРУЕМОГО УСТРОЙСТВА
$JSX == 4 ;РАСШИРЕННОЕ СЛОВО СОСТОЯНИ ЗАДАНИЯ
NOVBG$ == 100 ;БИТ ЗАПРЕТА VBGEXE
$SYPTR == 54 ;УКАЗАТЕЛЬ НА RMON
$CNFG1 == 300 ;СМЕЩЕНИЕ СЛОВА КОНФИГУРАЦИИ
FJOB$ == 200 ;БИТ ЗАГРУЗКИ FOREGROUND
$SYSGE == 372 ;СМЕЩЕНИЕ СЛОВА ГЕНЕРАЦИИ
MTTY$ == 20000 ;БИТ МНОГОТЕРМИНАЛЬНОЙ ПОДДЕРЖКИ
MST.1T == 0 ;СМЕЩЕНИЕ ДО ПЕРВОГО TCB
MST.CT == 2 ;СМЕЩЕНИЕ ДО TCB ПРОГРАММЫ
MST.LU == 4 ;МАКСИМАЛЬНЫЙ НОМЕР ЛИНИИ
MST.ST == 6 ;РАЗМЕР TCB
T.CSR == 16 ;АДРЕС CSR ТЕРМИНАЛА
.ASECT ;ЗАПРЕТ ЗАПУСКА ПОД VBGEXE
.=$JSX ;
.WORD NOVBG$ ;
.PSECT ;
.MCALL .EXIT,.MTSTAT,.PRINT ;МАКРОВЫЗОВЫ
$TKS:: .WORD TKS ;АДРЕС CSR (ЧТОБЫ ЛЕГЧЕ БЫЛО МЕНЯТЬ
;БЕЗ ПЕРЕСБОРКИ)
START:: MOV @#$SYPTR,R3 ;ПОЛУЧАЕМ АДРЕС RMON
; ПРОВЕРЯЕМ НЕТ ЛИ В ПАМЯТИ FOREGROUND/SYSTEM ПРОГРАММЫ.
; ПРИ НАЛИЧИИ ТАКОЙ ПРОГРАММЫ В ПАМЯТИ ЖЕЛЕЗО ЛУЧШЕ НЕ ТРОГАТЬ
; ЧТОБЫ ПОТОМ НЕ БЫЛО МУЧИТЕЛЬНО БОЛЬНО ЗА БЕСЦЕЛЬНО ПОТЕРЯННОЕ
; СОДЕРЖИМОЕ ДИСКА...
TSTB $CNFG1(R3) ;FOREGROUND LOADED?
BPL 10$ ;НЕТ
.PRINT #EFJOB ;ДА, ОШИБКА
.EXIT ;ВЫХОД
10$: MOV $TKS,R5 ;ПОЛУЧАЕМ АДРЕС CSR
BIT #MTTY$,$SYSGE(R3) ;МНОГОТЕРМИНАЛЬНАЯ СИСТЕМА?
BEQ 50$ ;НЕТ
.MTSTAT #AREA,#TSTAT ;ДА, ПОЛУЧАЕМ ИНФОРМАЦИЮ
BCC 20$ ;ОК
.PRINT #EMTST ;ОШИБКА (ПО ИДЕЕ НЕВОЗМОЖНА)
.EXIT ;ВЫХОД
20$: MOV R3,R4 ;ПОЛУЧАЕМ АДРЕС
ADD TSTAT+MST.1T,R4 ;...ПЕРВОГО TCB
MOV TSTAT+MST.LU,R1 ;ПОЛУЧАЕМ КОЛИЧЕСТВО
INC R1 ;...ЛИНИЙ
30$: CMP R5,T.CSR(R4) ;ИЩЕМ СОВПАДЕНИЕ
BNE 40$ ;
MOV #FAKE,T.CSR(R4) ;ПОДСТАВЛЯЕМ ЛЕВЫЙ CSR
BR 50$ ;
40$: ADD TSTAT+MST.ST,R4 ;ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ
SOB R1,30$ ;...TCB
CLR R4 ;СОВПАДЕНИЯ НЕ НАЙДЕНО
50$: CLR @R5 ;ЗАПРЕЩАЕМ ПРЕРЫВАНИЯ
60$: TSTB @R5 ;O
BPL .-2 ; F T
MOVB 2(R5),R0 ; F E
CMPB #'C-100,R0 ; L R
BEQ 70$ ; I M
TSTB 4(R5) ; N I
BPL .-4 ; E N
MOVB R0,6(R5) ; A
BR 60$ ; L
70$: TST R4 ;БЫЛ НАЙДЕН TCB?
BEQ 80$ ;НЕТ
MOV R5,T.CSR(R4) ;ДА. ВОССТАНАВЛИВАЕМ CSR
80$: .EXIT ;ВЫХОДИМ
FAKE:: .BLKW 4 ;ПОДСТАВНЫЕ РЕГИСТРЫ
AREA:: .BLKW 3 ;EMT AREA
TSTAT:: .BLKW 8. ;БЛОК ИНФОРМАЦИИ
EFJOB: .ASCIZ /?MTATT-F-Foreground loaded/
EMTST: .ASCIZ /?MTATT-F-MTSTAT failed/
.END START
---------- Post added at 17:29 ---------- Previous post was at 17:28 ----------
Да.
---------- Post added at 17:39 ---------- Previous post was at 17:29 ----------
Потерялся CLR R4 один в проге выше, а редактировать в этом кривофоруме никак не хочет. Ну да по смыслу понятно :)
Для тестирования работы последовательных портов с сигналом BREAK - мною написаны тесты BRKT1 и BRKT2. Оба требуют наличия с другой стороны тестируемой линии специального тестового варианта сервера HX Server, который умеет по запросу клиента посылать в линию сигнал BREAK, а также превращает получаемые в порту сигналы в текстовые сообщения.
Для проведения тестов нужно запустить прилагаемый HX Server на порту PC, подключенному к УКНЦ, ДВК или PDP-11, а на другой стороне - запускать программы BRKT1.SAV и BRKT2.SAV. Если адрес и вектор используемого со стороны PDP-11 порта отличаются от адреса и вектора порта С2 УКНЦ - программы следует перекомпилировать, указав в исходниках нужные значения.
Результаты тестирования сервер выводит в окно Teletype и сохраняет в файле Teletype.log.Код:TKS =: 176570
TKINT =: 370
TTKS =: 176570
Запускать тесты на УКНЦ можно загрузившись с HX - на этот случай в дистрибутиве тестового сервера уже находится образ BRKT1_&_BRKT2.DSK, подключенный к приводу HX1:
...
Запустил на своем нотебяке с USB<>2COM от St Lab.
Завтра попробую приличный комп проверить.
Код:===================================
BRKT1 - Test COM-port BREAK Part #1
===================================
Test 1: Ask HX Server for 0.3 ms BREAK..
Recived bytes: «376»
Test 2: Ask HX Server for 1 ms BREAK..
Recived bytes: «200»
Test 3: Ask HX Server for 2 ms BREAK..
Recived bytes: «000»
Test 4: Ask HX Server for 20 ms BREAK..
Recived bytes: «000»
Test 5: Ask HX Server for 50 ms BREAK..
Recived bytes: «000»
===================================
BRKT2 - Test COM-port BREAK Part #2
===================================
Test 1: Send SHORT BREAK..
«377»
Test 2: Send 1 byte BREAK..
«000»_Break__Break_EAK..
Test 3: Send 2 byte BREAK..
_Break_«000»
Test 4: Send 3 byte BREAK..
«000»_Break_
Test 5: Send 10 byte BREAK..
_Break__Break_«000»
Test 6: Send 20 byte BREAK..
«000»_Break__Break_
Test 7: Send Bad Frame 1 ..
«000»_Break_«216»«004»
Test 8: Send Bad Frame 2 ..
_Break__Break_«000»