Немига 406 ROM disasm

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

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

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

000004: DW		; Адрес прерывания
000006: DW		; PSW прерывания
000010: DW		; Адрес прерывания
000012: DW		; PSW прерывания
000014: DW		; Адрес прерывания - прерывание по T-разряду или команда BPT
000016: DW		; PSW прерывания
000020: DW		; Адрес прерывания - команда IOT
000022: DW		; PSW прерывания
000024: DW		; Адрес прерывания - питание
000026: DW		; PSW прерывания
000030: DW		; Адрес прерывания - команда EMT
000032: DW		; PSW прерывания
000034: DW		; Адрес прерывания - команда TRAP
000036: DW		; PSW прерывания

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

000100: DW		; Адрес прерывания - таймер

000104:	DW		; Адрес подпрограммы обработки сигнала Н4 - от сетевой карты
000110; DW		; Прерывание "мелодия закончилась кодом 040"
000112: DW		; PSW прерывания

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

; ==== Начало ПЗУ - см. PULT.MAC =====================================================

160000: DW	177570			; ??
160002: DW	160210, 000341		; Вектор прерывания сигнала/команды HALT
160006: DW	161726, 000340		; Вектор прерывания - дв.ошибка канала, запуск
160012: DW	161142, 000340		; Вектор прерывания - ошибка ввода адреса вектора
160016: JMP     @#163466		; MODE3  - Вызов с запретом системных прерываний
160022: JMP    	@#163504		; SYSLIN - Вывод в служебную строку
160026: JMP    	@#163722		; TT.OUT - Системный вывод через MODE
160032: JMP    	@#163726		; SYSOUT - Системный вывод
160036: JMP    	@#162274		; PRINT  - Вывод текста
160042: JMP    	@#165346		; DRAW   - Нарисовать линию, сохранив XOLD,YOLD
160046: JMP    	@#165340		; QDRAW     то же для QUASIC
160052: JMP    	@#165342		; FDRAW     то же для FORTRAN
160056: JMP    	@#165376		; LINE   - Нарисовать линию
160062: JMP    	@#165370		; QLINE     то же для QUASIC
160066: JMP    	@#165372		; FLINE     то же для FORTRAN
160072: JMP    	@#165606		; POINT  - Нарисовать точку
160076: JMP    	@#165600		; QPOINT    то же для QUASIC
160102: JMP    	@#165602		; FPOINT    то же для FORTRAN
160106: JMP    	@#165672		; RPOINT - Читать яркость точки
160112: JMP    	@#162236		; QRPOIN    то же для QUASIC
160116: JMP    	@#165664		; FRPOIN    то же для FORTRAN
160122: JMP    	@#162236		; DUMP   - напечатать восьмеричное число R3
160126: JMP     @177754			; SOUND

; ==== HALT MONITOR

