2020/c64/math.inc

297 lines
4.2 KiB
PHP

// vim: filetype=kickass
.const square1_lo = $c000
.const square1_hi = $c200
.const square2_lo = $c400
.const square2_hi = $c600
.const pearson_table = $c800
.const tree_values_lo = $c900
.const tree_values_hi = $ca00
.const tree_left = $cb00
.const tree_right = $cc00
.const udivmod32_dividend = $10 // 11,12,13
.const udivmod32_divisor = $14 // 15,16,17
.const udivmod32_result = $18 // 19,1a,1b
.const udivmod32_remainder = $1c // 1d,1e,1f
.macro i8_div5_a() {
sta zp_temp
lsr
adc #13
adc zp_temp
ror
lsr
lsr
adc zp_temp
ror
adc zp_temp
ror
lsr
lsr
}
.macro i16_div8(lo, hi) {
lsr cursor_pointer_hi
ror cursor_pointer_lo
lsr cursor_pointer_hi
ror cursor_pointer_lo
lsr cursor_pointer_hi
ror cursor_pointer_lo
}
//
// u16_div10
//
// Divides an unsigned 16-bit integer by 10.
//
// d = n * (1 / 10)
// = floor(n * floor(65536 / 10) / 65536)
// = floor(n * 6553 / 65536)
// = floor(n * 6553 >> 16)
//
// Input:
// - $03..$04 - 16-bit unsigned value
// - Generated multiplication table
//
// Output:
// - $24..$25 - 16-bit unsigned result
//
// Destroys: a, x, $22, $23, $fd, $fe
//
.macro u16_div10() {
lda #$19
sta $fe
lda #$99
sta $fd
sec
jsr multiply_16bit_unsigned
}
// Destroys: zp_temp
.macro i8_mul5_a() {
sta zp_temp
asl
asl
clc
adc zp_temp
}
// Destroys: lo, hi
.macro i16_mul2(lo, hi) {
asl lo
rol hi
}
// Destroys: lo, hi
.macro i16_mul4(lo, hi) {
i16_mul2(lo, hi)
i16_mul2(lo, hi)
}
// Destroys: lo, hi
.macro i16_mul8(lo, hi) {
i16_mul4(lo, hi)
i16_mul2(lo, hi)
}
// Destroys: a, $fd, $fe
.macro i16_mul10(dst) {
i16_mul2(dst, dst + 1)
lda dst
sta $fd
lda dst + 1
sta $fe
i16_mul4(dst, dst + 1)
i16_i16_add(dst, $fd)
}
// Destroys: -
.macro u32_mul2(lsb) {
asl lsb + 0
rol lsb + 1
rol lsb + 2
rol lsb + 3
}
// Destroys: a
.macro u32_mul10(lsb) {
u32_mul2(lsb)
lda lsb + 0
sta $2c + 0
lda lsb + 1
sta $2c + 1
lda lsb + 2
sta $2c + 2
lda lsb + 3
sta $2c + 3
u32_mul2(lsb)
u32_mul2(lsb)
i32_i32_add(lsb, $2c)
}
// Destroys: a
.macro i32_i16_add(dst, src) {
clc
lda dst + 0
adc src + 0
sta dst + 0
lda dst + 1
adc src + 1
sta dst + 1
bcc !+
inc dst + 2
!:
}
// Destroys: a
.macro i32_i32_add(dst, src) {
clc
lda dst + 0
adc src + 0
sta dst + 0
lda dst + 1
adc src + 1
sta dst + 1
lda dst + 2
adc src + 2
sta dst + 2
lda dst + 3
adc src + 3
sta dst + 3
}
// Destroys: a
.macro i16_i8_add_a(dst) {
clc
adc dst
sta dst
bcc !cc+
inc dst + 1
!cc:
}
.macro i32_add_a(dst) {
clc
adc dst
sta dst
bcc done
inc dst + 1
bne done
inc dst + 2
bne done
inc dst + 3
bne done
done:
// Everyday I'm rippling
}
// Destroys: a
.macro i16_i16_add(dst, src) {
clc
lda dst
adc src
sta dst
lda dst + 1
adc src + 1
sta dst + 1
}
// Destroys: a
.macro i16_inc(dst) {
lda #1
i16_i8_add_a(dst)
}
.macro y_buf_inc(buffer) {
iny
bne !+
inc buffer + 1
!:
}
// Destroys: a
.macro y_buf_dec(buffer) {
tya
bne !+
dec buffer + 1
!:
dey
}
// Destroys: a
.macro i16_i16_sub_imm(dst_lo, dst_hi, src_lo, src_hi, imm) {
sec
lda src_lo
sbc #<imm
sta dst_lo
lda src_hi
sbc #>imm
sta dst_hi
}
// Destroys: a
.macro i16_i16_sub(dst_lo, dst_hi, a_lo, a_hi, b_lo, b_hi) {
sec
lda a_lo
sbc b_lo
sta dst_lo
lda a_hi
sbc b_hi
sta dst_hi
}
.macro i16_imm_i16_sub(dst, imm, src) {
lda src
eor #$ff
sec
adc #<imm
sta dst
lda src + 1
eor #$ff
adc #>imm
sta dst + 1
}
.macro i16_i16_cmp_bne(a, b, target) {
lda a
cmp b
bne target
lda a + 1
cmp b + 1
bne target
}
.macro i32_i32_move(dst, src) {
lda dst + 0; sta dst + 0
lda dst + 1; sta dst + 1
lda dst + 2; sta dst + 2
lda dst + 3; sta dst + 3
}
.macro pearson_hash(dst, buffer) {
lda #0
sta dst
loop:
lda buffer, y
beq end
eor dst
tax
lda pearson_table, x
sta dst
jmp loop
end:
}