Немига 303 ROM disasm
Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0. |
Источник: https://github.com/nzeemin/nemigabtl/blob/master/docs/nemiga-303.lst
; Дизассемблированное ПЗУ компьютера НЕМИГА ПК 588 версия 3.03 ; 000004: DW ; Адрес прерывания 000006: DW ; PSW прерывания 000060: DW ; Прерывание клавиатура 000062: DW ; PSW прерывания 000064: DW ; Прерывание дисплей 000066: DW ; PSW прерывания 000100: DW 000110; DW ; Прерывание "мелодия закончилась кодом 040" 000112: DW ; PSW прерывания 000204: DW ; REV - рабочий регистр 000206: DW ; VFORM - регистр вертикального формата 000210: DW ; BRIGHT - регистр яркости (0..3) 000212: DW ; XNEW - регистр новой X-координаты 000214: DW ; YNEW - регистр новой Y-координаты 000216: DW ; XOLD - регистр старой X-координаты 000220: DW ; YOLD - регистр старой Y-координаты ; ==== Начало ПЗУ ==== 160000: DW 177570 ; ?? 160002: DW 160210, 000341 ; Вектор прерывания сигнала/команды HALT 160006: DW 162010, 000340 ; Вектор прерывания начального пуска 160012: DW 161126, 000340 ; Вектор прерывания?? 160016: JMP @#163512 ; MODE3 - Вызов с запретом системных прерываний 160022: JMP @#163532 ; SYSLIN - Вывод в служебную строку 160026: JMP @#163734 ; TT.OUT - Системный вывод через MODE 160032: JMP @#163740 ; SYSOUT - Системный вывод 160036: JMP @#162342 ; PRINT - Вывод текста 160042: JMP @#165344 ; DRAW - Нарисовать линию, сохранив XOLD,YOLD 160046: JMP @#165336 ; QDRAW то же для QUASIC 160052: JMP @#165340 ; FDRAW то же для FORTRAN 160056: JMP @#165374 ; LINE - Нарисовать линию 160062: JMP @#165366 ; QLINE то же для QUASIC 160066: JMP @#165370 ; FLINE то же для FORTRAN 160072: JMP @#165604 ; POINT - Нарисовать точку 160076: JMP @#165576 ; QPOINT то же для QUASIC 160102: JMP @#165600 ; FPOINT то же для FORTRAN 160106: JMP @#165670 ; RPOINT - Читать яркость точки 160112: JMP @#165660 ; QRPOIN то же для QUASIC 160116: JMP @#165662 ; FRPOIN то же для FORTRAN 160122: JMP @#162304 ; DUMP - напечатать восьмеричное число R3 160126: JMP @177754 ; SOUND ; ==== Обработчики прерываний ======================================================== ; Обработка канального сигнала СБРОС 160142: MOV #000357, @#000206 ; 239. -> VFORM 160150: CLR @#177560 ; Сброс состояния клавиатуры 160154: MOV #000200, @#177564 ; Устанавливаем состояние терминала 160162: CLR @#177770 160166: BIC #177541, @#177766 ; Оставляем только флаги #136 160174: MOV (SP)+, R0 160176: JMP @#161060 ; Завершаем обработку прерывания HALT ; ; Обработка нажатия СТОП?? кнопки ОСТ?? 160202: MOV (SP)+, R0 ; Восстанавливаем R0 160204: JMP @#161126 ; Переходим к сохранению регистров и пульту ; ; Обработчик прерывания по сигналу/команде HALT 160210: CMP #056311, @#177776 ; Проверка, настроена ли память режима HALT 160216: BEQ 160224 ; Да, настроена 160220: JMP @#162010 ; Нет => выход на процедуру холодного старта 160224: MOV R0, -(SP) ; Сохраняем R0 чтобы не испортить 160226: BIS #000200, @#177564 ; Устанавливаем состояние терминала 160234: BIT #176000, @#170006 ; Проверка регистра фиксации HALT 160242: BMI 160142 ; Канальный сигнал СБРОС? => переходим 160244: BEQ 160202 ; 6 ст битов пусты - кнопка ОСТ?? => переходим 160246: BIT #004000, @#170006 ; Сигнал Н4? - адаптер локальной сети 160254: BEQ 160262 ; Нет 160256: CALL @000104 ; ?? 160262: BIT #040000, @#170006 ; Сигнал Н1? - обращение к 177566 160270: BEQ 160302 ; Нет 160272: MOV @#177566, R0 ; Регистр данных терминала 160276: CALL @#163740 ; SYSOUT Вывод символа R0 на экран 160302: BIT #020000, @#170006 ; Сигнал Н2? - обращение к 177562 160310: BEQ 160334 ; Нет 160312: MOVB @#177767, R0 ; Провека буферной ячейки клавиатуры 160316: BEQ 160326 ; буфер пуст => переходим 160320: CLRB @#177767 ; Очищаем буфер 160324: BR 160520 160326: BIC #177677, @#177560 ; Чистим ~0100 в рег.статуса клавиатуры - есть клавиша 160334: MOV @#170006, R0 160340: BIT #002000, R0 ; Пришёл байт с клавиатуры? 160344: BEQ 160600 ; Нет 160346: BIC #177400, R0 ; Оставляем байт поступивший с клавиатуры 160352: BEQ 160202 ; Символ 00 - СТОП? ; Звук нажатия клавиши 160354: MOV R1, -(SP) 160356: MOV R2, -(SP) 160360: TSTB @#177761 ; Флаг блокировки вызова SOUND 160364: BNE 160402 ; <> 0 => не вызывать повторно 160366: CALL @#160126 ; SOUND 160372: BR 160402 160374: DW 160376 ; Адрес мелодии нажатия клавиши 160376: DB 011, 214, 001, 000 ; Мелодия - звук длиной 1/50 сек 160402: MOV #177766, R1 160406: MOV #000100, R2 160412: TSTB (R1) 160414: BPL 160514 160416: BITB #000300, R0 160422: BEQ 160472 160424: BPL 160454 160426: BIT R2, R0 160430: BEQ 160514 160432: BIC #177600, R0 160436: BITB R2, (R1)+ 160440: BNE 160514 160442: MOVB R0, (R1) 160444: MOV #000016, R0 160450: BISB R2, -(R1) 160452: BR 160514 160454: BITB R2, (R1)+ 160456: BEQ 160514 160460: MOVB R0, (R1) 160462: MOV #000017, R0 160466: BICB R2, -(R1) 160470: BR 160514 160472: CMPB R0, #000040 160476: BHIS 160514 160500: MOVB 161066(R0), @#177767 ; Нажатая клавиша -> в буферную ячейку 160506: BEQ 160514 160510: MOV #000033, R0 ; 160514: MOV (SP)+, R2 160516: MOV (SP)+, R1 160520: MOV R0, @#177562 ; Заносим символ в рег.данных клавиатуры 160524: MOV (SP)+, R0 160526: BIS #000200, @#177560 ; Состояние клавиатуры - сброс бита готовности 160534: BIT #000100, @#177560 ; Состояние клавиатуры - разрешено прерывание? 160542: BEQ 161060 ; нет => Завершаем обработку прерывания HALT 160544: BISB #000001, @#177766 160552: TSTB 000002(SP) 160556: BMI 161060 160560: BICB #000001, @#177766 160566: MOV @#000062, -(SP) ; Кладём в стек вызов 160572: MOV @#000060, -(SP) ; прерывания по вектору 60 160576: BR 161060 ; 160600: MOV (SP)+, R0 ; Восстанавливаем R0 160602: BIT #010000, @#170006 ; Сигнал Н3? 160610: BEQ 161060 ; нет => Завершаем обработку прерывания HALT ; Обработка сигнала Н3 - кадровый синхроимпульс, 50 Гц 160612: MOV R4, -(SP) ; Сохраняем R4 160614: TSTB @#177761 ; Флаг блокировки SOUND 160620: BPL 160746 ; bit7=0 - блокировано => переходим 160622: MOV @#177752, R4 ; Берём адрес продолжения мелодии 160626: INCB @#177760 ; Увеличиваем счётчик длительности ноты 160632: CMPB @#177760, 177777(R4) ; Сравниваем с длительностью ноты 160640: BLO 160746 ; пока не кончилась => переходим 160642: TSTB (R4) ; 200 ? 160644: BMI 160742 ; да => переходим 160646: BITB #000037, (R4) ; Есть ещё нота мелодии? 160652: BNE 160736 ; да => переходим 160654: BICB #000200, @#177761 ; Снимаем флаг блокировки SOUND ; Обработка флагов завершения мелодии 160662: BITB #000040, (R4) ; 040 и 140 ? 160666: BNE 160712 ; да => переходим 160670: TSTB (R4) ; 000 ? (никаких действий по окончании мелодии) 160672: BEQ 160746 ; да => переходим 160674: MOV @#177750, @#160710 ; Копируем адрес начала мелодии?? 160702: CALL @#160126 ; SOUND 160706: BR 160746 ; переходим к работе с курсором 160710: DW 000000 ; Окончание мелодии байтом 040 либо 140 160712: BITB #000100, (R4)+ ; байт 140? 160716: BNE 160732 ; да => переход 160720: MOV (SP)+, R4 160722: CLRB @#170006 ; Разрешаем системные прерывания 160726: MOV @#000110, PC ; Переход на прерывание по вектору 110 ; Окончание мелодии байтом 140 160732: CLRB (R4) ; Очистка байта после конца мелодии 160734: BR 160746 ; переходим к работе с курсором ; 160736: MOVB (R4)+, @#170030 ; Октава и громкость 160742: CALL @#162560 ; Обработка продолжения мелодии ; Мигание курсора 160746: DECB @#177756 ; Уменьшаем счётчик мигания 160752: BPL 161020 ; значение >= 0 ? => переходим 160754: MOVB #000007, @#177756 ; Новое значение счётчика 160762: COMB @#177757 ; Инвертировать состояние курсора при мигании 160766: MOV @#177772, R4 ; Смещение курсора 160772: BMI 161020 160774: TSTB @#177771 ; Состояние курсора?? 161000: BMI 161020 161002: ADD #143105, R4 ; + косвенный адрес, начало 25-й строки экрана 161006: BPL 161020 ; Если за экраном => переходим 161010: MOV R4, @#177572 ; Устанавливаем косвенный адрес 161014: COM @#177570 ; Инвертирование восьми пикселей курсора 161020: MOV (SP)+, R4 ; Восстанавливаем R4 161022: TSTB 000002(SP) 161026: BMI 161060 ; ?? => Завершаем обработку прерывания HALT 161030: BITB #000001, @#177766 161036: BNE 160560 161040: BIT #000100, @#177564 ; Разрешено прерывание в рег.состояния терминала? 161046: BEQ 161060 ; нет => переходим 161050: MOV @#000066, -(SP) ; Кладём в стек вызов 161054: MOV @#000064, -(SP) ; прерывания по вектору 64 ; Завершение обработки прерывания HALT 161060: CLRB @#170006 ; Разрешаем системные прерывания 161064: RTI ; Таблица байт 161066: ; Обработка прерывания?? Сохранение регистров и переход к пульту 161126: MOV (SP)+, @#177736 ; Сохраняем PC 161132: MOV (SP)+, @#177740 ; Сохраняем PSW 161136: MOV SP, @#177734 ; Сохраняем SP 161142: MOV #177734, SP ; Сохраняем остальные регистры 161146: MOV R5, -(SP) ; -> 177732 161150: MOV R4, -(SP) ; -> 177730 161152: MOV R3, -(SP) ; -> 177726 161154: MOV R2, -(SP) ; -> 177724 161156: MOV R1, -(SP) ; -> 177722 161160: MOV R0, -(SP) ; -> 177720 - начало блока регистров 161162: MOV @#000004, -(SP) 161166: MOV @#000006, -(SP) 161172: MOV @#177766, -(SP) 161176: CLR @#177766 161202: MOV #000340, @#000006 ; PSW для прерывания 161210: MOV #161406, @#000004 ; Адрес прерывания?? 161216: MOV #000060, @#170010 161224: BR 161406 ; Переход к пультовому терминалу ; ; ==== Программа пультового терминала ================================================ ; ; Просмотр ячеек памяти - переход к следующему слову 161226: INC R2 161230: INC R2 ; Команда '/' - просмотр ячеек памяти 161232: MOV #162764, R5 ; Строка 161236: CALL @#162342 ; Вывод строки, адрес в R5 161242: MOV R2, R3 ; Печатаем адрес 161244: CALL @#162304 ; Вывод R3 как 8-ричного числа 161250: MOV (R2), R3 ; Печатаем значение 161252: CALL @#162304 ; Вывод R3 как 8-ричного числа 161256: CALL @#162356 ; Получаем команду с клавиатуры 161262: TST R1 161264: BEQ 161270 161266: MOV R5, (R2) ; Заносим новое значение 161270: CMPB #000012, R0 ; Нажали ПС? 161274: BEQ 161226 ; Да, переходим к следующему слову памяти 161276: CMPB #000015, R0 ; Нажали ВВОД? 161302: BEQ 161406 ; Да, возвращамся в пульт 161304: CMPB #000136, R0 ; Нажали '^' ? 161310: BNE 161516 ; Нет - выводим признак ошибки и в пульт 161312: DEC R2 ; Переходим к предыдущему слову памяти 161314: DEC R2 161316: BR 161232 ; ; Команда 'G' - продолжение выполнения программы 161320: MOV (SP)+, @#177766 161324: TST R1 ; Параметр задан? 161326: BEQ 161342 ; Нет => восстановление регистров и возврат 161330: CLR @#177740 161334: MOV R5, @#177736 ; Адрес запуска 161340: RESET ; Восстановление всех регистров, возврат из прерывания 161342: MOV (SP)+, @#000006 161346: MOV (SP)+, @#000004 161352: MOV (SP)+, R0 161354: MOV (SP)+, R1 161356: MOV (SP)+, R2 161360: MOV (SP)+, R3 161362: MOV (SP)+, R4 161364: MOV (SP)+, R5 161366: MOV (SP), SP 161370: MOV @#177740, -(SP) ; PSW 161374: MOV @#177736, -(SP) ; PC 161400: RTI ; ; Вывод символа и переход к пульту 161402: CALL @#163734 ; TT.OUT Вывод символа ; Вывод приглашения пульта и ожидание команды 161406: MOV #162752, R5 ; Строка "Пульт>" 161412: MOV #177712, SP 161416: MOV #000340, @#000006 ; PSW для прерывания 161424: MOV #161516, @#000004 ; Адрес прерывания?? 161432: CALL @#162342 ; PRINT Вывод строки, адрес в R5 161436: CALL @#162356 ; Получаем команду с клавиатуры 161442: MOV R5, R2 161444: CMPB #000057, R0 ; Символ '/' - просмотр ячеек памяти 161450: BEQ 161232 161452: CMPB #000123, R0 ; Символ 'S' - вывод регистров ЦП 161456: BEQ 161524 161460: CMPB #000107, R0 ; Символ 'G' - выполнение программы 161464: BEQ 161320 161466: CMPB #000104, R0 ; Символ 'D' - загрузка с диска MD 161472: BEQ 161764 161474: CMPB #000130, R0 ; Символ 'X' - загрузка с диска DX 161500: BEQ 161646 161502: CMPB #000116, R0 ; Символ 'N' - загрузка с сети 161506: BEQ 162010 ; Переход на программу холодного старта 161510: CMPB #000014, R0 ; Нажат УПР + L - очистка экрана 161514: BEQ 161402 ; Вывод символа 014 и возврат к пульту ; Вывод знака вопроса (ошибка выполнения команды) и возврат в пультовый режим 161516: MOV #162751, R5 ; Строка " ?" 161522: BR 161412 ; ; Команда 'S' - вывод на экран регистров процессора 161524: MOV #000011, R2 ; 9 регистров 161530: MOV #161556, R5 ; Строка с названиями регистров 161534: CALL @#162342 ; Вывод строки 161540: MOV #177720, R4 ; Адрес блока сохранённых регистров 161544: MOV (R4)+, R3 161546: CALL @#162304 ; Вывод R3 как 8-ричного числа 161552: SOB R2, 161544 161554: BR 161406 ; Возврат в пульт 161556: DB ... ; Строка с названиями регистров ЦП ; Команда 'X' - загрузка с устройства DX ; (код загрузчика практически повторяет код загрузчика с DX/RX01 из ПЗУ ДВК) 161646: MOV #100247, R2 161652: CMP R5, #000001 ; номер диска = 1 ? 161656: BLO 161666 ; меньше 1 => переходим 161660: BHI 161516 ; больше 1 => показываем признак ошибки, возврат в пульт 161662: BIS #000020, R2 161666: MOV #177170, R1 ; Адрес регистра команд/состояния 161672: MOV #040000, (R1) 161676: BITB R2, (R1) ; < 161700: BEQ 161676 ; / Ожидаем результат или ошибку 161702: MOV #000007, R3 161706: MOV R1, R0 161710: MOV R2, (R0)+ 161712: BR 161720 161714: MOV #000001, (R0) 161720: ASR R3 ; 007 -> 003 -> 001 -> 000 161722: BLO 161730 ; 161724: MOV (PC)+, (R1) ; 161726: MOVB (R0), (R3)+ ; сохраняем полученный байт 161730: BIT R2, (R1) ; < 161732: BEQ 161730 ; / Ожидаем результат или ошибку 161734: BMI 161676 ; 161736: BLO 161714 ; повтор 161740: TSTB (R1) 161742: BMI 161726 161744: CLR R0 161746: CMPB #000247, R2 161752: ADC R0 161754: MOV #000200, @#177766 161762: CLR PC ; Запуск полученного блока ; ; Команда 'D' - загрузка с диска 161764: CMP R5, #000007 ; Номер устройства больше 7? 161770: BHI 161516 ; Да => показать признак ошибки, возврат в пульт 161772: CALL @#162774 ; Загрузка данных с дисковода 161776: BLO 161516 ; Ошибка? => возврат в пульт 162000: MOV #000200, @#177766 162006: CLR PC ; Запуск полученного блока ; ; ==== Программа холодного старта ==================================================== ; ; Холодный старт при включении питания 162010: MOV #001000, SP ; Устанавливаем стек 162014: CLR R0 162016: MOV #056311, -(R0) ; -> (177776) 162022: MOV #166064, -(R0) ; Адрес стандартного знакогенератора -> (177774) 162026: MOV #000010, R1 162032: CLR -(R0) ; <| 162034: SOB R1, 162032 ; / Очищаем 010 слов 177754-177773 - переменные?? 162036: MOV #162556, @#177754 ; Подставляем в SOUND пустую подпрограмму 162044: MOV #162064, @#000004 162052: CLR @#170024 ; Сброс второго счётчика?? 162056: MOV #162474, @#177754 ; Адрес полноценной программы SOUND 162064: RESET ; Сбрасываемся и переходим в режим USER?? 162066: MOV #000021, R0 ; Символ очистки всего экрана 162072: CALL @#163740 ; SYSOUT Вывод символа R0 на экран 162076: CALL @#163532 ; SYSLIN Вывод в служебную строку 162102: BR 162106 162104: DW 162664 ; Адрес строки названия машины и версии ПЗУ 162106: MOV #161126, @#000004 ; Адрес прерывания?? - переход в пульт 162114: MOV #000340, @#000006 ; PSW для прерывания ; Попытка загрузки из сети 162122: MOV #170010, R4 ; Адрес регистра состояния локальной сети 162126: MOV #000014, (R4) ; Настройка состояния сетевого адаптера 162132: MOV #162723, R5 ; Адрес строки "ждите..." 162136: CALL @#162342 ; Вывод строки; после этого R5 = "Ошибка сети ? Пульт>" 162142: MOV #162274, @#000004 ; Адрес прерывания ?? 162150: BIT #100040, (R4) ; Проверяем состояние локальной сети 162154: BMI 162274 ; ошибка сети, выходим 162156: BEQ 162150 162160: TST (R4) 162162: MOVB #000003, @#170006 ; Запрещение прерываний?? 162170: MOV #000016, (R4) 162174: CALL @#162252 ; Ожидаем слово из сети 162200: MOV 000002(R4), R2 ; Получили количество слов в блоке 162204: MOV R2, R3 162206: ASL R3 ; Удваиваем - получаем адрес за концом блока 162210: CMP (R3)+, (R3)+ ; Сдвигаем R3 ещё на 2 слова вперёд 162212: MOV R3, SP ; Новый стек 162214: CLR R0 ; R0 = 0 - адрес куда читаем блок 162216: CALL @#162252 ;<| Ожидаем слово из сети 162222: MOV 000002(R4), (R0)+ ; | Сохраняем полученое слово 162226: SOB R2, 162216 ; / продолжаем 162230: MOV #000020, (R4) 162234: CLR -(SP) ; оставляем PSW = 0 для RTI 162236: CLR -(SP) ; оставляем PC = 0 для RTI 162240: BIS #000200, @#177766 162246: JMP @#161060 ; разрешение прерываний и RTI ; Подпрограмма - ожидание слова из сети 162252: MOV #037777, R1 ; счётчик ожидания 162256: BIT #100040, (R4) 162262: BMI 162274 ; ошибка сети, выходим 162264: BEQ 162272 162266: TST (R4) 162270: RETURN 162272: SOB R1, 162256 162274: MOV #002060, (R4) 162300: JMP @#161412 ; Выводим "Ошибка сети ? Пульт>" и в пульт ; ; ==== Программы вывода на экран чисел и строк ======================================= ; ; Подпрограмма DUMP Вывод слова как 8-ричного числа; R3 = число 162304: MOV #000006, R1 ; Шесть разрядов 162310: CLR R0 162312: ROL R3 162314: ROL R0 162316: ADD #000060, R0 ; '0' 162322: CALL @#163734 ; TT.OUT Вывод символа 162326: CLR R0 162330: ROL R3 162332: ROL R0 162334: ROL R3 162336: ROL R0 162340: SOB R1, 162312 ; Подпрограмма PRINT - Вывод строки на экран; R5 = адрес строки 162342: MOVB (R5)+, R0 ; Очередной символ 162344: BNE 162350 ; Не ноль? 162346: RETURN ; Конец строки, выходим 162350: CALL @#163734 ; TT.OUT Вывод символа 162354: BR 162342 ; Продолжаем вывод строки ; ; Ввод команды; команда это символ либо 8-ричное число (параметр) и символ 162356: CLR R1 ; Длина параметра пока нулевая 162360: CLR R5 ; Параметр по умолчанию = 0 162362: TSTB @#177560 ; Получен ли символ с клавиатуры? 162366: BPL 162362 ; Пока не получен 162370: MOVB @#177562, R3 ; Считываем символ 162374: CMPB R3, #000177 162400: BNE 162430 162402: DEC R1 162404: BMI 162356 162406: ASH R5, #177775 162412: BIC #160000, R5 162416: MOV #000134, R0 162422: CALL @#163734 ; TT.OUT Вывод символа 162426: BR 162362 162430: MOV R3, R0 162432: CMPB R0, #000040 ; Это спецсимвол с кодом меньше кода пробела? 162436: BLO 162346 ; Да => выходим 162440: CALL @#163734 ; TT.OUT Вывод символа 162444: BIC #177407, R3 162450: CMP #000060, R3 ; Это цифра? 162454: BNE 162346 ; Нет => выходим 162456: BIC #177770, R0 162462: ASH R5, #000003 162466: BIS R0, R5 ; Добавляем 8-ричную позицию к числу в R5 162470: INC R1 ; Длина строки увеличилась 162472: BR 162362 ; Переходим к ожиданию следующего символа ; ; Подпрограмма SOUND 162474: MOV R4, -(SP) ; Сохраняем R4 162476: BICB #000200, @#177761 ; Предотвращаем повторный вызов SOUND: bit7=0 162504: CLR @#170024 ; Сброс таймер 2 (длительности) 162510: MOV 000002(SP), R4 ; Откуда вызвали SOUND 162514: MOV 000002(R4), R4 ; Получаем адрес мелодии 162520: TSTB (R4) 162522: BEQ 162554 162524: MOV R4, @#177750 ; Запоминаем адрес начала мелодии 162530: MOV #001516, @#170020 ; Пишем в регистр состояния таймера 162536: MOVB (R4)+, @#170030 ; Октава и громкость 162542: CALL @#162560 ; Обработка продолжения мелодии 162546: BISB #000200, @#177761 ; Возвращаем флаг блокировки SOUND: bit7=1 162554: MOV (SP)+, R4 ; Восстанавливаем R4 162556: RETURN ; 162560: MOV R3, -(SP) ; Сохраняем R3 162562: MOVB (R4)+, R3 162564: BIC #177760, R3 ; Оставляем нижние 4 бита - 00..17 162570: ASL R3 ; и умножаем на 2 162572: MOV 162624(R3), @#170022 ; Выбираем по R3 слово и пишем в первый счётчик 162600: MOVB (R4)+, @#170024 ; Задаём длительность 162604: CLRB @#177760 ; Очищаем счётчик длительности ноты 162610: MOV R4, @#177752 ; Запоминаем адрес продолжения мелодии 162614: TST @#170026 ; Устанавливаем триггер таймера 162620: MOV (SP)+, R3 ; Восстанавливаем R3 162622: RETURN ; Значения задержки первого таймера для нот 162624: DW 000000, 003570, 003414, 003246, 003110, 002754, 002630, 002510 162644: DW 002374, 002264, 002160, 002061, 001764, 000000, 000000, 000000 ; ; ==== Подпрограммы работы с дисководом MD =========================================== ; ; Чтение с дисковода для загрузки; R5 = номер устройства 162774: CALL @#163512 ; MODE3 163000: MOV #000001, R4 163004: MOV R5, -(SP) ; Запоминаем номер устройства 163006: ASR R5 ; Получаем номер привода 163010: BHIS 163016 163012: ADD #000004, R5 163016: MOV R5, @#004002 163022: MOV #000400, -(SP) 163026: CLR -(SP) 163030: MOV R4, -(SP) ; Сохраняем R4 163032: MOV #000006, R1 ; Повторять 6 раз 163036: MOV #000070, R0 ;<| Команда - мотор и ШАГ ВПЕРЁД 163042: CALL @#163342 ; | Готовимся и запускаем команду 163046: SOB R1, 163036 ; / Повтор цикла 163050: MOV #000030, R0 ; Команда - мотор и ШАГ НАЗАД 163054: CALL @#163342 ; Готовимся и запускаем команду 163060: CLR @#177106 ; Сбрасываем таймер 163064: BIT R4, @#177106 ; Ждём 163070: BNE 163064 163072: BIT #000010, (R5) ; TR00 ? 163076: BNE 163050 ; Нет => повторяем команду ШАГ НАЗАД 163100: CLR @#177106 ;<| Сбрасываем таймер 163104: BIT R4, (R5) ; | Сброшен RELOAD ? 163106: BEQ 163116 ; | Да - переходим к чтению секторов 163110: SOB R2, 163100 ; / Ждём 163112: JMP @#163332 ; Мы на 0-й дорожке, читаем первый сектор 163116: MOVB R4, R0 ; Количество секторов = 1 163120: MOV #004004, R3 ; Адрес буфера для чтения 163124: CALL @#163402 ; Прочитать сектора 163130: CLR @#004000 163134: MOV @#004000, R0 163140: MOVB 004016(R0), R0 ; Первый байт - кол-во секторов на 0-й дорожке 163144: MOV #004140, R3 ; Куда читать дорожку 163150: CALL @#163402 ; Прочитать сектора 163154: CLR R1 163156: MOV #004016, R5 163162: MOV #000120, R4 163166: MOVB (R5)+, R2 163170: MOV R1, R0 163172: ADD R2, R1 163174: CMP R1, (SP) 163176: BHI 163206 163200: SOB R4, 163166 163202: JMP @#163332 ; 163206: MOV (SP), R3 163210: SUB R0, R3 163212: SUB #000120, R4 163216: ADD @#004000, R4 163222: BEQ 163256 163224: MOV #000030, R0 163230: SUB R4, @#004000 163234: TST R4 163236: BPL 163246 163240: MOV #000070, R0 163244: NEG R4 163246: CALL @#163342 163252: SOB R4, 163246 163254: BR 163134 ; 163256: INC R3 163260: MOV #003750, R5 163264: ADD #000202, R5 163270: SOB R3, 163264 163272: MOV #000100, R4 163276: MOV (SP)+, R3 163300: MOV (SP)+, R2 163302: MOV (R5)+, (R2)+ 163304: DEC (SP) 163306: BEQ 163322 163310: SOB R4, 163302 163312: INC R3 163314: MOV R2, -(SP) 163316: MOV R3, -(SP) 163320: BR 163154 163322: TST (SP)+ 163324: MOV (SP)+, R0 163326: BR 163340 ; 163330: TST (SP)+ 163332: MOV (SP)+, (SP)+ 163334: MOV (SP)+, (SP)+ 163336: SEC 163340: RETURN ; ; Подготовка и запуск операции; R0 = операция 163342: MOV #177106, R5 ; Адрес регистра таймера дисковода 163346: MOV #000006, R2 ; 3 мс * 6 = 18 мс 163352: CLR (R5) ; Стартуем таймер 163354: BIT #000001, (R5) ; Таймер досчитал? 163360: BNE 163354 ; Нет 163362: SOB R2, 163352 ; Продолжаем ждать 163364: BIS @#004002, R0 163370: MOV R0, -(R5) ; Задаём режим 163372: TST -(R5) ; Заполняем флаги из регистра данных 163374: MOV #000001, -(R5) ; Запуск операции 163400: RETURN ; Теперь R5 = адрес регистра состояния ; ; Чтение секторов; R0 = кол-во секторов, R3 = адрес куда читать 163402: MOV R3, R1 163404: MOV R0, -(SP) ; Запомним кол-во секторов 163406: MOV #000012, R4 ; 10 - размер заголовка дорожки 163412: ADD #000202, R4 ; 130 - размер сектора 163416: SOB R0, 163412 ; Умножим 130 на кол-во секторов 163420: MOV #000010, R0 ; Команда - включить мотор и читать 163424: CALL @#163342 ; Организуем запуск команды 163430: MOV #177102, R2 ; Адрес регистра данных дисковода 163434: TSTB (R5) ; Готов прочитанный байт? 163436: BPL 163434 ; Пока нет - TR не установлен 163440: MOVB (R2), (R1)+ ; Читаем очередной байт 163442: SOB R4, 163434 ; Переходим к следующему 163444: MOV (R5), R0 ; Запомним состояние 163446: CLR (R5) ; Окончание операции чтения 163450: MOV (SP)+, R4 ; Вспомним кол-во секторов 163452: INC R4 163454: BIT #000141, R0 ; RELOAD или OP-FAILED или LOST-DATA ? 163460: BNE 163330 ; Да - завершаемся с ошибкой 163462: MOV #000010, R0 ; 8 - длина заголовка 163466: CLR R2 ; Начинаем считать контрольную сумму 163470: MOVB (R3)+, R1 ; Очередной байт 163472: ADD R1, R2 ; Добавляем к сумме 163474: SOB R0, 163470 163476: MOV #000200, R0 ; 128 - длина сектора 163502: CMP R2, (R3)+ ; Сумма совпала? 163504: BNE 163330 ; Нет - завершаемся с ошибкой 163506: SOB R4, 163466 ; Продолжаем подсчёт сумм секторов 163510: RETURN ; ; Подпрограмма MODE3: Вызов подпрограммы с запретом системных прерываний 163512: MOVB #000003, @#170006 ; Запрещение прерываний 163520: CALL @(SP)+ ; Выполняем как п/п то что после CALL @#163512 163522: MOVB #000000, @#170006 ; Разрешение прерываний 163530: RETURN ; ; Подпрограмма SYSLIN: Вывод в служебную строку 163532: CALL @#163512 ; MODE3 163536: MOV R0, -(SP) 163540: MOV R1, -(SP) 163542: MOV #177772, R0 ; Адрес переменной - место курсора 163546: MOV (R0), -(SP) 163550: MOV -(R0), -(SP) 163552: MOV 000012(SP), R1 163556: CMP (R0)+, (R1)+ 163560: MOV (R1), R1 163562: MOVB (R1)+, (R0)+ 163564: CLRB (R0)+ 163566: ADD #176000, -(R0) 163572: CLR -(R0) 163574: BIS #000010, -(R0) 163600: CMP @#177772, #176062 163606: BGE 163622 163610: MOVB (R1)+, R0 ; Получаем следующий символ 163612: BEQ 163622 ; 0? 163614: CALL @#163740 ; SYSOUT Вывод символа на экран 163620: BR 163600 163622: MOV #177766, R0 163626: BIC #000010, (R0)+ 163632: MOV (SP)+, (R0)+ 163634: MOV (SP)+, (R0)+ 163636: MOV (SP)+, R1 163640: MOV (SP)+, R0 163642: RETURN ; 163644: MOV #177772, R4 163650: SUB #000040, R2 163654: BPL 163660 163656: CLR R2 163660: DECB @#177770 163664: BEQ 163714 163666: MOV #000027, R5 163672: CMP R2, R5 163674: BHI 163700 163676: MOV R2, R5 163700: MUL R5, #001200 163704: BIC #177700, (R4) 163710: BIS R5, (R4) 163712: BR 164306 163714: MOV #000061, R5 163720: CMP R2, R5 163722: BHI 163726 163724: MOV R2, R5 163726: BIC #000077, (R4) 163732: BR 163710 ; ; ==== Программа вывода символов на экран ============================================ ; ; TT.OUT Вывод символа на экран; мл.байт R0 = символ 163734: CALL @#163512 ; MODE3 ; SYSOUT Вход - вывод символа ; Стандартная подпрограмма вывода символа 163740: MOV R0, -(SP) 163742: MOV R1, -(SP) 163744: MOV R2, -(SP) 163746: MOV R3, -(SP) 163750: MOV R4, -(SP) 163752: MOV R5, -(SP) 163754: CALL @#165176 ; Убрать курсор если он виден 163760: MOV 000012(SP), R2 163764: BIC #177400, R2 ; Оставляем только младший байт 163770: MOV #177770, R5 163774: TSTB (R5) 163776: BPL 164032 164000: CLRB (R5) 164002: CMP R2, #000131 164006: BEQ 164302 164010: CMP R2, #000113 164014: BHI 164306 164016: SUB #000100, R2 164022: BMI 164306 164024: MOVB 165306(R2), R4 164030: BR 164266 164032: BNE 163644 164034: MOVB @#177766, R4 164040: BPL 164072 164042: CLR @#177762 ; | Маска фона для символа 164046: CLR @#177764 ; | Маска гашения символа перед выводом 164052: ROLB R2 164054: CLC 164056: BPL 164070 164060: BITB #000040, R4 164064: BEQ 164070 164070: RORB R2 164072: CMP R2, #000040 164076: BLO 164230 164100: CMP #166064, @#177774 ; Знакогенератор стандартный? 164106: BNE 164130 ; нет => переход 164110: ROLB R2 164112: BPL 164120 164114: BIC #000100, R2 164120: BHIS 164126 164122: BIS #000100, R2 164126: ASR R2 164130: ADD #142005, R3 ; Начало основной части экрана 164134: SUB #000040, R2 ; Символ минус 32. 164140: ASL R2 ; Дальше умножаем на 10. 164142: MOV R2, R5 ; 164144: ASL R2 ; 164146: ASL R2 ; 164150: ADD R5, R2 ; Получили смещение в знакогенераторе 164152: ADD @#177774, R2 ; Знакогенератор 164156: MOV #000012, R4 ; Высота 10. пикселей 164162: MOVB (R2), R5 ;<| Берём строку символа 164164: SWAB R5 ; | Переносим в старший байт 164166: CLRB R5 ; | 164170: BISB (R2), R5 ; | Копируем в младший байт 164172: INC R2 ; | 164174: BIC @#177764, R5 ; | Маска гашения символа перед выводом 164200: MOV @#177762, R0 ; | Маска фона 164204: XOR R0, R5 ; | 164206: MOV R3, 000002(R1) ; | Устанавливаем косвенный адрес 164212: MOV R5, (R1) ; | Пишем в видеопамять 164214: ADD #000100, R3 ; | К следующей пиксел-строке 164220: SOB R4, 164162 ; / 164222: MOV #177572, R0 ; Регистр косвенного адреса 164226: BR 164424 ; Переходим к следующей позиции вывода ; Обработка символов с кодом меньше #040 164230: MOV #165322, R5 164234: BITB #000010, R4 164240: BNE 164252 164242: CMP (R5)+, (R5)+ 164244: TSTB R4 164246: BMI 164252 164250: CMP (R5)+, (R5)+ 164252: MOV (R5)+, R4 164254: MOV (R5), R5 164256: ASHC R4, R2 164260: BPL 164546 164262: MOVB 165246(R2), R4 ; По коду символа получаем смещение из таблицы 164266: BIC #177400, R4 ; смещение не больше 377 164272: ASL R4 ; смещение умножить на 2 164274: MOV #177770, R5 ; Размер экрана в байтах, начиная от начала ГЗУ 164300: ADD R4, PC ; Переходим по 164302 + 2 * смещение из таблицы 165246 ; +000 - символ 20 либо ESC+131 - прямая адресация курсора; ; следующие два байта строки: N строки+40, N позиции+40 164302: MOVB #000002, (R5) 164306: BR 164546 ; +003 - символ 36 - очистка служебной строки 164310: MOV #140000, R2 ; Косвенный адрес начала экрана 164314: MOV #002000, R3 ; Сколько слов чистить 164320: MOV R2, (R0) 164322: CLR (R1) 164324: INC R2 164326: SOB R3, 164320 164330: BR 164546 ; +014 - символ 27 - переход из режима "Немига" в VT-52 164332: BIC #000400, (R5) 164336: BIS #000200, -(R5) 164342: BR 164546 ; 164344: BIT #000200, 177776(R5) 164352: BNE 164366 ; +025 - VT-52 символ ESC+106 - вкл/откл звук подтверждения нажатия клавиши 164354: 164366: DECB (R5) 164370: BR 164546 ; +034 - символ 06 164372: CLR (R5) 164374: TST -(R5) 164376: CLR -(R5) 164400: CLR -(R5) 164402: BR 164546 ; +041 - символы 02..05 164404: COMB 177760(R2) 164410: BR 164546 ; +044 - символ 30 - погасить/включить курсор 164412: MOV #000200, R2 ; +046 - символ 01 - включить/выключить сдвиг экрана 164416: SWAB R2 164420: XOR R2, (R5) 164422: BR 164546 ; ; Переход к следующей позиции вывода 164424: MOV #177772, R5 ; Текущая позиция курсора 164430: INC (R5) ; Следующая позиция 164432: MOV (R5), R3 164434: MOV R3, R4 164436: BIC #177700, R4 ; Позиция в пределах строки 164442: CMP R4, #000062 ; Больше 50 ? 164446: BLO 164546 ; Меньше => завершаем процедуру 164450: BIC #000077, R3 ; Возвращаемся к началу строки 164454: MOV R3, (R5) ; Сохраняем новое место курсора 164456: ADD #001200, R3 ; Добавляем 10 пиксел-строк 164462: CMP R3, #034700 ; Дошли до конца экрана? 164466: BLO 164554 ; Нет => завершаем процедуру 164470: BIC #177700, R3 164474: BITB #000001, @#177771 ; Состояние курсора?? 164502: BNE 164554 ; Скроллинг экрана 164504: MOV #142005, R2 ; Косвенный адрес куда копировать 164510: MOV #143205, R3 ; Косвенный адрес откуда копировать 164514: MOV R3, (R0) ; Заносим адрес откуда 164516: MOV (R1), R4 ; Берём слово 164520: MOV R2, (R0) ; Заносим адрес куда 164522: MOV R4, (R1) ; Пишем слово 164524: INC R2 ; Переходим к след адресу куда 164526: INC R3 ; К след адресу откуда 164530: BNE 164514 ; Экран не кончился? => повторяем 164532: BR 165074 ; +115 - символ 10 - Backspace 164534: BIC #177700, R3 164540: BEQ 165104 164542: DEC @#177772 ; новое смещение курсора левее на 1 164546: BR 165104 ; +123 - символ 15 - возврат каретки 164550: BIC #000077, R3 ; На начало строки 164554: MOV R3, @#177772 ; Сохраняем позицию курсора 164560: BR 165104 ; +130 - символ 11 - горизонтальная табуляция с шагом 8 164562: MOV R3, R4 164564: BIC #177700, R4 164570: CMP R4, #000057 164574: BHIS 165104 164576: ADD #000010, R3 164602: BIC #000007, R3 164606: BR 164554 ; +??? - символ VT-52 16 - переход на русский регистр 164610: BIS #000040, -(R5) 164614: BR 165104 ; +??? - символ VT-52 17 - переход на латинский регистр 164616: BIC #000040, -(R5) 164622: BR 165104 ; +151 - символ VT-52 ESC+100 - переход в режим "Немига" 164624: BIC #177600, -(R5) 164630: BR 165104 ; +165 - символ VT-52 ESC+101 или "Немига" 22 - вверх 1 164654: 164662: MOV R3, @#177772 ; новое смещение курсора 164666: BR 165104 164670: ADD #001200, R3 ; на 10. линий вниз 164674: CMP R3, #034700 ; вышли за нижний край? 164700: BHIS 165104 ; да => тогда ничего не делаем 164702: BR 164662 ; устанавливаем новое смещение курсора и выходим ; 164704: INC R3 164706: MOV R3, R4 164710: BIC #177700, R4 164714: CMP R4, #000062 164720: BR 164700 ; 164722: CLR R3 164724: BR 164662 164726: SUB #001200, R3 164732: BPL 164662 164734: CLR R2 164736: MOV #176600, R3 164742: MOV #034600, R5 164746: DEC R3 164750: DEC R2 164752: MOV R3, (R0) 164754: MOV (R1), R4 164756: MOV R2, (R0) 164760: MOV R4, (R1) 164762: SOB R5, 164746 164764: MOV #001200, R5 164770: INC R3 164772: MOV R3, (R0) 164774: CLR (R1) 164776: SOB R5, 164770 165000: BR 165104 ; +240 - символ 007 - BELL 165002: BITB #000100, @#177761 ; Проверяем байт блокировки SOUND 165010: BNE 165104 165012: CALL @#160126 ; SOUND 165016: BR 165104 ; к завершению обработки символа 165020: DR 165022 ; адрес мелодии 165022: DB 001, 205, 017, 000 ; +252 - символ "Немига" 13, VT-52 ESC+113 - очистить строку от позиции курсора 165026: CALL @#165126 165032: BR 165104 ; +255 - символ "Немига "37, VT-52 ESC+112 - очистка экрана от позиции курсора 165034: CALL @#165126 165040: BIC #000077, R3 165044: MOV R3, R2 165046: ADD #142005, R2 ; Начало основной части экрана 165052: BPL 165104 165054: BR 165074 ; +266 - символ 21 - очистка всего экрана, включая служебную строку 165056: MOV #140000, R2 ; Косвенный адрес начала экрана 165062: BR 165070 ; +271 - символ 14 - перевод формата, очистка экрана, служебная строка сохраняется 165064: MOV #142000, R2 ; Начало экрана после служебной строки 165070: CLR @#177772 ; Курсор будет в начале экрана 165074: MOV R2, (R0) ;<| Косвенный адрес 165076: CLR (R1) ; | Очищаем слово 165100: INC R2 ; | Увеличиваем адрес 165102: BNE 165074 ; / дошли до конца ? нет => повторяем ; +301 - символ 00, ESC+105, ESC+107 - неиспользуемый код символа ; Завершение обработки символа 165104: CALL @#165176 ; Восстановление курсора 165110: MOV (SP)+, R5 165112: MOV (SP)+, R4 165114: MOV (SP)+, R3 165116: MOV (SP)+, R2 165120: MOV (SP)+, R1 165122: MOV (SP)+, R0 165124: RETURN ; Очистка строки от текущей позиции до конца строки 165126: MOV #000012, R5 ; 10. итераций 165132: MOV R3, R2 165134: MOV #000062, R4 ; 50. позиций в строке 165140: BIC #177700, R2 165144: SUB R2, R4 165146: BLE 165166 165150: MOV R3, R2 165152: ADD #142005, R2 ; Начало основной части экрана 165156: MOV R2, (R0) 165160: CLR (R1) 165162: INC R2 165164: SOB R4, 165156 165166: ADD #000100, R3 165172: SOB R5, 165132 165174: RETURN ; ; Подпрограмма стирания/восстановления курсора 165176: MOV #177570, R1 ; Регистр данных косвенного доступа к памяти 165202: MOV #177572, R0 ; Регистр косвенного адреса 165206: MOV @#177772, R3 ; Место курсора от начала ГЗУ 165212: BMI 165244 165214: TSTB @#177771 ; Состояние курсора?? 165220: BMI 165244 165222: TSTB @#177757 ; Состояние курсора при мигании 165226: BPL 165244 ; не виден => не нужно убирать 165230: MOV R3, R4 165232: ADD #143105, R4 ; + косвенный адрес 25-й строки экрана 165236: BPL 165244 165240: MOV R4, (R0) ; Устанавливаем косвенный адрес 165242: COM (R1) ; Инвертируем восемь пикселей - курсор 165244: RETURN ; Таблица смещений переходов для обработки спецсимволов 165246: DB 301, 046, 041, 041, 041, 041, 034, 240 ; 00..07 165256: DB 115, 130, 066, 252, 271, 123, 143, 146 ; 10..17 165266: DB 000, 266, 165, 154, 156, 210, 173, 014 ; 20..27 165276: DB 044, 201, 115, 021, 212, 066, 003, 255 ; 30..37 ; Таблица смещений переходов для обработки символов ESC + 100..113 165306: DB 151, 165, 173, 201, 115, 301, 025, 301 ; 100..107 165316: DB 210, 212, 255, 252 ; Точка входа QDRAW - DRAW для QUASIC 165336: MOV (SP), R5 ; Точка входа FDRAW - DRAW для FORTRAN 165340: CALL @#166040 ; Точка входа DRAW - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW) ; После выполнения операции XNEW=XOLD, YNEW=YOLD. 165344: CALL @#165374 165350: MOV @#000212, @#000216 ; XNEW -> XOLD 165356: MOV @#000214, @#000220 ; YNEW -> YOLD 165364: RETURN ; Точка входа QLINE - LINE для QAUSIC 165366: MOV (SP), R5 ; Точка входа FLINE - LINE для FORTRAN 165370: CALL @#166040 ; Точка входа LINE - нарисовать линию из (XOLD,YOLD) в (XNEW,YNEW) 165374: MOV #000212, R5 ; Адрес XNEW 165400: MOV (R5)+, R0 165402: MOV (R5)+, R1 165404: MOV (R5)+, R2 165406: MOV (R5)+, R3 165410: CLR @#000204 ; Очищаем REV 165414: MOV #000001, R4 165420: MOV R4, R5 165422: SUB R2, R0 165424: BPL 165432 165426: NEG R0 165430: NEG R5 165432: SUB R3, R1 165434: BPL 165442 165436: NEG R1 165440: NEG R4 165442: CMP R0, R1 165444: BGE 165474 165446: MOV R0, -(SP) 165450: MOV R1, R0 165452: MOV (SP), R1 165454: MOV R4, (SP) 165456: MOV R5, R4 165460: MOV (SP), R5 165462: MOV R2, (SP) 165464: MOV R3, R2 165466: MOV (SP)+, R3 165470: INC @#000204 ; Инкремент REV 165474: TST R0 165476: BEQ 165542 165500: ASL R1 165502: MOV R0, -(SP) 165504: ASL (SP) 165506: MOV R1, -(SP) 165510: SUB R0, (SP) 165512: CALL @#165542 165516: TST (SP) 165520: BMI 165530 165522: SUB 000002(SP), (SP) 165526: ADD R4, R3 165530: ADD R1, (SP) 165532: ADD R5, R2 165534: SOB R0, 165512 165536: CMP (SP)+, (SP)+ 165540: RETURN 165542: MOV R1, -(SP) ; Сохраняем регистры 165544: MOV R2, -(SP) 165546: MOV R3, -(SP) 165550: TST @#000204 ; Проверяем REV 165554: BEQ 165562 165556: MOV R2, R3 165560: MOV (SP), R2 165562: CALL @#165614 ; Выводим точку (R2,R3) 165566: MOV (SP)+, R3 ; Восстанавливаем регистры 165570: MOV (SP)+, R2 165572: MOV (SP)+, R1 165574: RETURN ; ; Точка входа QPOINT - POINT для QUASIC 165576: MOV (SP), R5 ; Точка входа FPOINT - POINT для FORTRAN 165600: CALL @#166040 ; Точка входа POINT - нарисовать точку 165604: MOV @#000212, R2 ; XNEW 165610: MOV @#000214, R3 ; YNEW 165614: CALL @#163512 ; MODE3 165620: CALL @#165746 ; Находим точку на экране 165624: BLO 165656 165626: TST (R1)+ 165630: MOV @#000210, R2 ; BRIGHT 165634: ASR R2 165636: BLO 165646 165640: BIC R3, @#177570 ; Пишем в экран 165644: BR 165652 165646: BIS R3, @#177570 ; Пишем в экран 165652: SWAB R3 165654: SOB R1, 165634 165656: RETURN ; ; Точка входа QRPOIN - RPOINT для QUASIC 165660: MOV (SP), R5 ; Точка входа FRPOIN - RPOINT для FORTRAN 165662: CALL @#166040 165666: BR 165674 ; Точка входа RPOINT - прочитать яркость точки 165670: MOV #000210, R4 ; Адрес BRIGHT 165674: MOV @#000212, R2 ; XNEW 165700: MOV @#000214, R3 ; YNEW 165704: CLR (R4) 165706: CALL @#163512 ; MODE3 165712: CALL @#165746 ; Находим точку на экране 165716: BLO 165742 165720: MOV #000002, R1 165724: SWAB R3 165726: BIT R3, @#177570 165732: BEQ 165736 165734: ADD R1, (R4) 165736: SOB R1, 165724 165740: RETURN 165742: DEC (R4) 165744: RETURN ; Нахождение точки на экране; устанавливает косвенный адрес, возвращает маску в R3 165746: MOV R2, R1 165750: CMP #000637, R2 165754: BLO 166036 165756: ASH R2, #177775 165762: CMP (R2)+, (R2)+ 165764: CMP #000377, R3 165770: BLO 166036 165772: CMP @#000206, R3 ; Сравниваем с VFORM 165776: BLO 166036 166000: COMB R3 166002: SWAB R3 166004: SEC 166006: ROR R3 166010: ASR R3 166012: BIS R3, R2 166014: MOV R2, @#177572 ; Устанавливаем косвенный адрес 166020: BIC #177770, R1 166024: INC R1 166026: CLR R3 166030: SEC 166032: ROR R3 166034: SOB R1, 166032 166036: RETURN ; Подготовка перед вызовом для FORTRAN 166040: MOV (R5)+, R0 166042: MOV (R5), R4 166044: BIC #177770, R0 166050: BEQ 166062 166052: MOV #000210, R3 ; Адрес BRIGHT 166056: MOV @(R5)+, (R3)+ 166060: SOB R0, 166056 166062: RETURN ; ; ==== Стандартный знакогенератор ==== 166064: DB ; Знакогенератор, 96 символов (0x20..0x80), 10 байт/символ ; ==== Регистры ==== 170000: DW ; Используется м/с умножителя 170002: DW ; Используется м/с умножителя 170004: DW ; Используется м/с умножителя 170006: DW ; Регистр данных клавиатуры / фиксации HALT запросов 170010: DW ; Регистр состояния адаптера локальной сети 170012: DW ; Регистр данных адаптера локальной сети 170014: DW ; ?? 170020: DW ; RgStSnd - регистр состояния таймера 170022: DW ; RgF - регистр частоты 170024: DW ; RgLength - регистр длительности 170026: DW ; RgOn - включение звука (обращение) 170030: DW ; RgOct - регистр октавы и громкости 170032: DW ; RgOff - выключение звука (обращение) 177100: DW ; RgStat - регистр состояния контроллера дисковода 177102: DW ; RgData - регистр данных 177104: DW ; RgCntrl - регистр управления 177106: DW ; RgTime - регистр таймера контроллера дисковода 177170: DW ; Регистр состояния дисковода DX 177172: DW ; Регистр данных дисковода DX 177514: DW ; Регистр данных устройства сопряжения 177516: DW ; Регистр состояния усройства сопряжения 177560: DW ; KBS - регистр состояния клавиатуры 177562: DW ; KBD - регистр данных клавиатуры 177564: DW ; TTS - регистр состояния дисплея 177566: DW ; TTD - регистр данных дисплея 177570: DW ; VDATA - регистр данных косвенного доступа 177572: DW ; VADDR - регистр адреса косвенного доступа ; ==== Блок переменных ==== 177720: DW ; R0 при останове 177722: DW ; R1 при останове 177724: DW ; R2 при останове 177726: DW ; R3 при останове 177730: DW ; R4 при останове 177732: DW ; R5 при останове 177734: DW ; SP при останове 177736: DW ; PC при останове 177740: DW ; PSW при останове 177750: DW ; Адрес начала мелодии 177752: DW ; Адрес продолжения мелодии 177754: DW ; Адрес подпрограммы SOUND 177756: DB ; Счётчик мигания курсора 177757: DB ; Состояние курсора: 000 - не виден, 377 - виден 177760: DB ; Счётчик длительности ноты 177761: DB ; Байт блокировки вызова SOUND 177762: DW ; FRG Маска фона для вывода символа 177764: DW ; COL Маска гашения символа перед выводом 177766: DW ; Какие-то важные флаги?? 177770: DW ; SIZE Размер экрана в байтах, начиная от начала ГЗУ 177772: DW ; CUR Место курсора от начала ГЗУ 177774: DW ; SYMGEN Адрес знакогенератора, по умолчанию 166064 177776: DW ; Значение #056311