Skip to content

Instantly share code, notes, and snippets.

@ConorOBrien-Foxx
Created September 5, 2016 19:47
Show Gist options
  • Save ConorOBrien-Foxx/ead029bf74cc58cc09bc2575eb69e9a9 to your computer and use it in GitHub Desktop.
Save ConorOBrien-Foxx/ead029bf74cc58cc09bc2575eb69e9a9 to your computer and use it in GitHub Desktop.
Z80 constant multiplication

Compile the C program like gcc <location>.c -o <location>. Call the ruby program like:

ruby gen.rb <HL initial value> <multiplier>
def input(prompt = "")
print prompt
$stdin.gets.chomp
end
def log2(n)
Math.log(n, 2)
end
def int_like(n)
n == n.to_i
end
op, ini_reg, val = ARGV
val = val.to_i
$compiled = ""
def type(str)
$compiled += str + "\n"
end
case op
when /^mul/
type "LD HL, #{ini_reg}"
# puts reg, op, val
if int_like log2 val
log2(val).to_i.times {
type "ADD HL, HL"
}
else
a, b = %x(c/pow2dif.exe #{val}).split(" ").map &:to_i
if 2**a + 2**b == val
b.times {
type "ADD HL, HL"
}
type "LD D, H"
type "LD E, L"
(a - b).times {
type "ADD HL, HL"
}
type "ADD HL, DE"
elsif 2**a - 2**b == val
(b - 1).times {
type "ADD HL, HL"
}
type "LD D, H"
type "LD E, L"
a.times {
type "ADD HL, HL"
}
type "SCF"
type "CCF"
type "SBC HL, DE"
else
lines = []
type "LD D, H"
type "LD E, L"
until val == 1
if val % 2 == 0
val /= 2
lines.push "ADD HL, HL"
else
val -= 1
lines.push "ADD HL, DE"
end
end
type lines.reverse.join "\n"
end
end
else
puts "unsupported op `#{op}`"
end
puts ".nolist
#include \"ti83plus.inc\"
#define b_call(x) bcall(x)
.list
.org $9D93
.db t2ByteTok, tAsmCmp
b_call(_ClrLCDFull)
ld hl, 0
ld (curRow), hl
#{$compiled.gsub(/^/, " " * 4)}
b_call(_DispHL)
RET
.end
.end"
#include <stdio.h>
#include <stdlib.h>
// thanks to LegionMammal978
// http://codegolf.stackexchange.com/users/33208/legionmammal978
int main(int argc, char *argv[]) {
unsigned int i0, i1;
long long num;
if (argc < 2) {
printf("Usage: %s number\n", argv[0]);
return 1;
}
num = strtoll(argv[1], NULL, 10);
i0 = 0;
while (!(num & 1)) {
num >>= 1;
i0++;
}
i1 = 0;
while (num) {
if (!(num & 1)) {
while (!(num & 1)) {
num >>= 1;
i1++;
}
break;
}
num >>= 1;
i1++;
}
printf("%u %u\n", i0 + i1, i0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment