Преобразование 16-разрядного целого числа без знака из HL в текст с использованием моей собственной не-ASCII-карты в виде десятичной дроби с использованием сборки LR35902
Мне нужно выяснить, как создать подпрограмму для LR35902 (процессор, похожий на Z80, похожий на Game Boy), который будет брать содержимое HL (а не то, куда оно указывает, фактическое число, хранящееся в нем) и преобразовывать его в 1 к 5. (фактические значения будут в диапазоне от 0 до 65 535, поскольку HL является 16-разрядным) не-ASCII* символы с использованием десятичной системы. У меня есть процедуры для печати, и я могу легко найти способ обрезать ведущие нули.
Все, что мне нужно, - это, по крайней мере, какой-то псевдокод для этой функции и, самое большее, настоящая процедура RGBDS LR35902 ASM.
* Вместо ASCII я использую свою собственную 1-байтовую символьную карту, в которой символ 0 равен шестнадцатеричному байту 17 $, увеличиваясь до 9, что составляет 20 $.
3 ответа
Как перевести секунды в базу 60 (часы, минуты, секунды)? 1234 секунды для примера
разделите 1234 на 3600 (60^2), чтобы получить часы, равные нулю 1234
разделите остаток 1234 на 60 (60^1), чтобы получить минуты, которые составляют остаток 20 минут 34
разделите остаток 34 на 1 (60^0), чтобы получить секунды, которые равны 34
Таким образом, 1234 секунды база 10, преобразованная в базу 60 (ЧЧ: ММ: СС), равна 00:20:34.
Не имеет значения, какие основания являются преобразованиями, то же самое, если только одно основание не является степенью другого основания (двоичное в шестнадцатеричное, шестнадцатеричное в двоичное, двоичное в восьмеричное, восьмеричное в двоичное), тогда вы можете использовать ярлыки.
Вы переходите от базы 2 к базе 10, а затем после этого вы можете использовать ASCII или любое другое представление для базовых 10 цифр.
Этот вопрос задавался здесь сотни раз. Следующий вопрос о том, как разделить на 10, если ваш процессор не имеет деления. Также спросил и ответил много раз.
Преобразование из цифр в ваше отображаемое представление на вас, нам нужно будет просмотреть всю таблицу, поскольку у вас есть только 10 цифр, с которыми вы можете справиться, если ничего другого не сделать, просто посмотрите таблицу.
Бонусные предварительные процедуры для преобразования количества очков HL или числа в A включены.
Это работает, это только вопрос обрезания ведущих нулей.
ConvertNumberHLPoint::
ld a, [hl]
ConvertNumberA::
ld h, 0
ld l, a
ConvertNumberHL::
; Get the number in hl as text in de
ld bc, -10000
call .one
ld bc, -1000
call .one
ld bc, -100
call .one
ld bc, -10
call .one
ld c, -1
.one
ld a, "0"-1
.two
inc a
add hl, bc
jr c, .two
push bc;
push af;
ld a, b;
cpl;
ld b, a;
ld a, c;
cpl;
ld c, a;
inc bc;
call c, .carry;
pop af;
add hl, bc;
pop bc;
ld [de], a
inc de
ret
.carry;
dec bc;
ret;
Если бы на LR35902 был такой код операции, как sbc hl, bc, как на Z80, можно было бы заменить строки, заканчивающиеся пустыми комментариями: ;
-- с этим. Вместо этого мы резервируем bc и af, инвертируем bc и увеличиваем его (дополняем два), затем, ради функции переноса в инструкции SBC, увеличиваем его снова, если перенос установлен, затем отменим резервное копирование af, добавляем hl к два дополняется до нашей эры, и, наконец, не резервное копирование до н.э
Эта процедура преобразует значение из HL в его представление ASCII, начиная с ячейки памяти, указывающей DE, в десятичной форме и с завершающими нулями, поэтому длина всегда будет 5 символов. Он был адаптирован из этого источника: http://map.grauw.nl/sources/external/z80bits.html#5.1 .
reg2ascdec: ld bc,55536
call OneDigit
ld bc,64536
call OneDigit
ld bc,65436
call OneDigit
ld c,-10
call OneDigit
ld c,b
OneDigit: ld a,47 ;replace with $16 (for $17-$20)
DivideMe: inc a
add hl,bc
jr c,DivideMe
sbc hl,bc
ld (de),a
inc de
ret