From 7a9bd95804669595848dcaea759913a69e7a030a Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Sat, 23 Dec 2023 03:29:03 -0600 Subject: [PATCH] day 20 part 2 im tired --- 20/main.s | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 20/main.s diff --git a/20/main.s b/20/main.s new file mode 100644 index 0000000..a020440 --- /dev/null +++ b/20/main.s @@ -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]