day 20 part 2 im tired
This commit is contained in:
parent
9f5df0a65c
commit
7a9bd95804
278
20/main.s
Normal file
278
20/main.s
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
%include "utils.s"
|
||||||
|
|
||||||
|
global _start
|
||||||
|
[bits 32]
|
||||||
|
[section .text]
|
||||||
|
|
||||||
|
%define FILENAME "input"
|
||||||
|
;%define FILENAME "input_test"
|
||||||
|
;%define FILENAME "input_test2"
|
||||||
|
|
||||||
|
;%define DBG
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
; read in modules
|
||||||
|
; module data (16 bytes):
|
||||||
|
; 0
|
||||||
|
; bit 1: type (0: flipflop, 1: conj) bit 0: state (0: low, 1: high)
|
||||||
|
; 1 2 3 4 5 6
|
||||||
|
; destination IDX list
|
||||||
|
; 7 8 9 A B C D E F
|
||||||
|
; input states (for conj modules)
|
||||||
|
; bit 0 is remembered state, higher is index
|
||||||
|
|
||||||
|
mov esi, file
|
||||||
|
read_modules:
|
||||||
|
lodsb
|
||||||
|
cmp al, '%'
|
||||||
|
je .flipflop
|
||||||
|
cmp al, '&'
|
||||||
|
je .conjunc
|
||||||
|
; broadcaster
|
||||||
|
%ifdef DBG
|
||||||
|
mov al, 'B'
|
||||||
|
call print_char
|
||||||
|
mov al, 'R'
|
||||||
|
call print_char
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
mov ch, 1<<1
|
||||||
|
mov al, 1
|
||||||
|
%ifdef DBG
|
||||||
|
call print_hex_byte
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
mov cl, -1 ; broadcaster is special
|
||||||
|
add esi, 14
|
||||||
|
mov edi, modules+16 ; module 1 is broadcast
|
||||||
|
jmp .get_dests
|
||||||
|
.flipflop:
|
||||||
|
mov cl, 0b00 ; low, flipflop
|
||||||
|
jmp .get_idx
|
||||||
|
.conjunc:
|
||||||
|
mov cl, 0b10 ; low, conj
|
||||||
|
jmp .get_idx
|
||||||
|
.get_idx:
|
||||||
|
; get ID
|
||||||
|
lodsb
|
||||||
|
%ifdef DBG
|
||||||
|
call print_char
|
||||||
|
%endif
|
||||||
|
mov bh, al
|
||||||
|
lodsb
|
||||||
|
%ifdef DBG
|
||||||
|
call print_char
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
mov bl, al
|
||||||
|
call id_to_idx ; idx in edx
|
||||||
|
mov ch, dl
|
||||||
|
%ifdef DBG
|
||||||
|
mov al, dl
|
||||||
|
call print_hex_byte
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
shl ch, 1
|
||||||
|
shl edx, 4 ; * 16
|
||||||
|
lea edi, [modules+edx]
|
||||||
|
add esi, 4
|
||||||
|
.get_dests:
|
||||||
|
; type/state in CL
|
||||||
|
mov [edi], cl
|
||||||
|
inc edi
|
||||||
|
.next_dest:
|
||||||
|
; get dest ID
|
||||||
|
lodsb
|
||||||
|
%ifdef DBG
|
||||||
|
call print_char
|
||||||
|
%endif
|
||||||
|
mov bh, al
|
||||||
|
lodsb
|
||||||
|
%ifdef DBG
|
||||||
|
call print_char
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
mov bl, al
|
||||||
|
call id_to_idx
|
||||||
|
cmp bx, 'fm'
|
||||||
|
jne .not_rx
|
||||||
|
mov [mf_idx], dx
|
||||||
|
.not_rx:
|
||||||
|
mov al, dl
|
||||||
|
%ifdef DBG
|
||||||
|
call print_hex_byte
|
||||||
|
call space
|
||||||
|
%endif
|
||||||
|
stosb
|
||||||
|
; store our idx<<1 in dest inputs
|
||||||
|
shl edx, 4 ; * 16
|
||||||
|
lea edx, [modules+edx+7]
|
||||||
|
.store_input:
|
||||||
|
cmp byte [edx], 0
|
||||||
|
jnz .check_next_input
|
||||||
|
mov byte [edx], ch
|
||||||
|
jmp .input_stored
|
||||||
|
.check_next_input:
|
||||||
|
inc edx
|
||||||
|
jmp .store_input
|
||||||
|
.input_stored:
|
||||||
|
; check if more
|
||||||
|
lodsb
|
||||||
|
cmp al, ','
|
||||||
|
jne .cont ; no more
|
||||||
|
inc esi ; space
|
||||||
|
jmp .next_dest
|
||||||
|
.cont:
|
||||||
|
%ifdef DBG
|
||||||
|
call newline
|
||||||
|
%endif
|
||||||
|
cmp esi, file.over
|
||||||
|
jb read_modules
|
||||||
|
|
||||||
|
main:
|
||||||
|
; start an iteration, broadcaster (1) sends low to everything
|
||||||
|
mov dword [queue_head], 0
|
||||||
|
mov dword [queue_tail], 2
|
||||||
|
mov word [queue], 0b10 ; low to index 1
|
||||||
|
call do_iters
|
||||||
|
inc dword [final_value]
|
||||||
|
jmp main
|
||||||
|
|
||||||
|
do_iters:
|
||||||
|
; get head of queue
|
||||||
|
mov eax, [queue_head]
|
||||||
|
mov ax, [eax+queue]
|
||||||
|
%ifdef DBG
|
||||||
|
call print_hex_word
|
||||||
|
call newline
|
||||||
|
%endif
|
||||||
|
mov cl, ah ; sender
|
||||||
|
movzx eax, al
|
||||||
|
shr eax, 1 ; get pulse
|
||||||
|
setc bl
|
||||||
|
jnc .not_high
|
||||||
|
cmp al, [mf_idx]
|
||||||
|
jne .not_high
|
||||||
|
push eax
|
||||||
|
mov al, cl
|
||||||
|
call print_hex_byte
|
||||||
|
call space
|
||||||
|
mov eax, [final_value]
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
pop eax
|
||||||
|
.not_high:
|
||||||
|
; get module
|
||||||
|
mov bh, al ; idx
|
||||||
|
shl eax, 4 ; * 16
|
||||||
|
lea edi, [modules+eax]
|
||||||
|
mov al, [edi]
|
||||||
|
cmp al, -1
|
||||||
|
je .broadcast
|
||||||
|
bt ax, 1
|
||||||
|
jc .conj
|
||||||
|
.flipflop:
|
||||||
|
; if high, do nothing
|
||||||
|
test bl, bl
|
||||||
|
jnz .cont
|
||||||
|
; if low, flip and send result
|
||||||
|
xor al, 1
|
||||||
|
bt ax, 0
|
||||||
|
setc bl
|
||||||
|
mov [edi], al
|
||||||
|
jmp add_cmds
|
||||||
|
.conj:
|
||||||
|
mov dl, 1
|
||||||
|
mov esi, 7
|
||||||
|
.check_mem:
|
||||||
|
mov al, [edi+esi]
|
||||||
|
test al, al
|
||||||
|
jz .mem_done
|
||||||
|
shr al, 1
|
||||||
|
setc dh
|
||||||
|
cmp al, cl
|
||||||
|
jne .mem_cont
|
||||||
|
shr bl, 1
|
||||||
|
setc dh
|
||||||
|
rcl al, 1
|
||||||
|
mov [edi+esi], al
|
||||||
|
.mem_cont:
|
||||||
|
and dl, dh
|
||||||
|
inc esi
|
||||||
|
cmp esi, 0xF
|
||||||
|
jbe .check_mem
|
||||||
|
.mem_done:
|
||||||
|
; send high if not all were high
|
||||||
|
xor dl, 1
|
||||||
|
mov bl, dl
|
||||||
|
jmp add_cmds
|
||||||
|
.broadcast:
|
||||||
|
jmp add_cmds ; just add commands with same pulse
|
||||||
|
.cont:
|
||||||
|
mov eax, [queue_head]
|
||||||
|
add eax, 2
|
||||||
|
and eax, 511
|
||||||
|
mov [queue_head], eax
|
||||||
|
cmp eax, [queue_tail]
|
||||||
|
jne do_iters
|
||||||
|
ret
|
||||||
|
; BH: module IDX, BL: pulse, EDI: *module
|
||||||
|
add_cmds:
|
||||||
|
mov dx, bx ; save
|
||||||
|
mov ecx, 1
|
||||||
|
.loop:
|
||||||
|
mov al, [edi+ecx]
|
||||||
|
test al, al
|
||||||
|
jz .done
|
||||||
|
mov bx, dx
|
||||||
|
shl al, 1
|
||||||
|
or bl, al
|
||||||
|
%ifdef DBG
|
||||||
|
call space
|
||||||
|
mov ax, bx
|
||||||
|
call print_hex_word
|
||||||
|
call newline
|
||||||
|
%endif
|
||||||
|
; add to queue
|
||||||
|
mov eax, [queue_tail]
|
||||||
|
mov [eax+queue], bx
|
||||||
|
add eax, 2
|
||||||
|
and eax, 511
|
||||||
|
mov [queue_tail], eax
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, 6
|
||||||
|
jbe .loop
|
||||||
|
.done:
|
||||||
|
jmp do_iters.cont
|
||||||
|
|
||||||
|
; ID in BX, IDX return in EDX
|
||||||
|
id_to_idx:
|
||||||
|
xor edx, edx
|
||||||
|
.test:
|
||||||
|
cmp [module_idx_to_id+edx*2], bx
|
||||||
|
je .found
|
||||||
|
inc dx
|
||||||
|
cmp dx, [next_module_idx]
|
||||||
|
jb .test
|
||||||
|
; new ID
|
||||||
|
mov [module_idx_to_id+edx*2], bx
|
||||||
|
inc word [next_module_idx]
|
||||||
|
.found:
|
||||||
|
ret
|
||||||
|
|
||||||
|
[section .data]
|
||||||
|
final_value: dd 1
|
||||||
|
next_module_idx: dw 2 ; 1 reserved for broadcaster
|
||||||
|
mf_idx: dw 0
|
||||||
|
queue_head: dd queue
|
||||||
|
queue_tail: dd queue
|
||||||
|
file: incbin FILENAME
|
||||||
|
.over: db 0 ; EOF
|
||||||
|
|
||||||
|
[section .bss]
|
||||||
|
modules: resb 64*16
|
||||||
|
module_idx_to_id: resw 64
|
||||||
|
queue: resw 64*8
|
||||||
|
|
||||||
|
[section .rodata]
|
Loading…
Reference in New Issue
Block a user