c64(day09): Actually add day 9
This commit is contained in:
parent
01ab067797
commit
df67c9069c
1 changed files with 596 additions and 0 deletions
596
c64/day09.asm
Normal file
596
c64/day09.asm
Normal file
|
@ -0,0 +1,596 @@
|
||||||
|
// vim: filetype=kickass
|
||||||
|
|
||||||
|
* = * "Day 09 Input"
|
||||||
|
!input:
|
||||||
|
.import text "../inputs/09"
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
* = * "Day 09 Code"
|
||||||
|
|
||||||
|
day09:
|
||||||
|
{
|
||||||
|
.const buffer = $b000
|
||||||
|
.const buffer_end = $bfa0
|
||||||
|
|
||||||
|
.const input_pointer = $40 // $40..42
|
||||||
|
.const atoi_result = $42 // $42..46
|
||||||
|
.const buffer_pointer = $46 // $46..48
|
||||||
|
.const outer_pointer = $48 // $48..4a
|
||||||
|
.const middle_pointer = $4a // $4a..4c
|
||||||
|
.const inner_pointer = $4c // $4c..4e
|
||||||
|
.const part1 = $4e // $4e..52
|
||||||
|
|
||||||
|
.const lower_pointer = $52 // $52..54
|
||||||
|
.const upper_pointer = $54 // $54..56
|
||||||
|
.const sum = $56 // $56..5a
|
||||||
|
|
||||||
|
.const min_value = $5a // $5a..5e
|
||||||
|
.const max_value = $5e // $5e..62
|
||||||
|
|
||||||
|
|
||||||
|
// XXX I'm using 32 bit integers for this day, even though some
|
||||||
|
// inputs are 64 bit. Seems like I get away with it though.
|
||||||
|
move_16_imm($03, !str_title+)
|
||||||
|
jsr write_string
|
||||||
|
|
||||||
|
move_16_imm(input_pointer, !input-)
|
||||||
|
move_16_imm(buffer_pointer, buffer)
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
!line:
|
||||||
|
// 32-bit integer to store the result in.
|
||||||
|
lda #0
|
||||||
|
sta atoi_result + 0
|
||||||
|
sta atoi_result + 1
|
||||||
|
sta atoi_result + 2
|
||||||
|
sta atoi_result + 3
|
||||||
|
|
||||||
|
!digit:
|
||||||
|
// Check for the newline character at the end of the line.
|
||||||
|
lda (input_pointer), y
|
||||||
|
cmp #'\n'
|
||||||
|
beq !newline+
|
||||||
|
|
||||||
|
// Multiply the stored number by 10.
|
||||||
|
u32_mul10(atoi_result)
|
||||||
|
|
||||||
|
// Subtract '0' from the current digit to convert it to binary.
|
||||||
|
lda (input_pointer), y
|
||||||
|
sec
|
||||||
|
sbc #'0'
|
||||||
|
|
||||||
|
// Add the binary digit to the stored number
|
||||||
|
i32_add_a(atoi_result)
|
||||||
|
|
||||||
|
y_buf_inc(input_pointer)
|
||||||
|
jmp !digit-
|
||||||
|
|
||||||
|
!newline:
|
||||||
|
sty zp_temp
|
||||||
|
ldy #0
|
||||||
|
|
||||||
|
lda atoi_result + 0
|
||||||
|
sta (buffer_pointer), y
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda atoi_result + 1
|
||||||
|
sta (buffer_pointer), y
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda atoi_result + 2
|
||||||
|
sta (buffer_pointer), y
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda atoi_result + 3
|
||||||
|
sta (buffer_pointer), y
|
||||||
|
|
||||||
|
lda buffer_pointer
|
||||||
|
clc
|
||||||
|
adc #4
|
||||||
|
sta buffer_pointer
|
||||||
|
bcc !cc+
|
||||||
|
inc buffer_pointer + 1
|
||||||
|
!cc:
|
||||||
|
|
||||||
|
ldy zp_temp
|
||||||
|
|
||||||
|
y_buf_inc(input_pointer)
|
||||||
|
|
||||||
|
// Check for the null terminator.
|
||||||
|
lda (input_pointer), y
|
||||||
|
beq !done+
|
||||||
|
jmp !line-
|
||||||
|
|
||||||
|
!done:
|
||||||
|
// outer for loop initial value
|
||||||
|
// outer_pointer = buffer + 25
|
||||||
|
lda #<(buffer + 25 * 4)
|
||||||
|
sta outer_pointer + 0
|
||||||
|
lda #>(buffer + 25 * 4)
|
||||||
|
sta outer_pointer + 1
|
||||||
|
|
||||||
|
!outer:
|
||||||
|
|
||||||
|
// middle for loop initial value
|
||||||
|
// middle_pointer = outer_pointer - 25
|
||||||
|
sec
|
||||||
|
lda outer_pointer + 0
|
||||||
|
sbc #(25 * 4)
|
||||||
|
sta middle_pointer + 0
|
||||||
|
lda outer_pointer + 1
|
||||||
|
sbc #0
|
||||||
|
sta middle_pointer + 1
|
||||||
|
|
||||||
|
// TODO if *middle_pointer > *outer_pointer: continue
|
||||||
|
|
||||||
|
!middle:
|
||||||
|
|
||||||
|
// inner_pointer = middle_pointer + 1
|
||||||
|
clc
|
||||||
|
lda middle_pointer + 0
|
||||||
|
adc #(1 * 4)
|
||||||
|
sta inner_pointer + 0
|
||||||
|
lda middle_pointer + 1
|
||||||
|
adc #0
|
||||||
|
sta inner_pointer + 1
|
||||||
|
|
||||||
|
!inner:
|
||||||
|
|
||||||
|
// if *inner_pointer + *middle_pointer == *outer_pointer:
|
||||||
|
// continue 'outer;
|
||||||
|
|
||||||
|
// *atoi_result = *inner_pointer + *middle_pointer
|
||||||
|
clc
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (inner_pointer), y
|
||||||
|
adc (middle_pointer), y
|
||||||
|
sta (atoi_result), y
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (inner_pointer), y
|
||||||
|
adc (middle_pointer), y
|
||||||
|
sta (atoi_result), y
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (inner_pointer), y
|
||||||
|
adc (middle_pointer), y
|
||||||
|
sta (atoi_result), y
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (inner_pointer), y
|
||||||
|
adc (middle_pointer), y
|
||||||
|
sta (atoi_result), y
|
||||||
|
|
||||||
|
// if *atoi_result == *outer_pointer:
|
||||||
|
ldy #0
|
||||||
|
lda (atoi_result), y
|
||||||
|
cmp (outer_pointer), y
|
||||||
|
bne !not_equal+
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (atoi_result), y
|
||||||
|
cmp (outer_pointer), y
|
||||||
|
bne !not_equal+
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (atoi_result), y
|
||||||
|
cmp (outer_pointer), y
|
||||||
|
bne !not_equal+
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (atoi_result), y
|
||||||
|
cmp (outer_pointer), y
|
||||||
|
bne !not_equal+
|
||||||
|
|
||||||
|
// continue 'outer;
|
||||||
|
jmp !middle_done+
|
||||||
|
|
||||||
|
!not_equal:
|
||||||
|
|
||||||
|
// inner for loop increment
|
||||||
|
// *inner_pointer += 1 * 4
|
||||||
|
clc
|
||||||
|
lda inner_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta inner_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc inner_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
// inner for loop conditional
|
||||||
|
// inner_pointer != outer_pointer
|
||||||
|
lda inner_pointer + 0
|
||||||
|
cmp outer_pointer + 0
|
||||||
|
bne !inner-
|
||||||
|
|
||||||
|
lda inner_pointer + 1
|
||||||
|
cmp outer_pointer + 1
|
||||||
|
bne !inner-
|
||||||
|
|
||||||
|
// for loop increment
|
||||||
|
// *middle_pointer += 1 * 4
|
||||||
|
clc
|
||||||
|
lda middle_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta middle_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc middle_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
// for loop conditional
|
||||||
|
// middle_pointer != outer_pointer
|
||||||
|
lda middle_pointer + 0
|
||||||
|
cmp outer_pointer + 0
|
||||||
|
bne !middle_continue+
|
||||||
|
|
||||||
|
lda middle_pointer + 1
|
||||||
|
cmp outer_pointer + 1
|
||||||
|
bne !middle_continue+
|
||||||
|
|
||||||
|
jmp !outer_done+
|
||||||
|
|
||||||
|
!middle_continue:
|
||||||
|
jmp !middle-
|
||||||
|
|
||||||
|
!middle_done:
|
||||||
|
|
||||||
|
// outer for loop increment
|
||||||
|
// *outer_pointer += 1 * 4
|
||||||
|
clc
|
||||||
|
lda outer_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta outer_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc outer_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
// outer for loop conditional
|
||||||
|
// *outer_pointer != $cfa0
|
||||||
|
lda outer_pointer + 0
|
||||||
|
cmp #$a0
|
||||||
|
bne !outer_continue+
|
||||||
|
|
||||||
|
lda outer_pointer + 1
|
||||||
|
cmp #$bf
|
||||||
|
bne !outer_continue+
|
||||||
|
|
||||||
|
jmp *
|
||||||
|
|
||||||
|
!outer_continue:
|
||||||
|
jmp !outer-
|
||||||
|
|
||||||
|
|
||||||
|
!outer_done:
|
||||||
|
|
||||||
|
// print (part1 = *outer_pointer)
|
||||||
|
ldy #0
|
||||||
|
lda (outer_pointer), y
|
||||||
|
sta part1 + 0
|
||||||
|
sta udivmod32_dividend + 0
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (outer_pointer), y
|
||||||
|
sta part1 + 1
|
||||||
|
sta udivmod32_dividend + 1
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (outer_pointer), y
|
||||||
|
sta part1 + 2
|
||||||
|
sta udivmod32_dividend + 2
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (outer_pointer), y
|
||||||
|
sta part1 + 3
|
||||||
|
sta udivmod32_dividend + 3
|
||||||
|
|
||||||
|
jsr print_decimal_u32
|
||||||
|
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta lower_pointer + 0
|
||||||
|
sta upper_pointer + 0
|
||||||
|
sta sum + 0
|
||||||
|
sta sum + 1
|
||||||
|
sta sum + 2
|
||||||
|
sta sum + 3
|
||||||
|
lda #$b0
|
||||||
|
sta lower_pointer + 1
|
||||||
|
sta upper_pointer + 1
|
||||||
|
|
||||||
|
!outer:
|
||||||
|
!upper:
|
||||||
|
// while sum < part1
|
||||||
|
lda sum + 3
|
||||||
|
cmp part1 + 3
|
||||||
|
beq !+ // sum[3] == part1[3]
|
||||||
|
bcc !upper_success+ // sum[3] < part1[3] => sum < part
|
||||||
|
bcs !lower+ // sum[3] >= part1[3] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 2
|
||||||
|
cmp part1 + 2
|
||||||
|
beq !+ // sum[2] == part1[2]
|
||||||
|
bcc !upper_success+ // sum[2] < part1[2] => sum < part
|
||||||
|
bcs !lower+ // sum[2] >= part1[2] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 1
|
||||||
|
cmp part1 + 1
|
||||||
|
beq !+ // sum[1] == part1[1]
|
||||||
|
bcc !upper_success+ // sum[1] < part1[1] => sum < part
|
||||||
|
bcs !lower+ // sum[1] >= part1[1] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 0
|
||||||
|
cmp part1 + 0
|
||||||
|
beq !outer_end+ // sum[0] == part1[0] => sum == part
|
||||||
|
bcs !lower+ // sum[0] >= part1[0] => sum > part
|
||||||
|
|
||||||
|
!upper_success:
|
||||||
|
// sum += *upper_pointer
|
||||||
|
ldy #0
|
||||||
|
clc
|
||||||
|
|
||||||
|
lda sum + 0
|
||||||
|
adc (upper_pointer), y // (upper_pointer) + 0
|
||||||
|
sta sum + 0
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 1
|
||||||
|
adc (upper_pointer), y // (upper_pointer) + 1
|
||||||
|
sta sum + 1
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 2
|
||||||
|
adc (upper_pointer), y // (upper_pointer) + 2
|
||||||
|
sta sum + 2
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 3
|
||||||
|
adc (upper_pointer), y // (upper_pointer) + 3
|
||||||
|
sta sum + 3
|
||||||
|
|
||||||
|
// upper_pointer += 1 * 4;
|
||||||
|
clc
|
||||||
|
lda upper_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta upper_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc upper_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
jmp !upper-
|
||||||
|
|
||||||
|
!outer_end:
|
||||||
|
// Hidden shortcut to outer_end because the jump was too long
|
||||||
|
jmp !outer_end+
|
||||||
|
|
||||||
|
!lower:
|
||||||
|
// while sum > part1
|
||||||
|
lda sum + 3
|
||||||
|
cmp part1 + 3
|
||||||
|
beq !+ // sum[3] == part1[3]
|
||||||
|
bcc !outer- // sum[3] < part[3] => sum < part
|
||||||
|
bcs !lower_success+ // sum[3] >= part[3] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 2
|
||||||
|
cmp part1 + 2
|
||||||
|
beq !+ // sum[2] == part1[2]
|
||||||
|
bcc !outer- // sum[2] < part[2] => sum < part
|
||||||
|
bcs !lower_success+ // sum[2] >= part[2] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 1
|
||||||
|
cmp part1 + 1
|
||||||
|
beq !+ // sum[1] == part1[1]
|
||||||
|
bcc !outer- // sum[1] < part[1] => sum < part
|
||||||
|
bcs !lower_success+ // sum[1] >= part[1] => sum > part
|
||||||
|
|
||||||
|
!:
|
||||||
|
lda sum + 0
|
||||||
|
cmp part1 + 0
|
||||||
|
beq !outer_end+ // sum[0] == part1[0]
|
||||||
|
bcs !outer- // sum[0] < part[0] => sum < part
|
||||||
|
|
||||||
|
!lower_success:
|
||||||
|
// sum -= *lower_pointer
|
||||||
|
ldy #0
|
||||||
|
sec
|
||||||
|
|
||||||
|
lda sum + 0
|
||||||
|
sbc (lower_pointer), y // (lower_pointer) + 0
|
||||||
|
sta sum + 0
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 1
|
||||||
|
sbc (lower_pointer), y // (lower_pointer) + 1
|
||||||
|
sta sum + 1
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 2
|
||||||
|
sbc (lower_pointer), y // (lower_pointer) + 2
|
||||||
|
sta sum + 2
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda sum + 3
|
||||||
|
sbc (lower_pointer), y // (lower_pointer) + 3
|
||||||
|
sta sum + 3
|
||||||
|
|
||||||
|
// lower_pointer += 1 * 4;
|
||||||
|
clc
|
||||||
|
lda lower_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta lower_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc lower_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
jmp !lower-
|
||||||
|
!lower_end:
|
||||||
|
|
||||||
|
!outer_end:
|
||||||
|
|
||||||
|
// Find the minimum and maximum values
|
||||||
|
lda #$ff
|
||||||
|
sta min_value + 0
|
||||||
|
sta min_value + 1
|
||||||
|
sta min_value + 2
|
||||||
|
sta min_value + 3
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta max_value + 0
|
||||||
|
sta max_value + 1
|
||||||
|
sta max_value + 2
|
||||||
|
sta max_value + 3
|
||||||
|
|
||||||
|
!loop:
|
||||||
|
ldy #3
|
||||||
|
lda (lower_pointer), y // lower[i] >> 24
|
||||||
|
cmp min_value + 3
|
||||||
|
beq !+
|
||||||
|
bcs !not_less+
|
||||||
|
bcc !less+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 16
|
||||||
|
cmp min_value + 2
|
||||||
|
beq !+
|
||||||
|
bcs !not_less+
|
||||||
|
bcc !less+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 8
|
||||||
|
cmp min_value + 1
|
||||||
|
beq !+
|
||||||
|
bcs !not_less+
|
||||||
|
bcc !less+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 0
|
||||||
|
cmp min_value + 0
|
||||||
|
bcs !not_less+
|
||||||
|
|
||||||
|
!less:
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta min_value + 0
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta min_value + 1
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta min_value + 2
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta min_value + 3
|
||||||
|
|
||||||
|
!not_less:
|
||||||
|
|
||||||
|
ldy #3
|
||||||
|
lda (lower_pointer), y // lower[i] >> 24
|
||||||
|
cmp max_value + 3
|
||||||
|
beq !+
|
||||||
|
bcc !not_more+
|
||||||
|
bcs !more+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 16
|
||||||
|
cmp max_value + 2
|
||||||
|
beq !+
|
||||||
|
bcc !not_more+
|
||||||
|
bcs !more+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 8
|
||||||
|
cmp max_value + 1
|
||||||
|
beq !+
|
||||||
|
bcc !not_more+
|
||||||
|
bcs !more+
|
||||||
|
!:
|
||||||
|
dey
|
||||||
|
lda (lower_pointer), y // lower[i] >> 0
|
||||||
|
cmp max_value + 0
|
||||||
|
bcc !not_more+
|
||||||
|
|
||||||
|
!more:
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta max_value + 0
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta max_value + 1
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta max_value + 2
|
||||||
|
iny
|
||||||
|
|
||||||
|
lda (lower_pointer), y
|
||||||
|
sta max_value + 3
|
||||||
|
|
||||||
|
!not_more:
|
||||||
|
|
||||||
|
clc
|
||||||
|
lda lower_pointer + 0
|
||||||
|
adc #4
|
||||||
|
sta lower_pointer + 0
|
||||||
|
bcc !+
|
||||||
|
inc lower_pointer + 1
|
||||||
|
!:
|
||||||
|
|
||||||
|
// for loop condition
|
||||||
|
// lower_pointer != upper_pointer
|
||||||
|
cmp upper_pointer + 0
|
||||||
|
bne !+
|
||||||
|
lda lower_pointer + 1
|
||||||
|
cmp upper_pointer + 1
|
||||||
|
beq !end+
|
||||||
|
!:
|
||||||
|
|
||||||
|
jmp !loop-
|
||||||
|
|
||||||
|
!end:
|
||||||
|
|
||||||
|
clc
|
||||||
|
lda min_value + 0
|
||||||
|
adc max_value + 0
|
||||||
|
sta udivmod32_dividend + 0
|
||||||
|
|
||||||
|
lda min_value + 1
|
||||||
|
adc max_value + 1
|
||||||
|
sta udivmod32_dividend + 1
|
||||||
|
|
||||||
|
lda min_value + 2
|
||||||
|
adc max_value + 2
|
||||||
|
sta udivmod32_dividend + 2
|
||||||
|
|
||||||
|
lda min_value + 3
|
||||||
|
adc max_value + 3
|
||||||
|
sta udivmod32_dividend + 3
|
||||||
|
|
||||||
|
move_16_imm($03, str_part2)
|
||||||
|
jsr write_string
|
||||||
|
|
||||||
|
jsr print_decimal_u32
|
||||||
|
|
||||||
|
move_16_imm($03, str_done)
|
||||||
|
jsr write_string
|
||||||
|
|
||||||
|
jmp *
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
!str_title:
|
||||||
|
.text "# Day 09"
|
||||||
|
.byte '\n', '\n'
|
||||||
|
.text "Part 1: "
|
||||||
|
.byte 0
|
Loading…
Reference in a new issue