.RESET - Обработка канального сигнала СБРОС
160142: MOV	#000357, @#000206	; 239. -> VFORM
160150: CLR	@#177560		; Сброс состояния клавиатуры
160154: MOV	#000200, @#177564	; Уст. состояние терминала - не готов, запрет прерывания
160162: CLR	@#177770
160166: BIC	#177541, @#177766	; Режим дисплея - оставляем только флаги #136
HOUT:
160174: MOV	(SP)+, R0
160176: JMP	@#161074		; .PULT - Завершаем обработку прерывания HALT
;
; Обработка нажатия СТОП и кнопки ОСТ
PULT:				; УПР/СТОП или команда HALT
160202: MOV	(SP)+, R0		; Восстанавливаем R0
160204: JMP	@#161142		; Переходим к сохранению регистров и пульту
;
; Обработчик прерывания по сигналу/команде HALT
HMON::			; диспетчер HALT прерываний.
160210: CMP	#056364, @#177776	; Проверка, настроена ли память режима HALT
160216: BEQ	160224			; да, настроена
160220: JMP	@#161720		; нет => DOUBL - перезапуск
O.K.:
160224: MOV	R0, -(SP)		; Сохраняем R0 чтобы не испортить
160226: BIS	#000200, @#177564	; ТТ: всегда готов !
160234: BIT	#176000, @#170006	; Проверка старших 6 бит регистра фиксации HALT
160242: BMI	160142			; была команда RESET
160244: BEQ	160202			; была команда HALT
160246: BIT	#004000, @#170006	; Сигнал Н4? - адаптер локальной сети
160254: BEQ	160262			; нет
160256: CALL	@000104			; SH4 - локальная сеть.
.DISP:
160262: BIT	#040000, @#170006	; SH1 - по записи в TTD
160270: BEQ	160302			; нет => переходим
160272: MOV	@#177566, R0		; Регистр данных терминала - символ для вывода на экран
160276: CALL	@#163726		; SYSOUT Вывод символа R0 на экран
.RDKEY:
160302: BIT	#020000, @#170006	; SH2 - по чтению из KBD
160310: BEQ	160334			; нет => переходим
160312: MOVB	@#177767, R0		; Провека буферной ячейки клавиатуры
160316: BEQ	160326			; буфер пуст => переходим
160320:	CLRB	@#177767		; Очищаем буфер
160324: BR	160526			; вывод второй части.
EMPTY:
160326: BIC	#177677, @#177560	; сброс бита прерывания клавиатуры.
.KEY::
160334: MOV	@#170006, R0		; KEY - по нажатию клавиши.
160340: BIT	#002000, R0		; Пришёл байт с клавиатуры?
160344: BEQ	160606			; нет =>
160346: BIC	#177400, R0		; код КОИ-8
160352: BEQ	160202			; код 0 -- УПР/СТОП.
160354: TSTB	@#177560		; Состояние клавиатуры - готов к приёму?
160360: BMI	160606			; нет =>
; Нажата клавиша - выдаём звук нажатия клавиши
160362: MOV	R1, -(SP)
160364: MOV	R2, -(SP)
160366: TSTB	@#177761		; Флаг блокировки вызова SOUND
160372: BNE	160410			; играет мелодия.
160374: CALL	@#160126		; SOUND
160400: BR	160410			;
160402: DW	160404			; Адрес мелодии нажатия клавиши
160404: DB	011, 214, 001, 000	; Мелодия - звук длиной 1/50 сек
; Обработка нажатой клавиши
160410: MOV	#177766, R1		; Адрес Режим дисплея
160414: MOV	#000100, R2
160420: TSTB	(R1)			; проверяем бит 7 в Режим дисплея
160422: BPL	160522			l бит 7 = 0 ? => переход
160424: BITB   	#000300, R0
160430: BEQ    	160500
160432: BPL    	160462
160434: BIT    	R2, R0
160436: BEQ    	160522
160440: BIC    	#177600, R0
160444: BITB   	R2, (R1)+
160446: BNE    	160522
160450: MOVB   	R0, (R1)
160452: MOV    	#000016, R0
160456: BISB   	R2, -(R1)
160460: BR     	160522
LAT:
160462: BITB   	R2, (R1)+		; лат. регистр установлен ?
160464: BEQ    	160522
160466: MOVB   	R0, (R1)		; нет - двойной код: ЛАТ-символ.
160470: MOV    	#000017, R0
160474: BICB   	R2, -(R1)
160476: BR     	160522
160500: CMPB   	R0, #000040		; >= ' ' ?
160504: BHIS   	160522			; да => 
160506: MOVB   	161102(R0), @#177767	; управляющие последовательности.
160514: BEQ    	160522			; типа: АР2-код.
160516: MOV    	#000033, R0		; код ESC
REG2:
160522: MOV	(SP)+, R2
160524: MOV	(SP)+, R1
160526: MOV	R0, @#177562		; стандартная клавиатура.
160532: MOV	(SP)+, R0
160534: BIS	#000200, @#177560	; Состояние клавиатуры - сброс бита готовности
160542: BIT	#000100, @#177560	; Состояние клавиатуры - разрешено прерывание?
160550: BEQ	161074			; нет => Завершаем обработку прерывания HALT
160552: BISB   	#000001, @#177766	; Запрещаем прерывание по вектору 000064
160560: TSTB   	000002(SP)
160564: BMI    	161074			; => Завершаем обработку прерывания HALT
INT.K:			; эмуляция прерывания от клавиатуры.
160566: BICB   	#000001, @#177766	; Разрешаем прерывание по вектору 000064
160574: MOV    	@#000062, -(SP)		; Кладём в стек PSW
160600: MOV    	@#000060, -(SP)		; адрес прерывания по вектору 60
160604: BR     	161074			; HOUT1 - Завершаем обработку прерывания HALT
.CLOCK::			; SH3 - по системным часам.
160606: MOV	(SP)+, R0		; Восстанавливаем R0
160610: BIT	#010000, @#170006	; Сигнал Н3?
160616: BEQ	161074			; нет => Завершаем обработку прерывания HALT
; Обработка сигнала Н3
160620: MOV	R4, -(SP)		; Сохраняем R4
160622: TST	@#177760		; Флаг блокировки SOUND
160626: BPL	160750			; bit7=0 => переходим
160630: MOV	@#177752, R4		; Берём адрес продолжения мелодии
160634: INCB	@#177760		; Увеличиваем счётчик длительности ноты
160640: CMPB	@#177760, 177777(R4)	; Сравниваем с длительностью ноты
160646: BLO	160750			; пока не кончилась => переходим
160650: TSTB	(R4)			; 200 ?
160652: BMI	160744			; да => переходим
160654: BITB	#000037, (R4)		; Есть ещё нота мелодии?
160660: BNE	160740			; да => переходим
160662: BIC	#100000, @#177760	; Снимаем флаг блокировки SOUND
; Обработка флагов завершения мелодии
160670: BITB	#000040, (R4)		; 040 и 140 ?
160674: BNE	160712			; да => переходим
160676: TSTB	(R4)			; 000 ? (никаких действий по окончании мелодии)
160700: BEQ	160750			; да => переходим
160702: CALL   	@#160126		; SOUND
160706: BR     	160750
160710: DW	000000
; Окончание мелодии байтом 040 либо 140
160712: BITB   	#000100, (R4)+		; байт 140?
160716: BNE    	160734			; да => переход
160720: MOV    	(SP)+, R4
160722: MOV    	@#000112, -(SP)		; Сохраняем в стеке переход
160726: MOV    	@#000110, -(SP)		; на прерывание по вектору 110
160732: BR     	161074			; к разрешению прерываний и RTI
; Окончание мелодии байтом 140
160734: CLRB   	(R4)			; Очистка байта после конца мелодии
160736: BR     	160750			; переходим к работе с курсором
;
160740: MOVB   	(R4)+, @#170030		; Октава и громкость
160744: CALL   	@#162520		; Обработка продолжения мелодии
; Мигание курсора
160750: DECB	@#177756		; Уменьшаем счётчик мигания
160754: BPL	161034			; значение >= 0 ? => переходим
160756: MOVB	#000007, @#177756	; Новое значение счётчика
160764: COMB	@#177757		; Инвертировать состояние курсора при мигании
160770: MOV	@#177772, R4		; Смещение курсора
160774: BMI	161034
160776: TSTB	@#177771		; Состояние курсора??
161002: BMI	161034
161004: ADD	@#177746, R4		; + адрес 25-й строки экрана
161010: BMI	161034
161012: ROL	R4
161014: BMI	161034
161016: BIS	#000001, @#177574	; Включаем экран в основную память
161024: COM	(R4)			; Инвертирование восьми пикселей - курсор
161026: BIC	#000001, @#177574	; Отключаем экран из основной памяти
161034: MOV	(SP)+, R4		; Восстанавливаем R4
161036: TSTB	000002(SP)		; приоритет ССП < 4 ?
161042: BMI	161074			; ?? => Завершаем обработку прерывания HALT
161044: BITB   	#000001, @#177766	; был запрос от клавиатуры ?
161052: BNE    	160566
161054: BIT    	#000100, @#177564	; прерывание от дисплея нужно ?
161062: BEQ    	161074			; нет => Завершаем обработку прерывания HALT
; Эмуляция прерывания от дисплея
161064: MOV    	@#000066, -(SP)		; сохраняем PSW
161070: MOV    	@#000064, -(SP)		; и адрес для перехода по вектору 000064
; HOUT1: Завершение обработки прерывания HALT
161074: CLRB	@#170006		; Разрешаем системные прерывания
161100: RTI
; Таблица байт - маппинг кодов клавиш 000..037 в ESC-коды
; TCK: таблица перекодировки  управяющиx клавиш  в  режимe VT-52
161102: DB	...

