Немига 303 ROM disasm — различия между версиями

Материал из Emuverse
Перейти к: навигация, поиск
(Новая страница: «{{Emuverse}} Источник: https://github.com/nzeemin/nemigabtl/blob/master/docs/nemiga-303.lst <pre> ; Дизассемблированное ПЗУ комп…»)
 
 
Строка 5: Строка 5:
 
;
 
;
  
000204: DW ; REV    Рабочий регистр
+
000004: DW ; Адрес прерывания
000206: DW ; VFORM
+
000006: DW ; PSW прерывания
000210: DW ; BRIGHT
+
 
000212: DW ; XNEW
+
000060: DW ; Прерывание клавиатура
000214: DW ; YNEW
+
000062: DW ; PSW прерывания
000216: DW ; XOLD
+
000064: DW ; Прерывание дисплей
000220: DW ; YOLD
+
000066: DW ; PSW прерывания
 +
 
 +
000100: DW
 +
 
 +
000110; DW ; Прерывание "мелодия закончилась кодом 040"
 +
000112: DW ; PSW прерывания
 +
 
 +
000204: DW ; REV    - рабочий регистр
 +
000206: DW ; VFORM - регистр вертикального формата
 +
000210: DW ; BRIGHT - регистр яркости (0..3)
 +
000212: DW ; XNEW   - регистр новой X-координаты
 +
000214: DW ; YNEW   - регистр новой Y-координаты
 +
000216: DW ; XOLD   - регистр старой X-координаты
 +
000220: DW ; YOLD   - регистр старой Y-координаты
  
 
; ==== Начало ПЗУ ====
 
; ==== Начало ПЗУ ====
160000: DW 177570 ; ??
+
160000: DW 177570 ; ??
160002: DW 160210, 000341 ; Вектор прерывания сигнала/команды HALT
+
160002: DW 160210, 000341 ; Вектор прерывания сигнала/команды HALT
 
160006: DW 162010, 000340 ; Вектор прерывания начального пуска
 
160006: DW 162010, 000340 ; Вектор прерывания начального пуска
 
160012: DW 161126, 000340 ; Вектор прерывания??
 
160012: DW 161126, 000340 ; Вектор прерывания??
160016: JMP    @#163512 ; MODE3
+
160016: JMP    @#163512 ; MODE3 - Вызов с запретом системных прерываний
160022: JMP    @#163532 ; SYSLIN -- Вывод в служебную строку
+
160022: JMP    @#163532 ; SYSLIN - Вывод в служебную строку
160026: JMP    @#163734 ; TT.OUT
+
160026: JMP    @#163734 ; TT.OUT - Системный вывод через MODE
160032: JMP    @#163740 ; SYSOUT
+
160032: JMP    @#163740 ; SYSOUT - Системный вывод
160036: JMP    @#162342 ; PRINT
+
160036: JMP    @#162342 ; PRINT - Вывод текста
160042: JMP    @#165344 ; DRAW  -- Нарисовать линию, сохранив XOLD,YOLD
+
160042: JMP    @#165344 ; DRAW  - Нарисовать линию, сохранив XOLD,YOLD
 
160046: JMP    @#165336 ; QDRAW    то же для QUASIC
 
160046: JMP    @#165336 ; QDRAW    то же для QUASIC
 
160052: JMP    @#165340 ; FDRAW    то же для FORTRAN
 
160052: JMP    @#165340 ; FDRAW    то же для FORTRAN
160056: JMP    @#165374 ; LINE  -- Нарисовать линию
+
160056: JMP    @#165374 ; LINE  - Нарисовать линию
 
160062: JMP    @#165366 ; QLINE    то же для QUASIC
 
160062: JMP    @#165366 ; QLINE    то же для QUASIC
 
160066: JMP    @#165370 ; FLINE    то же для FORTRAN
 
160066: JMP    @#165370 ; FLINE    то же для FORTRAN
160072: JMP    @#165604 ; POINT  -- Нарисовать точку
+
160072: JMP    @#165604 ; POINT  - Нарисовать точку
 
160076: JMP    @#165576 ; QPOINT    то же для QUASIC
 
160076: JMP    @#165576 ; QPOINT    то же для QUASIC
 
160102: JMP    @#165600 ; FPOINT    то же для FORTRAN
 
160102: JMP    @#165600 ; FPOINT    то же для FORTRAN
160106: JMP    @#165670 ; RPOINT -- Читать яркость точки
+
160106: JMP    @#165670 ; RPOINT - Читать яркость точки
 
160112: JMP    @#165660 ; QRPOIN    то же для QUASIC
 
160112: JMP    @#165660 ; QRPOIN    то же для QUASIC
 
160116: JMP    @#165662 ; FRPOIN    то же для FORTRAN
 
160116: JMP    @#165662 ; FRPOIN    то же для FORTRAN
160122: JMP    @#162304 ; DUMP -- напечатать восьмеричное число R3
+
160122: JMP    @#162304 ; DUMP   - напечатать восьмеричное число R3
160126: JMP @177754 ; SOUND
+
160126: JMP     @177754 ; SOUND
  
 
; ==== Обработчики прерываний ========================================================
 
; ==== Обработчики прерываний ========================================================
Строка 62: Строка 75:
 
160242: BMI 160142 ; Канальный сигнал СБРОС? => переходим
 
160242: BMI 160142 ; Канальный сигнал СБРОС? => переходим
 
160244: BEQ 160202 ; 6 ст битов пусты - кнопка ОСТ?? => переходим
 
160244: BEQ 160202 ; 6 ст битов пусты - кнопка ОСТ?? => переходим
160246: BIT #004000, @#170006 ; Сигнал Н4? -- адаптер локальной сети
+
160246: BIT #004000, @#170006 ; Сигнал Н4? - адаптер локальной сети
 
160254: BEQ 160262 ; Нет
 
160254: BEQ 160262 ; Нет
 
160256: CALL @000104 ; ??
 
160256: CALL @000104 ; ??
160262: BIT #040000, @#170006 ; Сигнал Н1? -- обращение к 177566
+
160262: BIT #040000, @#170006 ; Сигнал Н1? - обращение к 177566
 
160270: BEQ 160302 ; Нет
 
160270: BEQ 160302 ; Нет
 
160272: MOV @#177566, R0 ; Регистр данных терминала
 
160272: MOV @#177566, R0 ; Регистр данных терминала
 
160276: CALL @#163740 ; SYSOUT Вывод символа R0 на экран
 
160276: CALL @#163740 ; SYSOUT Вывод символа R0 на экран
160302: BIT #020000, @#170006 ; Сигнал Н2? -- обращение к 177562
+
160302: BIT #020000, @#170006 ; Сигнал Н2? - обращение к 177562
 
160310: BEQ 160334 ; Нет
 
160310: BEQ 160334 ; Нет
160312: MOVB @#177767, R0 ; Провека буферной ячейки??
+
160312: MOVB @#177767, R0 ; Провека буферной ячейки клавиатуры
160316: BEQ 160326 ; Буфер пуст
+
160316: BEQ 160326 ; буфер пуст => переходим
 
160320: CLRB @#177767 ; Очищаем буфер
 
160320: CLRB @#177767 ; Очищаем буфер
 
160324: BR 160520
 
160324: BR 160520
Строка 80: Строка 93:
 
160344: BEQ 160600 ; Нет
 
160344: BEQ 160600 ; Нет
 
160346: BIC #177400, R0 ; Оставляем байт поступивший с клавиатуры
 
160346: BIC #177400, R0 ; Оставляем байт поступивший с клавиатуры
160352: BEQ 160202 ; Символ 00 -- СТОП?
+
160352: BEQ 160202 ; Символ 00 - СТОП?
 
; Звук нажатия клавиши
 
; Звук нажатия клавиши
 
160354: MOV R1, -(SP)
 
160354: MOV R1, -(SP)
Строка 88: Строка 101:
 
160366: CALL @#160126 ; SOUND
 
160366: CALL @#160126 ; SOUND
 
160372: BR 160402
 
160372: BR 160402
160374: DW 160376 ; Адрес мелодии
+
160374: DW 160376 ; Адрес мелодии нажатия клавиши
 
160376: DB 011, 214, 001, 000 ; Мелодия - звук длиной 1/50 сек
 
160376: DB 011, 214, 001, 000 ; Мелодия - звук длиной 1/50 сек
 
160402: MOV #177766, R1
 
160402: MOV #177766, R1
Строка 120: Строка 133:
 
160514: MOV (SP)+, R2
 
160514: MOV (SP)+, R2
 
160516: MOV (SP)+, R1
 
160516: MOV (SP)+, R1
160520: MOV R0, @#177562 ; Записываем символ в рег.данных клавиатуры
+
160520: MOV R0, @#177562 ; Заносим символ в рег.данных клавиатуры
 
160524: MOV (SP)+, R0
 
160524: MOV (SP)+, R0
160526: BIS #000200, @#177560 ; Состояние клавиатуры -- сброс бита готовности
+
160526: BIS #000200, @#177560 ; Состояние клавиатуры - сброс бита готовности
160534: BIT #000100, @#177560 ; Состояние клавиатуры -- разрешено прерывание?
+
160534: BIT #000100, @#177560 ; Состояние клавиатуры - разрешено прерывание?
 
160542: BEQ 161060 ; нет => Завершаем обработку прерывания HALT
 
160542: BEQ 161060 ; нет => Завершаем обработку прерывания HALT
 
160544: BISB  #000001, @#177766
 
160544: BISB  #000001, @#177766
Строка 135: Строка 148:
 
160600: MOV (SP)+, R0 ; Восстанавливаем R0
 
160600: MOV (SP)+, R0 ; Восстанавливаем R0
 
160602: BIT #010000, @#170006 ; Сигнал Н3?
 
160602: BIT #010000, @#170006 ; Сигнал Н3?
160610: BEQ 161060 ; Нет => Завершаем обработку прерывания HALT
+
160610: BEQ 161060 ; нет => Завершаем обработку прерывания HALT
 
; Обработка сигнала Н3 - кадровый синхроимпульс, 50 Гц
 
; Обработка сигнала Н3 - кадровый синхроимпульс, 50 Гц
 
160612: MOV R4, -(SP) ; Сохраняем R4
 
160612: MOV R4, -(SP) ; Сохраняем R4
Строка 163: Строка 176:
 
160720: MOV    (SP)+, R4
 
160720: MOV    (SP)+, R4
 
160722: CLRB  @#170006 ; Разрешаем системные прерывания
 
160722: CLRB  @#170006 ; Разрешаем системные прерывания
; Переход на прерывание по вектору 110
+
160726: MOV    @#000110, PC ; Переход на прерывание по вектору 110
160726: MOV    @#000110, PC
+
 
; Окончание мелодии байтом 140
 
; Окончание мелодии байтом 140
 
160732: CLRB  (R4) ; Очистка байта после конца мелодии
 
160732: CLRB  (R4) ; Очистка байта после конца мелодии
Строка 209: Строка 221:
 
161154: MOV R2, -(SP) ; -> 177724
 
161154: MOV R2, -(SP) ; -> 177724
 
161156: MOV R1, -(SP) ; -> 177722
 
161156: MOV R1, -(SP) ; -> 177722
161160: MOV R0, -(SP) ; -> 177720 -- начало блока регистров
+
161160: MOV R0, -(SP) ; -> 177720 - начало блока регистров
 
161162: MOV @#000004, -(SP)
 
161162: MOV @#000004, -(SP)
 
161166: MOV @#000006, -(SP)
 
161166: MOV @#000006, -(SP)
Строка 221: Строка 233:
 
; ==== Программа пультового терминала ================================================
 
; ==== Программа пультового терминала ================================================
 
;
 
;
; Просмотр ячеек памяти -- переход к следующему слову
+
; Просмотр ячеек памяти - переход к следующему слову
 
161226: INC R2
 
161226: INC R2
 
161230: INC R2
 
161230: INC R2
Строка 240: Строка 252:
 
161302: BEQ 161406 ; Да, возвращамся в пульт
 
161302: BEQ 161406 ; Да, возвращамся в пульт
 
161304: CMPB #000136, R0 ; Нажали '^' ?
 
161304: CMPB #000136, R0 ; Нажали '^' ?
161310: BNE 161516 ; Нет -- выводим признак ошибки и в пульт
+
161310: BNE 161516 ; Нет - выводим признак ошибки и в пульт
 
161312: DEC R2 ; Переходим к предыдущему слову памяти
 
161312: DEC R2 ; Переходим к предыдущему слову памяти
 
161314: DEC R2
 
161314: DEC R2
Строка 294: Строка 306:
 
161522: BR 161412
 
161522: BR 161412
 
;
 
;
; Команда 'S' -- вывод на экран регистров процессора
+
; Команда 'S' - вывод на экран регистров процессора
 
161524: MOV #000011, R2 ; 9 регистров
 
161524: MOV #000011, R2 ; 9 регистров
 
161530: MOV #161556, R5 ; Строка с названиями регистров
 
161530: MOV #161556, R5 ; Строка с названиями регистров
Строка 305: Строка 317:
 
161556: DB ... ; Строка с названиями регистров ЦП
 
161556: DB ... ; Строка с названиями регистров ЦП
  
; Команда 'X' -- загрузка с устройства DX
+
; Команда 'X' - загрузка с устройства DX
 
; (код загрузчика практически повторяет код загрузчика с DX/RX01 из ПЗУ ДВК)
 
; (код загрузчика практически повторяет код загрузчика с DX/RX01 из ПЗУ ДВК)
 
161646: MOV #100247, R2
 
161646: MOV #100247, R2
Строка 337: Строка 349:
 
161762: CLR    PC ; Запуск полученного блока
 
161762: CLR    PC ; Запуск полученного блока
 
;
 
;
; Команда 'D' -- загрузка с диска
+
; Команда 'D' - загрузка с диска
 
161764: CMP R5, #000007 ; Номер устройства больше 7?
 
161764: CMP R5, #000007 ; Номер устройства больше 7?
 
161770: BHI 161516 ; Да => показать признак ошибки, возврат в пульт
 
161770: BHI 161516 ; Да => показать признак ошибки, возврат в пульт
Строка 350: Строка 362:
 
162010: MOV #001000, SP ; Устанавливаем стек
 
162010: MOV #001000, SP ; Устанавливаем стек
 
162014: CLR R0
 
162014: CLR R0
162016: MOV #056311, -(R0) ; Сохраняем признак режима HALT -> (177776)
+
162016: MOV #056311, -(R0) ; -> (177776)
162022: MOV #166064, -(R0) ; Адрес знакогенератора -> (177774)
+
162022: MOV #166064, -(R0) ; Адрес стандартного знакогенератора -> (177774)
 
162026: MOV #000010, R1
 
162026: MOV #000010, R1
 
162032: CLR -(R0) ; <|
 
162032: CLR -(R0) ; <|
Строка 382: Строка 394:
 
162200: MOV    000002(R4), R2 ; Получили количество слов в блоке
 
162200: MOV    000002(R4), R2 ; Получили количество слов в блоке
 
162204: MOV    R2, R3
 
162204: MOV    R2, R3
162206: ASL    R3 ; Удваиваем -- получаем адрес за концом блока
+
162206: ASL    R3 ; Удваиваем - получаем адрес за концом блока
 
162210: CMP    (R3)+, (R3)+ ; Сдвигаем R3 ещё на 2 слова вперёд
 
162210: CMP    (R3)+, (R3)+ ; Сдвигаем R3 ещё на 2 слова вперёд
 
162212: MOV    R3, SP ; Новый стек
 
162212: MOV    R3, SP ; Новый стек
162214: CLR    R0 ; R0 = 0 -- адрес куда читаем блок
+
162214: CLR    R0 ; R0 = 0 - адрес куда читаем блок
 
162216: CALL  @#162252 ;<| Ожидаем слово из сети
 
162216: CALL  @#162252 ;<| Ожидаем слово из сети
 
162222: MOV    000002(R4), (R0)+ ; | Сохраняем полученое слово
 
162222: MOV    000002(R4), (R0)+ ; | Сохраняем полученое слово
Строка 394: Строка 406:
 
162240: BIS    #000200, @#177766
 
162240: BIS    #000200, @#177766
 
162246: JMP    @#161060 ; разрешение прерываний и RTI
 
162246: JMP    @#161060 ; разрешение прерываний и RTI
; Подпрограмма -- ожидание слова из сети
+
; Подпрограмма - ожидание слова из сети
 
162252: MOV    #037777, R1 ; счётчик ожидания
 
162252: MOV    #037777, R1 ; счётчик ожидания
 
162256: BIT    #100040, (R4)
 
162256: BIT    #100040, (R4)
Строка 420: Строка 432:
 
162336: ROL R0
 
162336: ROL R0
 
162340: SOB R1, 162312
 
162340: SOB R1, 162312
; Подпрограмма PRINT -- Вывод строки на экран; R5 = адрес строки
+
; Подпрограмма PRINT - Вывод строки на экран; R5 = адрес строки
 
162342: MOVB (R5)+, R0 ; Очередной символ
 
162342: MOVB (R5)+, R0 ; Очередной символ
 
162344: BNE 162350 ; Не ноль?
 
162344: BNE 162350 ; Не ноль?
Строка 473: Строка 485:
 
162560: MOV R3, -(SP) ; Сохраняем R3
 
162560: MOV R3, -(SP) ; Сохраняем R3
 
162562: MOVB (R4)+, R3
 
162562: MOVB (R4)+, R3
162564: BIC #177760, R3 ; Оставляем нижние 4 бита -- 00..17
+
162564: BIC #177760, R3 ; Оставляем нижние 4 бита - 00..17
 
162570: ASL R3 ; и умножаем на 2
 
162570: ASL R3 ; и умножаем на 2
 
162572: MOV 162624(R3), @#170022 ; Выбираем по R3 слово и пишем в первый счётчик
 
162572: MOV 162624(R3), @#170022 ; Выбираем по R3 слово и пишем в первый счётчик
Строка 501: Строка 513:
 
163030: MOV R4, -(SP) ; Сохраняем R4
 
163030: MOV R4, -(SP) ; Сохраняем R4
 
163032: MOV #000006, R1 ; Повторять 6 раз
 
163032: MOV #000006, R1 ; Повторять 6 раз
163036: MOV #000070, R0 ;<| Команда -- мотор и ШАГ ВПЕРЁД
+
163036: MOV #000070, R0 ;<| Команда - мотор и ШАГ ВПЕРЁД
 
163042: CALL @#163342 ; | Готовимся и запускаем команду
 
163042: CALL @#163342 ; | Готовимся и запускаем команду
 
163046: SOB R1, 163036 ; / Повтор цикла
 
163046: SOB R1, 163036 ; / Повтор цикла
163050: MOV #000030, R0 ; Команда -- мотор и ШАГ НАЗАД
+
163050: MOV #000030, R0 ; Команда - мотор и ШАГ НАЗАД
 
163054: CALL @#163342 ; Готовимся и запускаем команду
 
163054: CALL @#163342 ; Готовимся и запускаем команду
 
163060: CLR @#177106 ; Сбрасываем таймер
 
163060: CLR @#177106 ; Сбрасываем таймер
Строка 513: Строка 525:
 
163100: CLR @#177106 ;<| Сбрасываем таймер
 
163100: CLR @#177106 ;<| Сбрасываем таймер
 
163104: BIT R4, (R5) ; | Сброшен RELOAD ?
 
163104: BIT R4, (R5) ; | Сброшен RELOAD ?
163106: BEQ 163116 ; | Да -- переходим к чтению секторов
+
163106: BEQ 163116 ; | Да - переходим к чтению секторов
 
163110: SOB R2, 163100 ; / Ждём
 
163110: SOB R2, 163100 ; / Ждём
 
163112: JMP @#163332
 
163112: JMP @#163332
Строка 522: Строка 534:
 
163130: CLR @#004000
 
163130: CLR @#004000
 
163134: MOV @#004000, R0
 
163134: MOV @#004000, R0
163140: MOVB 004016(R0), R0 ; Первый байт -- кол-во секторов на 0-й дорожке
+
163140: MOVB 004016(R0), R0 ; Первый байт - кол-во секторов на 0-й дорожке
 
163144: MOV #004140, R3 ; Куда читать дорожку
 
163144: MOV #004140, R3 ; Куда читать дорожку
 
163150: CALL @#163402 ; Прочитать сектора
 
163150: CALL @#163402 ; Прочитать сектора
Строка 592: Строка 604:
 
163402: MOV R3, R1
 
163402: MOV R3, R1
 
163404: MOV R0, -(SP) ; Запомним кол-во секторов
 
163404: MOV R0, -(SP) ; Запомним кол-во секторов
163406: MOV #000012, R4 ; 10 -- размер заголовка дорожки
+
163406: MOV #000012, R4 ; 10 - размер заголовка дорожки
163412: ADD #000202, R4 ; 130 -- размер сектора
+
163412: ADD #000202, R4 ; 130 - размер сектора
 
163416: SOB R0, 163412 ; Умножим 130 на кол-во секторов
 
163416: SOB R0, 163412 ; Умножим 130 на кол-во секторов
163420: MOV #000010, R0 ; Команда -- включить мотор и читать
+
163420: MOV #000010, R0 ; Команда - включить мотор и читать
 
163424: CALL @#163342 ; Организуем запуск команды
 
163424: CALL @#163342 ; Организуем запуск команды
 
163430: MOV #177102, R2 ; Адрес регистра данных дисковода
 
163430: MOV #177102, R2 ; Адрес регистра данных дисковода
 
163434: TSTB (R5) ; Готов прочитанный байт?
 
163434: TSTB (R5) ; Готов прочитанный байт?
163436: BPL 163434 ; Пока нет -- TR не установлен
+
163436: BPL 163434 ; Пока нет - TR не установлен
 
163440: MOVB (R2), (R1)+ ; Читаем очередной байт
 
163440: MOVB (R2), (R1)+ ; Читаем очередной байт
 
163442: SOB R4, 163434 ; Переходим к следующему
 
163442: SOB R4, 163434 ; Переходим к следующему
Строка 607: Строка 619:
 
163452: INC R4
 
163452: INC R4
 
163454: BIT #000141, R0 ; RELOAD или OP-FAILED или LOST-DATA ?
 
163454: BIT #000141, R0 ; RELOAD или OP-FAILED или LOST-DATA ?
163460: BNE 163330 ; Да -- завершаемся с ошибкой
+
163460: BNE 163330 ; Да - завершаемся с ошибкой
163462: MOV #000010, R0 ; 8 -- длина заголовка
+
163462: MOV #000010, R0 ; 8 - длина заголовка
 
163466: CLR R2 ; Начинаем считать контрольную сумму
 
163466: CLR R2 ; Начинаем считать контрольную сумму
 
163470: MOVB (R3)+, R1 ; Очередной байт
 
163470: MOVB (R3)+, R1 ; Очередной байт
 
163472: ADD R1, R2 ; Добавляем к сумме
 
163472: ADD R1, R2 ; Добавляем к сумме
 
163474: SOB R0, 163470
 
163474: SOB R0, 163470
163476: MOV #000200, R0 ; 128 -- длина сектора
+
163476: MOV #000200, R0 ; 128 - длина сектора
 
163502: CMP R2, (R3)+ ; Сумма совпала?
 
163502: CMP R2, (R3)+ ; Сумма совпала?
163504: BNE 163330 ; Нет -- завершаемся с ошибкой
+
163504: BNE 163330 ; Нет - завершаемся с ошибкой
 
163506: SOB R4, 163466 ; Продолжаем подсчёт сумм секторов
 
163506: SOB R4, 163466 ; Продолжаем подсчёт сумм секторов
 
163510: RETURN
 
163510: RETURN
Строка 679: Строка 691:
 
; TT.OUT Вывод символа на экран; мл.байт R0 = символ
 
; TT.OUT Вывод символа на экран; мл.байт R0 = символ
 
163734: CALL @#163512 ; MODE3
 
163734: CALL @#163512 ; MODE3
; SYSOUT Вход -- вывод символа
+
; SYSOUT Вход - вывод символа
 
; Стандартная подпрограмма вывода символа
 
; Стандартная подпрограмма вывода символа
 
163740: MOV R0, -(SP)
 
163740: MOV R0, -(SP)
Строка 716: Строка 728:
 
164076: BLO 164230
 
164076: BLO 164230
 
164100: CMP #166064, @#177774 ; Знакогенератор стандартный?
 
164100: CMP #166064, @#177774 ; Знакогенератор стандартный?
164106: BNE 164130
+
164106: BNE 164130 ; нет => переход
 
164110: ROLB R2
 
164110: ROLB R2
 
164112: BPL 164120
 
164112: BPL 164120
Строка 763: Строка 775:
 
164274: MOV #177770, R5 ; Размер экрана в байтах, начиная от начала ГЗУ
 
164274: MOV #177770, R5 ; Размер экрана в байтах, начиная от начала ГЗУ
 
164300: ADD R4, PC ; Переходим по 164302 + 2 * смещение из таблицы 165246
 
164300: ADD R4, PC ; Переходим по 164302 + 2 * смещение из таблицы 165246
; +000 -- символ 20 либо ESC+131 -- прямая адресация курсора;
+
; +000 - символ 20 либо ESC+131 - прямая адресация курсора;
 
; следующие два байта строки: N строки+40, N позиции+40
 
; следующие два байта строки: N строки+40, N позиции+40
 
164302: MOVB  #000002, (R5)
 
164302: MOVB  #000002, (R5)
 
164306: BR    164546
 
164306: BR    164546
; +003 -- символ 36 -- очистка служебной строки
+
; +003 - символ 36 - очистка служебной строки
 
164310: MOV    #140000, R2 ; Косвенный адрес начала экрана
 
164310: MOV    #140000, R2 ; Косвенный адрес начала экрана
 
164314: MOV    #002000, R3 ; Сколько слов чистить
 
164314: MOV    #002000, R3 ; Сколько слов чистить
Строка 775: Строка 787:
 
164326: SOB    R3, 164320
 
164326: SOB    R3, 164320
 
164330: BR    164546
 
164330: BR    164546
; +014 -- символ 27 -- переход из режима "Немига" в VT-52
+
; +014 - символ 27 - переход из режима "Немига" в VT-52
 
164332: BIC    #000400, (R5)
 
164332: BIC    #000400, (R5)
 
164336: BIS    #000200, -(R5)
 
164336: BIS    #000200, -(R5)
Строка 782: Строка 794:
 
164344: BIT #000200, 177776(R5)
 
164344: BIT #000200, 177776(R5)
 
164352: BNE 164366
 
164352: BNE 164366
; +025 -- VT-52 символ ESC+106 -- вкл/откл звук подтверждения нажатия клавиши
+
; +025 - VT-52 символ ESC+106 - вкл/откл звук подтверждения нажатия клавиши
 
164354:
 
164354:
  
 
164366: DECB (R5)
 
164366: DECB (R5)
 
164370: BR 164546
 
164370: BR 164546
; +034 -- символ 06
+
; +034 - символ 06
 
164372: CLR (R5)
 
164372: CLR (R5)
 
164374: TST -(R5)
 
164374: TST -(R5)
Строка 793: Строка 805:
 
164400: CLR -(R5)
 
164400: CLR -(R5)
 
164402: BR 164546
 
164402: BR 164546
; +041 -- символы 02..05
+
; +041 - символы 02..05
 
164404: COMB 177760(R2)
 
164404: COMB 177760(R2)
 
164410: BR 164546
 
164410: BR 164546
; +044 -- символ 30 -- погасить/включить курсор
+
; +044 - символ 30 - погасить/включить курсор
 
164412: MOV    #000200, R2
 
164412: MOV    #000200, R2
; +046 -- символ 01 -- включить/выключить сдвиг экрана
+
; +046 - символ 01 - включить/выключить сдвиг экрана
 
164416: SWAB  R2
 
164416: SWAB  R2
 
164420: XOR    R2, (R5)
 
164420: XOR    R2, (R5)
Строка 830: Строка 842:
 
164530: BNE 164514 ; Экран не кончился? => повторяем
 
164530: BNE 164514 ; Экран не кончился? => повторяем
 
164532: BR 165074
 
164532: BR 165074
; +115 -- символ 10 -- Backspace
+
; +115 - символ 10 - Backspace
 
164534: BIC    #177700, R3
 
164534: BIC    #177700, R3
 
164540: BEQ    165104
 
164540: BEQ    165104
 
164542: DEC    @#177772 ; новое смещение курсора левее на 1
 
164542: DEC    @#177772 ; новое смещение курсора левее на 1
 
164546: BR    165104
 
164546: BR    165104
; +123 -- символ 15 -- возврат каретки
+
; +123 - символ 15 - возврат каретки
 
164550: BIC #000077, R3 ; На начало строки
 
164550: BIC #000077, R3 ; На начало строки
 
164554: MOV R3, @#177772 ; Сохраняем позицию курсора
 
164554: MOV R3, @#177772 ; Сохраняем позицию курсора
 
164560: BR    165104
 
164560: BR    165104
; +130 -- символ 11 -- горизонтальная табуляция с шагом 8
+
; +130 - символ 11 - горизонтальная табуляция с шагом 8
 
164562: MOV    R3, R4
 
164562: MOV    R3, R4
 
164564: BIC    #177700, R4
 
164564: BIC    #177700, R4
Строка 847: Строка 859:
 
164602: BIC #000007, R3
 
164602: BIC #000007, R3
 
164606: BR 164554
 
164606: BR 164554
; +??? -- символ VT-52 16 -- переход на русский регистр
+
; +??? - символ VT-52 16 - переход на русский регистр
 
164610: BIS    #000040, -(R5)
 
164610: BIS    #000040, -(R5)
 
164614: BR    165104
 
164614: BR    165104
; +??? -- символ VT-52 17 -- переход на латинский регистр
+
; +??? - символ VT-52 17 - переход на латинский регистр
 
164616: BIC    #000040, -(R5)
 
164616: BIC    #000040, -(R5)
 
164622: BR    165104
 
164622: BR    165104
; +151 -- символ VT-52 ESC+100 -- переход в режим "Немига"
+
; +151 - символ VT-52 ESC+100 - переход в режим "Немига"
 
164624: BIC    #177600, -(R5)
 
164624: BIC    #177600, -(R5)
 
164630: BR    165104
 
164630: BR    165104
  
; +165 -- символ VT-52 ESC+101 или "Немига" 22 -- вверх 1
+
; +165 - символ VT-52 ESC+101 или "Немига" 22 - вверх 1
 
164654:
 
164654:
  
Строка 893: Строка 905:
 
164776: SOB    R5, 164770
 
164776: SOB    R5, 164770
 
165000: BR    165104
 
165000: BR    165104
; +240 -- символ 007 -- BELL
+
; +240 - символ 007 - BELL
 
165002: BITB  #000100, @#177761 ; Проверяем байт блокировки SOUND
 
165002: BITB  #000100, @#177761 ; Проверяем байт блокировки SOUND
 
165010: BNE    165104
 
165010: BNE    165104
Строка 900: Строка 912:
 
165020: DR 165022 ; адрес мелодии
 
165020: DR 165022 ; адрес мелодии
 
165022: DB 001, 205, 017, 000
 
165022: DB 001, 205, 017, 000
; +252 -- символ "Немига" 13, VT-52 ESC+113 -- очистить строку от позиции курсора
+
; +252 - символ "Немига" 13, VT-52 ESC+113 - очистить строку от позиции курсора
 
165026: CALL  @#165126
 
165026: CALL  @#165126
 
165032: BR    165104
 
165032: BR    165104
; +255 -- символ "Немига "37, VT-52 ESC+112 -- очистка экрана от позиции курсора
+
; +255 - символ "Немига "37, VT-52 ESC+112 - очистка экрана от позиции курсора
 
165034: CALL @#165126
 
165034: CALL @#165126
 
165040: BIC #000077, R3
 
165040: BIC #000077, R3
Строка 910: Строка 922:
 
165052: BPL 165104
 
165052: BPL 165104
 
165054: BR 165074
 
165054: BR 165074
; +266 -- символ 21 -- очистка всего экрана, включая служебную строку
+
; +266 - символ 21 - очистка всего экрана, включая служебную строку
 
165056: MOV #140000, R2 ; Косвенный адрес начала экрана
 
165056: MOV #140000, R2 ; Косвенный адрес начала экрана
 
165062: BR 165070
 
165062: BR 165070
; +271 -- символ 14 -- перевод формата, очистка экрана, служебная строка сохраняется
+
; +271 - символ 14 - перевод формата, очистка экрана, служебная строка сохраняется
 
165064: MOV #142000, R2 ; Начало экрана после служебной строки
 
165064: MOV #142000, R2 ; Начало экрана после служебной строки
 
165070: CLR @#177772 ; Курсор будет в начале экрана
 
165070: CLR @#177772 ; Курсор будет в начале экрана
Строка 920: Строка 932:
 
165100: INC R2 ; | Увеличиваем адрес
 
165100: INC R2 ; | Увеличиваем адрес
 
165102: BNE 165074 ; / дошли до конца ? нет => повторяем
 
165102: BNE 165074 ; / дошли до конца ? нет => повторяем
; +301 -- символ 00, ESC+105, ESC+107 -- неиспользуемый код символа
+
; +301 - символ 00, ESC+105, ESC+107 - неиспользуемый код символа
 
; Завершение обработки символа
 
; Завершение обработки символа
 
165104: CALL @#165176 ; Восстановление курсора
 
165104: CALL @#165176 ; Восстановление курсора
Строка 960: Строка 972:
 
165236: BPL 165244
 
165236: BPL 165244
 
165240: MOV R4, (R0) ; Устанавливаем косвенный адрес
 
165240: MOV R4, (R0) ; Устанавливаем косвенный адрес
165242: COM (R1) ; Инвертируем восемь пикселей -- курсор
+
165242: COM (R1) ; Инвертируем восемь пикселей - курсор
 
165244: RETURN
 
165244: RETURN
 
; Таблица смещений переходов для обработки спецсимволов
 
; Таблица смещений переходов для обработки спецсимволов
Строка 971: Строка 983:
 
165316: DB 210, 212, 255, 252
 
165316: DB 210, 212, 255, 252
  
; Точка входа QDRAW -- DRAW для QUASIC
+
; Точка входа QDRAW - DRAW для QUASIC
 
165336: MOV    (SP), R5
 
165336: MOV    (SP), R5
; Точка входа FDRAW -- DRAW для FORTRAN
+
; Точка входа FDRAW - DRAW для FORTRAN
 
165340: CALL  @#166040
 
165340: CALL  @#166040
; Точка входа DRAW -- нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
+
; Точка входа DRAW - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
 
; После выполнения операции XNEW=XOLD, YNEW=YOLD.
 
; После выполнения операции XNEW=XOLD, YNEW=YOLD.
 
165344: CALL  @#165374
 
165344: CALL  @#165374
Строка 981: Строка 993:
 
165356: MOV    @#000214, @#000220 ; YNEW -> YOLD
 
165356: MOV    @#000214, @#000220 ; YNEW -> YOLD
 
165364: RETURN
 
165364: RETURN
; Точка входа QLINE -- LINE для QAUSIC
+
; Точка входа QLINE - LINE для QAUSIC
 
165366: MOV    (SP), R5
 
165366: MOV    (SP), R5
; Точка входа FLINE -- LINE для FORTRAN
+
; Точка входа FLINE - LINE для FORTRAN
 
165370: CALL  @#166040
 
165370: CALL  @#166040
; Точка входа LINE -- нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
+
; Точка входа LINE - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
 
165374: MOV    #000212, R5 ; Адрес XNEW
 
165374: MOV    #000212, R5 ; Адрес XNEW
 
165400: MOV    (R5)+, R0
 
165400: MOV    (R5)+, R0
Строка 1044: Строка 1056:
 
165574: RETURN
 
165574: RETURN
 
;
 
;
; Точка входа QPOINT -- POINT для QUASIC
+
; Точка входа QPOINT - POINT для QUASIC
 
165576: MOV (SP), R5
 
165576: MOV (SP), R5
; Точка входа FPOINT -- POINT для FORTRAN
+
; Точка входа FPOINT - POINT для FORTRAN
 
165600: CALL @#166040
 
165600: CALL @#166040
; Точка входа POINT -- нарисовать точку
+
; Точка входа POINT - нарисовать точку
 
165604: MOV @#000212, R2 ; XNEW
 
165604: MOV @#000212, R2 ; XNEW
 
165610: MOV @#000214, R3 ; YNEW
 
165610: MOV @#000214, R3 ; YNEW
Строка 1065: Строка 1077:
 
165656: RETURN
 
165656: RETURN
 
;
 
;
; Точка входа QRPOIN -- RPOINT для QUASIC
+
; Точка входа QRPOIN - RPOINT для QUASIC
 
165660: MOV    (SP), R5
 
165660: MOV    (SP), R5
; Точка входа FRPOIN -- RPOINT для FORTRAN
+
; Точка входа FRPOIN - RPOINT для FORTRAN
 
165662: CALL  @#166040
 
165662: CALL  @#166040
 
165666: BR    165674
 
165666: BR    165674
; Точка входа RPOINT -- прочитать яркость точки
+
; Точка входа RPOINT - прочитать яркость точки
 
165670: MOV    #000210, R4 ; Адрес BRIGHT
 
165670: MOV    #000210, R4 ; Адрес BRIGHT
 
165674: MOV    @#000212, R2 ; XNEW
 
165674: MOV    @#000212, R2 ; XNEW
Строка 1112: Строка 1124:
 
166036: RETURN
 
166036: RETURN
 
; Подготовка перед вызовом для FORTRAN
 
; Подготовка перед вызовом для FORTRAN
166040: MOV (R5)+, R0
+
166040: MOV     (R5)+, R0
166042: MOV (R5), R4
+
166042: MOV     (R5), R4
166044: BIC #177770, R0
+
166044: BIC     #177770, R0
166050: BEQ 166062
+
166050: BEQ     166062
166052: MOV #000210, R3
+
166052: MOV     #000210, R3 ; Адрес BRIGHT
166056: MOV @(R5)+, (R3)+
+
166056: MOV     @(R5)+, (R3)+
166060: SOB R0, 166056
+
166060: SOB     R0, 166056
166062: RETURN
+
166062: RETURN
 
;
 
;
 
; ==== Стандартный знакогенератор ====
 
; ==== Стандартный знакогенератор ====
166064: DB ; Знакогенератор, 120 символов, 8 байт/символ
+
166064: DB ; Знакогенератор, 96 символов (0x20..0x80), 10 байт/символ
 +
 
 +
; ==== Регистры ====
 +
170000: DW ; Используется м/с умножителя
 +
170002: DW ; Используется м/с умножителя
 +
170004: DW ; Используется м/с умножителя
 +
170006: DW ; Регистр данных клавиатуры / фиксации HALT запросов
 +
170010: DW ; Регистр состояния адаптера локальной сети
 +
170012: DW ; Регистр данных адаптера локальной сети
 +
170014: DW ; ??
 +
 
 +
170020: DW ; RgStSnd  - регистр состояния таймера
 +
170022: DW ; RgF      - регистр частоты
 +
170024: DW ; RgLength - регистр длительности
 +
170026: DW ; RgOn    - включение звука (обращение)
 +
170030: DW ; RgOct    - регистр октавы и громкости
 +
170032: DW ; RgOff    - выключение звука (обращение)
 +
 
 +
177100: DW ; RgStat  - регистр состояния контроллера дисковода
 +
177102: DW ; RgData  - регистр данных
 +
177104: DW ; RgCntrl  - регистр управления
 +
177106: DW ; RgTime  - регистр таймера контроллера дисковода
 +
 
 +
177170: DW ; Регистр состояния дисковода DX
 +
177172: DW ; Регистр данных дисковода DX
 +
 
 +
177514: DW ; Регистр данных устройства сопряжения
 +
177516: DW ; Регистр состояния усройства сопряжения
 +
 
 +
177560: DW ; KBS      - регистр состояния клавиатуры
 +
177562: DW ; KBD      - регистр данных клавиатуры
 +
177564: DW ; TTS      - регистр состояния дисплея
 +
177566: DW ; TTD      - регистр данных дисплея
 +
 
 +
177570: DW ; VDATA    - регистр данных косвенного доступа
 +
177572: DW ; VADDR    - регистр адреса косвенного доступа
  
 
; ==== Блок переменных ====
 
; ==== Блок переменных ====
Строка 1146: Строка 1193:
 
177770: DW ; SIZE  Размер экрана в байтах, начиная от начала ГЗУ
 
177770: DW ; SIZE  Размер экрана в байтах, начиная от начала ГЗУ
 
177772: DW ; CUR    Место курсора от начала ГЗУ
 
177772: DW ; CUR    Место курсора от начала ГЗУ
177774: DW ; SYMGEN Адрес знакогенератора
+
177774: DW ; SYMGEN Адрес знакогенератора, по умолчанию 166064
 
177776: DW ; Значение #056311
 
177776: DW ; Значение #056311
 
</pre>
 
</pre>
  
 
[[Категория:Немига|*]]
 
[[Категория:Немига|*]]

Текущая версия на 12:14, 18 марта 2021

Creative-Commons.png Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0.

Источник: https://github.com/nzeemin/nemigabtl/blob/master/docs/nemiga-303.lst

; Дизассемблированное ПЗУ компьютера НЕМИГА ПК 588 версия 3.03
;

000004: DW				; Адрес прерывания
000006: DW				; PSW прерывания

000060: DW				; Прерывание клавиатура
000062: DW				; PSW прерывания
000064: DW				; Прерывание дисплей
000066: DW				; PSW прерывания

000100: DW

000110; DW				; Прерывание "мелодия закончилась кодом 040"
000112: DW				; PSW прерывания

000204: DW				; REV    - рабочий регистр
000206: DW				; VFORM  - регистр вертикального формата
000210: DW				; BRIGHT - регистр яркости (0..3)
000212: DW				; XNEW   - регистр новой X-координаты
000214: DW				; YNEW   - регистр новой Y-координаты
000216: DW				; XOLD   - регистр старой X-координаты
000220: DW				; YOLD   - регистр старой Y-координаты

; ==== Начало ПЗУ ====
160000: DW	177570			; ??
160002: DW	160210, 000341		; Вектор прерывания сигнала/команды HALT
160006: DW	162010, 000340		; Вектор прерывания начального пуска
160012: DW	161126, 000340		; Вектор прерывания??
160016: JMP     @#163512		; MODE3  - Вызов с запретом системных прерываний
160022: JMP    	@#163532		; SYSLIN - Вывод в служебную строку
160026: JMP    	@#163734		; TT.OUT - Системный вывод через MODE
160032: JMP    	@#163740		; SYSOUT - Системный вывод
160036: JMP    	@#162342		; PRINT  - Вывод текста
160042: JMP    	@#165344		; DRAW   - Нарисовать линию, сохранив XOLD,YOLD
160046: JMP    	@#165336		; QDRAW     то же для QUASIC
160052: JMP    	@#165340		; FDRAW     то же для FORTRAN
160056: JMP    	@#165374		; LINE   - Нарисовать линию
160062: JMP    	@#165366		; QLINE     то же для QUASIC
160066: JMP    	@#165370		; FLINE     то же для FORTRAN
160072: JMP    	@#165604		; POINT  - Нарисовать точку
160076: JMP    	@#165576		; QPOINT    то же для QUASIC
160102: JMP    	@#165600		; FPOINT    то же для FORTRAN
160106: JMP    	@#165670		; RPOINT - Читать яркость точки
160112: JMP    	@#165660		; QRPOIN    то же для QUASIC
160116: JMP    	@#165662		; FRPOIN    то же для FORTRAN
160122: JMP    	@#162304		; DUMP   - напечатать восьмеричное число R3
160126: JMP     @177754			; SOUND

; ==== Обработчики прерываний ========================================================

; Обработка канального сигнала СБРОС
160142: MOV	#000357, @#000206	; 239. -> VFORM
160150: CLR	@#177560		; Сброс состояния клавиатуры
160154: MOV	#000200, @#177564	; Устанавливаем состояние терминала
160162: CLR	@#177770
160166: BIC	#177541, @#177766	; Оставляем только флаги #136
160174: MOV	(SP)+, R0
160176: JMP	@#161060		; Завершаем обработку прерывания HALT
;
; Обработка нажатия СТОП?? кнопки ОСТ??
160202: MOV	(SP)+, R0		; Восстанавливаем R0
160204: JMP	@#161126		; Переходим к сохранению регистров и пульту
;
; Обработчик прерывания по сигналу/команде HALT
160210: CMP	#056311, @#177776	; Проверка, настроена ли память режима HALT
160216: BEQ	160224			; Да, настроена
160220: JMP	@#162010		; Нет => выход на процедуру холодного старта
160224: MOV	R0, -(SP)		; Сохраняем R0 чтобы не испортить
160226: BIS	#000200, @#177564	; Устанавливаем состояние терминала
160234: BIT	#176000, @#170006	; Проверка регистра фиксации HALT
160242: BMI	160142			; Канальный сигнал СБРОС? => переходим
160244: BEQ	160202			; 6 ст битов пусты - кнопка ОСТ?? => переходим
160246: BIT	#004000, @#170006	; Сигнал Н4? - адаптер локальной сети
160254: BEQ	160262			; Нет
160256: CALL	@000104			; ??
160262: BIT	#040000, @#170006	; Сигнал Н1? - обращение к 177566
160270: BEQ	160302			; Нет
160272: MOV	@#177566, R0		; Регистр данных терминала
160276: CALL	@#163740		; SYSOUT Вывод символа R0 на экран
160302: BIT	#020000, @#170006	; Сигнал Н2? - обращение к 177562
160310: BEQ	160334			; Нет
160312: MOVB	@#177767, R0		; Провека буферной ячейки клавиатуры
160316: BEQ	160326			; буфер пуст => переходим
160320:	CLRB	@#177767		; Очищаем буфер
160324:	BR	160520
160326: BIC	#177677, @#177560	; Чистим ~0100 в рег.статуса клавиатуры - есть клавиша
160334: MOV	@#170006, R0
160340: BIT	#002000, R0		; Пришёл байт с клавиатуры?
160344: BEQ	160600			; Нет
160346: BIC	#177400, R0		; Оставляем байт поступивший с клавиатуры
160352: BEQ	160202			; Символ 00 - СТОП?
; Звук нажатия клавиши
160354: MOV	R1, -(SP)
160356: MOV	R2, -(SP)
160360: TSTB	@#177761		; Флаг блокировки вызова SOUND
160364: BNE	160402			; <> 0 => не вызывать повторно
160366: CALL	@#160126		; SOUND
160372: BR	160402
160374: DW	160376			; Адрес мелодии нажатия клавиши
160376: DB	011, 214, 001, 000	; Мелодия - звук длиной 1/50 сек
160402: MOV	#177766, R1
160406: MOV	#000100, R2
160412: TSTB	(R1)
160414: BPL	160514
160416: BITB   	#000300, R0
160422: BEQ    	160472
160424: BPL    	160454
160426: BIT    	R2, R0
160430: BEQ    	160514
160432: BIC    	#177600, R0
160436: BITB   	R2, (R1)+
160440: BNE    	160514
160442: MOVB   	R0, (R1)
160444: MOV    	#000016, R0
160450: BISB   	R2, -(R1)
160452: BR     	160514
160454: BITB   	R2, (R1)+
160456: BEQ    	160514
160460: MOVB   	R0, (R1)
160462: MOV    	#000017, R0
160466: BICB   	R2, -(R1)
160470: BR     	160514
160472: CMPB   	R0, #000040
160476: BHIS   	160514
160500: MOVB   	161066(R0), @#177767	; Нажатая клавиша -> в буферную ячейку
160506: BEQ    	160514
160510: MOV    	#000033, R0
;
160514: MOV	(SP)+, R2
160516: MOV	(SP)+, R1
160520: MOV	R0, @#177562		; Заносим символ в рег.данных клавиатуры
160524: MOV	(SP)+, R0
160526: BIS	#000200, @#177560	; Состояние клавиатуры - сброс бита готовности
160534: BIT	#000100, @#177560	; Состояние клавиатуры - разрешено прерывание?
160542: BEQ	161060			; нет => Завершаем обработку прерывания HALT
160544: BISB   	#000001, @#177766
160552: TSTB   	000002(SP)
160556: BMI    	161060
160560: BICB   	#000001, @#177766
160566: MOV    	@#000062, -(SP)		; Кладём в стек вызов
160572: MOV    	@#000060, -(SP)		; прерывания по вектору 60
160576: BR     	161060
;
160600: MOV	(SP)+, R0		; Восстанавливаем R0
160602: BIT	#010000, @#170006	; Сигнал Н3?
160610: BEQ	161060			; нет => Завершаем обработку прерывания HALT
; Обработка сигнала Н3 - кадровый синхроимпульс, 50 Гц
160612: MOV	R4, -(SP)		; Сохраняем R4
160614: TSTB	@#177761		; Флаг блокировки SOUND
160620: BPL	160746			; bit7=0 - блокировано => переходим
160622: MOV	@#177752, R4		; Берём адрес продолжения мелодии
160626: INCB	@#177760		; Увеличиваем счётчик длительности ноты
160632: CMPB	@#177760, 177777(R4)	; Сравниваем с длительностью ноты
160640: BLO	160746			; пока не кончилась => переходим
160642: TSTB	(R4)			; 200 ?
160644: BMI	160742			; да => переходим
160646: BITB	#000037, (R4)		; Есть ещё нота мелодии?
160652: BNE	160736			; да => переходим
160654: BICB	#000200, @#177761	; Снимаем флаг блокировки SOUND
; Обработка флагов завершения мелодии
160662: BITB	#000040, (R4)		; 040 и 140 ?
160666: BNE	160712			; да => переходим
160670: TSTB	(R4)			; 000 ? (никаких действий по окончании мелодии)
160672: BEQ	160746			; да => переходим
160674: MOV    	@#177750, @#160710	; Копируем адрес начала мелодии??
160702: CALL   	@#160126		; SOUND
160706: BR     	160746			; переходим к работе с курсором
160710: DW	000000
; Окончание мелодии байтом 040 либо 140
160712: BITB   	#000100, (R4)+		; байт 140?
160716: BNE    	160732			; да => переход
160720: MOV    	(SP)+, R4
160722: CLRB   	@#170006		; Разрешаем системные прерывания
160726: MOV    	@#000110, PC		; Переход на прерывание по вектору 110
; Окончание мелодии байтом 140
160732: CLRB   	(R4)			; Очистка байта после конца мелодии
160734: BR     	160746			; переходим к работе с курсором
;
160736: MOVB   	(R4)+, @#170030		; Октава и громкость
160742: CALL   	@#162560		; Обработка продолжения мелодии
; Мигание курсора
160746: DECB	@#177756		; Уменьшаем счётчик мигания
160752: BPL	161020			; значение >= 0 ? => переходим
160754: MOVB	#000007, @#177756	; Новое значение счётчика
160762: COMB	@#177757		; Инвертировать состояние курсора при мигании
160766: MOV	@#177772, R4		; Смещение курсора
160772: BMI	161020
160774: TSTB	@#177771		; Состояние курсора??
161000: BMI	161020
161002: ADD	#143105, R4		; + косвенный адрес, начало 25-й строки экрана
161006: BPL	161020			; Если за экраном => переходим
161010: MOV	R4, @#177572		; Устанавливаем косвенный адрес
161014: COM	@#177570		; Инвертирование восьми пикселей курсора
161020: MOV	(SP)+, R4		; Восстанавливаем R4
161022: TSTB	000002(SP)
161026: BMI	161060			; ?? => Завершаем обработку прерывания HALT
161030: BITB   	#000001, @#177766
161036: BNE    	160560
161040: BIT    	#000100, @#177564	; Разрешено прерывание в рег.состояния терминала?
161046: BEQ    	161060			; нет => переходим
161050: MOV    	@#000066, -(SP)		; Кладём в стек вызов
161054: MOV    	@#000064, -(SP)		; прерывания по вектору 64
; Завершение обработки прерывания HALT
161060: CLRB	@#170006		; Разрешаем системные прерывания
161064: RTI	
; Таблица байт
161066:

; Обработка прерывания?? Сохранение регистров и переход к пульту
161126: MOV	(SP)+, @#177736		; Сохраняем PC
161132: MOV	(SP)+, @#177740		; Сохраняем PSW
161136: MOV	SP, @#177734		; Сохраняем SP
161142: MOV	#177734, SP		; Сохраняем остальные регистры
161146: MOV	R5, -(SP)		; -> 177732
161150: MOV	R4, -(SP)		; -> 177730
161152: MOV	R3, -(SP)		; -> 177726
161154: MOV	R2, -(SP)		; -> 177724
161156: MOV	R1, -(SP)		; -> 177722
161160: MOV	R0, -(SP)		; -> 177720 - начало блока регистров
161162: MOV	@#000004, -(SP)
161166: MOV	@#000006, -(SP)
161172: MOV	@#177766, -(SP)
161176: CLR	@#177766
161202: MOV	#000340, @#000006	; PSW для прерывания
161210: MOV	#161406, @#000004	; Адрес прерывания??
161216: MOV	#000060, @#170010
161224: BR	161406			; Переход к пультовому терминалу
;
; ==== Программа пультового терминала ================================================
;
; Просмотр ячеек памяти - переход к следующему слову
161226: INC	R2
161230: INC	R2
; Команда '/' - просмотр ячеек памяти
161232: MOV	#162764, R5		; Строка
161236: CALL	@#162342		; Вывод строки, адрес в R5
161242: MOV	R2, R3			; Печатаем адрес
161244: CALL	@#162304		; Вывод R3 как 8-ричного числа
161250: MOV	(R2), R3		; Печатаем значение
161252: CALL	@#162304		; Вывод R3 как 8-ричного числа
161256: CALL	@#162356		; Получаем команду с клавиатуры
161262: TST	R1
161264: BEQ	161270
161266:	MOV	R5, (R2)		; Заносим новое значение
161270: CMPB	#000012, R0		; Нажали ПС?
161274: BEQ	161226			; Да, переходим к следующему слову памяти
161276: CMPB	#000015, R0		; Нажали ВВОД?
161302: BEQ	161406			; Да, возвращамся в пульт
161304: CMPB	#000136, R0		; Нажали '^' ?
161310: BNE	161516			; Нет - выводим признак ошибки и в пульт
161312: DEC	R2			; Переходим к предыдущему слову памяти
161314: DEC	R2
161316: BR	161232
;
; Команда 'G' - продолжение выполнения программы
161320: MOV	(SP)+, @#177766
161324: TST	R1			; Параметр задан?
161326: BEQ	161342			; Нет => восстановление регистров и возврат
161330: CLR	@#177740
161334: MOV	R5, @#177736		; Адрес запуска
161340: RESET	
; Восстановление всех регистров, возврат из прерывания
161342: MOV	(SP)+, @#000006
161346: MOV	(SP)+, @#000004
161352: MOV	(SP)+, R0
161354: MOV	(SP)+, R1
161356: MOV	(SP)+, R2
161360: MOV	(SP)+, R3
161362: MOV	(SP)+, R4
161364: MOV	(SP)+, R5
161366: MOV	(SP), SP
161370: MOV	@#177740, -(SP)		; PSW
161374: MOV	@#177736, -(SP)		; PC
161400: RTI	
;
; Вывод символа и переход к пульту
161402: CALL	@#163734		; TT.OUT Вывод символа
; Вывод приглашения пульта и ожидание команды
161406: MOV	#162752, R5		; Строка "Пульт>"
161412: MOV	#177712, SP
161416: MOV	#000340, @#000006	; PSW для прерывания
161424: MOV	#161516, @#000004	; Адрес прерывания??
161432: CALL	@#162342		; PRINT Вывод строки, адрес в R5
161436: CALL	@#162356		; Получаем команду с клавиатуры
161442: MOV	R5, R2
161444: CMPB	#000057, R0		; Символ '/' - просмотр ячеек памяти
161450: BEQ	161232
161452: CMPB	#000123, R0		; Символ 'S' - вывод регистров ЦП
161456: BEQ	161524
161460: CMPB	#000107, R0		; Символ 'G' - выполнение программы
161464: BEQ	161320
161466: CMPB	#000104, R0		; Символ 'D' - загрузка с диска MD
161472: BEQ	161764
161474: CMPB	#000130, R0		; Символ 'X' - загрузка с диска DX
161500: BEQ	161646
161502: CMPB	#000116, R0		; Символ 'N' - загрузка с сети
161506: BEQ	162010			; Переход на программу холодного старта
161510: CMPB	#000014, R0		; Нажат УПР + L - очистка экрана
161514: BEQ	161402			; Вывод символа 014 и возврат к пульту
; Вывод знака вопроса (ошибка выполнения команды) и возврат в пультовый режим
161516: MOV	#162751, R5		; Строка " ?"
161522: BR	161412
;
; Команда 'S' - вывод на экран регистров процессора
161524: MOV	#000011, R2		; 9 регистров
161530: MOV	#161556, R5		; Строка с названиями регистров
161534: CALL	@#162342		; Вывод строки
161540: MOV	#177720, R4		; Адрес блока сохранённых регистров
161544: MOV	(R4)+, R3
161546: CALL	@#162304		; Вывод R3 как 8-ричного числа
161552: SOB	R2, 161544
161554: BR	161406			; Возврат в пульт
161556: DB	...			; Строка с названиями регистров ЦП

; Команда 'X' - загрузка с устройства DX
; (код загрузчика практически повторяет код загрузчика с DX/RX01 из ПЗУ ДВК)
161646: MOV	#100247, R2
161652: CMP	R5, #000001		; номер диска = 1 ?
161656: BLO	161666			; меньше 1 => переходим
161660:	BHI	161516			; больше 1 => показываем признак ошибки, возврат в пульт
161662:	BIS	#000020, R2
161666: MOV	#177170, R1		; Адрес регистра команд/состояния
161672: MOV	#040000, (R1)
161676: BITB	R2, (R1)		; <
161700: BEQ	161676			; / Ожидаем результат или ошибку
161702:	MOV	#000007, R3
161706:	MOV	R1, R0
161710:	MOV	R2, (R0)+
161712:	BR	161720
161714:	MOV    	#000001, (R0)
161720:	ASR    	R3			; 007 -> 003 -> 001 -> 000
161722:	BLO    	161730			; 
161724:	MOV    	(PC)+, (R1)		; 
161726:	MOVB   	(R0), (R3)+		; сохраняем полученный байт
161730:	BIT    	R2, (R1)		; <
161732:	BEQ    	161730			; / Ожидаем результат или ошибку
161734:	BMI    	161676			; 
161736:	BLO    	161714			; повтор
161740:	TSTB   	(R1)
161742:	BMI    	161726
161744:	CLR    	R0
161746:	CMPB   	#000247, R2
161752:	ADC    	R0
161754:	MOV    	#000200, @#177766
161762:	CLR    	PC			; Запуск полученного блока
;
; Команда 'D' - загрузка с диска
161764: CMP	R5, #000007		; Номер устройства больше 7?
161770: BHI	161516			; Да => показать признак ошибки, возврат в пульт
161772: CALL	@#162774		; Загрузка данных с дисковода
161776: BLO	161516			; Ошибка? => возврат в пульт
162000: MOV	#000200, @#177766
162006: CLR	PC			; Запуск полученного блока
;
; ==== Программа холодного старта ====================================================
;
; Холодный старт при включении питания
162010: MOV	#001000, SP		; Устанавливаем стек
162014: CLR	R0
162016: MOV	#056311, -(R0)		; -> (177776)
162022: MOV	#166064, -(R0)		; Адрес стандартного знакогенератора -> (177774)
162026: MOV	#000010, R1
162032: CLR	-(R0)			; <|
162034: SOB	R1, 162032		;  / Очищаем 010 слов 177754-177773 - переменные??
162036: MOV	#162556, @#177754	; Подставляем в SOUND пустую подпрограмму
162044: MOV	#162064, @#000004
162052: CLR	@#170024		; Сброс второго счётчика??
162056: MOV	#162474, @#177754	; Адрес полноценной программы SOUND
162064: RESET				; Сбрасываемся и переходим в режим USER??
162066: MOV	#000021, R0		; Символ очистки всего экрана
162072: CALL	@#163740		; SYSOUT Вывод символа R0 на экран
162076: CALL	@#163532		; SYSLIN Вывод в служебную строку
162102: BR	162106
162104: DW	162664			; Адрес строки названия машины и версии ПЗУ
162106: MOV	#161126, @#000004	; Адрес прерывания?? - переход в пульт
162114: MOV	#000340, @#000006	; PSW для прерывания
; Попытка загрузки из сети
162122: MOV	#170010, R4		; Адрес регистра состояния локальной сети
162126: MOV	#000014, (R4)		; Настройка состояния сетевого адаптера
162132: MOV	#162723, R5		; Адрес строки "ждите..."
162136: CALL	@#162342		; Вывод строки; после этого R5 = "Ошибка сети ? Пульт>"
162142: MOV	#162274, @#000004	; Адрес прерывания ??
162150: BIT	#100040, (R4)		; Проверяем состояние локальной сети
162154: BMI	162274			; ошибка сети, выходим
162156: BEQ    	162150
162160: TST    	(R4)
162162: MOVB   	#000003, @#170006	; Запрещение прерываний??
162170: MOV    	#000016, (R4)
162174: CALL   	@#162252		; Ожидаем слово из сети
162200: MOV    	000002(R4), R2		; Получили количество слов в блоке
162204: MOV    	R2, R3
162206: ASL    	R3			; Удваиваем - получаем адрес за концом блока
162210: CMP    	(R3)+, (R3)+		; Сдвигаем R3 ещё на 2 слова вперёд
162212: MOV    	R3, SP			; Новый стек
162214: CLR    	R0			; R0 = 0 - адрес куда читаем блок
162216: CALL   	@#162252		;<| Ожидаем слово из сети
162222: MOV    	000002(R4), (R0)+	; | Сохраняем полученое слово
162226: SOB    	R2, 162216		; / продолжаем
162230: MOV    	#000020, (R4)
162234: CLR    	-(SP)			; оставляем PSW = 0 для RTI
162236: CLR    	-(SP)			; оставляем PC = 0 для RTI
162240: BIS    	#000200, @#177766
162246: JMP    	@#161060		; разрешение прерываний и RTI
; Подпрограмма - ожидание слова из сети
162252: MOV    	#037777, R1		; счётчик ожидания
162256: BIT    	#100040, (R4)
162262: BMI    	162274			; ошибка сети, выходим
162264: BEQ    	162272
162266: TST    	(R4)
162270: RETURN 	
162272: SOB    	R1, 162256
162274: MOV	#002060, (R4)
162300: JMP	@#161412		; Выводим "Ошибка сети ? Пульт>" и в пульт
;
; ==== Программы вывода на экран чисел и строк =======================================
;
; Подпрограмма DUMP Вывод слова как 8-ричного числа; R3 = число
162304: MOV	#000006, R1		; Шесть разрядов
162310: CLR	R0
162312: ROL	R3
162314: ROL	R0
162316: ADD	#000060, R0		; '0'
162322: CALL	@#163734		; TT.OUT Вывод символа
162326: CLR	R0
162330: ROL	R3
162332: ROL	R0
162334: ROL	R3
162336: ROL	R0
162340: SOB	R1, 162312
; Подпрограмма PRINT - Вывод строки на экран; R5 = адрес строки
162342: MOVB	(R5)+, R0		; Очередной символ
162344: BNE	162350			; Не ноль?
162346: RETURN				; Конец строки, выходим
162350: CALL	@#163734		; TT.OUT Вывод символа
162354: BR	162342			; Продолжаем вывод строки
;
; Ввод команды; команда это символ либо 8-ричное число (параметр) и символ
162356: CLR	R1			; Длина параметра пока нулевая
162360: CLR	R5			; Параметр по умолчанию = 0
162362: TSTB	@#177560		; Получен ли символ с клавиатуры?
162366: BPL	162362			; Пока не получен
162370: MOVB	@#177562, R3		; Считываем символ
162374: CMPB	R3, #000177
162400: BNE	162430
162402: DEC	R1
162404: BMI	162356
162406: ASH    	R5, #177775
162412: BIC    	#160000, R5
162416: MOV    	#000134, R0
162422: CALL   	@#163734		; TT.OUT Вывод символа
162426: BR     	162362
162430: MOV	R3, R0
162432: CMPB	R0, #000040		; Это спецсимвол с кодом меньше кода пробела?
162436: BLO	162346			; Да => выходим
162440: CALL	@#163734		; TT.OUT Вывод символа
162444: BIC	#177407, R3
162450: CMP	#000060, R3		; Это цифра?
162454: BNE	162346			; Нет => выходим
162456: BIC	#177770, R0
162462: ASH	R5, #000003
162466: BIS	R0, R5			; Добавляем 8-ричную позицию к числу в R5
162470: INC	R1			; Длина строки увеличилась
162472: BR	162362			; Переходим к ожиданию следующего символа
; 
; Подпрограмма SOUND
162474: MOV	R4, -(SP)		; Сохраняем R4
162476: BICB	#000200, @#177761	; Предотвращаем повторный вызов SOUND: bit7=0
162504: CLR	@#170024		; Сброс таймер 2 (длительности)
162510: MOV	000002(SP), R4		; Откуда вызвали SOUND
162514: MOV	000002(R4), R4		; Получаем адрес мелодии 
162520: TSTB	(R4)
162522: BEQ	162554
162524: MOV	R4, @#177750		; Запоминаем адрес начала мелодии
162530: MOV	#001516, @#170020	; Пишем в регистр состояния таймера
162536: MOVB	(R4)+, @#170030		; Октава и громкость
162542: CALL	@#162560		; Обработка продолжения мелодии
162546: BISB	#000200, @#177761	; Возвращаем флаг блокировки SOUND: bit7=1
162554: MOV	(SP)+, R4		; Восстанавливаем R4
162556: RETURN	
;
162560: MOV	R3, -(SP)		; Сохраняем R3
162562: MOVB	(R4)+, R3
162564: BIC	#177760, R3		; Оставляем нижние 4 бита - 00..17
162570: ASL	R3			; и умножаем на 2
162572: MOV	162624(R3), @#170022	; Выбираем по R3 слово и пишем в первый счётчик
162600: MOVB	(R4)+, @#170024		; Задаём длительность
162604: CLRB	@#177760		; Очищаем счётчик длительности ноты
162610: MOV	R4, @#177752		; Запоминаем адрес продолжения мелодии
162614: TST	@#170026		; Устанавливаем триггер таймера
162620: MOV	(SP)+, R3		; Восстанавливаем R3
162622: RETURN
; Значения задержки первого таймера для нот
162624: DW	000000, 003570, 003414, 003246, 003110, 002754, 002630, 002510
162644: DW	002374, 002264, 002160, 002061, 001764, 000000, 000000, 000000

;
; ==== Подпрограммы работы с дисководом MD ===========================================
;
; Чтение с дисковода для загрузки; R5 = номер устройства
162774: CALL	@#163512		; MODE3
163000: MOV	#000001, R4
163004: MOV	R5, -(SP)		; Запоминаем номер устройства
163006: ASR	R5			; Получаем номер привода
163010: BHIS	163016
163012: ADD	#000004, R5
163016: MOV	R5, @#004002
163022: MOV	#000400, -(SP)
163026: CLR	-(SP)
163030: MOV	R4, -(SP)		; Сохраняем R4
163032: MOV	#000006, R1		; Повторять 6 раз
163036: MOV	#000070, R0		;<| Команда - мотор и ШАГ ВПЕРЁД
163042: CALL	@#163342		; | Готовимся и запускаем команду
163046: SOB	R1, 163036		; / Повтор цикла
163050: MOV	#000030, R0		; Команда - мотор и ШАГ НАЗАД
163054: CALL	@#163342		; Готовимся и запускаем команду
163060: CLR	@#177106		; Сбрасываем таймер
163064: BIT	R4, @#177106		; Ждём
163070: BNE	163064
163072: BIT	#000010, (R5)		; TR00 ?
163076: BNE	163050			; Нет => повторяем команду ШАГ НАЗАД
163100: CLR	@#177106		;<| Сбрасываем таймер
163104: BIT	R4, (R5)		; | Сброшен RELOAD ?
163106: BEQ	163116			; | Да - переходим к чтению секторов
163110: SOB	R2, 163100		; / Ждём
163112: JMP	@#163332
; Мы на 0-й дорожке, читаем первый сектор
163116: MOVB	R4, R0			; Количество секторов = 1
163120: MOV	#004004, R3		; Адрес буфера для чтения
163124: CALL	@#163402		; Прочитать сектора
163130: CLR	@#004000
163134: MOV	@#004000, R0
163140: MOVB	004016(R0), R0		; Первый байт - кол-во секторов на 0-й дорожке
163144: MOV	#004140, R3		; Куда читать дорожку
163150: CALL	@#163402		; Прочитать сектора
163154: CLR	R1
163156: MOV	#004016, R5
163162: MOV	#000120, R4
163166: MOVB	(R5)+, R2
163170: MOV	R1, R0
163172: ADD	R2, R1
163174: CMP	R1, (SP)
163176: BHI	163206
163200: SOB    	R4, 163166
163202: JMP    	@#163332
;
163206: MOV	(SP), R3
163210: SUB	R0, R3
163212: SUB	#000120, R4
163216: ADD	@#004000, R4
163222: BEQ	163256
163224: MOV    	#000030, R0
163230: SUB    	R4, @#004000
163234: TST    	R4
163236: BPL    	163246
163240: MOV    	#000070, R0
163244: NEG    	R4
163246: CALL   	@#163342
163252: SOB    	R4, 163246
163254: BR     	163134
;
163256: INC	R3
163260: MOV	#003750, R5
163264: ADD	#000202, R5
163270: SOB	R3, 163264
163272: MOV	#000100, R4
163276: MOV	(SP)+, R3
163300: MOV	(SP)+, R2
163302: MOV	(R5)+, (R2)+
163304: DEC	(SP)
163306: BEQ	163322
163310: SOB	R4, 163302
163312: INC	R3
163314: MOV	R2, -(SP)
163316: MOV	R3, -(SP)
163320: BR	163154
163322: TST	(SP)+
163324: MOV	(SP)+, R0
163326: BR	163340
;
163330: TST	(SP)+
163332: MOV	(SP)+, (SP)+
163334: MOV	(SP)+, (SP)+
163336: SEC	
163340: RETURN
;
; Подготовка и запуск операции; R0 = операция
163342: MOV	#177106, R5		; Адрес регистра таймера дисковода
163346: MOV	#000006, R2		; 3 мс * 6 = 18 мс
163352: CLR	(R5)			; Стартуем таймер
163354: BIT	#000001, (R5)		; Таймер досчитал?
163360: BNE	163354			; Нет
163362: SOB	R2, 163352		; Продолжаем ждать
163364: BIS	@#004002, R0
163370: MOV	R0, -(R5)		; Задаём режим
163372: TST	-(R5)			; Заполняем флаги из регистра данных
163374: MOV	#000001, -(R5)		; Запуск операции
163400: RETURN				; Теперь R5 = адрес регистра состояния
;
; Чтение секторов; R0 = кол-во секторов, R3 = адрес куда читать
163402: MOV	R3, R1
163404: MOV	R0, -(SP)		; Запомним кол-во секторов
163406: MOV	#000012, R4		; 10 - размер заголовка дорожки
163412: ADD	#000202, R4		; 130 - размер сектора
163416: SOB	R0, 163412		; Умножим 130 на кол-во секторов
163420: MOV	#000010, R0		; Команда - включить мотор и читать
163424: CALL	@#163342		; Организуем запуск команды
163430: MOV	#177102, R2		; Адрес регистра данных дисковода
163434: TSTB	(R5)			; Готов прочитанный байт?
163436: BPL	163434			; Пока нет - TR не установлен
163440: MOVB	(R2), (R1)+		; Читаем очередной байт
163442: SOB	R4, 163434		; Переходим к следующему
163444: MOV	(R5), R0		; Запомним состояние
163446: CLR	(R5)			; Окончание операции чтения
163450: MOV	(SP)+, R4		; Вспомним кол-во секторов
163452: INC	R4
163454: BIT	#000141, R0		; RELOAD или OP-FAILED или LOST-DATA ?
163460: BNE	163330			; Да - завершаемся с ошибкой
163462: MOV	#000010, R0		; 8 - длина заголовка
163466: CLR	R2			; Начинаем считать контрольную сумму
163470: MOVB	(R3)+, R1		; Очередной байт
163472: ADD	R1, R2			; Добавляем к сумме
163474: SOB	R0, 163470
163476: MOV	#000200, R0		; 128 - длина сектора
163502: CMP	R2, (R3)+		; Сумма совпала?
163504: BNE	163330			; Нет - завершаемся с ошибкой
163506: SOB	R4, 163466		; Продолжаем подсчёт сумм секторов
163510: RETURN	
;
; Подпрограмма MODE3: Вызов подпрограммы с запретом системных прерываний
163512: MOVB	#000003, @#170006	; Запрещение прерываний
163520: CALL	@(SP)+			; Выполняем как п/п то что после CALL @#163512
163522: MOVB	#000000, @#170006	; Разрешение прерываний
163530: RETURN	
;
; Подпрограмма SYSLIN: Вывод в служебную строку
163532: CALL	@#163512		; MODE3
163536: MOV	R0, -(SP)
163540: MOV	R1, -(SP)
163542: MOV	#177772, R0		; Адрес переменной - место курсора
163546: MOV	(R0), -(SP)
163550: MOV	-(R0), -(SP)
163552: MOV	000012(SP), R1
163556: CMP	(R0)+, (R1)+
163560: MOV	(R1), R1
163562: MOVB	(R1)+, (R0)+
163564: CLRB	(R0)+
163566: ADD	#176000, -(R0)
163572: CLR	-(R0)
163574: BIS	#000010, -(R0)
163600: CMP	@#177772, #176062
163606: BGE	163622
163610: MOVB	(R1)+, R0		; Получаем следующий символ
163612: BEQ	163622			; 0?
163614: CALL	@#163740		; SYSOUT Вывод символа на экран
163620: BR	163600
163622: MOV	#177766, R0
163626: BIC	#000010, (R0)+
163632: MOV	(SP)+, (R0)+
163634: MOV	(SP)+, (R0)+
163636: MOV	(SP)+, R1
163640: MOV	(SP)+, R0
163642: RETURN	
;
163644: MOV    	#177772, R4
163650: SUB    	#000040, R2
163654: BPL    	163660
163656: CLR    	R2
163660: DECB   	@#177770
163664: BEQ    	163714
163666: MOV    	#000027, R5
163672: CMP    	R2, R5
163674: BHI    	163700
163676: MOV    	R2, R5
163700: MUL    	R5, #001200
163704: BIC    	#177700, (R4)
163710: BIS    	R5, (R4)
163712: BR     	164306
163714: MOV    	#000061, R5
163720: CMP    	R2, R5
163722: BHI    	163726
163724: MOV    	R2, R5
163726: BIC    	#000077, (R4)
163732: BR     	163710
;
; ==== Программа вывода символов на экран ============================================
;
; TT.OUT Вывод символа на экран; мл.байт R0 = символ
163734: CALL	@#163512		; MODE3
; SYSOUT Вход - вывод символа
; Стандартная подпрограмма вывода символа
163740: MOV	R0, -(SP)
163742: MOV	R1, -(SP)
163744: MOV	R2, -(SP)
163746: MOV	R3, -(SP)
163750: MOV	R4, -(SP)
163752: MOV	R5, -(SP)
163754: CALL	@#165176		; Убрать курсор если он виден
163760: MOV	000012(SP), R2
163764: BIC	#177400, R2		; Оставляем только младший байт
163770: MOV	#177770, R5
163774: TSTB	(R5)
163776: BPL	164032
164000: CLRB	(R5)
164002: CMP	R2, #000131
164006: BEQ	164302
164010: CMP	R2, #000113
164014: BHI	164306
164016: SUB	#000100, R2
164022: BMI	164306
164024: MOVB	165306(R2), R4
164030: BR	164266
164032: BNE	163644
164034: MOVB	@#177766, R4
164040: BPL	164072
164042: CLR	@#177762		; | Маска фона для символа
164046: CLR	@#177764		; | Маска гашения символа перед выводом
164052: ROLB	R2
164054: CLC	
164056: BPL	164070
164060: BITB	#000040, R4
164064: BEQ	164070
164070: RORB	R2
164072: CMP	R2, #000040
164076: BLO	164230
164100: CMP	#166064, @#177774	; Знакогенератор стандартный?
164106: BNE	164130			; нет => переход
164110: ROLB	R2
164112: BPL	164120
164114: BIC	#000100, R2
164120: BHIS	164126
164122: BIS	#000100, R2
164126: ASR	R2
164130: ADD	#142005, R3		; Начало основной части экрана
164134: SUB	#000040, R2		; Символ минус 32.
164140: ASL	R2			; Дальше умножаем на 10.
164142: MOV	R2, R5			;
164144: ASL	R2			;
164146: ASL	R2			;
164150: ADD	R5, R2			; Получили смещение в знакогенераторе
164152: ADD	@#177774, R2		; Знакогенератор
164156: MOV	#000012, R4		; Высота 10. пикселей
164162: MOVB	(R2), R5		;<| Берём строку символа
164164: SWAB	R5			; | Переносим в старший байт
164166: CLRB	R5			; |
164170: BISB	(R2), R5		; | Копируем в младший байт
164172: INC	R2			; |
164174: BIC	@#177764, R5		; | Маска гашения символа перед выводом
164200: MOV	@#177762, R0		; | Маска фона
164204: XOR	R0, R5			; |
164206: MOV	R3, 000002(R1)		; | Устанавливаем косвенный адрес
164212: MOV	R5, (R1)		; | Пишем в видеопамять
164214: ADD	#000100, R3		; | К следующей пиксел-строке
164220: SOB	R4, 164162		; /
164222: MOV	#177572, R0		; Регистр косвенного адреса
164226: BR	164424			; Переходим к следующей позиции вывода
; Обработка символов с кодом меньше #040
164230: MOV	#165322, R5
164234: BITB	#000010, R4
164240: BNE	164252
164242: CMP	(R5)+, (R5)+
164244: TSTB	R4
164246: BMI	164252
164250: CMP	(R5)+, (R5)+
164252: MOV	(R5)+, R4
164254: MOV	(R5), R5
164256: ASHC	R4, R2
164260: BPL	164546
164262: MOVB	165246(R2), R4		; По коду символа получаем смещение из таблицы
164266: BIC	#177400, R4		; смещение не больше 377
164272: ASL	R4			; смещение умножить на 2
164274: MOV	#177770, R5		; Размер экрана в байтах, начиная от начала ГЗУ
164300: ADD	R4, PC			; Переходим по 164302 + 2 * смещение из таблицы 165246
; +000 - символ 20 либо ESC+131 - прямая адресация курсора;
; следующие два байта строки: N строки+40, N позиции+40
164302: MOVB   	#000002, (R5)
164306: BR     	164546
; +003 - символ 36 - очистка служебной строки
164310: MOV    	#140000, R2		; Косвенный адрес начала экрана
164314: MOV    	#002000, R3		; Сколько слов чистить
164320: MOV    	R2, (R0)
164322: CLR    	(R1)
164324: INC    	R2
164326: SOB    	R3, 164320
164330: BR     	164546
; +014 - символ 27 - переход из режима "Немига" в VT-52
164332: BIC    	#000400, (R5)
164336: BIS    	#000200, -(R5)
164342: BR     	164546
;
164344: BIT	#000200, 177776(R5)
164352: BNE	164366
; +025 - VT-52 символ ESC+106 - вкл/откл звук подтверждения нажатия клавиши
164354:

164366: DECB	(R5)
164370: BR	164546
; +034 - символ 06
164372: CLR	(R5)
164374: TST	-(R5)
164376: CLR	-(R5)
164400: CLR	-(R5)
164402: BR	164546
; +041 - символы 02..05
164404: COMB	177760(R2)
164410: BR	164546
; +044 - символ 30 - погасить/включить курсор
164412: MOV    	#000200, R2
; +046 - символ 01 - включить/выключить сдвиг экрана
164416: SWAB   	R2
164420: XOR    	R2, (R5)
164422: BR     	164546
;
; Переход к следующей позиции вывода
164424: MOV	#177772, R5		; Текущая позиция курсора
164430: INC	(R5)			; Следующая позиция		
164432: MOV	(R5), R3
164434: MOV	R3, R4
164436: BIC	#177700, R4		; Позиция в пределах строки
164442: CMP	R4, #000062		; Больше 50 ?
164446: BLO	164546			; Меньше => завершаем процедуру
164450: BIC	#000077, R3		; Возвращаемся к началу строки
164454: MOV	R3, (R5)		; Сохраняем новое место курсора
164456: ADD	#001200, R3		; Добавляем 10 пиксел-строк
164462: CMP	R3, #034700		; Дошли до конца экрана?
164466: BLO	164554			; Нет => завершаем процедуру
164470: BIC	#177700, R3
164474: BITB	#000001, @#177771	; Состояние курсора??
164502: BNE	164554
; Скроллинг экрана
164504: MOV	#142005, R2		; Косвенный адрес куда копировать
164510: MOV	#143205, R3		; Косвенный адрес откуда копировать
164514: MOV	R3, (R0)		; Заносим адрес откуда
164516: MOV	(R1), R4		; Берём слово
164520: MOV	R2, (R0)		; Заносим адрес куда
164522: MOV	R4, (R1)		; Пишем слово
164524: INC	R2			; Переходим к след адресу куда
164526: INC	R3			; К след адресу откуда
164530: BNE	164514			; Экран не кончился? => повторяем
164532: BR	165074
; +115 - символ 10 - Backspace
164534: BIC    	#177700, R3
164540: BEQ    	165104
164542: DEC    	@#177772		; новое смещение курсора левее на 1
164546: BR     	165104
; +123 - символ 15 - возврат каретки
164550: BIC	#000077, R3		; На начало строки
164554: MOV	R3, @#177772		; Сохраняем позицию курсора
164560: BR     	165104
; +130 - символ 11 - горизонтальная табуляция с шагом 8
164562: MOV    	R3, R4
164564: BIC    	#177700, R4
164570: CMP    	R4, #000057
164574: BHIS   	165104
164576: ADD	#000010, R3
164602: BIC	#000007, R3
164606: BR	164554
; +??? - символ VT-52 16 - переход на русский регистр
164610: BIS    	#000040, -(R5)
164614: BR     	165104
; +??? - символ VT-52 17 - переход на латинский регистр
164616: BIC    	#000040, -(R5)
164622: BR     	165104
; +151 - символ VT-52 ESC+100 - переход в режим "Немига"
164624: BIC    	#177600, -(R5)
164630: BR     	165104

; +165 - символ VT-52 ESC+101 или "Немига" 22 - вверх 1
164654:

164662: MOV	R3, @#177772	; новое смещение курсора
164666: BR	165104
164670: ADD    	#001200, R3	; на 10. линий вниз
164674: CMP    	R3, #034700	; вышли за нижний край?
164700: BHIS   	165104		; да => тогда ничего не делаем
164702: BR     	164662		; устанавливаем новое смещение курсора и выходим
;
164704: INC    	R3
164706: MOV    	R3, R4
164710: BIC    	#177700, R4
164714: CMP    	R4, #000062
164720: BR     	164700
;
164722: CLR	R3
164724: BR	164662
164726: SUB    	#001200, R3
164732: BPL    	164662
164734: CLR    	R2
164736: MOV    	#176600, R3
164742: MOV    	#034600, R5
164746: DEC    	R3
164750: DEC    	R2
164752: MOV    	R3, (R0)
164754: MOV    	(R1), R4
164756: MOV    	R2, (R0)
164760: MOV    	R4, (R1)
164762: SOB    	R5, 164746
164764: MOV    	#001200, R5
164770: INC    	R3
164772: MOV    	R3, (R0)
164774: CLR    	(R1)
164776: SOB    	R5, 164770
165000: BR     	165104
; +240 - символ 007 - BELL
165002: BITB   	#000100, @#177761	; Проверяем байт блокировки SOUND
165010: BNE    	165104
165012: CALL   	@#160126		; SOUND
165016: BR     	165104			; к завершению обработки символа
165020: DR	165022			; адрес мелодии
165022: DB	001, 205, 017, 000
; +252 - символ "Немига" 13, VT-52 ESC+113 - очистить строку от позиции курсора
165026: CALL   	@#165126
165032: BR     	165104
; +255 - символ "Немига "37, VT-52 ESC+112 - очистка экрана от позиции курсора
165034: CALL	@#165126
165040: BIC	#000077, R3
165044: MOV	R3, R2
165046: ADD	#142005, R2		; Начало основной части экрана
165052: BPL	165104
165054: BR	165074
; +266 - символ 21 - очистка всего экрана, включая служебную строку
165056: MOV	#140000, R2		; Косвенный адрес начала экрана
165062: BR	165070
; +271 - символ 14 - перевод формата, очистка экрана, служебная строка сохраняется
165064: MOV	#142000, R2		; Начало экрана после служебной строки
165070: CLR	@#177772		; Курсор будет в начале экрана
165074: MOV	R2, (R0)		;<| Косвенный адрес
165076: CLR	(R1)			; | Очищаем слово
165100: INC	R2			; | Увеличиваем адрес
165102: BNE	165074			; / дошли до конца ? нет => повторяем
; +301 - символ 00, ESC+105, ESC+107 - неиспользуемый код символа
; Завершение обработки символа
165104: CALL	@#165176		; Восстановление курсора
165110: MOV	(SP)+, R5
165112: MOV	(SP)+, R4
165114: MOV	(SP)+, R3
165116: MOV	(SP)+, R2
165120: MOV	(SP)+, R1
165122: MOV	(SP)+, R0
165124: RETURN	
; Очистка строки от текущей позиции до конца строки
165126: MOV	#000012, R5		; 10. итераций
165132: MOV	R3, R2
165134: MOV	#000062, R4		; 50. позиций в строке
165140: BIC	#177700, R2
165144: SUB	R2, R4
165146: BLE	165166
165150: MOV	R3, R2
165152: ADD	#142005, R2		; Начало основной части экрана
165156: MOV	R2, (R0)
165160: CLR	(R1)
165162: INC	R2
165164: SOB	R4, 165156
165166: ADD	#000100, R3
165172: SOB	R5, 165132
165174: RETURN	
;
; Подпрограмма стирания/восстановления курсора
165176: MOV	#177570, R1		; Регистр данных косвенного доступа к памяти
165202: MOV	#177572, R0		; Регистр косвенного адреса
165206: MOV	@#177772, R3		; Место курсора от начала ГЗУ
165212: BMI	165244
165214: TSTB	@#177771		; Состояние курсора??
165220: BMI	165244
165222: TSTB	@#177757		; Состояние курсора при мигании
165226: BPL	165244			; не виден => не нужно убирать
165230: MOV	R3, R4
165232: ADD	#143105, R4		; + косвенный адрес 25-й строки экрана
165236: BPL	165244
165240: MOV	R4, (R0)		; Устанавливаем косвенный адрес
165242: COM	(R1)			; Инвертируем восемь пикселей - курсор
165244: RETURN	
; Таблица смещений переходов для обработки спецсимволов
165246: DB	301, 046, 041, 041, 041, 041, 034, 240	; 00..07
165256: DB	115, 130, 066, 252, 271, 123, 143, 146	; 10..17
165266: DB	000, 266, 165, 154, 156, 210, 173, 014	; 20..27
165276: DB	044, 201, 115, 021, 212, 066, 003, 255	; 30..37
; Таблица смещений переходов для обработки символов ESC + 100..113
165306: DB	151, 165, 173, 201, 115, 301, 025, 301	; 100..107
165316: DB	210, 212, 255, 252

; Точка входа QDRAW - DRAW для QUASIC
165336: MOV    	(SP), R5
; Точка входа FDRAW - DRAW для FORTRAN
165340: CALL   	@#166040
; Точка входа DRAW - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
; После выполнения операции XNEW=XOLD, YNEW=YOLD.
165344: CALL   	@#165374
165350: MOV    	@#000212, @#000216	; XNEW -> XOLD
165356: MOV    	@#000214, @#000220	; YNEW -> YOLD
165364: RETURN 	
; Точка входа QLINE - LINE для QAUSIC
165366: MOV    	(SP), R5
; Точка входа FLINE - LINE для FORTRAN
165370: CALL   	@#166040
; Точка входа LINE - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
165374: MOV    	#000212, R5		; Адрес XNEW
165400: MOV    	(R5)+, R0
165402: MOV    	(R5)+, R1
165404: MOV    	(R5)+, R2
165406: MOV    	(R5)+, R3
165410: CLR    	@#000204		; Очищаем REV
165414: MOV    	#000001, R4
165420: MOV    	R4, R5
165422: SUB    	R2, R0
165424: BPL    	165432
165426: NEG    	R0
165430: NEG    	R5
165432: SUB    	R3, R1
165434: BPL    	165442
165436: NEG    	R1
165440: NEG    	R4
165442: CMP    	R0, R1
165444: BGE    	165474
165446: MOV    	R0, -(SP)
165450: MOV    	R1, R0
165452: MOV    	(SP), R1
165454: MOV    	R4, (SP)
165456: MOV    	R5, R4
165460: MOV    	(SP), R5
165462: MOV    	R2, (SP)
165464: MOV    	R3, R2
165466: MOV    	(SP)+, R3
165470: INC    	@#000204		; Инкремент REV
165474: TST    	R0
165476: BEQ    	165542
165500: ASL    	R1
165502: MOV    	R0, -(SP)
165504: ASL    	(SP)
165506: MOV    	R1, -(SP)
165510: SUB    	R0, (SP)
165512: CALL   	@#165542
165516: TST    	(SP)
165520: BMI    	165530
165522: SUB    	000002(SP), (SP)
165526: ADD    	R4, R3
165530: ADD    	R1, (SP)
165532: ADD    	R5, R2
165534: SOB    	R0, 165512
165536: CMP    	(SP)+, (SP)+
165540: RETURN 	
165542: MOV    	R1, -(SP)		; Сохраняем регистры
165544: MOV    	R2, -(SP)
165546: MOV    	R3, -(SP)
165550: TST    	@#000204		; Проверяем REV
165554: BEQ    	165562
165556: MOV    	R2, R3
165560: MOV    	(SP), R2
165562: CALL   	@#165614		; Выводим точку (R2,R3)
165566: MOV    	(SP)+, R3		; Восстанавливаем регистры
165570: MOV    	(SP)+, R2
165572: MOV    	(SP)+, R1
165574: RETURN 	
;
; Точка входа QPOINT - POINT для QUASIC
165576: MOV	(SP), R5
; Точка входа FPOINT - POINT для FORTRAN
165600: CALL	@#166040
; Точка входа POINT - нарисовать точку
165604: MOV	@#000212, R2		; XNEW
165610: MOV	@#000214, R3		; YNEW
165614: CALL	@#163512		; MODE3
165620: CALL	@#165746		; Находим точку на экране
165624: BLO	165656
165626: TST	(R1)+
165630: MOV	@#000210, R2		; BRIGHT
165634: ASR	R2
165636: BLO	165646
165640: BIC	R3, @#177570		; Пишем в экран
165644: BR	165652
165646: BIS	R3, @#177570		; Пишем в экран
165652: SWAB	R3
165654: SOB	R1, 165634
165656: RETURN	
;
; Точка входа QRPOIN - RPOINT для QUASIC
165660: MOV    	(SP), R5
; Точка входа FRPOIN - RPOINT для FORTRAN
165662: CALL   	@#166040
165666: BR     	165674
; Точка входа RPOINT - прочитать яркость точки
165670: MOV    	#000210, R4		; Адрес BRIGHT
165674: MOV    	@#000212, R2		; XNEW
165700: MOV    	@#000214, R3		; YNEW
165704: CLR    	(R4)
165706: CALL   	@#163512		; MODE3
165712: CALL   	@#165746		; Находим точку на экране
165716: BLO    	165742
165720: MOV    	#000002, R1
165724: SWAB   	R3
165726: BIT    	R3, @#177570
165732: BEQ    	165736
165734: ADD    	R1, (R4)
165736: SOB    	R1, 165724
165740: RETURN 	
165742: DEC    	(R4)
165744: RETURN 	
; Нахождение точки на экране; устанавливает косвенный адрес, возвращает маску в R3
165746: MOV	R2, R1
165750: CMP	#000637, R2
165754: BLO	166036
165756: ASH	R2, #177775
165762: CMP	(R2)+, (R2)+
165764: CMP	#000377, R3
165770: BLO	166036
165772: CMP	@#000206, R3		; Сравниваем с VFORM
165776: BLO	166036
166000: COMB	R3
166002: SWAB	R3
166004: SEC	
166006: ROR	R3
166010: ASR	R3
166012: BIS	R3, R2
166014: MOV	R2, @#177572		; Устанавливаем косвенный адрес
166020: BIC	#177770, R1
166024: INC	R1
166026: CLR	R3
166030: SEC	
166032: ROR	R3
166034: SOB	R1, 166032
166036: RETURN	
; Подготовка перед вызовом для FORTRAN
166040: MOV     (R5)+, R0
166042: MOV     (R5), R4
166044: BIC     #177770, R0
166050: BEQ     166062
166052: MOV     #000210, R3		; Адрес BRIGHT
166056: MOV     @(R5)+, (R3)+
166060: SOB     R0, 166056
166062: RETURN  
;
; ==== Стандартный знакогенератор ====
166064: DB			; Знакогенератор, 96 символов (0x20..0x80), 10 байт/символ

; ==== Регистры ====
170000: DW			; Используется м/с умножителя
170002: DW			; Используется м/с умножителя
170004: DW			; Используется м/с умножителя
170006: DW			; Регистр данных клавиатуры / фиксации HALT запросов
170010: DW			; Регистр состояния адаптера локальной сети
170012: DW			; Регистр данных адаптера локальной сети
170014: DW			; ??

170020: DW			; RgStSnd  - регистр состояния таймера
170022: DW			; RgF      - регистр частоты
170024: DW			; RgLength - регистр длительности
170026: DW			; RgOn     - включение звука (обращение)
170030: DW			; RgOct    - регистр октавы и громкости
170032: DW			; RgOff    - выключение звука (обращение)

177100: DW			; RgStat   - регистр состояния контроллера дисковода
177102: DW			; RgData   - регистр данных
177104: DW			; RgCntrl  - регистр управления
177106: DW			; RgTime   - регистр таймера контроллера дисковода

177170: DW			; Регистр состояния дисковода DX
177172: DW			; Регистр данных дисковода DX

177514: DW			; Регистр данных устройства сопряжения
177516: DW			; Регистр состояния усройства сопряжения

177560: DW			; KBS      - регистр состояния клавиатуры
177562: DW			; KBD      - регистр данных клавиатуры
177564: DW			; TTS      - регистр состояния дисплея
177566: DW			; TTD      - регистр данных дисплея

177570: DW			; VDATA    - регистр данных косвенного доступа
177572: DW			; VADDR    - регистр адреса косвенного доступа

; ==== Блок переменных ====
177720: DW			; R0  при останове
177722: DW			; R1  при останове
177724: DW			; R2  при останове
177726: DW			; R3  при останове
177730: DW			; R4  при останове
177732: DW			; R5  при останове
177734: DW			; SP  при останове
177736: DW			; PC  при останове
177740: DW			; PSW при останове
177750: DW			; Адрес начала мелодии
177752:	DW			; Адрес продолжения мелодии
177754: DW			; Адрес подпрограммы SOUND
177756: DB			; Счётчик мигания курсора
177757: DB			; Состояние курсора: 000 - не виден, 377 - виден
177760: DB			; Счётчик длительности ноты
177761: DB			; Байт блокировки вызова SOUND
177762: DW			; FRG    Маска фона для вывода символа
177764: DW			; COL    Маска гашения символа перед выводом
177766: DW			; Какие-то важные флаги??
177770: DW			; SIZE   Размер экрана в байтах, начиная от начала ГЗУ
177772: DW			; CUR    Место курсора от начала ГЗУ
177774: DW			; SYMGEN Адрес знакогенератора, по умолчанию 166064
177776: DW			; Значение #056311