2020/c64/day01.asm

191 lines
3.6 KiB
NASM
Raw Normal View History

// vim: filetype=kickass
2020-12-09 02:13:51 +00:00
* = * "Day 01"
//
// day01
//
// Destroys:
2020-12-09 02:39:44 +00:00
// a, x, y, $02..$04, $10..$1c, $20..$25, $fd..$fe, everything you've ever loved
2020-12-09 02:13:51 +00:00
//
.const input_pointer = $03
.const buffer_pointer = $20
.const atoi_result = $22
.const outer_pointer = $20
.const inner_pointer = $22
.const remainder = $24
// Need to be $03 and $fd due to multiply_16bit_unsigned
2020-12-09 08:01:02 +00:00
.const outer_value = $26
2020-12-09 02:13:51 +00:00
.const inner_value = $fd
day01:
2020-12-09 02:13:51 +00:00
move_16_imm($03, str_title)
jsr write_string
2020-12-09 02:13:51 +00:00
//
// Parse the input at day01_input into an array of integers.
//
move_16_imm(input_pointer, day01_input)
move_16_imm(buffer_pointer, buffer)
ldy #0
!line:
2020-12-09 02:13:51 +00:00
// Create a temporary 16-bit integer to store the result in
// in between digits.
move_16_imm(atoi_result, 0)
!digit:
2020-12-09 02:13:51 +00:00
// Check for the newline character at the end of the line.
lda (input_pointer), y
cmp #'\n'
2020-12-09 02:13:51 +00:00
beq !newline+
2020-12-09 02:13:51 +00:00
// Multiply the stored number by 10.
i16_mul10(atoi_result)
2020-12-09 02:13:51 +00:00
// Subtract '0' from the current digit to convert it to "binary".
lda (input_pointer), y
sec
sbc #'0'
2020-12-09 02:13:51 +00:00
// Add the binary digit to the stored number
i16_i8_add_a(atoi_result)
2020-12-09 02:13:51 +00:00
// Increment y.
iny
2020-12-09 01:08:57 +00:00
bne !digit-
2020-12-09 02:13:51 +00:00
// If y overflows, increment the MSB of the input pointer as well,
// for a 16-bit increment.
inc input_pointer + 1
jmp !digit-
2020-12-09 02:13:51 +00:00
!newline:
sty zp_temp
2020-12-09 02:13:51 +00:00
// Append the result of the conversion to the array.
2020-12-09 01:08:57 +00:00
ldy #0
2020-12-09 02:13:51 +00:00
lda atoi_result + 0
sta (buffer_pointer), y
2020-12-09 01:08:57 +00:00
iny
2020-12-09 02:13:51 +00:00
lda atoi_result + 1
sta (buffer_pointer), y
2020-12-09 02:13:51 +00:00
// Increment the buffer pointer by 2.
2020-12-09 01:08:57 +00:00
lda #2
2020-12-09 02:13:51 +00:00
i16_i8_add_a(buffer_pointer)
2020-12-09 02:13:51 +00:00
ldy zp_temp
iny
2020-12-09 01:08:57 +00:00
bne !+
2020-12-09 02:13:51 +00:00
inc input_pointer + 1
2020-12-09 01:08:57 +00:00
!:
2020-12-09 02:13:51 +00:00
// Check for the null terminator.
lda (input_pointer), y
bne !line-
2020-12-09 01:08:57 +00:00
2020-12-09 02:13:51 +00:00
move_16_imm($03, str_parse_done)
2020-12-09 01:08:57 +00:00
jsr write_string
2020-12-09 02:13:51 +00:00
move_16_imm(outer_pointer, buffer)
2020-12-09 01:08:57 +00:00
// Add every number to every other number
!outer:
2020-12-09 02:13:51 +00:00
move_16_imm(inner_pointer, buffer)
2020-12-09 01:08:57 +00:00
// $03..$04 = buffer[i]
ldy #0
2020-12-09 02:13:51 +00:00
lda (outer_pointer), y
sta outer_value
2020-12-09 01:08:57 +00:00
iny
2020-12-09 02:13:51 +00:00
lda (outer_pointer), y
sta outer_value + 1
2020-12-09 01:08:57 +00:00
dey
2020-12-09 02:13:51 +00:00
lda (outer_pointer), y
2020-12-09 01:08:57 +00:00
bne !not_zero+
iny
2020-12-09 02:13:51 +00:00
lda (outer_pointer), y
2020-12-09 01:08:57 +00:00
bne !not_zero+
jmp !error+
!not_zero:
// Subtract from 2020 to see what number we need
2020-12-09 02:13:51 +00:00
i16_imm_i16_sub(remainder, 2020, outer_value)
2020-12-09 01:08:57 +00:00
!inner:
// $fd..$fe = buffer[j]
ldy #0
2020-12-09 02:13:51 +00:00
lda (inner_pointer), y
sta inner_value
2020-12-09 01:08:57 +00:00
iny
2020-12-09 02:13:51 +00:00
lda (inner_pointer), y
sta inner_value + 1
2020-12-09 01:08:57 +00:00
dey
2020-12-09 02:13:51 +00:00
lda (inner_pointer), y
2020-12-09 01:08:57 +00:00
bne !not_zero+
iny
2020-12-09 02:13:51 +00:00
lda (inner_pointer), y
2020-12-09 01:08:57 +00:00
bne !not_zero+
2020-12-09 02:13:51 +00:00
i16_inc(outer_pointer)
2020-12-09 01:08:57 +00:00
jmp !outer-
2020-12-09 02:13:51 +00:00
!not_zero:
2020-12-09 01:08:57 +00:00
// j++
lda #2
2020-12-09 02:13:51 +00:00
i16_i8_add_a(inner_pointer)
// Continue the loop if the number didn't match the needed number.
i16_i16_cmp_bne(remainder, inner_value, !inner-)
2020-12-09 01:08:57 +00:00
!done:
2020-12-09 01:08:57 +00:00
// Multiply the results together
sec
jsr multiply_16bit_unsigned
2020-12-09 02:13:51 +00:00
move_16_imm($03, str_calc_done)
2020-12-09 01:08:57 +00:00
jsr write_string
2020-12-09 02:13:51 +00:00
// Print the 32-bit result as decimal.
2020-12-09 01:08:57 +00:00
lda $25
sta udivmod32_dividend + 3
lda $24
sta udivmod32_dividend + 2
lda $23
sta udivmod32_dividend + 1
lda $22
sta udivmod32_dividend + 0
jsr print_decimal_u32
rts
!error:
2020-12-09 02:13:51 +00:00
move_16_imm($03, str_no_result)
2020-12-09 01:08:57 +00:00
jsr write_string
rts
2020-12-09 01:08:57 +00:00
str_title:
.text "# Day 01, part 1:"
.byte '\n', 0
str_parse_done:
.text "* Finished parsing"
.byte '\n', 0
2020-12-09 01:08:57 +00:00
str_calc_done:
.text "* Finished calculating"
.byte '\n', 0
2020-12-09 01:08:57 +00:00
str_no_result:
.byte '\n'
2020-12-09 01:08:57 +00:00
.text "! Could not find a result"
.byte '\n', 0