; Обработка прерывания по вектору 160012 - Сохранение регистров и переход к пульту
.PULT::
161142: MOV	(SP)+, @#177736		; убрать вектор состояния.
161146: MOV	(SP)+, @#177740		;  из стека.
161152: MOV	SP, @#177734		; установить системный стек.
161156: MOV	#177734, SP		;
161162: MOV	R5, -(SP)		; -> 177732
161164: MOV	R4, -(SP)		; -> 177730
161166: MOV	R3, -(SP)		; -> 177726
161170: MOV	R2, -(SP)		; -> 177724
161172: MOV	R1, -(SP)		; -> 177722
161174: MOV	R0, -(SP)		; -> 177720 - начало блока регистров
161176: MOV	@#000004, -(SP)		; Адрес прерывания
161202: MOV	@#000006, -(SP)		; PSW прерывания
161206: MOV	@#177766, -(SP)		; Сохраняем Режим дисплея
161212: CLR	@#177766		; Очищаем Режим дисплея - режим немига.
161216: MOV	#000340, @#000006	; есть ли локальная сеть ?
161224: MOV	#161444, @#000004	; 
161232: MOV	#000060, @#170010	; в сети - режим останов.
161240: BR	161444			; ..CSI - Переход к пультовому терминалу
;
; ==== Программа пультового терминала
;
; NEXT: Просмотр ячеек памяти - переход к следующему слову
161242: INC    	R2			; открыть следующую.
161244: INC    	R2
; Команда '/' - просмотр ячеек памяти
; OPEN:			; открыть ячейку.
161246: CMP    	R2, @#177744		; Сравниваем с нижней границей
161252: BLO    	161270			; меньше => переходим
161254: CMP    	R2, #177600
161260: BHIS   	161546			; => выводим признак ошибки и в пульт
161262: CMP    	R2, #170000
161266: BLO    	161546			; => выводим признак ошибки и в пульт
161270: MOV    	#162716, R5		; Строка
161274: CALL   	@#			; PRINT
161300: MOV    	R2, R3			; Печатаем адрес
161302: CALL   	@#162236		; DUMP Вывод R3 как 8-ричного числа
161306: MOV    	(R2), R3		; Печатаем значение
161310: CALL   	@#162236		; DUMP Вывод R3 как 8-ричного числа
161314: CALL   	@#162310
161320: TST    	R1
161322: BEQ    	161326
161324: MOV    	R5, (R2)		; Заносим новое значение
161326: CMPB   	#000012, R0		; Нажали ПС?
161332: BEQ    	161242			; Да, переходим к следующему слову памяти
161334: CMPB   	#000015, R0		; Нажали ВВОД?
161340: BEQ    	161444			; Да, возвращамся в пульт
161342: CMPB   	#000136, R0		; Нажали '^' ?
161346: BNE    	161546			; Нет - выводим признак ошибки и в пульт
161350: DEC    	R2			; Переходим к предыдущему слову памяти
161352: DEC    	R2
161354: BR     	161246
;
; Команда 'G' - продолжение выполнения программы
GO:				; старт/продолжение программы.
161356: MOV    	(SP)+, @#177766		; Восстанавливаем Режим дисплея
161362: TST    	R1			; Параметр задан?
161364: BEQ    	161400			; нет => восстановление регистров и возврат
161366: CLR    	@#177740
161372: MOV    	R5, @#177736		; Адрес запуска
161376: RESET  	
; Восстановление всех регистров, возврат из прерывания
EXIT:
161400: MOV    	(SP)+, @#000006
161404: MOV    	(SP)+, @#000004
161410: MOV    	(SP)+, R0
161412: MOV    	(SP)+, R1
161414: MOV    	(SP)+, R2
161416: MOV    	(SP)+, R3
161420: MOV    	(SP)+, R4
161422: MOV    	(SP)+, R5
161424: MOV    	(SP), SP
161426: MOV    	@#177740, -(SP)		; PSW
161432: MOV    	@#177736, -(SP)		; PC
161436: RTI   
;
; Вывод символа и переход к пульту
CLEAR:		; очистить экран.
161440: CALL   	@#163722		; TT.OUT Вывод символа
; Вывод приглашения пульта и ожидание команды
; ..CSI:			; прием и интерпретация команд.
161444: MOV	#162704, R5		; Строка "Пульт>"
PRIERR:
161450: MOV	#177712, SP
161454: MOV	#000340, @#000006	; PSW для прерывания
161462: MOV	#161546, @#000004	; Адрес прерывания по вектору 4
161470: CALL	@#162274		; PRINT Вывод строки, адрес в R5
161474: CALL	@#162310		; Получаем команду с клавиатуры
161500: MOV	R5, R2
161502: CMPB	#000057, R0		; Символ '/' - просмотр ячеек памяти
161506: BEQ	161246
161510: CMPB	#000123, R0		; Символ 'S' - вывод регистров ЦП
161514: BEQ	161554
161516: CMPB	#000107, R0		; Символ 'G' - выполнение программы
161522: BEQ	161356
161524: CMPB	#000104, R0		; Символ 'D' - загрузка с диска MD
161530: BEQ	161676
161532: CMPB   	#000116, R0		; Символ 'N' - загрузка с сети
161536: BEQ    	161726			; => начальный пуск
161540: CMPB   	#000014, R0		; Нажат УПР + L - очистка экрана
161544: BEQ    	161440
; Вывод знака вопроса (ошибка выполнения команды) и возврат в пультовый режим
ERROR:			; ошибочная команда.
; также используется как адрес прерывания по вектору 4
161546: MOV	#162703, R5		; Строка " ?"
161552: BR	161450
;
; Команда 'S' - вывод на экран регистров процессора
; LOOK:				; просмотр регистров.
161554: MOV    	#000011, R2		; 9 регистров
161560: MOV    	#161606, R5		; Строка с названиями регистров
161564: CALL   	@#162274		; Вывод строки
161570: MOV    	#177720, R4
161574: MOV    	(R4)+, R3
161576: CALL   	@#162236		; Вывод R3 как 8-ричного числа
161602: SOB    	R2, 161574
161604: BR     	161444			; Возврат в пульт
161606: DB	...			; Строка с названиями регистров ЦП

