по адресам 100000-117777 - не всегда, а только если 177054 бит 0 равен 1, и не выбран картридж с ПЗУ (биты 1-2 того же регистра).
Вид для печати
/* не вы интересовались как выключить курсор */
интересовался как "просто", без десятка строк кода выключить курсор, но на последних двух страницах пытался узнать как работать с ПЗУ и как с этим связан листинг emuverse.
/*Вы нас за идиотов держите*/
Никто Вас ни за кого не держит..
.....................
Вот кстати на обеде не удержался попробовал:
.....
CLR @#23164 ; Запретить курсор
MOV #2,@#7134
MOVB #177,@23160 ; Убрать курсор с экрана;
..........
Прекрасно работает и без вашего любимого скакания по таблице строк....
Просто и красиво :) Трудно было подсказать?
............
В любом случае спасибо за участие.. :)
S_V_B, http://archive.pdp-11.org.ru/ukdwk_a...t/Other/UKROM/
наследие заслуженных УК-НЦ программистов, в частности соавтора UKNCBTL Alex_K, он кстати на форум заходит не так уж и редко (здоровья, Алексею!).
это чудо техники - младшая родственница гигантских PDP, то есть некий ПРОМЫШЛЕННЫЙ СТАНДАРТ
RT-11 - то же стандарт, идеально вылизанная, продуманная система реального времени под которую
есть трансляторы всех самых популярных языков, МАКРО-11 лучший и самый правильный ассемблер,
а цифры 8 и 9 придумали враги ))) Реализация графики как и работа с ней у каждой машинки сделана по своему,
у ДВК = КЦГД, у УК-НЦ встроенная БКашка в виде ПП, у БК своя там область экрана и заморочки с ней связанные
Системная МАКРО библиотека и сам язык более рассчитаны не на специфику (напрямую к железу), а на системные вызовы,
тем самым добывается запуск на любой ЭВМ под RT-11 или её эмуляцией.
Возможно ли в UKNCBTL ставить точки останова?
Пробовал в текст BPT вставлять, просто вылетает из программы.
Пошаговое выполнение есть, а как остановить?
Там есть типа "одна" точка останова. В консоли отладчика вводим g12345 -- это значит ставится точка на адрес 12345, запускается на выполнение. Точка пропадает при первом останове эмулятора, без разницы ручном или по точке. Только при выполнении команды g12345 внимательно смотрите на каком процессоре вы сейчас стоите. Текущий процессор переключается командой p.
Команда Step Over реализована так же -- определяется адрес следующей команды, выполняется g12345 с этим адресом.
Полный хелп по всем командам консоли отладчика -- команда h.
https://github.com/nzeemin/ukncbtl-doc/wiki/Debugger-ru
Возможно ли как то собрать бинарный файл который можно просто загрузить в память и выполнить?
Т.е. например, запускается программа, загружает этот файл в память(расчитанный на загрузку с адреса 024000) и посылает его в память ПП, или же в дополнительную память, адреса которой выше верхней границы памяти используемой ОС.
Удаление в знак протеста против действий MM
Удаление в знак протеста против действий MM
randomizer, я не уверен, но адрес запуска можно прописать компилятору принудительно (?), команда GET загружает файл (.SAV по умолчанию) в пользовательское ОЗУ, после этого программа может быть запущена командой STart
Формат LDA описан в RT-11 Volume And File Formats Manual. В общем случае файл делится на куски, каждый из них предваряется заголовком в котором прописан адрес в который этот кусок грузится и его длина, а в конце идет контрольная сумма. Заканчивается файл голым заголовком который сообщает стартовый адрес или 1 если его нет. Формат предназначен для записи на перфоленту. Так же используется в XXDP для запускаемых файлов (там формат немного расширен для использования расширенной памяти).
Если нужен чистый код без нулевого блока SAV файла, то проще сделать(нужна программа SPLIT.SAV из стандартного набора RT-11).Код:.SPLIT FILE.SAV/B:1 ,FILE.BIN
Одни недостаток, при генерации .SAV, и после выполнения команды SPLIT, размер файла оказыватся округлённым до размера блока. А в .LDA файле прописаны размеры кодовых блоков. Пожалуй всё же .LDA файлы удобней, за минусом того, что в программу нужно будет включать загручик для них.
Прочитал вопрос полностью.
Если речь идет о загрузке в ПП, то проще собирать обычный REL файл и грузить его программой PRUN - для того ее и делал. Бонус: не требуется позиционно-независимого программирования, грузится только чистый код.
В любом случае, в качестве примера можно посмотреть IOSCAN - там программа собирается как обычный SAV, как LDA как программа для загрузки в ПП УКНЦ, как загрузчик для ленты итд.
В комплекте с PRUN есть примеры программ для ПП которые выполняют определенный действия (в том числе убираются из памяти по завершении или остаются и выполняют нужные функции).
Описание PRUN V2.0.
Пока у меня задача можно сказать попроще. ОС загружается в адреса ниже 170000, выше есть ещё 3Кбайтная страница быстрой памяти. В эту память я как раз и хочу вынести несколько процедур. И пожалуй да, будет проще из .SAV файла вырезать нужный участок и загрузить в эту область.
перекинул вопрос в тему, надо системнее справочки шпаргалочки, потом искать проще )
@S_V_B
Как и можно ли выполнить LOAD SYS из программы?
допустим я хотел бы из своей программы запускать часики @form 'a CL.SYS которые?
Это хороший пример, поскольку часики для старта не нужны никакие SET, just LO CL?
Код:.TITLE RELEAS
;In this example, the Null handler (NL) is loaded into memory,
;used, then released. If NL is LOADed the handler is
;resident, and .FETCH will return HSPACE in R0.
.MCALL .FETCH,.RELEAS,.EXIT,.PRINT
START: .FETCH #HSPACE,#NLNAME ;Load NL handler
BCS FERR ;Not available
; Use handler
.RELEAS #NLNAME ;Mark NL no longer in memory
.EXIT
FERR: .PRINT #NONL ;NL not available
.EXIT
NLNAME: .RAD50 /NL / ;Name for NL handler
NONL: .ASCIZ /?ERELEA-F-NL handler not available/
.EVEN
HSPACE: ;Beginning of handler area
.END START
Выше Hunta привет пример.
Вроде CL поддерживает вызов .FETCH - не помню уже. Если нет - можно сделать :)
Разве что замечу, что метка перед .END не всегда будет последним адресом программы. Более универсальный метод - взять значение по адресу 50 и прибавить к нему 2 (или взять значение, генерируемое директивой .LIMIT).
Hunta,
form, благодарю )
пока результат такой, буду эксп-ть )
двойное зависание - обожаю, но "сбой аппаратуры" это абсолютный хит!Код:*** CТOП ***
000016/ 000000
@ 0
*** ДBOЙНOE ЗABИCAНИE ***
000006/ 000000
@
Вот этот код
под эмулятором Патрона показал вот такой результатКод:.TITLE RELEAS
.MCALL .FETCH,.RELEAS,.EXIT,.PRINT
START: .FETCH #HSPACE,#NLNAME ;Load NL handler
BCS FERR ;Not available
; Use handler
.RELEAS #NLNAME ;Mark NL no longer in memory
.PRINT #OK ;NL not available
.EXIT
FERR: .PRINT #NONL ;NL not available
.EXIT
NLNAME: .RAD50 /NL / ;Name for NL handler
NONL: .ASCIZ /?RELEAS-F-NL handler not available/
OK: .ASCIZ /?RELEAS-I-Ok!/
.EVEN
HSPACE: ;Beginning of handler area
.END START
Код:HD (177720) disk driver v1.6 2017
SL V08.00 [SW] Сторожевых С.В. 1988
KZ V01.00 (C) ВЦ МИЭТ, НОЯБРЬ 1987
RT-11SB (Y) V05.07
.SET TT FORM
.SET TT SCOPE
.SET EDIT K52
.SET SL ON
.DAY
Время Дата
11:29:52 30-Май-2019, Четверг
.ASS HD1 DK
.EXE T
?RELEAS-I-Ok!
.
Использование .DSTAT и .SETTOP имеет смысл если хочется грузить драйвера начиная сверху вниз, а промежуток до них использовать на свое усмотрение. MU BASIC-11 так делает например.
В остальном смысла особого нет так как единственное что делает .SETTOP - это просто переставляет значение ячейки 50.
Так что если нет нужды в вышеописанном варианте, можно просто использовать .FETCH с указанием первого свободного адреса, а на выходе получать новый свободный адрес с учетом загруженного драйвера.
Бонусом будет отсутствие лишней суеты с файлом SWAP.SYS после выхода из программы :)
Что касается XM, в нем FG job е может использовать .FETCH, а в виртуальной BG программе .SETTOP просто переставит лимит задачи на который .FETCH и загруженному драйверу глубоко наплевать :)
Ну и для полноты картины, остается упомянуть VBGEXE BG job - в этом случае указанный в .FETCH адрес вообще никак не используется.
заменил название на CL
закомментировал выгрузку
часики появились на долю секунды но одновременно с .EXIT исчезли
???
Код:! Apxивны дeл ЖД ! ЛAТ
.TITLE RELEAS
.MCALL .FETCH,.RELEAS,.EXIT,.PRINT
START: .FETCH #HSPACE,#NLNAME ;Load NL handler
BCS FERR ;Not available
; Use handler
; .RELEAS #NLNAME ;Mark NL no longer in memory
.PRINT #OK ;NL not available
.EXIT
FERR: .PRINT #NONL ;NL not available
.EXIT
NLNAME: .RAD50 /CL / ;Name for NL handler
NONL: .ASCIZ /?RELEAS-F-NL handler not available/
OK: .ASCIZ /?RELEAS-I-Ok!/
.EVEN
HSPACE: ;Beginning of handler area
.END START
Я писал программы, которые всю доступную память забирали себе в пул, из которой потом и выделялась память кусками. По описанной мной схеме мой код так с подгрузкой драйверов и работал - получить информацию - сколько надо памяти (посмотрел - да, .DSTAT), получить, проверить, что выдали затребованное, загрузить драйвер
Так и должно быть. С помощью .FETCH драйвер подгружается для программы, а не насовсем.
Если хочется из программы подгрузить драйвер нужно использовать другой вариант: с помощью .DSTAT проверить загружен ли он, если нет - сделать выход с выполнением командами LOAD CL и RUN имяпрограммы (пример выходя с командой есть в описании макробиблиотеки).
- - - Добавлено - - -
Начальный верхний адрес - это содержимое @#50 плюс 2.
После вызова .FETCH, новый адрес вернется в R0
- - - Добавлено - - -
У меня тоже некоторые проги так делают.
В последних прогах где-то перешел на родной $INIDM от DEC :)
https://pic.maxiol.com/images/155920...0075909177.png
красота, да будут часики на экране ! @form про команду на выходе - я понял, мне наверное и то и то нужно
- - - Добавлено - - -
@form > Начальный верхний адрес - это содержимое @#50 плюс 2.
После вызова .FETCH, новый адрес вернется в R0
Правильно или не очень )))
- такой вариант часы запускает.
Код:
START: MOV @#50,R0
SUB #2,@#R0
.FETCH @#R0,#NLNAME ;Load NL handler
BCS FERR ;Not available
; Use handler
поправил в такой вид, часики подгружает и на выходе выгружает,Код:.TITLE RELEAS
.MCALL .FETCH,.RELEAS,.EXIT,.PRINT
START: MOV @#50,R1
ADD #2, R1
.FETCH R1,#NLNAME ;Load NL handler
BCS FERR ;Not available
; Use handler
; .RELEAS #NLNAME ;Mark NL no longer in memory
.PRINT #OK ;NL not available
BR .
FERR: .PRINT #NONL ;NL not available
.EXIT
NLNAME: .RAD50 /CL / ;Name for NL handler
NONL: .ASCIZ /?RELEAS-F-NL handler not available/
OK: .ASCIZ /?RELEAS-I-Ok!/
.EVEN
HSPACE: ;Beginning of handler area
.END START
получается .RELEAS можно не использовать? я его закомментил как видно.
Годится. Вместо ADD #2,R1 здесь можно использовать TST (R1)+ - это на слово короче.
Он нужен только если тебе в рамках работы программы потребовалось освободить память от ранее .FETCHнутого драйвера. Специально вызывать его перед выходом не надо - он неявно сам выполнится когда потребуется.
Да! Я это и хотел попросить разжевать для меня. Я очень туг в плане этой регистровой математики, иначе быть мне системщиком однозначно. По синтаксису я понимаю эту строку так, сравниваем с нулём содержимое R1? Но что в
данном случае означают скобки с плюсом и как сравнение с нулём может заменить операцию сложения (типа сдвиг, смещение). ??? может немного сумбурно, но я же хотел чётко понимать процедуру, а не тупо шпаргалить. вот прибавить двойку мне более понято, ещё вопрос третий вариант два INC подряд будет тем же самом в плане результата, ведь можно
тогда написать свой макрос где тупо задать количество операций INC или DEC?
- - - Добавлено - - -
ура! я сдал Олегу контрольную ))) Спасибо за шпору Хунта!
Просто проверяем значение ячейки памяти, адрес которой хранится в регистре (как итог - знаем равно нулю/меньше нуля или наоборот). В данном случае для нас результат проверки неинтересен, для нас важно, что такой адрес существует в принципе (иначе такая команда не годилась бы).
Это значит что после обращения, значение регистра увеличится на 2 (или на 1 если обращение байтовое [исключение - регистры 6 (SP) и 7 (PC) - они всегда на 2 изменяются]).
Это не имеет смысла поскольку уже два вызова INC/DEC - это два слова (для регистра), а дальше - больше. Тут как раз ADD будет лучше.