Немига 406 ROM disasm

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

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

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

000204: DW				; REV    Рабочий регистр
000206: DW				; VFORM
000210: DW				; BRIGHT
000212: DW				; XNEW
000214: DW				; YNEW
000216: DW				; XOLD
000220: DW				; YOLD

; ==== Начало ПЗУ ====
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
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

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

; Обработка канального сигнала СБРОС
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	@#161074		; Завершаем обработку прерывания HALT
;
; Обработка нажатия СТОП?? кнопки ОСТ??
160202: MOV	(SP)+, R0		; Восстанавливаем R0
160204: JMP	@#161142		; Переходим к сохранению регистров и пульту
;
; Обработчик прерывания по сигналу/команде HALT
160210: CMP	#056364, @#177776	; Проверка, настроена ли память режима HALT
160216: BEQ	160224			; Да, настроена
160220: JMP	@#161720		; Нет => выход на процедуру холодного старта
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	@#163726		; SYSOUT Вывод символа R0 на экран
160302: BIT	#020000, @#170006	; Сигнал Н2? -- обращение к 177562
160310: BEQ	160334			; Нет
160312: MOVB   	@#177767, R0		; Провека буферной ячейки??
160316: BEQ    	160326			; Буфер пуст
160320: CLRB   	@#177767		; Очищаем буфер
160324: BR     	160526
160326: BIC     #177677, @#177560	; Чистим ~0100 в регистре статуса клавиатуры
160334: MOV	@#170006, R0
160340: BIT	#002000, R0		; Пришёл байт с клавиатуры?
160344: BEQ	160606			; Нет
160346: BIC	#177400, R0		; Оставляем байт поступивший с клавиатуры
160352: BEQ	160202			; Символ 00 -- СТОП?
160354: TSTB	@#177560
160360: BMI	160606
; Звук нажатия клавиши
160362: MOV	R1, -(SP)
160364: MOV	R2, -(SP)
160366: TSTB	@#177761		; Флаг блокировки вызова SOUND
160372: BNE	160410			; <> 0 => не вызывать повторно
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)
160422: BPL	160522
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
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
160516: MOV    	#000033, R0
;
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
160560: TSTB   	000002(SP)
160564: BMI    	161074
160566: BICB   	#000001, @#177766
160574: MOV    	@#000062, -(SP)
160600: MOV    	@#000060, -(SP)
160604: BR     	161074
;
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
; Окончание мелодии
160712: BITB   	#000100, (R4)+
160716: BNE    	160734
160720: MOV    	(SP)+, R4
; Переход на прерывание по вектору 110
160722: MOV    	@#000112, -(SP)
160726: MOV    	@#000110, -(SP)
160732: BR     	161074			; к разрешению прерываний и RTI
; Очистка байта после мелодии
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
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)
161042: BMI	161074			; ?? => Завершаем обработку прерывания HALT
161044: BITB   	#000001, @#177766
161052: BNE    	160566
161054: BIT    	#000100, @#177564	; Разрешено прерывание в состоянии терминала?
161062: BEQ    	161074			; нет => переходим
161064: MOV    	@#000066, -(SP)
161070: MOV    	@#000064, -(SP)
; Завершение обработки прерывания HALT
161074: CLRB	@#170006		; Разрешение прерываний
161100: RTI
; Таблица байт
161102: DB
	