;NOTE: Команда 'X' - загрузка с устройства DX - удалена
;
; Команда 'D' - загрузка с диска MD
BOOT:				; загрузка с дисков MD
161676: CMP	R5, #7			; Номер устройства больше 7?
161702: BHI	161546			; да => ERROR
161704: CALL	@#162726		; MDBOOT - Загрузка данных с дисковода
161710: MOV    	#000200, @#177766	; Режим дисплея = VT52
161716: CLR    	PC			; Запуск полученного блока
;
161720: MOV    	#160000, @#177744	; Нижняя граница памяти доступной для команд пульта
;
; ==== Программа холодного старта - COLD START & BOOTSTRAP FROM LOCNET
;
; Холодный старт при включении питания
DOUBLE::
LOCNET:	
161726: MOV	#001000, SP		; Устанавливаем стек
161732: CLR	R0
161734: MOV	#056364, -(R0)		; -> (177776)
161740: MOV	#164042, -(R0)		; Адрес стандартной п/п вывода символа -> (177774)
161744: CLR	@#177574		; Отключаем экран из основной памяти
161750: MOV	#000007, R1
161754: CLR	-(R0)			; <|
161756: SOB	R1, 161754		;  / Очищаем 7 слов 177756-177773
161760: MOV	#162516, -(R0)		; -> (177754)
161764: MOV	#162002, @#000004	; Адрес прерывания 4
161772: CLR	@#170024		; Сброс длительности
161776: MOV	#162426, (R0)		; Адрес SOUND -> (177754)
162002: MOV	#165036, -(R0)		; Адрес мелодии BELL -> (177752)
162006: MOV	(R0), -(R0)		; тот же адрес -> (177750)
162010: MOV	#003100, -(R0)		; #003100 -> (177746)
162014: RESET				; сброс всех устройств
162016: MOV	#000021, R0		; символ "очистка экрана"
162022: CALL	@#163722		; TT.OUT Вывод символа
162026: MOV	#161142, @#000004	; Адрес прерывания 4 - сохранить регистры и выход в пульт
162034: MOV	#000340, @#000006	; PSW для прерывания
; Попытка загрузки из сети
162042: MOV	#170010, R4		; Адрес регистра состояния локальной сети
162046: CALL	@#163504		; SYSLIN - Вывод в служебную строку
162052: BR	162056
162056: MOV	#000014, (R4)		; Настройка состояния сетевого адаптера
162062: MOV	#162671, R5
162066: CALL	@#162274
162072: MOV	#162226, @#000004
162100: BIT	#100040, (R4)
162104: BMI	162226
162106: BEQ    	162100
162110: TST    	(R4)
162112: MOVB   	#000003, @#170006	; Запрещение прерываний
162120: MOV    	#000016, (R4)
162124: CALL   	@#162206		; Ожидаем слово из сети
162130: MOV    	000002(R4), R2
162134: MOV    	#177712, SP
162140: MOV    	#177572, R0
162144: CLR    	(R0)
162146: CALL   	@#162206		; Ожидаем слово из сети
162152: MOV    	000002(R4), 177776(R0)
162160: INC    	(R0)
162162: SOB    	R2, 162146
162164: MOV    	#000020, (R4)
162170: CLR    	-(SP)
162172: CLR    	-(SP)
162174: BIS    	#000200, @#177766	; Режим дисплея
162202: JMP    	@#161074
; Подпрограмма - ожидание слова из сети
162206: CLR    	R1			; счётчик ожидания
162210: BIT    	#100040, (R4)
162214: BMI    	162226			; ошибка сети, выходим
162216: BEQ    	162224
162220: TST    	(R4)
162222: RETURN 	
162224: SOB    	R1, 162210		; продолжаем цикл ожидания
ERRLN:
162226: MOV	#002060, (R4)		; ошибка в сети, ОСТАНОВ.
162232: JMP	@#161546
;
; ==== Программы вывода на экран чисел и строк
;
; Подпрограмма DUMP Вывод слова как 8-ричного числа; R3 = число
DUMP::
162236: MOV	#000006, R1		; Шесть разрядов
DUMP1::
162242: CLR	R0
162244: ROL	R3
162246: ROL	R0
162250: ADD	#000060, R0		; '0'
162254: CALL	@#163722		; TT.OUT Вывод символа
162260: CLR	R0
162262: ROL	R3
162264: ROL	R0
162266: ROL	R3
162270: ROL	R0
162272: SOB	R1, 162244
; Подпрограмма PRINT - Вывод строки на экран; R5 = адрес строки
PRINT::
162274: MOVB	(R5)+, R0		; Очередной символ
162276: BNE	162302			; Не ноль? => продолжаем
162300: RETURN				; Конец строки, выходим
162302: CALL	@#163722		; TT.OUT Вывод символа
162306: BR	162274			; Продолжаем вывод строки
;
; Ввод команды; команда это символ либо 8-ричное число (параметр) и символ
GET:				; ввод строки.
162310: CLR	R1			;   R0 - последний введенный код.
162312: CLR	R5			;   R1 - число введенных цифр.
162314: TSTB	@#177560		;   R5 - введенное значение, OCT
162320: BPL	162314
162322: MOVB	@#177562, R3		; Считываем символ
162326: CMPB	R3, #000177		; забой ?
162332: BNE	162362
162334: DEC    	R1
162336: BMI    	162310
162340: ASH    	R5, #177775
162344: BIC    	#160000, R5
162350: MOV    	#000134, R0
162354: CALL   	@#163722		; TT.OUT Вывод символа
162360: BR     	162314
162362: MOV	R3, R0
162364: CMPB	R0, #000040
162370: BLO	162300
162372: CALL	@#163722		; TT.OUT Вывод символа
162376: BIC	#177407, R3
162402: CMP	#000060, R3		; символ '0' ?
162406: BNE	162300
162410: BIC    	#177770, R0
162414: ASH    	R5, #000003
162420: BIS    	R0, R5
162422: INC    	R1
162424: BR     	162314
;
; Подпрограмма SOUND
SOUND::				; музыка.
162426: MOV	R4, -(SP)		; Сохраняем R4
162430: BICB	#000200, @#177761
162436: CLR	@#170024		; Сброс длительности
162442: MOV	000002(SP), R4		; Откуда вызвали SOUND
162446: MOV	000002(R4), R4		; Получаем адрес мелодии 
162452: BNE	162460
162454: MOV    	@#177750, R4
162460: TSTB	(R4)
162462: BEQ	162514
162464: MOV	R4, @#177750		; Запоминаем адрес начала мелодии
162470: MOV	#001516, @#170020	; Пишем в регистр состояния таймера
162476: MOVB	(R4)+, @#170030		; Октава и громкость
162502: CALL	@#162520		; Обработка продолжения мелодии
162506: BISB	#000200, @#177761	; Возвращаем флаг блокировки SOUND: bit7=1
162514: MOV	(SP)+, R4		; Восстанавливаем R4
162516: RETURN	
; Обработка продолжения мелодии
162520: MOV	R3, -(SP)		; Сохраняем R3
162522: MOVB	(R4)+, R3
162524: BIC	#177760, R3		; Оставляем нижние 4 бита - 00..17
162530: ASL	R3			; и умножаем на 2
162532: MOV	162564(R3), @#170022	; Выбираем по R3 слово и пишем в регистр частоты
162540: MOVB	(R4)+, @#170024		; Задаём длительность звука
162544: CLRB	@#177760		; Очищаем счётчик длительности ноты
162550: MOV	R4, @#177752		; Запоминаем адрес продолжения мелодии
162554: TST	@#170026		; Включение звука
162560: MOV	(SP)+, R3		; Восстанавливаем R3
162562: RETURN	
; Значения задержки первого таймера для нот
NOTY:
162564: DW	000000, 002253, 002150, 002050, 001755, 001664, 001577, 001515
162604: DW	001435, 001361, 001306, 001237, 001171, 000000, 000000, 000000

; Строковые буферы
HELLO::	.BYTE 	4,6,5
AUTOR:	.RUS	<mrti>
	.BYTE	11,11,11
NAME:	.RUS	<kw>
	.BYTE	5
	.RUS	< nemiga>
VERS:	.BYTE	5
	.ASCII	/ 4.07/
	.BYTE	6,11
H.END::	.BYTE	40,0
RMP::	.RUS	<rmp >
	.BYTE	0
RMU::	.RUS	<rmu >
	.BYTE	0

LOCBO:	.BYTE	14
	.RUS	<VDITE...>
	.BYTE	0
ERR:	.ASCII	/?/
PROMPT:	.BYTE	6,15,12
	.RUS	<pULXT>
	.ASCIZ	/>/

MODI:	.BYTE	12,15,,':,40,,40,0

