Немига 406 ROM disasm
Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0. |
Источник: https://github.com/nzeemin/nemigabtl/blob/master/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 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 165676: MOV @#000212, R2 165702: MOV @#000214, R3 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 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 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