Mother2GbaTranslation/m2-formatting.asm

276 lines
4.4 KiB
NASM

m2_formatting:
//==============================================================================
// http://en.wikipedia.org/wiki/Double_dabble
// int bin_to_bcd(int binary)
// In:
// r0: binary number
// Out:
// r0: BCD-coded number
// r1: amount of digits used
//==============================================================================
.bin_to_bcd:
push {r2-r7,lr}
mov r2,r8
mov r3,r9
push {r2-r3}
lsl r0,r0,#5
mov r1,#0
mov r3,#27
mov r4,#3
lsl r4,r4,#8
lsl r5,r4,#4
lsl r6,r5,#4
lsl r7,r6,#12
mov r9,r7
lsl r7,r6,#8
mov r8,r7
lsl r7,r6,#4
//--------------------------------
-
// Ones
lsl r2,r1,#28
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r1,#3
+
// Tens
lsl r2,r1,#24
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,#0x30
+
// Hundreds
lsl r2,r1,#20
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r1,r4
+
// Thousands
lsl r2,r1,#16
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r1,r5
+
// Ten-thousands
lsl r2,r1,#12
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r1,r6
+
// Hundred-thousands
lsl r2,r1,#8
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r1,r7
+
// Millions
lsl r2,r1,#4
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r8
+
// Ten-millions
lsr r2,r2,#28
cmp r2,#5
bcc +
add r1,r9
+
// Shift
lsl r1,r1,#1
tst r0,r0
bpl +
add r1,r1,#1
+
lsl r0,r0,#1
sub r3,r3,#1
bne -
mov r0,r1
//--------------------------------
// Check how many digits are used
mov r3,#1
-
lsr r1,r1,#4
beq +
add r3,r3,#1
b -
+
//--------------------------------
mov r1,r3
pop {r2-r3}
mov r8,r2
mov r9,r3
pop {r2-r7,pc}
//==============================================================================
// int bcd_to_bin(int bcd)
// In:
// r0: BCD-coded number
// Out:
// r0: binary number
//==============================================================================
.bcd_to_bin:
push {r1-r4,lr}
mov r1,#0
mov r2,#10
mov r3,#1
//--------------------------------
// Ones
lsl r4,r0,#28
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Tens
lsl r4,r0,#24
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Hundreds
lsl r4,r0,#20
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Thousands
lsl r4,r0,#16
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Ten-thousands
lsl r4,r0,#12
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Hundred-thousands
lsl r4,r0,#8
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Millions
lsl r4,r0,#4
lsr r4,r4,#28
mul r4,r3
add r1,r1,r4
mul r3,r2
// Ten-millions
lsr r4,r0,#28
mul r4,r3
add r1,r1,r4
//--------------------------------
mov r0,r1
pop {r1-r4,pc}
//==============================================================================
// ushort format_cash(int amount, char* output, int digits)
// In:
// r0: amount
// r1: output string
// r2: digits
// Out:
// r0: = digits - (digits rendered) - 1
//==============================================================================
.format_cash:
push {r1-r7,lr}
mov r4,r1
mov r6,r2
//--------------------------------
// Figure out how many digits we need
bl .bin_to_bcd
mov r5,r1
mov r7,r1
// The window is 56 pixels wide:
// each digit uses 6 pixels, the $ sign uses 6, and the
// double-zero uses 8
mov r2,#42 // = 56 - 6 - 8
lsl r3,r1,#2
add r3,r3,r1
add r1,r1,r3 // r1 *= 6
sub r1,r2,r1 // r1 = 42 - r1
// Store the control code to the output
mov r2,#0x5F
strb r2,[r4,#0]
mov r2,#0xFF
strb r2,[r4,#1]
strb r1,[r4,#2]
// Store the dollar sign
mov r2,#0x54
strb r2,[r4,#3]
add r4,r4,#4
// Store the digits to the output
mov r2,#8
sub r2,r2,r5
lsl r2,r2,#2
lsl r0,r2 // Now the number is pushed to the left of the register
-
lsr r1,r0,#28 // Get the left-most digit
add r1,#0x60 // Integer-to-char
strb r1,[r4,#0]
add r4,r4,#1
lsl r0,r0,#4
sub r5,r5,#1
bne -
// Store the double-zero sign
mov r1,#0x56
strb r1,[r4,#0]
// Store the end code
mov r1,#0
strb r1,[r4,#1]
mov r1,#0xFF
strb r1,[r4,#2]
//--------------------------------
sub r5,r6,r7
sub r0,r5,#1
pop {r1-r7,pc}