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