; Обработка прерывания?? Сохранение регистров и переход к пульту
161142: MOV	(SP)+, @#177736		; Сохраняем PC
161146: MOV	(SP)+, @#177740		; Сохраняем PSW
161152: MOV	SP, @#177734		; Сохраняем SP
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)
161206: MOV	@#177766, -(SP)
161212: CLR	@#177766
161216: MOV	#000340, @#000006	; PSW для прерывания
161224: MOV	#161444, @#000004	; Адрес прерывания??
161232: MOV	#000060, @#170010
161240: BR	161444			; Переход к пультовому терминалу
;
; ==== Программа пультового терминала ================================================
;
; Просмотр ячеек памяти -- переход к следующему слову
161242: INC    	R2
161244: INC    	R2
; Команда '/' - просмотр ячеек памяти
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' - продолжение выполнения программы
161356: MOV    	(SP)+, @#177766
161362: TST    	R1
161364: BEQ    	161400
161366: CLR    	@#177740
161372: MOV    	R5, @#177736
161376: RESET  	
; Восстановление всех регистров, возврат из прерывания
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   
;
; Вывод символа и переход к пульту
161440: CALL   	@#163722		; TT.OUT Вывод символа
; Вывод приглашения пульта и ожидание команды
161444: MOV	#162704, R5		; Строка "Пульт>"
161450: MOV	#177712, SP
161454: MOV	#000340, @#000006	; PSW для прерывания
161462: MOV	#161546, @#000004	; Адрес прерывания??
161470: CALL	@#162274
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
; Вывод знака вопроса (ошибка выполнения команды) и возврат в пультовый режим
161546: MOV	#162703, R5
161552: BR	161450
;
; Команда 'S' -- вывод на экран регистров процессора
161552: BR     	161450
161554: MOV    	#000011, R2
161560: MOV    	#161606, R5
161564: CALL   	@#162274
161570: MOV    	#177720, R4
161574: MOV    	(R4)+, R3
161576: CALL   	@#162236
161602: SOB    	R2, 161574
161604: BR     	161444
161606: DB	...

;NOTE: Команда 'X' -- загрузка с устройства DX -- удалена
;
; Команда 'D' -- загрузка с диска
161676: CMP	R5, #000007		; Номер устройства больше 7?
161702: BHI	161546			; Да => показать признак ошибки, возврат в пульт
161704: CALL	@#162726		; Загрузка данных с дисковода
161710: MOV    	#000200, @#177766
161716: CLR    	PC
161720: MOV    	#160000, @#177744
;
; ==== Программа холодного старта ====================================================
;
; Холодный старт при включении питания
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	; Адрес прерывания
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	; Адрес прерывания??
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		; продолжаем цикл ожидания
162226: MOV	#002060, (R4)
162232: JMP	@#161546
;
; ==== Программы вывода на экран чисел и строк =======================================
;
; Подпрограмма DUMP Вывод слова как 8-ричного числа; R3 = число
162236: MOV	#000006, R1		; Шесть разрядов
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 = адрес строки
162274: MOVB	(R5)+, R0		; Очередной символ
162276: BNE	162302			; Не ноль?
162300: RETURN				; Конец строки, выходим
162302: CALL	@#163722		; TT.OUT Вывод символа
162306: BR	162274			; Продолжаем вывод строки
;
; Ввод команды; команда это символ либо 8-ричное число (параметр) и символ
162310: CLR	R1
162312: CLR	R5
162314: TSTB	@#177560
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
162406: BNE	162300
162410: BIC    	#177770, R0
162414: ASH    	R5, #000003
162420: BIS    	R0, R5
162422: INC    	R1
162424: BR     	162314
;
; Подпрограмма SOUND
162426: MOV	R4, -(SP)		; Сохраняем R4
162430: BICB	#000200, @#177761
162436: CLR	@#170024		; Сброс таймер 2 (длительности)
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	
; Значения задержки первого таймера для нот
162564: DW	000000, 002253, 002150, 002050, 001755, 001664, 001577, 001515
162604: DW	001435, 001361, 001306, 001237, 001171, 000000, 000000, 000000

