Господа, знаю, что тема замусоленная и многократно поднималась много где, в т.ч. и в прессе. Это "по мотивам" процедуры Сержа Колотова, претендует на высокую эффективность. Но, видя чудеса кодинга, вполне верю в конструктивную критику. :-) Критикуем, господа. Вывод делается средствами ПЗУ.
Код:
/*--------------------------------- Cut here ---------------------------------*/
void Basic_PRCHAR_ROM (unsigned char ch) __z88dk_fastcall {
__asm
LD IY,#0x5C3A
LD A,L
EX AF,AF
LD A,#2
CALL 0x1601
EX AF,AF
RST 0x10
__endasm;
} //Basic_PRCHAR_ROM
/*--------------------------------- Cut here ---------------------------------*/
void Basic_PRWORD_ROM (unsigned int n) __naked __z88dk_fastcall {
__asm
LD IY,#0x5C3A
/* Из журнала Deja Vu #04, Кемерово, 01.04.98
(c) Колотов Сеpгей, г.Шадpинск, SerzhSoft
Доработано для печати только значащих цифр */
;----------------------------------------;
;Печать десятичного числа в HL (0..65535)
;----------------------------------------;
PUSH HL ;закинули печатаемое число на стек
LD A,#2 ;открываем канал 2
CALL #0x1601 ;(печать в области основного экрана)
LD HL,#DECTB_W$ ;адрес таблицы степеней десятки
LD BC,#0x505 ;макс. возможное количество цифр: 5
;установим также рег. C - кол-во незначащих нулей + 1
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
DEC C ;проверяем: может это незначащий нуль?
JR Z,LP_PRNT$ ; если уже были другие цифры, печатаем
DEC A ;если это нуль, то он незначащий
JR Z,LP_NOPR$ ; ничего не печатаем
INC A ;это не нуль, увеличим на 1 для печати
LP_PRNT$: ADD A,#"0"-1 ;перевод A в ASCII-код ("0".."9")
RST 0x10 ;печать десятичной цифры
LD C,#1 ;уже была печать, дальше все значащие
LP_NOPR$: EX (SP),HL ;HL=адрес эл-та, число -> на стек
DJNZ LP_PDW1$ ;цикл по цифрам
POP HL ;убрали оставшийся ноль со стека
RET ;выход из процедуры
;----------------------------------------;
DECTB_W$: .DW 10000,1000,100,10,1 ;Таблица степеней десятки;
;----------------------------------------;
__endasm;
} //Basic_PRWORD_ROM
/*--------------------------------- Cut here ---------------------------------*/
void Basic_PRINT_ROM (int n) __naked __z88dk_fastcall {
__asm
BIT 7,H
JP Z,_Basic_PRWORD_ROM
EX DE,HL
XOR A
LD L,A
LD H,A
SBC HL,DE
PUSH HL
LD L,#0x2D
CALL _Basic_PRCHAR_ROM
JP _Basic_PRWORD_ROM+10
__endasm;
} //Basic_PRINT_ROM
P.S. Зависимость Basic_PRINT_ROM от Basic_PRCHAR_ROM не критикуем, прямой вставкой не заменяем. Так задумано ;-)