;
; ==== Подпрограммы работы с дисководом MD - см. BOOT.MAC ============================
;
; Чтение с дисковода для загрузки; R5 = номер устройства
MDBOOT::
162726: CALL	@#163466		; MODE3
162732: MOV	#000001, R4
162736: MOV	R5, -(SP)		; логический No устройства.
162740: ASR	R5
162742: BHIS	162750
162750: MOV	R5, @#004002		; -> B$PDN Физический номер устройства.
162754: MOV	#000400, -(SP)		; один блок по адресу 0 с 1-го сектора
162760: CLR	-(SP)
162762: MOV	R4, -(SP)
162764: MOV	#000006, R1
162770: MOV	#000070, R0
162774: CALL	@#163256
163000: SOB	R1, 162770
163002: MOV	#000030, R0
163006: CALL	@#163256
163012: CLR	@#177106
163016: BIT	R4, @#177106
163022: BNE	163016
163024: BIT	#000010, (R5)
163030: BNE	163002
163032: CLR	@#177106
163036: BIT	R4, (R5)
163040: BEQ	163046
163042: SOB    	R2, 163032
163044: HALT   
; Мы на 0-й дорожке, читаем первый сектор
ERR1::
163046: MOVB	R4, R0			; чтение описателя
163050: MOV	#004004, R3		; B$Area
163054: CALL	@#163316
163060: CLR    	@#004000		; B$Trck
163064: MOV    	@#004000, R0		; B$Trck
163070: MOVB   	004016(R0), R0		; дорожка в буфер.
163074: MOV    	#004140, R3
163100: CALL   	@#163316
163104: CLR    	R1
163106: MOV    	#004016, R5
163112: MOV    	#000120, R4
163116: MOVB   	(R5)+, R2
163120: MOV    	R1, R0
163122: ADD    	R2, R1
163124: CMP    	R1, (SP)
163126: BHI    	163134
163130: SOB    	R4, 163116
163132: HALT   	
ERR2::
163134: MOV    	(SP), R3		; абсолютный No сектора.
163136: SUB    	R0, R3			; относительный No сектора на дорожке.
163140: SUB    	#000120, R4		; (-No) нужной дорожки.
163144: ADD    	@#004000, R4
163150: BEQ    	163204
163152: MOV    	#000030, R0
163156: SUB    	R4, @#004000
163162: TST    	R4
163164: BPL    	163174
163166: MOV    	#000070, R0
163172: NEG    	R4
163174: CALL   	@#163256
163200: SOB    	R4, 163174
163202: BR     	163064
;
163204: INC    	R3
163206: MOV    	#003750, R5
163212: ADD    	#000202, R5
163216: SOB    	R3, 163212
163220: MOV    	#000100, R4
163224: MOV    	(SP)+, R3
163226: MOV    	(SP)+, R2
163230: MOV    	(R5)+, (R2)+
163232: DEC    	(SP)
163234: BEQ    	163250
163236: SOB    	R4, 163230
163240: INC    	R3
163242: MOV    	R2, -(SP)
163244: MOV    	R3, -(SP)
163246: BR     	163104
163250: TST    	(SP)+
163252: MOV    	(SP)+, R0
163254: RETURN 	
;
; Подготовка и запуск операции; R0 = операция
.SCOM:
163256: MOV	#177106, R5
163262: MOV	#000006, R2
163266: CLR	(R5)
163270: BIT	#000001, (R5)
163274: BNE	163270
163276: SOB	R2, 163266
163300: BIS	@#004002, R0
163304: MOV	R0, -(R5)
163306: TST	-(R5)
163310: MOV	#000001, -(R5)
163314: RETURN	
;
; Чтение секторов; R0 = кол-во секторов, R3 = адрес буфера куда читать
.RDTR:
163316: MOV	R3, R1
163320: MOV	R0, -(SP)
163322: MOV	#000012, R4
163326: ADD	#000202, R4
163332: SOB	R0, 163326
163334: MOV	#000010, R0
163340: CALL	@#163256
163344: MOV	#177102, R2
163350: TSTB	(R5)
163352: BPL	163350
163354: MOVB	(R2), (R1)+
163356: SOB	R4, 163350
163360: MOV	(R5), R0
163362: CLR	(R5)			; Окончание операции чтения
163364: BIT	#000141, R0		; RELOAD или OP-FAILED или LOST-DATA ?
163370: BEQ	163374			; Нет => переходим

163374: ADD	#000012, R3
163400: MOV	#000100, R0
163404: CLR	R2			; Начинаем считать контрольную сумму
163406: MOVB	@#004007, R4		; Берём байт для ксорирования
163412: MOV	@#004012, R5		; Берём слово для ксорирования
163416: COM	R5			; инвертируем слово для ксорирования
163420: CLC	
163422: XOR	R4, (R3)
163424: XOR	R5, (R3)
163426: ROL	R4
163430: ROR	R5
163432: ROL	R0
163434: MOVB	(R3)+, R1
163436: ADD	R1, R2			; Добавляем к сумме
163440: MOVB	(R3)+, R1
163442: ADD	R1, R2			; Добавляем к сумме
163444: ASR	R0
163446: SOB	R0, 163422
163450: CMP	R2, (R3)+
163452: BEQ	163456
163454: HALT				; Выход в Пульт
163456: DEC    	(SP)
163460: BNE    	163400
163462: TST    	(SP)+
163464: RETURN 	

; ==== Эмуляция дисплея - см. TTIO.MAC ===============================================

