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