/* my code example */ ;----------------------------------------; ;Printing in Different Evaluation Systems; ; LIBrary v2.0 ; ; (c) SerzhSoft, Shadrinsk, august, 1997 ; ;----------------------------------------; _NULL EQU 0 ;Используется в изменяемых командах ;----------------------------------------; ; print in DEC system: ; ;----------------------------------------; PDEC_3B ;Печать десятичного числа в AHL (00000000..16777215) LD DE,34464 ;DE=100000-65536 LD BC,#FF01 ;B=-1 - счетчик сотен тысяч; С=1 LP_PD31 INC B ;увеличиваем счетчик сотен тысяч AND A ;сбрасываем флаг переноса для SUB SBC HL,DE ;уменьшаем трехбайтное число AHL SBC A,C ;на одну сотню тысяч JR NC,LP_PD31 ;повторяем пока нет переполнения ADD HL,DE ;восстанавливаем положительное ADC A,C ;значение у AHL; AHL<100000 PUSH AF ;сохраняем на стеке нужные нам PUSH HL ;впоследствии регистры A, HL LD A,B ;количество сотен тысяч в числе CALL PDEC_B ;печатаем это значение POP HL ;восстанавливаем со стека POP AF ;регистры A, HL DEC A ;если остаток<65536, JR NZ,PDEC_W ;то переходим на печать 0..65535 LD DE,5536 ;иначе - число 65536..99999 ADD HL,DE ;прибавляем остаток от десятков ADC A,B ;тысяч, и их сами - отдельно PUSH HL ;------------------------------------ LD HL,DECTB_W ;Обходимый фрагмент процедуры PDEC_W LD B,#05 ;------------------------------------ JR LP_PDW1+1 ;прыжок через обнуление десятков тысяч ;--------------------------------------------------------------------- PDEC_B ;Печать десятичного числа в A (000..255) LD L,A ;поместили LD H,#00 ; число в HL PUSH HL ;закинули печатаемое число на стек LD HL,DECTB_W+4 ;адрес в таблице, начиная с сотни LD B,#03 ;максимальное возможное количество цифр - три JR LP_PDW1 ;переход на цикл печати ;--------------------------------------------------------------------- PDEC_W ;Печать десятичного числа в HL (00000..65535) PUSH HL ;закинули печатаемое число на стек LD HL,DECTB_W ;адрес таблицы степеней десятки LD B,#05 ;максимальное возможное количество цифр LP_PDW1 XOR A ;обнулили счетчик и флаг C для SBC LD E,(HL) ;взяли текущую степень INC HL ; десятки из таблицы LD D,(HL) ; и поместили в DE INC HL ;перешли к следующему элементу таблицы EX (SP),HL ;адрес элемента <-> печатаемое число LP_PDW2 INC A ;увеличиваем счетчик SBC HL,DE ;вычитаем текущую степень десятки JR NC,LP_PDW2 ;повторяем пока HL>=0 ADD HL,DE ;HL=HL mod DE; A=HL div DE ADD A,"0"-1 ;перевод A в ASCII-код ("0".."9") RST #10 ;печать десятичной цифры EX (SP),HL ;HL=адрес элемента, число -> на стек DJNZ LP_PDW1 ;цикл по цифрам POP HL ;убрали оставшийся ноль со стека RET ;выход из процедуры ;--------------------------------------------------------------------- DECTB_W DW 10000,1000,100,10,1 ;Таблица степеней десятки ;----------------------------------------; ; print in HEX system: ; ;----------------------------------------; PHEX_W ;Печать шестнадцатиричного числа в HL (0000..FFFF) LD A,H ;печать старшего байта числа CALL PHEX_B ;вызов процедуры HEX-печати байта LD A,L ;печать младшего байта числа ;--------------------------------------------------------------------- PHEX_B ;Печать шестнадцатиричного числа в A (00..FF) CALL PHEX_HB ;печатать по полубайтам ;--------------------------------------------------------------------- PHEX_HB ;Печать старшего полубайта в A (0..F) RRCA ;меняем RRCA ; местами RRCA ; старший RRCA ; и младший полубайты ;--------------------------------------------------------------------- PHEX_LB ;Печать младшего полубайта в A (0..F) PUSH AF ;сохранили A на стеке AND #0F ;отбросили лишние старшие биты CP #0A ;если A<10, JR C,GO_PHL ; то перепрыгнули ADD A,"A"-"9"-1 ;корректировка: после "9" идет "A" GO_PHL ADD A,"0" ;перевод в ASCII-код RST #10 ;печать HEX-цифры ("0".."F") POP AF ;восстановили A со стека RET ;выход из процедуры ;----------------------------------------; ; print in BIN system: ; ;----------------------------------------; PBIN_W ;Печать двоичного числа в HL (16 разрядов 0/1) LD A,H ;печть старшего байта числа CALL PBIN_B ;вызов процедуры BIN-печати байта LD A,L ;печть младшего байта числа ;--------------------------------------------------------------------- PBIN_B ;Печать двоичного числа в A (8 рязрядов 0/1) LD B,#08 ;в байте - 8 битов LP_PBB RLCA ;поочередно 'выдвигаем' биты в CF PUSH AF ;сохранить A на стеке LD A,#18 ;в зависимости от флага C: RLA ;A="0" или A="1" RST #10 ;печать очередного бита POP AF ;восстановить A со стека DJNZ LP_PBB ;поразрядный цикл RET ;выход из процедуры ;----------------------------------------; ; print in USER system: ; ;----------------------------------------; PUSE_W ;Печать числа в установленной MKUSETB системе счисления в HL PUSH HL ;закинули печатаемое число на стек HL_PUW LD HL,_NULL ;адрес конца таблицы степеней LP_PUW1 DEC HL ;загружаем в DE очередную LD D,(HL) ; степень числа DEC HL ; из таблицы LD E,(HL) ; двигаясь сверху-вниз EX (SP),HL ;адрес таблицы <-> печатаемое число XOR A ;обнуление A и сброс флага C LP_PUW2 INC A ;вычисляем очередной SBC HL,DE ; разряд числа и результат JR NC,LP_PUW2 ; помещаем в A (A=1+(HL div DE)) ADD HL,DE ;восстанавливаем положительное значение ADD A,"0"-1 ;переводим A в ASCII-код CP "9"+1 ;если код меньше "9", JR C,GO_PUW1 ; то переход на печать ADD A,"A"-"9"-1 ;коррекция (после "9" идет "A") GO_PUW1 RST #10 ;печать очередной цифры числа EX (SP),HL ;HL=адрес таблицы, число -> стек DEC DE ;если степень LD A,D ; числа не равна единице OR E ; (самый первый элемент таблицы), JR NZ,LP_PUW1 ; то продолжаем работу POP HL ;убираем со стека ненужный 0 RET ;выход из процедуры ;--------------------------------------------------------------------- MKUSETB ;Создание таблицы степеней с основанием в A LD HL,USE_TBL ;адрес создаваемой таблицы LD DE,#0001 ;инициализация счетчика степени LP_MUT1 LD (HL),E ;запись текущего INC HL ; значения степени LD (HL),D ; в таблицу и переход INC HL ; к ее следующей ячейке PUSH HL ;сохраняем адрес на стеке LD B,A ;основание степени -> в счетчик цикла LD HL,#0000 ;обнуление результата LP_MUT2 ADD HL,DE ;подсчитываем результат JR C,GO_MUT ;если HL>65535, то прерываем счет DJNZ LP_MUT2 ;повторяем <основание> раз EX DE,HL ;результат - в DE (новая степень) GO_MUT POP HL ;восстанавливаем адрес таблицы JR NC,LP_MUT1 ;если не прерывались, то повторяем LD (HL_PUW+1),HL ;адрес конца таблицы -> в PUSE_W RET ;выход из процедуры ;--------------------------------------------------------------------- USE_TBL DS 32 ;Таблица степеней текущей системы счисления ;----------------------------------------; ; print in RIM system: ; ;----------------------------------------; PRIM_B ;Печать числа в римской записи в A (I..CCLV) LD L,A ;скопировать LD H,#00 ; A в HL ;--------------------------------------------------------------------- PRIM_W ;Печать числа в римской записи в HL (I..MMMCMXCIX) PUSH HL ;закинули печатаемое число на стек LD HL,RIM_TBL ;адрес таблицы знаков DB #DD ;работаем с половинкой регистра IX LD L,#07 ;LD XL, число знаков в римском счислении LP_PRW1 LD E,(HL) ;считываем из таблицы значение INC HL ; очередного знака римской системы LD D,(HL) ; счисления и помещаем в DE INC HL ;затем в регистр C считываем LD C,(HL) ; ASCII-код знака INC HL ;переход к следующему знаку LD (HL_PRW+1),HL ;сохранили адрес следующего знака EX (SP),HL ;адрес -> на стек, HL=печатаемое число XOR A ;обнуление счетчика и сброс CF LP_PRW2 INC A ;в цикле производим SBC HL,DE ; деление HL на DE (вычитаем, JR NC,LP_PRW2 ; пока нет переполнения) ADD HL,DE ;восстанавливаем положительное значение DEC A ;т.к. A на 1 больше HL div DE, JR Z,GO_PRW1 ; то если A=1 - ничего не печатаем LD B,A ;количество печатаемых символов LP_PRW3 LD A,C ;код знака RST #10 ;печатаем его DJNZ LP_PRW3 ;сколько надо - столько и печатаем GO_PRW1 DB #DD ;работаем с половинкой регистра IX LD A,L ;LD A,XL - номер текущего знака DEC A ;если это последний знак (I), то JR Z,GO_PRW4 ; двухбуквенного сочетания нет EX (SP),HL ;HL=адрес следующего знака, число -> стек RRA ;если номер текущего знака четный, JR C,GO_PRW2 ; то сочетание с следующим знаком, INC HL ; иначе - перепрыгнуть через один INC HL ; знак. В результате получим адрес INC HL ; знака, для получения двойного GO_PRW2 LD A,C ; знакосочетания (IV, CM, XL...) LD C,(HL) ; взяли из таблицы значение для INC HL ; этого знака и получили LD B,(HL) ; разность между значением INC HL ; основного и этим значением. EX DE,HL ; Например, для основного знака X AND A ; дополнительным будет I, а их SBC HL,BC ; разность соответственно: EX DE,HL ; 10-1=9, т.е. IX LD C,A ;код основного знака LD A,(HL) ;код дополнительного знака EX (SP),HL ;HL=печатаемое число SBC HL,DE ;если оно < дополнительного JR C,GO_PRW3 ; значения, то не печатаем RST #10 ;печать дополнительного знака LD A,C ;основной знак RST #10 ;печать JR GO_PRW4 ;результат - двухбуквенное сочетание GO_PRW3 ADD HL,DE ;восстановили (+) у числа GO_PRW4 EX (SP),HL ;число -> на стек HL_PRW LD HL,_NULL ;адрес следующего знака в таблице DB #DD ;работаем с половинкой регистра IX DEC L ;DEC XL - уменьшаем счетчик знаков JR NZ,LP_PRW1 ;крутим цикл пока есть еще знаки POP HL ;сняли ненужный уже ноль со стека RET ;выход из процедуры ;--------------------------------------------------------------------- RIM_TBL ;Таблица значимости букв в написании римских чисел DW 1000 DB "M" ;M=1000 ;CM=900 DW 500 DB "D" ;D=500 ;CD=400 DW 100 DB "C" ;C=100 ;XC=90 DW 50 DB "L" ;L=50 ;XL=40 DW 10 DB "X" ;X=10 ;IX=9 DW 5 DB "V" ;V=5 ;IV=4 DW 1 DB "I" ;I=1 ;-nop- ;----------------------------------------; ; end of PDES LIB 2.0 ; ;----------------------------------------;