; MODE3 - Переключение моды HALT-монитора.
163466: MOVB	#000003, @#170006	; Запрещение прерываний
163474: CALL	@(SP)+
163476: CLRB	@#170006		; Разрешение прерываний
163502: RETURN	
;
; SYSLIN - Вывод служебной строки.
163504: CALL	@#163466		; MODE3
163510: MOV	R0, -(SP)
163512: MOV	R1, -(SP)
163514: MOV	#177772, R0		; POSITN
163520: MOV	(R0), -(SP)		; сохранить позицию,
163522: MOV	-(R0), -(SP)		;  AR2,RGMOUT
163524: MOV	000012(SP), R1		;  параметр.
163530: CMP	(R0)+, (R1)+		; R0=@POSITN
163532: MOV	(R1), R1		; R1=@STRING
163534: MOVB	(R1)+, (R0)+		; POSITN+1
163536: CLRB	(R0)+			; POS+2
163540: ADD	#176000, -(R0)		; POS
163544: CLR	-(R0)			; AR2,RGMOUT=0
163546: BIS	#000010, -(R0)		; RGMIOT - вывод сл.строки.
163552: CMP	@#177772, #176060	; CMP POSITN,#BEG.SL+LENGHT
163560: BGE	163574			; выход за пределы.
163562: MOVB	(R1)+, R0		; Получаем следующий символ
163564: BEQ	163700			; конец строки.
163566: CALL	@#163726		; SYSOUT Вывод символа на экран
163572: BR	163552
163574: MOV	R1, -(SP)
163576: MOV	#162702, R5
163602: MOV	@#167776, R3
163606: CALL	@#162236
163612: MOV	(SP)+, R1
163614: MOV	(R4), R3
163616: INC	@#177772
163622: MOV	#000004, R2
163626: BIC	#102777, R3
163632: BEQ	163700
163634: ROL	R3
163636: COM	R3
163640: BIC	#007777, R3
163644: BEQ	163650
163650: MOVB	(R1)+, R0		; Получаем следующий символ
163652: CALL	@#163726		; SYSOUT Вывод символа на экран
163656: SOB	R2, 163650
163660: TST	R3
163662: BEQ	163700
163700: MOV	#177766, R0		; Адрес Режим дисплея
163704: BIC	#000010, (R0)+
163710: MOV	(SP)+, (R0)+
163712: MOV	(SP)+, (R0)+
163714: MOV	(SP)+, R1
163716: MOV	(SP)+, R0
163720: RETURN	
;
; Программа вывода символов на экран
; TT.OUT Вывод символа на экран с переключением моды; мл.байт R0 = символ
163722: CALL	@#163466		; MODE3
; SYSOUT - Системный вывод - вывод символа R0 на экран
163726: MOV	SP, @#177642
163732: MOV	#177642, SP
163736: BIS	#000001, @#177574	; Включаем экран в основную память
163744: CALL	@177774			; Вызов процедуры вывода символа
163750: BIC	#000001, @#177574	; Отключаем экран от основной памяти
163756: MOV	(SP), SP
163760: RETURN	
; SETCRS - Прямая адресация курсора.
163762: MOV    	#177772, R4
163766: SUB    	#000040, R5
163772: BPL    	163776
163774: CLR    	R5
163776: DECB   	@#177770
164002: BEQ    	164026
164004: CMP    	R5, #000027		; 23. = макс. номер строки.
164010: BHI    	164360
164012: MUL    	R5, #001200		; вычислить отн.адрес.
164016: BIC    	#177700, (R4)
164022: BIS    	R5, (R4)
164024: BR     	164360
164026: CMP    	R5, #000077		; макс. номер позиции.
164032: BHI    	164360
164034: BIC    	#000077, (R4)
164040: BR     	164022
; Стандартная п/п вывода символа, ставится по умолчанию в 177774 SYMGEN
; MODOUT - Вывод символов режиме переключения памяти.
164042: MOV	R0, -(SP)
164044: MOV	R1, -(SP)
164046: MOV	R2, -(SP)
164050: MOV	R3, -(SP)
164052: MOV	R4, -(SP)
164054: MOV	R5, -(SP)
164056: CALL	@#165206		; CURSOR: Убрать курсор если он виден
164062: MOV	000012(SP), R5
164066: BIC	#177400, R5
164072: MOV	#000100, R1
164076: MOV	#177770, R2		; Адрес SIZE
164102: TSTB	(R2)			; авторегистр ?
164104: BPL	164136
164106: CLRB   	(R2)
164110: CMP    	R5, #000131		; коды командных последова-
164114: BEQ    	164354			; тельностей VT-52
164116: CMP    	R5, #000113
164122: BHI    	164360
164124: SUB    	R1, R5
164126: BMI    	164360
164130: MOVB   	165310(R5), R4
164134: BR     	164340
164136: BNE	163762			; АР2>0 --> прям.адр.курсора.
164140: MOVB	@#177766, R4		; Режим дисплея VT52 или Немига ?
164144: BPL	164176			; Немига.
164146: CLR    	@#177762
164152: CLR    	@#177764
164156: ROLB   	R5
164160: CLC    	
164162: BPL    	164174			; не буква.
164164: BITB   	#000040, R4
164170: BEQ    	164174			; латинский регистр.
164172: SEC    				; русская.
164174: RORB   	R5
164176: CMP	R5, #000040
164202: BLO	164302			; не отображаемый символ.
VISI:
164204: ROLB	R5
164206: BPL	164212
164210: BIC	R1, R5
164212: BHIS	164216
164214: BIS	R1, R5
164216: ASR	R5
164220: ADD	#002000, R3		; абсол. адрес позиции.
164224: ASL	R3
164226: SUB	#000040, R5
164232: MUL	R5, #000012
164236: ADD	#166064, R5		; адрес матрицы в знакогенераторе.
164242: MOV	#000012, R4		; 10. кол-во линий.
164246: ASL	R1
LOOP:
164250: MOVB	(R5), R2		; линия матрицы символа.
164252: SWAB	R2
164254: CLRB	R2
164256: BISB	(R5)+, R2		; в обоих байтах: 3/3 яркости.
164260: BIC	@#177764, R2		; код яркости.
164264: MOV	@#177762, R0		; инверсия.
164270: XOR	R0, R2
164272: MOV	R2, (R3)
164274: ADD	R1, R3
164276: SOB	R4, 164250
164300: BR	164470			; STEP смещение курсора.
; Отработка управляющих кодов - символов с кодом меньше #040
164302: MOV	#165324, R2		; T.SYLN - таблица разрешенных кодов.
164306: BITB	#000010, R4		; R4 = RGMIOT
164312: BNE	164324			; " SYSLIN "
164314: CMP	(R2)+, (R2)+		; "VT-52"
164316: TSTB	R4
164320: BMI	164324
164322: CMP	(R2)+, (R2)+		; "NEMIGA"
164324: MOV	(R2)+, R0		; ст.слово.
164326: MOV	(R2), R1		; мл.слово.
164330: ASHC	R0, R5			; сдвинуть до нужного бита.
164332: BPL	164600			; .OUTT функция разрешена.
164334: MOVB	165250(R5), R4
164340: BIC	#177400, R4		; переход на отработку функции.
164344: ASL	R4
164346: MOV	#177770, R2
164352: ADD	R4, PC
; ..PC..			;** ключ прямой адрес.курсора.
164354: MOVB   	#2, (R2)
164360: BR     	164600			; .OUTT
; CL.SL:			;** очистка служ. строки.
164362: CLR    	R5
164364: MOV    	#002000, R3
164370: CLR    	(R5)+
164372: SOB    	R3, 164370
164374: BR     	164600
; VT52:				;** переход в режим VT-52
164376: BIC    	#000400, (R2)
164402: BIS    	#000200, -(R2)
164406: BR     	164600
; ..AR2::			;** авторегистр.
164410: BIT    	#000200, 177776(R2)
164416: BNE    	164432
; CLRRS:			; ВКЛ/ВЫКЛ звука.
164420: MOV    	#040000, R5
164424: XOR    	R5, @#177760
164430: BR     	164600
; NOCLR:	DECB	@R2	; -1 - ключ авторегистра.
164432: DECB   	(R2)
164434: BR     	164600
; RRGM:				;** сброс режимов вывода.
164436: CLR    	(R2)
164440: TST	-(R2)
164442: CLR	-(R2)		; M.BIC = 0
164444: CLR	-(R2)		; M.XOR = 0
164446: BR	164600
; SRGM:				;** установка режима вывода.
164450: COMB	177760(R5)
164454: BR	164600
; IC:				;** ВКЛ/ВЫКЛ курсора.
164456: MOV    	#000200, R5
; ROLLON:			;** ВКЛ/ВЫКЛ ролика.
164462: SWAB   	R5
164464: XOR    	R5, (R2)
164466: BR     	164600
; STEP:				;** шаг вправо.
164470: MOV	#177772, R2		; Текущая позиция курсора
164474: INC	(R2)			; Следующая позиция
164476: MOV	(R2), R3	; R3=POSITN
164500: MOV	R3, R4
164502: BIC	#177700, R4		; Позиция в пределах строки
164506: BNE	164600
; LF:				;** LINE FEED - перевод строки.
164516: ADD	#001200, R3
164522: CMP	R3, #034700	; конец строки ?
164526: BLO	164606
164600: BR	165116
; ???
164602: BIC	#000077, R3	; на первую позицию.
164606: MOV	R3, @#177772
164612: BR	165116
; HT:				;** горизонтальная табуляция.
164614: MOV	R3, R4
164616: BIC	#177700, R4
164622: CMP	R4, #000077	; табуляция невозможна.
164626: BHIS	165116
164630: ADD	#000010, R3
164634: BIC	#000007, R3
164640: BR	164606
; R.RUS				; ** русский регистр.
164642: BIS    	#000040, -(R2)
164646: BR     	165116
; R.LAT				; ** латинский регистр.
164650: BIC    	#000040, -(R2)
164654: BR     	165116
; NEMIGA			; ** переход в режим "Немига".
164656: BIC    	#177600, -(R2)
164662: BR     	165116
164664: ADD    	#000200, R3
164670: SUB    	#000100, R3
164674: BMI    	164664
164676: CMP    	R3, #034700
164702: BHIS   	164670
164704: BR     	164714
164706: SUB    	#001200, R3
164712: BMI    	165116
164714: MOV    	R3, @#177772
164720: BR     	165116
164722: ADD    	#001200, R3
164726: CMP    	R3, #034700
164732: BHIS   	165116
164734: BR     	164714
164736: INC    	R3
164740: MOV    	R3, R4
164742: BIC    	#177700, R4
164746: BEQ    	165116
164750: BR     	164714
164752: CLR    	R3
164754: BR     	164714
164756: SUB    	#001200, R3
164762: BPL    	164714
; Скроллинг экрана
164764: MOV    	#100000, R5		; Адрес куда копировать
164770: MOV    	#075400, R3		; Адрес откуда копировать
164774: MOV    	#034600, R2		; Сколько слов копировать
165000: MOV    	-(R3), -(R5)		; копируем слово
165002: SOB    	R2, 165000		; повторяем
; Очистка строки
165004: MOV    	#001200, R2		; Сколько слов очищать
165010: CLR    	(R3)+			; стираем слово
165012: SOB    	R2, 165010		; повторяем
165014: BR     	165116			; => к завершению обработки символа
; COD7::			;** звук.
165016: BITB   	#000100, @#177761	; Проверяем байт блокировки SOUND
165024: BNE    	165116			; => к завершению обработки символа
165026: CALL   	@#160126		; SOUND
165032: BR     	165116			; => к завершению обработки символа
165034: DW	165036			; адрес мелодии
165036: DB	001, 205, 017, 000	; .COD7 - мелодия
; DELL:				;** стирание строки от позиции курсора.
165042: CALL   	@#165140		; Очистка строки от текущей позиции до конца строки
165046: BR     	165116			; => к завершению обработки символа
; DELS:				;** стирание кадра от позиции курсора.
165050: CALL   	@#165140		; Очистка строки от текущей позиции до конца строки
165054: BIC    	#000077, R3
165060: MOV    	R3, R5
165062: ADD    	#002000, R5
165066: BMI    	165116			; => к завершению обработки символа
165070: BR     	165106
; ES:				;** очистка экрана.
165072: CLR	R5
165074: BR	165102			; => EES
; FF:				;** FORM FEED - очистка кадра.
165076: MOV	#002000, R5
165102: CLR	@#177772
165106: ASL	R5
165110: CLR	(R5)+
165112: TST	R5
165114: BPL	165110
; +???
; OUTT - Завершение обработки символа
165116: CALL	@#165206		; Восстановление курсора
165122: MOV	(SP)+, R5
165124: MOV	(SP)+, R4
165126: MOV	(SP)+, R3
165130: MOV	(SP)+, R2
165132: MOV	(SP)+, R1
165134: MOV	(SP)+, R0
165136: RETURN	
; Очистка строки от текущей позиции до конца строки
; DL:				; удаление части строки.
165140: MOV    	#000012, R2		; 10. итераций
165144: MOV    	R3, R5
165146: MOV    	#000100, R4		; 64. позиции в строке
165152: BIC    	#177700, R5
165156: SUB    	R5, R4
165160: BLE    	165176
165162: MOV    	R3, R5
165164: ADD    	#002000, R5		; Начало основной части экрана
165170: ASL    	R5
165172: CLR    	(R5)+			; стираем слово
165174: SOB    	R4, 165172		; повторяем
165176: ADD    	#000100, R3		; к следующей пиксельной строке
165202: SOB    	R2, 165144		; продолжаем цикл
165204: RETURN 	
;
; CURSOR - гашение/засветка курсора.
165206: MOV	@#177772, R3		; Место курсора от начала ГЗУ
165212: BMI	165246
165214: TSTB	@#177771		; Состояние курсора??
165220: BMI	165246
165222: TST	@#177756		; Счётчик мигания курсора
165226: BPL	165246			; не виден => не нужно убирать
165230: MOV    	R3, R4
165232: ADD    	@#177746, R4		; + адрес 25-й строки экрана
165236: BMI    	165246
165240: ROL    	R4
165242: BMI    	165246
165244: COM    	(R4)			; Инвертируем восемь пикселей - курсор
165246: RETURN	
; Таблицы смещений программ обработки управл. кодов.
; TABL - Таблица смещений переходов для обработки спецсимволов
165250: DB	261, 043, 036, 036, 036, 036, 031, 221	; 00..07
165260: DB	105, 120, 061, 233, 251, 113, 133, 136	; 10..17
165270: DB	000, 247, 155, 144, 146, 177, 163, 011	; 20..27
165300: DB	041, 171, 105, 016, 201, 061, 003, 236	; 30..37
; TAR2 - Таблица смещений переходов для обработки символов ESC + 100..113
165310: DB	141, 155, 163, 171, 105, 261, 022, 261	; 100..107
165320: DB	177, 201, 236, 233