;
; ==== Подпрограммы работы с дисководом MD ===========================================
;
; Чтение с дисковода для загрузки; R5 = номер устройства
162726: CALL	@#163466		; MODE3
162732: MOV	#000001, R4
162736: MOV	R5, -(SP)
162740: ASR	R5
162742: BHIS	162750
162750: MOV	R5, @#004002
162754: MOV	#000400, -(SP)
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-й дорожке, читаем первый сектор
163046: MOVB	R4, R0
163050: MOV	#004004, R3
163054: CALL	@#163316
163060: CLR    	@#004000
163064: MOV    	@#004000, R0
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   	
;
163134: MOV    	(SP), R3
163136: SUB    	R0, R3
163140: SUB    	#000120, R4
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 = операция
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 = адрес куда читать
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 	
;
; Подпрограмма MODE3: Запрет прерываний до возврата из подпрограммы
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
163520: MOV	(R0), -(SP)
163522: MOV	-(R0), -(SP)
163524: MOV	000012(SP), R1
163530: CMP	(R0)+, (R1)+
163532: MOV	(R1), R1
163534: MOVB	(R1)+, (R0)+
163536: CLRB	(R0)+
163540: ADD	#176000, -(R0)
163544: CLR	-(R0)
163546: BIS	#000010, -(R0)
163552: CMP	@#177772, #176060
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 Вход -- вывод символа
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	
;
163762: MOV    	#177772, R4
163766: SUB    	#000040, R5
163772: BPL    	163776
163774: CLR    	R5
163776: DECB   	@#177770
164002: BEQ    	164026
164004: CMP    	R5, #000027
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
;
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		; Убрать курсор если он виден
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
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
164140: MOVB	@#177766, R4
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
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
164246: ASL	R1
164250: MOVB	(R5), R2
164252: SWAB	R2
164254: CLRB	R2
164256: BISB	(R5)+, R2
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
; Обработка символов с кодом меньше #040
164302: MOV	#165324, R2
164306: BITB	#000010, R4
164312: BNE	164324
164314: CMP	(R2)+, (R2)+
164316: TSTB	R4
164320: BMI	164324
164322: CMP	(R2)+, (R2)+
164324: MOV	(R2)+, R0
164326: MOV	(R2), R1
164330: ASHC	R0, R5
164332: BPL	164600
164334: MOVB	165250(R5), R4
164340: BIC	#177400, R4		; смещение не больше 377
164344: ASL	R4
164346: MOV	#177770, R2
164352: ADD	R4, PC
; +000
164354: MOVB   	#000002, (R2)
164360: BR     	164600
164362: CLR    	R5
164364: MOV    	#002000, R3
164370: CLR    	(R5)+
164372: SOB    	R3, 164370
164374: BR     	164600
164376: BIC    	#000400, (R2)
164402: BIS    	#000200, -(R2)
164406: BR     	164600
;
164410: BIT    	#000200, 177776(R2)
164416: BNE    	164432
164420: MOV    	#040000, R5
164424: XOR    	R5, @#177760
164430: BR     	164600
164432: DECB   	(R2)
164434: BR     	164600
; +0??
164436: CLR    	(R2)
164440: TST	-(R2)
164442: CLR	-(R2)
164444: CLR	-(R2)
164446: BR	164600
; +0??
164450: COMB	177760(R5)
164454: BR	164600
; +0??
164456: MOV    	#000200, R5
164462: SWAB   	R5
164464: XOR    	R5, (R2)
164466: BR     	164600
; Переход к следующей позиции вывода
164470: MOV	#177772, R2		; Текущая позиция курсора
164474: INC	(R2)			; Следующая позиция
164476: MOV	(R2), R3
164500: MOV	R3, R4
164502: BIC	#177700, R4		; Позиция в пределах строки
164506: BNE	164600
; +0??
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
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
164642: BIS    	#000040, -(R2)
164646: BR     	165116
164650: BIC    	#000040, -(R2)
164654: BR     	165116
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
; ?? -- символ 007 -- BELL
165016: BITB   	#000100, @#177761	; Проверяем байт блокировки SOUND
165024: BNE    	165116
165026: CALL   	@#160126		; SOUND
165032: BR     	165116			; к завершению обработки символа
165034: DW	165036			; адрес мелодии
165036: DB	001, 205, 017, 000	; мелодия
; +???
165042: CALL   	@#165140
165046: BR     	165116
; +???
165050: CALL   	@#165140
165054: BIC    	#000077, R3
165060: MOV    	R3, R5
165062: ADD    	#002000, R5
165066: BMI    	165116
165070: BR     	165106
; +???
165072: CLR	R5
165074: BR	165102
; +???
165076: MOV	#002000, R5
165102: CLR	@#177772
165106: ASL	R5
165110: CLR	(R5)+
165112: TST	R5
165114: BPL	165110
; +???
; Завершение обработки символа
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	
; Очистка строки от текущей позиции до конца строки
165140: MOV    	#000012, R2
165144: MOV    	R3, R5
165146: MOV    	#000100, R4
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 	
;
; Подпрограмма стирания/восстановления курсора
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	
; Таблица смещений переходов для обработки спецсимволов
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
; Таблица смещений переходов для обработки символов ESC + 100..113
165310: DB	141, 155, 163, 171, 105, 261, 022, 261	; 100..107
165320: DB	177, 201, 236, 233

