Вот так правильней ;)
Вид для печати
А теперь классика:
Код:;+
;
; CVBTOD
; Converts the binary value passed in R0 to a string of
; ascii characters which is the decimal equivalent and
; places them in the buffer pointed to by R1
;
; CALL:
; R0 = 16-bit number
; R1 -> conversion buffer
;
; RETURNS:
; R0 = 0
; R1 -> byte following last digit in converted number
;
;-
CVBTOD: MOV R0,-(SP) ;SAVE THE NUMBER PASSED TO US
CLR R0 ;SET FOR CRUDE DIVIDE BY 10.
10$: INC R0 ;BUMP QUOTIENT
SUB #10.,(SP) ;REDUCE NUMBER BY 10.
BHIS 10$ ;IF SIGN DIDN'T CHANGE...
ADD #10.+60,(SP) ;MAKE REMAINDER PRINTABLE
DEC R0 ;REDUCE QUOTIENT
BEQ 20$ ;IF ZERO, TIME TO PRINT
CALL CVBTOD ;OTHERWISE, RECURSE !
20$: MOVB (SP)+,(R1)+ ;STORE A CONVERTED DIGIT
RETURN ;UNWIND THE RECURSION
Со счётом 40:34 победил автор из DEC (и это я ещё не засчитал буфер и не возможность разместить в ПЗУ)Код:
TEST MACRO V05.06R Tuesday 04-Jun-19 Page 1
11
12 000000 .PSECT A1
13 ; Decimal by Manwe
14 ; input: R0 - number to print
15 ; output: R1 - pointer to text string
16
17 000000 012701 000046' DECIM: MOV #NUMBER,R1 ; pointer to output text string
18 000004 105041 CLRB -(R1) ; end of text marker
19 000006 012704 000012 MOV #10.,R4
20 000012 012705 177777 10$: MOV #-1.,R5
21 000016 005205 20$: INC R5 ; counter of 10s
22 000020 160400 SUB R4,R0
23 000022 103375 BHIS 20$ ; branch if higher or same
24 000024 062700 000072 ADD #72,R0 ; #10. + '0' ASCII code
25 000030 110041 MOVB R0,-(R1) ; store R0 to text string
26 000032 010500 MOV R5,R0 ; let's count next how many 10s in number of 10s
27 000034 001366 BNE 10$
28 000036 000207 RETURN ; returns text string pointer in R1
29
30 000040 .BLKB 6
31 000046 NUMBER:
32
33 000000 .PSECT A2
34 000000 010046 CVBTOD: MOV R0,-(SP) ;SAVE THE NUMBER PASSED TO US
35 000002 005000 CLR R0 ;SET FOR CRUDE DIVIDE BY 10.
36 000004 005200 10$: INC R0 ;BUMP QUOTIENT
37 000006 162716 000012 SUB #10.,(SP) ;REDUCE NUMBER BY 10.
38 000012 103374 BHIS 10$ ;IF SIGN DIDN'T CHANGE...
39 000014 062716 000072 ADD #10.+60,(SP) ;MAKE REMAINDER PRINTABLE
40 000020 005300 DEC R0 ;REDUCE QUOTIENT
41 000022 001402 BEQ 20$ ;IF ZERO, TIME TO PRINT
42 000024 004767 177750 CALL CVBTOD ;OTHERWISE, RECURSE !
43 000030 112621 20$: MOVB (SP)+,(R1)+ ;STORE A CONVERTED DIGIT
44 000032 000207 RETURN
- - - Добавлено - - -
Как видно, в DEC знали про этот подход или у них был свой Дженсен ;)
Для комплекта ещё - вариант из Stop the Express для MS-0515.
Но на самом деле тут в конце приписан ещё лишний нолик, потому что выводятся заработанные очки.
Точку входа Z34420 можно использовать для печати 3-значного числа.
Код:; Подпрограмма: Печать 5-значного десятичного числа; R3=число
Z34400: MOV #023420, R2 ; 10000.
Z34404: CALL Z34454 ;
Z34410: MOV #001750, R2 ; 1000.
Z34414: CALL Z34454 ;
Z34420: MOV #000144, R2 ; 100.
Z34424: CALL Z34454 ;
Z34430: MOV #000012, R2 ; 10.
Z34434: CALL Z34454 ;
Z34440: ADD #000060, R3 ; '0'
Z34444: MOVB R3, (R1)+ ;
Z34446: MOVB #000060, (R1)+ ;
Z34452: RETURN ;
Z34454: MOV #000060, R0 ; '0'
Z34460: SUB R2, R3 ;
Z34462: BLO Z34470 ;
Z34464: INC R0 ;
Z34466: BR Z34460 ;
Z34470: ADD R2, R3 ;
Z34472: MOVB R0, (R1)+ ; копируем в экран план
Z34474: RETURN
Кто запустил УКНЦшников в тему БК-0010?!!
:)
А в чём "невозможность" размещения в ПЗУ? Буфер текстовой строки - это любое место в ОЗУ.
И зачем было считать за часть программы занесение адреса текстового буфера в R1, если в другой программе он не считается?
Ещё они не заносят в текстовый буфер символ конца строки (0). Если из моей программы убрать и это, она станет на одно слово короче DECовской. Тогда получится 13:14 в мою пользу!
:)
Так-то идея с рекурсией прикольная, респект. Но с практической точки зрения там много операций со стеком, что сказывается на производительности. Этот алгоритм и без того тормозной, так ещё и усугублять постоянными обращениями к (SP)... Наверное, целью было сэкономить регистры любой ценой.Код:; Decimal by Manwe
; input: R0 - number to print
; R1 - pointer to text buffer + 6
; output: R1 - pointer to the text to print
DECIM: CLRB -(R1) ; end of text marker
MOV #10.,R4
1: MOV #-1.,R5
2: INC R5 ; counter of 10s
SUB R4,R0
BHIS 2 ; branch if higher or same
ADD #72,R0 ; #10. + '0' ASCII code
MOVB R0,-(R1) ; store R0 to text string
MOV R5,R0 ; let's count next how many 10s in number of 10s
BNE 1
RET ; returns text string pointer in R1
Естественно, "в DEC был свой Дженсен" - несколько хакеров из MIT перешли на работу в DEC. Собственно, они повлияли на само становление архитектуры PDP-1.
Вариант из Stop the Express занимает 31 слово (в десятичной системе счисления).
Я делал быстрый (без CALLов) вариант со степенями 10. Из полезного: не печатает лидирующие нули, добавляет в конец символ конца строки.
Размер 25 слов:
Код:; Fast DECIMAL by Manwe
; input: R0 - number
; R1 - pointer to output text string
DECIM: MOV #TEN,R5 ; table address
1: CMP (R5)+,R0 ; skip leading zeros
BHI 1 ; branch if higher, for 16-bit not signed
MOV -(R5),R3
BEQ 4 ; if less then 10
2: MOV #57,R4 ; 0 symbol in ASCII codepage - 1
3: INC R4 ; count digits
SUB R3,R0
BHIS 3 ; branch if higher or same, for 16-bit not signed
MOVB R4,(R1)+ ; print R4
ADD (R5)+,R0
MOV (R5),R3
BNE 2
4: ADD #60,R0 ; 0 symbol in ASCII codepage
MOVB R0,(R1)+ ; print R0
CLRB (R1) ; write end marker of the text string
RET
TEN: .WORD 10000.,1000.,100.,10.,0
Не нашёл более подходящей темы, спрошу здесь.
При обращении к адресу @#167776 БК-0011М вылетает на середине команды. По адресам 160000-177777 находится область регистров внешних устройств и конкретно по адресу 167776 в данный момент ничего не подключено (обычно бывает подключён контроллер СМК и в этой ячейке памяти записана версия контроллера).
Действительно ли БК должна прерываться по 4-ому вектору при обращении к адресу 167776?
Касается ли это только БК-0011М, или также БК-0010?
Известны ли какие-то ещё устройства, использующие порт 167776?
Заранее спасибо.
Адрес существует всегда! но по нему могут не отвечать. Или никто не живет или разговаривать не хотят. А могут только читать а писать нет!
Для БК страница ввода-вывода определена в документации 177600-177776 и называется областью системных регистров. В этом одно из несоответствий архитектуре PDP-11
Код:1. Конфигурация без расширенной памяти.
0 ------------------------------
! Область стека и системных !
! переменных !
1000 ------------------------------
! ОЗУ пользователя !
40000 ------------------------------
! ОЗУ экрана !
100000 ------------------------------
! Системное ПЗУ !
120000 ------------------------------
! Сменное (съемное) !
! ПЗУ (Фокал) !
140000 ------------------------------
! Сменное ПЗУ !
160000 ------------------------------
! Сменное системное ПЗУ !
177600 ------------------------------
! Область системных !
! регистров !
177777 ------------------------------
2. Конфигурация с расширенной памятью.
0 ------------------------------
! Область стека и системных !
! переменных !
1000 ------------------------------
! ОЗУ пользователя !
40000 ------------------------------
! ОЗУ пользователя или !
! экрана !
70000 ------------------------------
! ОЗУ экрана !
100000 ------------------------------
! Системное ПЗУ (монитор и !
! драйверы) !
120000 ------------------------------
! ПЗУ-интерпретатор Фокала !
140000 ------------------------------
! ПЗУ резервное !
160000 ------------------------------
! ПЗУ. тесты !
177600 ------------------------------
! Область системных !
! регистров !
177777 ------------------------------
Адрес, при обращении по которому в течении 15 мкс не прилетел BRPLY L
Ну, строго говоря, в архитектуре PDP-11 нигде не постулируется, что в старших 8 кб адресного пространства располагается страница в/в или что там обязательно только регистры внешних устройств. Более точный вариант для PDP - сигнал BBS7 L, хотя и это - не постулат. Но если требуется работа ОС от DEC без необходимости модификации - это до некоторой степени предполагается. Хотя более точный вариант (но тоже не постулат) - по адресам 177560-177566 - регистры адаптера подключения консольного терминала плюс по некоторым адреса (не обязательно на странице в/в) ПЗУ с по крайне мере начальным загрузчиком (или ввод его тем или иным способом) плюс по некоторым адресам (не обязательно на странице в/в) регистров устройства, откуда пойдёт начальная загрузка некоей системы. Но это не обязательно, особенно в варианте с прошитым в ПЗУ софтом.