150 lines
2.6 KiB
ArmAsm
150 lines
2.6 KiB
ArmAsm
.global _start
|
|
_start:
|
|
mova stack_top,r0
|
|
mov r0,r15
|
|
|
|
_input:
|
|
mov.l start,r8
|
|
mov.l size,r9
|
|
|
|
/* returns stride in r1 */
|
|
mov.l input_stride_ptr,r0
|
|
jsr @r0
|
|
mov r8,r1 /* r1 arg: copy of r8 */
|
|
|
|
mov r1,r10 /* r10: stride */
|
|
|
|
/* part 1 */
|
|
mov #3,r13 /* right 3 */
|
|
mov #1,r14 /* down 1 */
|
|
|
|
mova _solve,r0
|
|
jsr @r0
|
|
nop
|
|
|
|
ldc r7,gbr /* part1 answer */
|
|
|
|
/* part 2 */
|
|
mova part2_data,r0
|
|
mov r0,r4 /* r4: part2 data start */
|
|
mov #10,r3
|
|
add r4,r3 /* r3: part2 data end */
|
|
|
|
mov #1,r6 /* r6: tree multiplier */
|
|
|
|
part2_loop:
|
|
mov.b @r4+,r13 /* right */
|
|
mov.b @r4+,r14 /* down */
|
|
|
|
mova _solve,r0
|
|
jsr @r0
|
|
nop
|
|
|
|
dmulu.l r7,r6
|
|
cmp/eq r4,r3
|
|
bf/s part2_loop
|
|
sts macl,r6
|
|
|
|
/* part2 answer : mach,macl */
|
|
|
|
trapa #0
|
|
|
|
/* right, down */
|
|
.balign 4
|
|
part2_data:
|
|
.byte 1, 1
|
|
.byte 3, 1
|
|
.byte 5, 1
|
|
.byte 7, 1
|
|
.byte 1, 2
|
|
|
|
/* r7: number of trees (in/out) */
|
|
.balign 4
|
|
_solve:
|
|
/* initial state */
|
|
mov #0,r7 /* number of trees encountered */
|
|
mov #0,r11 /* position X */
|
|
mov #0,r12 /* position Y */
|
|
solve_loop:
|
|
/* return value in r1 */
|
|
sts.l pr,@-r15
|
|
mova _slope_step,r0
|
|
jsr @r0
|
|
nop
|
|
lds.l @r15+,pr
|
|
|
|
cmp/pz r1 /* r1 ≥ 0 */
|
|
bf solve_end /* this is the end */
|
|
bra solve_loop
|
|
add r1,r7 /* increment tree count */
|
|
|
|
solve_end:
|
|
rts
|
|
nop
|
|
|
|
.balign 4
|
|
_slope_step:
|
|
/* r11: position X */
|
|
/* r12: position Y */
|
|
/* r13: right N */
|
|
/* r14: down N */
|
|
/* r8 : start */
|
|
/* r9 : size */
|
|
/* r10: stride */
|
|
/* return r1 : tree encountered (-1,0,1) */
|
|
|
|
add r13,r11 /* r11 + r13 → r11 (X) */
|
|
add r14,r12 /* r12 + r14 → r12 (Y) */
|
|
|
|
/* Y-coordinate × stride → r5 */
|
|
mulu.w r10,r12 /* offset */
|
|
sts macl,r5
|
|
|
|
sts.l pr,@-r15
|
|
|
|
/* X-axis wrap-around */
|
|
mov r11,r1
|
|
mov r10,r0
|
|
add #-1,r0 /* subtract 1 to remove newline */
|
|
mov.l div32_16_ptr,r2
|
|
jsr @r2 /* r1 ÷ r0 → r1 ; (clobbers r0,r1) */
|
|
mov r0,r2 /* save width in r2 (not clobbered) */
|
|
|
|
lds.l @r15+,pr
|
|
|
|
/* recover the modulus with a multiplication + subtraction */
|
|
mulu.w r2,r1
|
|
sts macl,r1
|
|
mov r11,r0
|
|
sub r1,r0 /* r0 - r1 → r0
|
|
|
|
/* calculate offset (y_off + x_off → off) */
|
|
add r5,r0
|
|
/* compare r0 offset with r9 size */
|
|
cmp/hs r9,r0 /* r0 ≥ r9 → T */
|
|
bt end_of_slope
|
|
|
|
/* get tree */
|
|
mov.b @(r0,r8),r0
|
|
cmp/eq #0x23,r0 /* 0x23 ascii `#` */
|
|
rts
|
|
movt r1
|
|
end_of_slope:
|
|
rts
|
|
mov #-1,r1 /* -1: end of slope */
|
|
|
|
.balign 4
|
|
div32_16_ptr: .long _div32_16
|
|
input_stride_ptr: .long _input_stride
|
|
|
|
.balign 4
|
|
start: .long _binary_2020_day3_input_txt_start
|
|
size: .long _binary_2020_day3_input_txt_size
|
|
|
|
.balign 4
|
|
stack_bot:
|
|
.rept 16
|
|
.long 0
|
|
.endr
|
|
stack_top:
|