add aoc 2020 day1

This commit is contained in:
Zack Buhman 2022-04-05 14:07:50 -07:00
parent 5781add994
commit 05a68be57b
6 changed files with 277 additions and 1 deletions

View File

@ -6,7 +6,7 @@ all:
m4 < $< > $@ m4 < $< > $@
%.bin: %.asm %.bin: %.asm
$(HOME)/6502-asm/main $< $@ $(HOME)/6502-asm/main $^ $@
%.rom: %.bin %.rom: %.bin
python $(HOME)/6502-asm/link.py $< $@ python $(HOME)/6502-asm/link.py $< $@
@ -17,6 +17,8 @@ all:
clean: clean:
rm -f *.bin *.rom rm -f *.bin *.rom
aoc/2020/day1/solution.bin: aoc/2020/day1/solution.asm aoc/mul24.asm aoc/hex.asm aoc/lcd.asm aoc/2020/day1/input.bin
.SUFFIXES: .SUFFIXES:
.INTERMEDIATE: .INTERMEDIATE:
.PRECIOUS: %.bin %.rom %.asm .PRECIOUS: %.bin %.rom %.asm

101
aoc/2020/day1/solution.asm Normal file
View File

@ -0,0 +1,101 @@
;; uint16_t * input;
;; uint8_t * input_len = 0;
;; uint16_t * input_j = 2;
;; uint16_t * input_k = 4;
;; uint8_t * k_index = 1;
BRA r :reset ; RESB
NOP i ; IRQB
;; reset stack
reset: LDX # ff
TXS i
;; *input_k = input
LDA # :_bin_aoc/2020/day1/input_start_l
STA zp 4
LDA # :_bin_aoc/2020/day1/input_start_h
STA zp 5
;; *input_len = _bin_aoc/2020/day1/input_size / 2
LDA # :_bin_aoc/2020/day1/input_size_h
LSR A
LDA # :_bin_aoc/2020/day1/input_size_l
ROR A
STA zp 0
;; *k_index = *input_len
STA zp 1
_day1_loopx: LDA # :_bin_aoc/2020/day1/input_start_l ;;
STA zp 2 ;;
LDA # :_bin_aoc/2020/day1/input_start_h ;;
STA zp 3 ;; *input_j = input
LDA zp 0 ;; (input_size)
TAX i ;; X = *input_len
_day1_loop: CLC i ;; /* 16-bit addition+comparison (lower byte) */
LDY # 0 ;;
LDA (zp),y 2 ;;
ADC (zp),y 4 ;; A = ((uint8_t *)(*input_j))[0] + ((uint8_t *)(*input_k))[0]
PHP s ;;
CMP # e4 ;;
BNE r :_day1_next ;; if (A != 0xE4) goto _next
PLP s ;; /* 16-bit addition+comparison (upper byte) */
LDY # 1 ;;
LDA (zp),y 2 ;;
ADC (zp),y 4 ;; A = ((uint8_t *)(*input_j))[1] + ((uint8_t *)(*input_k))[1]
CMP # 07 ;;
BEQ r :_day1_found ;; if (A == 0x07) goto _found
_day1_next: CLC i ;;
LDA zp 2 ;;
ADC # 2 ;;
STA zp 2 ;;
LDA zp 3 ;;
ADC # 0 ;;
STA zp 3 ;; *input_j = *input_j + 2
DEX i ;;
BNE r :_day1_loop ;; if (--X != 0) goto _loop
CLC i ;;
LDA zp 4 ;;
ADC # 2 ;;
STA zp 4 ;;
LDA zp 5 ;;
ADC # 0 ;;
STA zp 5 ;; *input_k = *input_k + 2
LDY zp 1 ;;
DEY i ;;
STY zp 1 ;; *k_index = k_index - 1;
BNE r :_day1_loopx ;; if (*k_index != 0) goto _loopx
_day1_notfound: BRA r :_day1_notfound
_day1_found: LDX # 8
LDY # 0 ;; copy **input_j and **input_k to mul24 `a` and `b` arguments
LDA (zp),y 2 ;;
STA zp,x 0 ;;
LDA (zp),y 4 ;;
STA zp,x 3 ;;
;;
LDY # 1 ;;
LDA (zp),y 2 ;;
STA zp,x 1 ;;
LDA (zp),y 4 ;;
STA zp,x 4 ;;
;;
LDA # 0 ;;
STA zp,x 2 ;;
STA zp,x 5 ;;
JSR a :mul24
JSR a :lcd_reset
LDX # 10
LDY # 3
JSR a :lcd_hex
_day1_stop: BRA r :_day1_stop

39
aoc/hex.asm Normal file
View File

