0

我需要弄清楚如何为 LR35902(Game Boy 的类似 Z80 的 CPU)制作一个例程,它将获取 HL 的内容(不是它指向的位置,存储在其中的实际数字)并将其转换为 1 到 5 (实际值范围从 0 到 65,535,因为 HL 是 16 位)使用十进制系统的非 ASCII* 字符。我有要打印的例程,并且可以很容易地找到一种裁剪前导零的方法。

我所需要的只是这个函数的至少一些伪代码和一个实际的RGBDS LR35902 ASM 例程。

*我使用自己的 1-byte-per-character charmap 代替 ASCII,其中字符 0 是十六进制字节 $17,一直增加到 9,即 $20。

4

2 回答 2

2

如何将秒数转换为以 60 为底(时分秒)?例如 1234 秒

将 1234 除以 3600 (60^2) 得到小时数,余数为零 1234

将余数 1234 除以 60 (60^1) 得到分钟,即 20 分钟余数 34

将余数 34 除以 1 (60^0) 得到秒数,即 34

所以 1234 秒 base 10 转换为 base 60 (HH:MM:SS) 是 00:20:34

不管基数是什么转换都是相同的,除非一个基数是另一个基数的幂(二进制到十六进制,十六进制到二进制,二进制到八进制,八进制到二进制)然后你可以走捷径。

您将从以 2 为基数到以 10 为基数,然后您可以使用 ASCII 或任何其他表示以 10 为基数的数字。

这个问题在这里被问了数百次。如果你的处理器没有除法,我如何除以 10 的下一个问题。也问了很多次,也回答了很多次。

从数字到您的显示表示的转换由您完成,我们需要查看整个表格,因为您只有 10 位数字需要处理,如果没有其他操作,只需查找表格即可。

于 2016-07-29T20:37:22.577 回答
1

将 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 添加到two 的补码 bc,最后取消备份 bc。

于 2016-07-30T07:57:59.263 回答