; Таблицы разрешенных кодов.
T.SYLN:	.WORD	^B0011111011000011,^B0000000000000010
T.VT52:	.WORD	^B0000001111101111,^B0000000010010010	; 0-17,20-37
T.NEMG:	.WORD	^B1111111111111100,^B1111111111111111

; ==== Графические примитивы - см. GRAF.MAC ==========================================
;
; Рисование линии из точки с координатами (XOLD,YOLD)
; в точку с координатами (X2,Y2). После выполнения операции:
; XOLD=X2,YOLD=Y2.
;	DRAW	BRIGHT,X2,Y2 [,XOLD,YOLD]
; Точка входа QDRAW - DRAW для QUASIC
165340: MOV    	(SP), R5
; Точка входа FDRAW - DRAW для FORTRAN
165342: CALL   	@#166040
; Точка входа DRAW - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
; После выполнения операции XNEW=XOLD, YNEW=YOLD.
165346: CALL   	@#165376
165352: MOV    	@#000212, @#000216	; XNEW -> XOLD
165360: MOV    	@#000214, @#000220	; YNEW -> YOLD
165366: RETURN 	
;
; Рисование линии из точки (X2,Y2) в точку (X1,Y1)
;	LINE	BRIGHT [,X1 [,Y1 [,X2 [,Y2]]]]
; Точка входа QLINE - LINE для QAUSIC
165370: MOV    	(SP), R5
; Точка входа FLINE - LINE для FORTRAN
165372: CALL   	@#166040
; Точка входа LINE - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
165376: MOV    	#000212, R5		; Адрес XNEW
165402: MOV    	(R5)+, R0		; X NEW
165404: MOV    	(R5)+, R1		; Y NEW
165406: MOV    	(R5)+, R2		; X OLD
165410: MOV    	(R5)+, R3		; Y OLD
165412: CLR    	@#000204		; реверс: меньше или больше П/4.
165416: MOV    	#1, R4
165422: MOV    	R4, R5
165424: SUB    	R2, R0			; DELTA X= XN-XO
165426: BPL    	165434
165430: NEG    	R0			; модуль приращения DX
165432: NEG    	R5			; знак  DX +/-1
165434: SUB    	R3, R1			; DELTA Y=YN-YO
165436: BPL    	165444
165440: NEG    	R1			; модуль DY
165442: NEG    	R4			; SIGN DY +/-1
165444: CMP    	R0, R1			; IF DX<DY THEN
165446: BGE    	165476			;   реверс :
165450: MOV    	R0, -(SP)
165452: MOV    	R1, R0
165454: MOV    	(SP), R1		; DX <-> DY
165456: MOV    	R4, (SP)
165460: MOV    	R5, R4
165462: MOV    	(SP), R5		; SX <-> SY
165464: MOV    	R2, (SP)
165466: MOV    	R3, R2
165470: MOV    	(SP)+, R3		; XO <-> YO
165472: INC    	@#000204		; флаг реверса.
165476: TST    	R0			;  IF DX=0
165500: BEQ    	165544			;     THEN DY=0 - единственная точка.
165502: ASL    	R1			; 2DY
165504: MOV    	R0, -(SP)
165506: ASL    	(SP)			; 2DX
165510: MOV    	R1, -(SP)
165512: SUB    	R0, (SP)		; 2DY-2DX=D - флаг наклона.
165514: CALL   	@#165544		; вывод точки.
165520: TST    	(SP)
165522: BMI    	165532
165524: SUB    	000002(SP), (SP)	; D=D-2DX
165530: ADD    	R4, R3			; YO=YO+SY
165532: ADD    	R1, (SP)		; D=D+2DY
165534: ADD    	R5, R2			; XO=XO+SX
165536: SOB    	R0, 165514		;  счетчик=DX
165540: CMP    	(SP)+, (SP)+		; восстановить стек.
165542: RETURN 	
; OUT - вывод точки
165544: MOV    	R1, -(SP)
165546: MOV    	R2, -(SP)
165550: MOV    	R3, -(SP)
165552: TST    	@#000204		; реверс ?
165556: BEQ    	165564
165560: MOV    	R2, R3			; восстановить X,Y
165562: MOV    	(SP), R2
165564: CALL   	@#165616		; записать точку.
165570: MOV    	(SP)+, R3
165572: MOV    	(SP)+, R2
165574: MOV    	(SP)+, R1
165576: RETURN 	
;
; Нарисовать точку.
;	POINT	BRIGHT [,X [,Y]]
; Точка входа QPOINT - POINT для QUASIC
165600: MOV    	(SP), R5
; Точка входа FPOINT - POINT для FORTRAN
165602: CALL   	@#166040
; Точка входа POINT - нарисовать точку
165606: MOV    	@#000212, R2
165612: MOV    	@#000214, R3
165616: CALL   	@#163466		; MODE3
165622: CALL   	@#165750		; Находим точку на экране
165626: BLO    	165660
165630: TST    	(R1)+
165632: MOV    	@#000210, R2		; BRIGHT
165636: ASR    	R2
165640: BLO    	165650
165642: BIC    	R3, @#177570		; Пишем в экран
165646: BR     	165654
165650: BIS    	R3, @#177570		; Пишем в экран
165654: SWAB   	R3
165656: SOB    	R1, 165636
165660: RETURN 	
;
; Чтение яркости точки с координатами (X,Y)
;	RPOINT	BRIGHT,X,Y
; Точка входа QRPOIN - RPOINT для QUASIC
165662: MOV    	(SP), R5
; Точка входа FRPOIN - RPOINT для FORTRAN
165664: CALL   	@#166040
165670: BR     	165676
; Точка входа RPOINT - прочитать яркость точки
165672: MOV    	#000210, R4		; адрес кода яркости.
165676: MOV    	@#000212, R2		; XNEW
165702: MOV    	@#000214, R3		; YNEW
165706: CLR    	(R4)
165710: CALL   	@#163466		; MODE3
165714: CALL   	@#165750		; Находим точку на экране
165720: BLO    	165744
165722: MOV    	#000002, R1
165726: SWAB   	R3			; чтение яркости.
165730: BIT    	R3, @#177570
165734: BEQ    	165740
165736: ADD    	R1, (R4)
165740: SOB    	R1, 165726
165742: RETURN 	
165744: DEC    	(R4)			; яркость -1  -- за экраном.
165746: RETURN 	
; COORD - Нахождение точки на экране; устанавливает адрес, возвращает маску в R3
165750: MOV    	R2, R1
165752: CMP    	#000777, R2
165756: BLO    	166036
165760: ASH    	R2, #177775
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 	
; FORT - Подготовка перед вызовом для FORTRAN
166040: MOV     (R5)+, R0		; число параметров.
166042: MOV     (R5), R4		; адрес яркости.
166044: BIC     #177770, R0
166050: BEQ     166062
166052: MOV     #000210, R3		; внутренние значения.
166056: MOV     @(R5)+, (R3)+		; область заполнения.
166060: SOB     R0, 166056
166062: RETURN  
;
; ==== Стандартный знакогенератор - см. SYMG.MAC ====
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   - регистр таймера контроллера дисковода

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

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

