Не ясна логика проверки ;)
Вид для печати
Тогда что есть CMP (R0)+,(R0)+
:)
Не знание предмета
- - - Добавлено - - -
Что можно творить на MACRO-11
Код:PROCEDURE READ1
;
; R0 - sector num
; R1 - word count - zeroed
; R2 - memory address - updated
;
; in work
; R3 - sector count
;
BEGIN
LET R4 := BTCSR2
LET (R4) := #DC.STA!DC.NIE
LET R3 := R1 OFF.BY #377
SWAB R3
IF #377 SET.IN R1 THEN
LET R3 := R3 + #1
END
; R3 sector count
LET R4 := R4 + #P$STAT-P$CSR2
REPEAT
LET R5 :B= (R4)
.ASSUME CS.BSY EQ <^O200>
UNTIL RESULT IS PL AND #CS.DRD SET.IN R5
LET R4 := R4 + #P$SCNT-P$STAT
LET (R4)+ := R3 ; 24
.ASSUME P$SNUM EQ <P$SCNT+2>
LET (R4)+ := R0 ; 26
.ASSUME P$CYLL EQ <P$SNUM+2>
SWAB R0
LET (R4)+ := R0 ; 30
.ASSUME P$CYLH EQ <P$CYLL+2>
LET (R4)+ := @#B$DEVU ; 32
.ASSUME P$DH EQ <P$CYLH+2>
LET (R4)+ := BTDH ; 34
.ASSUME P$CMD EQ <P$DH+2>
LET (R4) := #CS.RD ; 36
REPEAT
REPEAT
LET R5 :B= (R4)
.ASSUME CS.BSY EQ <^O200>
UNTIL RESULT IS PL AND #CS.DRQ SET.IN R5
IF #CS.ERR SET.IN (R4) GOTO 80$
LET R4 := R4 + #P$DBUF-P$STAT
THRU R3 := #256.
IF R1 NE #0 THEN
LET (R2)+ := (R4)
LET R1 := R1 - #1
ELSE
TST (R4)
END
END
LET R4 := R4 + #P$STAT-P$DBUF
UNTIL R1 EQ #0
LET CARRY := OFF
RETURN
80$:
RESET
JMP BIOERR
END READ1
ок, попробую по другому спросить, вы видите ошибку явно там,
где у меня "мёртвая зона" и так
[CODE]
1. сойдёт я получил за вариант с ADD #2,R1
на замену этой команды form посоветовал оптимизацию TST (R1)+
я конечно как честный Паскале-Любитель синтаксис ассембл. не совсем
чётко понимаю, но я забыл о чотности и что арифметика "словесная",
то есть смещение ()+ всегда на 2 и только байтовая может быть нечётной
получив такую рекомендацию я пишу код в моём понимании означающий
MOV @#50,R1 ; КЛАДЁМ СОДЕРЖИМОЕ ЯЧЕЙКИ 50 В R1
TST (R1)+ ; form ПОЯСНИЛ, ЧТО ЭТО ПРОВЕРКА НА СУЩЕСТВ. АДРЕСА
; НУЖНОГО, ДАЛЕЕ Я ПИШУ
BEQ GOGOGO ; ЕСЛИ РЕЗУЛЬТАТ ПРЕД.-ЕЙ КОМАНДЫ 0 ЗНАЧИТ ВСЁ ОК И
; МЫ ИДЁМ ФЭТЧИТЬ ДРАЙВЕР, И СЛЕДУЩИЕ ДВЕ СТРОКИ ПЕРЕД
МЕТКОЙ GOGOGO - ЭТО сообщение об ошибке и екзит
за что сразу учебником по макушке%
господа не лишайте стипендии в чём ошибка,
помните вы смотрите на бублик изнутри, я же снаружи да ещё через упаковку ) две разницы !
В ячейке 50 - последний используемый (в данный момент) программой адрес. Нуля там не будет в принципе. Первый свободный - последний используемый + 2. В .FETCH надо указать - с какого адреса грузить. Поскольку первый свободный - это последний используемый + 2 - берём содержимое ячейки 50, добавляем два и этот адрес указываем в вызове .FETCH.
Знающие систему команд и способы адресации PDP-11 вместо ADD #2 используют TST (R1)+, которая сделает следующее - возьмёт содержимое R1, извлечёт содержимое ячейку по адресу, извлечённому из R1 (попутно устанавливая или сбрасывая флаги), увеличит извлечённое из R1 значение на 2 (поскольку команда словная) и запишет обратно в R1. Нас интересует только воздействие на R1, поэтому дальше никаких проверок флагов не делается (хотя обычно после TST они проверяются тем или иным способом). Возможная проблема - R1 указывает на несуществующую память и мы словим прерывание по V4 - в данном случае неактуальна, потому что @#50 всегда (ну, точнее, если мы работает под RT11) указывает на существующую память (последняя ячейка программы).Код:MOV @#50, R1
ADD #2, R1
.FETCH R1, #CL
- - - Добавлено - - -
Вдогонку
Возможные проблемы в коде в сообщении
- после программы не достаточно памяти для загрузки выбранного драйвера (не сильно страшно, подозреваю, что монитор откажется грузить, если памяти не хватает)
- насколько я понял из описания, .FETCH не корректирует значение в @#50, в R0 он возвращает адрес следующей ячейки памяти после загруженного драйвера (а это уже серьёзней, код из другого места может взять содержимое из ячейки @#50 и затереть драйвер)
- даже если за .RELEASE идёт .EXIT - отсутствие .RELEASE - это неряшливый стиль, в результате чего могут появиться вопросы и который потенциально может привести к ошибкам в программе - человек просто забудет написать .RELEASE там, где он точно нужен и потенциально получить нехватку памяти
Правильный подход
- получить информацию (включая размер) о драйвере
- сохранить текущую верхнюю границу + 2
- используя текущую верхнюю границу программы и размер драйвера - посчитать новую и установить её, используя .SETTOP (попутно установится и новое значение в @#50
- загрузить драйвер, используя сохранённое значение из 2-ого пункта
плюс в каждом пункте проверять корректность выполнения действий в пункте
Да, границы проверяются. Даже в старых SJ где много чего без всяких проверок делается.
Добавлю: предварительно сохранить старое значение и восстановить его перед переходом в точку следующего цикла программы (если программа циклическая [например просит ввода команды]) или просто обнулить @#50 перед выходом - это позволит предотвратить лишнюю дисковую активность после .EXIT.