@ -0,0 +1,39 @@
;;
;;
;; args:
;; X: zero page offset
;; Y: length
lcd_hex: NOP i
;; top nib
_hex_loop: LDA zp,x 0
LSR A
LSR A
LSR A
LSR A
CMP # a
BCS r :_hex_nib0_af
_hex_nib0_09: CLC i
ADC # 30
BRA r :_hex_nib0_out
_hex_nib0_af: CLC i
ADC # 37
_hex_nib0_out: JSR a :lcd_w_rs1
;; bottom nib
LDA zp,x 0
AND # f
CMP # a
BCS r :_hex_nib1_af
_hex_nib1_09: CLC i
ADC # 30
BRA r :_hex_nib1_out
_hex_nib1_af: CLC i
ADC # 37
_hex_nib1_out: JSR a :lcd_w_rs1
DEX i
DEY i
BNE r :_hex_loop
RTS s

85
aoc/lcd.asm.in Normal file
View File

@ -0,0 +1,85 @@
include(`common.m4')
;;; begin lcd_reset
;; Set pins 0-2 on Port A to Output
lcd_reset: LDA # %00000111
STA a DDRA
;; Function Set:
;; D7 D6 D5 D4 D3 D2 D1 D0
;; 0 0 1 B L F x x
;; (Bits 8/4, Lines 2/1, Font 5x11/5x8)
LDA # %00111000
JSR a :lcd_w_rs0
;; Clear Display:
;; D7 D6 D5 D4 D3 D2 D1 D0
;; 0 0 0 0 0 0 0 1
LDA # %00000001
JSR a :lcd_w_rs0
;; Entry Mode Set:
;; D7 D6 D5 D4 D3 D2 D1 D0
;; 0 0 0 0 0 1 I/D S
;; (Increment/Decrement, Shift)
LDA # %00000110
JSR a :lcd_w_rs0
;; Display ON/OFF:
;; D7 D6 D5 D4 D3 D2 D1 D0
;; 0 0 0 0 0 D C B
;; (Display, Cursor, Blink)
LDA # %00001110
JSR a :lcd_w_rs0
RTS s
;;; end lcd_reset
;; write "instruction"
lcd_w_rs0: JSR a :lcd_wait
STA a PORTB
LDA # 0
STA a PORTA
LDA # hh(L_E)
STA a PORTA
LDA # 0
STA a PORTA
RTS s
;; write "data" to lcd
lcd_w_rs1: JSR a :lcd_wait
STA a PORTB
LDA # hh(L_RS)
STA a PORTA
LDA # hh(L_RS|L_E)
STA a PORTA
LDA # hh(L_RS)
STA a PORTA
RTS s
;;; begin lcd_wait
lcd_wait: PHA s
LDA # %00000000 ;; Set pins 0-7 on Port B to Input
STA a DDRB
_lcd_wait: LDA # hh(L_RW)
STA a PORTA
LDA # hh(L_E|L_RW)
STA a PORTA
LDA a PORTB
AND # %10000000
BNE r :_lcd_wait
LDA # hh(L_RW)
STA a PORTA
LDA # %11111111 ;; Set pins 0-7 on Port B to Output
STA a DDRB
PLA s
RTS s
;;; end lcd_wait

46
aoc/mul24.asm Normal file
View File

@ -0,0 +1,46 @@
;; multiply two 24-bit operands; 24-bit product
;;
;; r = a * b
;;
;; args:
;; X: zero page offset
;; uint24_t * a = [0, 1, 2]
;; uint24_t * b = [3, 4, 5]
;; uint24_t * r = [6, 7, 8]
mul24: LDA # 0
STA zp,x 6
STA zp,x 7
STA zp,x 8
_mul24_loop: LDA zp,x 0 ;; while (a) {
ORA zp,x 1 ;;
ORA zp,x 2 ;;
BEQ r :_mul24_ret ;;
LDA # 1 ;; if (a & 1)
AND zp,x 0 ;;
BEQ r :_mul24_nand_1 ;;
CLC i ;; r += b;
LDA zp,x 3 ;;; 7..0
ADC zp,x 6 ;;
STA zp,x 6 ;;
LDA zp,x 4 ;;; 15..8
ADC zp,x 7 ;;
STA zp,x 7 ;;
LDA zp,x 5 ;;; 23..16
ADC zp,x 8 ;;
STA zp,x 8 ;;
_mul24_nand_1: LSR zp,x 2 ;; a >>= 1
ROR zp,x 1 ;;
ROR zp,x 0 ;;
ASL zp,x 3 ;; b <<= 1
ROL zp,x 4 ;;
ROL zp,x 5 ;;
JMP a :_mul24_loop ;; }
_mul24_ret: RTS s ;; return;

View File

@ -1,6 +1,9 @@
; -*-asm-*- ; -*-asm-*-
include(`common.m4') include(`common.m4')
BRA r :reset ; RESB
NOP i ; IRQ
;; reset stack ;; reset stack
reset: LDX # ff reset: LDX # ff
TXS i TXS i