177570: DW		; VDATA    - регистр данных косвенного доступа
177572: DW		; VADDR    - регистр адреса косвенного доступа
177574: DW		; Регистр управления; бит 0 - маппинг видеопамяти на нижнюю память

; ==== Блок переменных ====
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 при останове
177744: DW		; Нижняя граница памяти доступной для команд пульта
177746: DW		; Значение #003100 - адрес 25-й строки экрана
177750: DW		; Адрес начала мелодии
177752:	DW		; Адрес продолжения мелодии
177754: DW		; Адрес подпрограммы SOUND
177756: DB		; Счётчик мигания курсора
177757: DB		; Состояние курсора: 000 - не виден, 377 - виден
177760: DB		; Счётчик мелодии
177761: DB		; Байт блокировки вызова SOUND
			;   бит7 = мелодия играет
			;   бит6 = звук выключен
177762: DW		; FRG    Маска фона для вывода символа (M.XOR)
177764: DW		; COL    Маска гашения символа перед выводом (M.BIC)
177766: DB		; Режим дисплея
			;   bit0 - запрос от клавиатуры, прерывание по вектору 000064
			;   bit3 - работа со служебной строкой
			;   bit4 - работа с цветом в режиме VT52
			;   bit5 - русский регистр вывода
			;   bit6 - русский регистр ввода
			;   bit7 - режим эмуляции VT52
177767: DB		; Буферная ячейка клавиатуры
177770: DW		; SIZE   Размер экрана в байтах, начиная от начала ГЗУ
177772: DW		; CUR    Место курсора от начала ГЗУ
177774: DW		; SYGEN  Адрес подпрограммы вывода символа, по умолчанию 163674
177776: DW		; Значение #056364