; Точка входа 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
165360: MOV    	@#000214, @#000220
165366: RETURN 	
; Точка входа QLINE -- LINE для QAUSIC
165370: MOV    	(SP), R5
; Точка входа FLINE -- LINE для FORTRAN
165372: CALL   	@#166040
; Точка входа LINE -- нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW)
165376: MOV    	#000212, R5
165402: MOV    	(R5)+, R0
165404: MOV    	(R5)+, R1
165406: MOV    	(R5)+, R2
165410: MOV    	(R5)+, R3
165412: CLR    	@#000204
165416: MOV    	#000001, R4
165422: MOV    	R4, R5
165424: SUB    	R2, R0
165426: BPL    	165434
165430: NEG    	R0
165432: NEG    	R5
165434: SUB    	R3, R1
165436: BPL    	165444
165440: NEG    	R1
165442: NEG    	R4
165444: CMP    	R0, R1
165446: BGE    	165476
165450: MOV    	R0, -(SP)
165452: MOV    	R1, R0
165454: MOV    	(SP), R1
165456: MOV    	R4, (SP)
165460: MOV    	R5, R4
165462: MOV    	(SP), R5
165464: MOV    	R2, (SP)
165466: MOV    	R3, R2
165470: MOV    	(SP)+, R3
165472: INC    	@#000204
165476: TST    	R0
165500: BEQ    	165544
165502: ASL    	R1
165504: MOV    	R0, -(SP)
165506: ASL    	(SP)
165510: MOV    	R1, -(SP)
165512: SUB    	R0, (SP)
165514: CALL   	@#165544
165520: TST    	(SP)
165522: BMI    	165532
165524: SUB    	000002(SP), (SP)
165530: ADD    	R4, R3
165532: ADD    	R1, (SP)
165534: ADD    	R5, R2
165536: SOB    	R0, 165514
165540: CMP    	(SP)+, (SP)+
165542: RETURN 	
165544: MOV    	R1, -(SP)
165546: MOV    	R2, -(SP)
165550: MOV    	R3, -(SP)
165552: TST    	@#000204
165556: BEQ    	165564
165560: MOV    	R2, R3
165562: MOV    	(SP), R2
165564: CALL   	@#165616
165570: MOV    	(SP)+, R3
165572: MOV    	(SP)+, R2
165574: MOV    	(SP)+, R1
165576: RETURN 	
;
; Точка входа 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 	
;
; Точка входа QRPOIN -- RPOINT для QUASIC
165662: MOV    	(SP), R5
; Точка входа FRPOIN -- RPOINT для FORTRAN
165664: CALL   	@#166040
165670: BR     	165676
; Точка входа RPOINT -- прочитать яркость точки
165672: MOV    	#000210, R4		; Адрес BRIGHT
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)
165746: RETURN 	
; Нахождение точки на экране; устанавливает адрес, возвращает маску в 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 	
; Подготовка перед вызовом для 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			; Знакогенератор, 8 байт/символ

; ==== Блок переменных ====
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
177750: DW			; Адрес начала мелодии
177752:	DW			; Адрес продолжения мелодии
177754: DW			; Адрес подпрограммы SOUND
177756: DB			; Счётчик мигания курсора
177760: DB			; Счётчик мелодии
177761: DB			; Байт блокировки вызова SOUND
177762: DW			; FRG    Маска фона для вывода символа
177764: DW			; COL    Маска гашения символа перед выводом
177766: DW			; Какие-то важные флаги??
177770: DW			; SIZE   Размер экрана в байтах, начиная от начала ГЗУ
177772: DW			; CUR    Место курсора от начала ГЗУ
177774: DW			; Адрес подпрограммы вывода символа, по умолчанию 163674
177776: DW			; Значение #056364