Compare commits

..

2 Commits

Author SHA1 Message Date
Lucia Ceionia
83f5ba9fae day 16 part 2 2023-12-16 19:26:15 -06:00
Lucia Ceionia
45fc62c759 day 16 part 1 2023-12-16 18:41:45 -06:00
6 changed files with 1339 additions and 0 deletions

3
16/Makefile Normal file
View File

@ -0,0 +1,3 @@
all:
nasm -g -felf32 main.s && ld -melf_i386 -g main.o

110
16/input Normal file
View File

@ -0,0 +1,110 @@
\....|...-...../.....|....................-./............|/.....................-........./.....-.............
\..........-.....................-......................................|....................\..../.....-.....
....\......-...../../../...\......................\.........................-.............|.............|.....
.........../..../...........|/\.............\........\.......|.........|..|../............/.........|.........
\./...\........\..........\......./....../...............................|....|........|................/.....
|-.....|............/...............|...\...|...../......../.....|............|..\..|..../.......-.........\..
........-.............||../..........|.........../..................../.|.....|\..-/......./...\...\....-.....
....................//........................./..........\.......|...|.........../......\-......-...\........
....../..........\......\.....................\................\......\..\..|.................................
.................\...............-....../........./....-./..........|..../..-..|../................\..........
.............-...............-......|.../.....-.....//.\................../..........-......-...........-.....
.........../.\.....................\............-..........|.......\..................\.......................
...............\............/.|...\........../....\.............|...........\...............|.../........\....
./..............\................-\.../\.......-....................-..............-|.............\.-.........
../....../.........|..../......\...\.\.................|......./.......|...............-.........-............
-...-............................\.............-.\........-.....|.........././-......|......-..../...|........
................-.....................|..|...\.././.............|..........................-.............-....
.......|...............................|.......................................-......../.............|-...-..
.\|............................\................|.....-.....-................................./...-..\...../..
.......\......-....\|......|........................................./...||...............\...................
.................../......../.......-......\..............|..\...........-.........-.............../..........
........................\......................../.................-........................\.....\...........
..........|......|........................|.|\...............\...|.............-...-....-............--.......
............|........../....\..........\........../..-..|...........-...\........................./..-........
.............||../..../.......................-/.......\.....\............./|..-...............|.....|........
................................|..\.........-......./...........-../-............\................\....-../..
.............-.............................|.\...............................\\...............................
..|.......-................................\.......|.......\.....................|../\..........\..........-..
......-..\..........-.................\.-..../\......./......./..-.......................\.....-........\.....
............................../.....................\.................\................|..../\.............\..
..............................-.......\.........-..........\....../............./.....-........\...-.........|
/..................\...||..|...........\...............-............\..........|./.....-.-./.............../..
.....|......./...............\.......-................-...........................................\...........
.|.................../.....\............./.....\.................-.../.......-..............\..-..............
......\........|...|...........//..........|\.\..............................-..../...-............|..........
|......\....|\......|........../.........../........-.........|.-\//................/..\....|.../........|....
.-....-......................./.........\.........-.../............................-..|........|.....|...|....
.........-..................-..........-....-....................-....-./.......................|.../......\..
..-../......................-\.....|...\........./.-...............-.................../../............|......
.-/.......-../.......-...|\...../..........-...\.......\.........-....\-................-......|........-.....
.............................\\\............-..............|........../...................-......../....../../
.....-....\....\......................-..\...............-..|...............-................-.......\......|.
..-...\.............................../.../.............................--.......-..|.|\...../...............\
......\.../...-.....|....|......\.../|...................................-................-................./.
.......-......-.../..................|../..................\..........................\-..........-\..........
.-.......\.........|....|\/./-\.-.....|..................-...................................-|...\...........
...........-........../\..................\./..........................\...../...........-...\...../..\....-..
..-.|...../|......\..\........|.............-.....|..........\...-...-../......................../.......|....
......../................/..\.......\..-...|.....\.......|\..........................-..\../..........\./.....
........\.-......|......|..........|........-...................-..\.....-./..............-.\......\..........
........|./..................\........|......................\............................./.-\....\........-.
........\.|......\................/..\....-/.\.....-.....|............................\..\.|............|...-.
...-.....-|..................|...............-./.....................\..\............|.....-..................
..........|\./.....\..................|.........|.....................-\./..\........\........................
../........\..............|....-...............................................|..........-......../..........
..\..............|...../../....................-....\.....................|........\...\\.....................
...........................-...\......\......./../..........\-...../.......................-...........\......
-.|........................../.....|...............\..........-.............\...-................-.......-....
/../.........\........./......-.../..-..................-.......................\............--...............
\...............|......-..../......................................-........./|......................\|....../
.....\.......................................-...................-.../...........\.......|../.............|...
....-....||......\..\.......-.........-......../..../............\..................................-.........
...-..|.......\..\..|..........-../-..........\............../...............|..../........./....../.......|./
.......................\.......././.............\..................-..........|................../....|.......
-.|.....................\\.........../......./.|................/................|./......./....-.............
......-...............-....-................|./\..\-/...../......../....-....\....|.-.................../...\.
...............\......-...\...\....-....-/....................\./....../..................-|........\./...../.
.\......................./..\.........\.........|............|.......-../..\.-..|.-..........................|
..|../.....................|/......................./......../.../.........-.../.|./.|.-..............|....-..
...-.-/............/............|..........|....../\...\./.....|..................|....\............/.........
.....|........./.........\.............../......./../../...................|.......//.......\..\..........\...
......./.............\...........\.\..............................................\...................|.......
...............-|...../..-............................\.....-.............../\.........-....................\.
.........-.....................-...\...................-..../.................||....\.........-.......-..-....
.|../..\...\......|..\./.........\..............|..\/......../...............-..-....................-.....\..
..................|........\.-.....|.......\............../................................/...-....|...../...
...........-......./........-...--........\.../..-...../.|............|......./...............|....../\......\
.../.....\...................-..../....................................-......................|.............-.
.\.....|....-.....|.....-...................................................|../....\..................\.....-
....-........../\......../.......-....\............................./-.............-..........................
....\.........-........./......../....|..............\........\../.................\.|...............\........
.........-..............|./............-.......................\.......\......-\......\......../..............
-.|...|./-..........\..........-...-............|...-......................\..\.............................-.
............/......................../.........................................\/..........|.....|.-........|/
....../..|./..././.....-......................../....|................../..|........-.....................|./.
.......................\....................../......./......\/........\......./....../\|.....\...............
\...........\/.|../..................../...............\\...\..../..................\......./.................
.../................/...............\./....-./........../........./\..-.................................\.....
........-.......-...........\........-.......\............|............|.....-........|..|..../...............
.............|...|............/....\............................................-..\......./.../..........\...
...................../-..|...........-................../.\...|.....\.....|/.................|................
..|................\.....-...........|.\............-.........|....../...................\......-.|.......\...
........\......../.....-...\..\...........\........|/.............../......|.......|.\..|........|............
..........\.....................-..|/.....\............-............../.......................|./........\....
.......\........|...........\......\.......-..-.....|............./......|\..............................|....
.........\.......................-............-/.................................\............|...............
.........\................/.............................../..........\................-../../......|......-...
....\...-./...............\...............|.....\|....|/...............-...........................-..........
.|.......\.......-............./.......\............./....................|......|../......-...........\......
.....\.....-.....\...\................/......\...\../.\...\....\-....-././...............................|./..
.....................-.\.\.........../......./...-......./-.........................\.......|../....\..|..../.
|..\......./-......-...../..-....../.................../..-.....................-..../...........\...../......
......................................./................|....\/....\............/....../......................
......................../..........|........-............|.........................|.\................|....../
-.............-...|...........-....-..-.|\.......|......\..........-......|-...-......\.......................
...........\.\\.../.................\..........\..-......-......|.-............................-.||...|....../
....|................--........|.|..........|......\.............................................-............
.-..|................/../..-.........................../...../.....\.../....-.....\-..................../.....
............./|..........................\...................................-..-..........|....\..|..........
....|...../........./.-....-..................../.........../....................-................\./.........

10
16/input_test Normal file
View File

@ -0,0 +1,10 @@
.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....

502
16/main.s Normal file
View File

@ -0,0 +1,502 @@
%include "utils.s"
global _start
[bits 32]
[section .text]
%define LINE_LEN 111 ; real
%define FILENAME "input"
;%define LINE_LEN 11 ; test
;%define FILENAME "input_test"
;%define ITER_PRINT
_start:
; bit 3 bit 2 bit 1 bit 0
; up down left right
; start top left going right
mov dword [test_edge_line], 0
mov dword [test_edge_col], 0
mov byte [test_edge_dir], 1
mov byte [energized], 1
jmp next_iteration
next_edge_tile:
; clear energized
mov edi, energized
xor eax, eax
mov ecx, (128*128)/4
rep stosd
mov eax, [test_edge_line]
mov ecx, [test_edge_col]
mov bl, [test_edge_dir]
cmp bl, 1 ; we're testing going right
jne .maybe_2
; we're going down first col
cmp eax, LINE_LEN-2 ; check if last line
je .bl_corner
inc eax
jmp start_iterations
.bl_corner:
mov bl, 8 ; try going up
jmp start_iterations
.maybe_2:
cmp bl, 2 ; we're testing going left
jne .maybe_4
; we're going up the last col
cmp eax, 0 ; check if first line
je .tr_corner
dec eax
jmp start_iterations
.tr_corner:
mov bl, 4 ; try going down
jmp start_iterations
.maybe_4:
cmp bl, 4 ; we're testing going down
jne .maybe_8
; we're going along the top line backward
cmp ecx, 0 ; check if first col
je .tl_corner
dec ecx
jmp start_iterations
.tl_corner:
jmp game_over ; nothing to do! jump to exit
.maybe_8: ; we're testing going up
; we're going along the bottom line
cmp ecx, LINE_LEN-2 ; check if last col
je .br_corner
inc ecx
jmp start_iterations
.br_corner:
mov bl, 2 ; try going left
jmp start_iterations
start_iterations:
mov [test_edge_line], eax
mov [test_edge_col], ecx
mov [test_edge_dir], bl
mov edx, LINE_LEN
mul edx
add eax, ecx
mov byte [energized+eax], bl
next_iteration:
%ifdef ITER_PRINT
; debug printing
dbg:
xor esi, esi ; top line
.for_lines:
xor ecx, ecx ; leftmost char
.for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
pushad
test al, al
jz .prnt_char
p_string ansi_color_highbold_green
cmp bl, '.'
jne .prnt_char
popcnt ecx, eax
cmp ecx, 1
jg .prnt_num
cmp al, 1
je .prnt_right
cmp al, 2
je .prnt_left
cmp al, 4
je .prnt_down
.prnt_up: mov al, '^'
call print_char
jmp .prnt_done
.prnt_down: mov al, 'v'
call print_char
jmp .prnt_done
.prnt_left: mov al, '<'
call print_char
jmp .prnt_done
.prnt_right: mov al, '>'
call print_char
jmp .prnt_done
.prnt_num:
mov eax, ecx
call print_dec
jmp .prnt_done
.prnt_char:
mov al, [esi+ecx+file]
call print_char
.prnt_done:
p_string ansi_color_reset
popad
.for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe .for_chars
.for_chars_done:
.for_lines_cont:
call newline
add esi, LINE_LEN
cmp esi, len(file)
jb .for_lines
call newline
; debug printing end
%endif
xor esi, esi ; top line
for_lines:
xor ecx, ecx ; leftmost char
for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
; skip if not energized
test eax, eax
jz for_chars_cont
; select thing
cmp bl, '.'
je empty
cmp bl, '/'
je mirror_one
cmp bl, '\'
je mirror_two
cmp bl, '-'
je horz_split
cmp bl, '|'
je vert_split
p_string what_the_fuck
jmp exit
empty: ; .
; propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-1], 1<<1
.t_down:
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .done
or byte [esi+ecx+energized-LINE_LEN], 1<<3
.done:
jmp for_chars_cont
mirror_one: ; /
; our energized is what hits us
; test right >/
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
.t_left: ; /<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
.t_down:
bt eax, 2 ; v
jnc .t_up ; /
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.t_up:
bt eax, 3 ; /
jnc .done ; ^
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.done:
jmp for_chars_cont
mirror_two: ; \
; our energized is what hits us
; test right >\
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
.t_left: ; \<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.t_down:
bt eax, 2 ; v
jnc .t_up ; \
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.t_up:
bt eax, 3 ; \
jnc .done ; ^
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp for_chars_cont
horz_split: ; -
; our energized is what hits us
; right and left propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_vert
or byte [esi+ecx+energized-1], 1<<1
; down and up go both left and right
.t_vert:
and eax, 1<<2 | 1<<3
jz .done
or byte [esi+ecx+energized+1], 1<<0 ; right going right
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp for_chars_cont
vert_split: ; |
; our energized is what hits us
; down and up propagate
; test down
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .t_vert
or byte [esi+ecx+energized-LINE_LEN], 1<<3
; left and right go both down and up
.t_vert:
and eax, 1<<0 | 1<<1
jz .done
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.done:
for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe for_chars
for_chars_done:
for_lines_cont:
add esi, LINE_LEN
cmp esi, len(file)
jb for_lines
xor ebp, ebp ; energized count
sub esi, LINE_LEN ; last line
; now go through backward
bkwd_for_lines:
mov ecx, LINE_LEN-2 ; rightmost char
bkwd_for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
; skip if not energized
test eax, eax
jz bkwd_for_chars_cont
inc ebp ; energized count
; select thing
cmp bl, '.'
je bkwd_empty
cmp bl, '/'
je bkwd_mirror_one
cmp bl, '\'
je bkwd_mirror_two
cmp bl, '-'
je bkwd_horz_split
cmp bl, '|'
je bkwd_vert_split
p_string what_the_fuck
jmp exit
bkwd_empty: ; .
; propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-1], 1<<1
.t_down:
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .done
or byte [esi+ecx+energized-LINE_LEN], 1<<3
.done:
jmp bkwd_for_chars_cont
bkwd_mirror_one: ; /
; our energized is what hits us
; test right >/
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
.t_left: ; /<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
.t_down:
bt eax, 2 ; v
jnc .t_up ; /
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.t_up:
bt eax, 3 ; /
jnc .done ; ^
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.done:
jmp bkwd_for_chars_cont
bkwd_mirror_two: ; \
; our energized is what hits us
; test right >\
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
.t_left: ; \<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.t_down:
bt eax, 2 ; v
jnc .t_up ; \
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.t_up:
bt eax, 3 ; \
jnc .done ; ^
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp bkwd_for_chars_cont
bkwd_horz_split: ; -
; our energized is what hits us
; right and left propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_vert
or byte [esi+ecx+energized-1], 1<<1
; down and up go both left and right
.t_vert:
and eax, 1<<2 | 1<<3
jz .done
or byte [esi+ecx+energized+1], 1<<0 ; right going right
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp bkwd_for_chars_cont
bkwd_vert_split: ; |
; our energized is what hits us
; down and up propagate
; test down
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .t_vert
or byte [esi+ecx+energized-LINE_LEN], 1<<3
; left and right go both down and up
.t_vert:
and eax, 1<<0 | 1<<1
jz .done
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.done:
bkwd_for_chars_cont:
dec ecx
jnz bkwd_for_chars
bkwd_for_chars_done:
bkwd_for_lines_cont:
sub esi, LINE_LEN
jns bkwd_for_lines
cmp ebp, [last_energized]
mov [last_energized], ebp
jne next_iteration
; print final
xor ebp, ebp
print_final:
xor esi, esi ; top line
.for_lines:
xor ecx, ecx ; leftmost char
.for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
test al, al
jz .prnt_char
inc ebp
p_string ansi_color_highbold_green
cmp bl, '.'
jne .prnt_char
popcnt edx, eax
cmp edx, 1
jg .prnt_num
cmp al, 1
je .prnt_right
cmp al, 2
je .prnt_left
cmp al, 4
je .prnt_down
.prnt_up: mov al, '^'
call print_char
jmp .prnt_done
.prnt_down: mov al, 'v'
call print_char
jmp .prnt_done
.prnt_left: mov al, '<'
call print_char
jmp .prnt_done
.prnt_right: mov al, '>'
call print_char
jmp .prnt_done
.prnt_num:
mov eax, edx
call print_dec
jmp .prnt_done
.prnt_char:
mov al, [esi+ecx+file]
call print_char
.prnt_done:
p_string ansi_color_reset
.for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe .for_chars
.for_chars_done:
.for_lines_cont:
call newline
add esi, LINE_LEN
cmp esi, len(file)
jb .for_lines
mov eax, ebp
call print_dec
call newline
call newline
cmp [final_value], ebp
cmova ebp, [final_value]
mov [final_value], ebp
jmp next_edge_tile
game_over:
mov eax, [final_value]
call print_dec
call newline
jmp exit
[section .data]
final_value: dd 0
last_energized: dd 0
test_edge_line: dd 0
test_edge_col: dd 0
test_edge_dir: dd 0
file: incbin FILENAME
.over:
[section .bss]
padding: resb 128
energized: resb 128*128
[section .rodata]
what_the_fuck: db "Something is terribly wrong in this world."
.over:
ansi_color_reset: db `\e[0m`
.over:
ansi_color_green: db `\e[0;32m`
.over:
ansi_color_highbold_green: db `\e[1;92m`
.over:

429
16/main_part1.s Normal file
View File

@ -0,0 +1,429 @@
%include "utils.s"
global _start
[bits 32]
[section .text]
%define LINE_LEN 111 ; real
%define FILENAME "input"
;%define LINE_LEN 11 ; test
;%define FILENAME "input_test"
;%define ITER_PRINT
_start:
; bit 3 bit 2 bit 1 bit 0
; up down left right
; top left starts going right
mov byte [energized], 1
next_iteration:
%ifdef ITER_PRINT
; debug printing
dbg:
xor esi, esi ; top line
.for_lines:
xor ecx, ecx ; leftmost char
.for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
pushad
test al, al
jz .prnt_char
p_string ansi_color_highbold_green
cmp bl, '.'
jne .prnt_char
popcnt ecx, eax
cmp ecx, 1
jg .prnt_num
cmp al, 1
je .prnt_right
cmp al, 2
je .prnt_left
cmp al, 4
je .prnt_down
.prnt_up: mov al, '^'
call print_char
jmp .prnt_done
.prnt_down: mov al, 'v'
call print_char
jmp .prnt_done
.prnt_left: mov al, '<'
call print_char
jmp .prnt_done
.prnt_right: mov al, '>'
call print_char
jmp .prnt_done
.prnt_num:
mov eax, ecx
call print_dec
jmp .prnt_done
.prnt_char:
mov al, [esi+ecx+file]
call print_char
.prnt_done:
p_string ansi_color_reset
popad
.for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe .for_chars
.for_chars_done:
.for_lines_cont:
call newline
add esi, LINE_LEN
cmp esi, len(file)
jb .for_lines
call newline
; debug printing end
%endif
xor esi, esi ; top line
for_lines:
xor ecx, ecx ; leftmost char
for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
; skip if not energized
test eax, eax
jz for_chars_cont
; select thing
cmp bl, '.'
je empty
cmp bl, '/'
je mirror_one
cmp bl, '\'
je mirror_two
cmp bl, '-'
je horz_split
cmp bl, '|'
je vert_split
p_string what_the_fuck
jmp exit
empty: ; .
; propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-1], 1<<1
.t_down:
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .done
or byte [esi+ecx+energized-LINE_LEN], 1<<3
.done:
jmp for_chars_cont
mirror_one: ; /
; our energized is what hits us
; test right >/
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
.t_left: ; /<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
.t_down:
bt eax, 2 ; v
jnc .t_up ; /
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.t_up:
bt eax, 3 ; /
jnc .done ; ^
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.done:
jmp for_chars_cont
mirror_two: ; \
; our energized is what hits us
; test right >\
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
.t_left: ; \<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.t_down:
bt eax, 2 ; v
jnc .t_up ; \
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.t_up:
bt eax, 3 ; \
jnc .done ; ^
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp for_chars_cont
horz_split: ; -
; our energized is what hits us
; right and left propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_vert
or byte [esi+ecx+energized-1], 1<<1
; down and up go both left and right
.t_vert:
and eax, 1<<2 | 1<<3
jz .done
or byte [esi+ecx+energized+1], 1<<0 ; right going right
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp for_chars_cont
vert_split: ; |
; our energized is what hits us
; down and up propagate
; test down
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .t_vert
or byte [esi+ecx+energized-LINE_LEN], 1<<3
; left and right go both down and up
.t_vert:
and eax, 1<<0 | 1<<1
jz .done
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.done:
for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe for_chars
for_chars_done:
for_lines_cont:
add esi, LINE_LEN
cmp esi, len(file)
jb for_lines
xor ebp, ebp ; energized count
sub esi, LINE_LEN ; last line
; now go through backward
bkwd_for_lines:
mov ecx, LINE_LEN-2 ; rightmost char
bkwd_for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
; skip if not energized
test eax, eax
jz bkwd_for_chars_cont
inc ebp ; energized count
; select thing
cmp bl, '.'
je bkwd_empty
cmp bl, '/'
je bkwd_mirror_one
cmp bl, '\'
je bkwd_mirror_two
cmp bl, '-'
je bkwd_horz_split
cmp bl, '|'
je bkwd_vert_split
p_string what_the_fuck
jmp exit
bkwd_empty: ; .
; propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-1], 1<<1
.t_down:
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .done
or byte [esi+ecx+energized-LINE_LEN], 1<<3
.done:
jmp bkwd_for_chars_cont
bkwd_mirror_one: ; /
; our energized is what hits us
; test right >/
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
.t_left: ; /<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
.t_down:
bt eax, 2 ; v
jnc .t_up ; /
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.t_up:
bt eax, 3 ; /
jnc .done ; ^
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.done:
jmp bkwd_for_chars_cont
bkwd_mirror_two: ; \
; our energized is what hits us
; test right >\
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
.t_left: ; \<
bt eax, 1
jnc .t_down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.t_down:
bt eax, 2 ; v
jnc .t_up ; \
or byte [esi+ecx+energized+1], 1<<0 ; right going right
.t_up:
bt eax, 3 ; \
jnc .done ; ^
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp bkwd_for_chars_cont
bkwd_horz_split: ; -
; our energized is what hits us
; right and left propagate
; test right
bt eax, 0
jnc .t_left
or byte [esi+ecx+energized+1], 1<<0
.t_left:
bt eax, 1
jnc .t_vert
or byte [esi+ecx+energized-1], 1<<1
; down and up go both left and right
.t_vert:
and eax, 1<<2 | 1<<3
jz .done
or byte [esi+ecx+energized+1], 1<<0 ; right going right
or byte [esi+ecx+energized-1], 1<<1 ; left going left
.done:
jmp bkwd_for_chars_cont
bkwd_vert_split: ; |
; our energized is what hits us
; down and up propagate
; test down
bt eax, 2
jnc .t_up
or byte [esi+ecx+energized+LINE_LEN], 1<<2
.t_up:
bt eax, 3
jnc .t_vert
or byte [esi+ecx+energized-LINE_LEN], 1<<3
; left and right go both down and up
.t_vert:
and eax, 1<<0 | 1<<1
jz .done
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
.done:
bkwd_for_chars_cont:
dec ecx
jnz bkwd_for_chars
bkwd_for_chars_done:
bkwd_for_lines_cont:
sub esi, LINE_LEN
jns bkwd_for_lines
cmp ebp, [last_energized]
mov [last_energized], ebp
jne next_iteration
; print final
xor ebp, ebp
print_final:
xor esi, esi ; top line
.for_lines:
xor ecx, ecx ; leftmost char
.for_chars:
movzx eax, byte [esi+ecx+energized]
movzx ebx, byte [esi+ecx+file]
test al, al
jz .prnt_char
inc ebp
p_string ansi_color_highbold_green
cmp bl, '.'
jne .prnt_char
popcnt edx, eax
cmp edx, 1
jg .prnt_num
cmp al, 1
je .prnt_right
cmp al, 2
je .prnt_left
cmp al, 4
je .prnt_down
.prnt_up: mov al, '^'
call print_char
jmp .prnt_done
.prnt_down: mov al, 'v'
call print_char
jmp .prnt_done
.prnt_left: mov al, '<'
call print_char
jmp .prnt_done
.prnt_right: mov al, '>'
call print_char
jmp .prnt_done
.prnt_num:
mov eax, edx
call print_dec
jmp .prnt_done
.prnt_char:
mov al, [esi+ecx+file]
call print_char
.prnt_done:
p_string ansi_color_reset
.for_chars_cont:
inc ecx
cmp ecx, LINE_LEN-2
jbe .for_chars
.for_chars_done:
.for_lines_cont:
call newline
add esi, LINE_LEN
cmp esi, len(file)
jb .for_lines
call newline
game_over:
mov eax, ebp
call print_dec
call newline
jmp exit
[section .data]
final_value: dd 0
last_energized: dd 0
file: incbin FILENAME
.over:
[section .bss]
padding: resb 128
energized: resb 128*128
[section .rodata]
what_the_fuck: db "Something is terribly wrong in this world."
.over:
ansi_color_reset: db `\e[0m`
.over:
ansi_color_green: db `\e[0;32m`
.over:
ansi_color_highbold_green: db `\e[1;92m`
.over:

285
16/utils.s Normal file
View File

@ -0,0 +1,285 @@
[bits 32]
[section .text]
; call # val val2
; int $0x80 eax eax edx -
;
; arg1 arg2 arg3 arg4 arg5 arg6 arg7
; ebx ecx edx esi edi ebp -
exit:
mov eax, 1 ; exit
int 0x80
; filename in EBX
; return handle in EBX
; read only
open_file:
push eax
push ecx
mov eax, 5 ; open
xor ecx, ecx ; read only
int 0x80
mov ebx, eax
pop ecx
pop eax
ret
; file handle in EBX
; buffer in ECX
; count of bytes to read in EDX
; return bytes actually read in EAX
; exits on error
read_file:
mov eax, 3 ; read
int 0x80
test eax, eax
js .err
ret
.err:
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, .err_str
mov edx, 21
int 0x80
jmp exit
.err_str: db `Could not read file.\n`
; string input in ESI
; value in EAX
; CF set if none, clear if some
; ESI set past checked area
dec_parse:
push ebx
push edx
push edi
xor eax, eax
xor edi, edi
mov ebx, 10 ; base
lodsb
sub al, '0'
js .no_input
cmp al, 9
jle .got_char
.no_input:
stc ; set CF
jmp .done
.loop:
xor eax,eax
lodsb
sub al, '0'
js .dec_done
cmp al, 9
jg .dec_done
.got_char:
xchg edi,eax
mul ebx
add edi,eax
jmp .loop
.dec_done:
clc ; clear CF
.done:
mov eax,edi
pop edi
pop edx
pop ebx
ret
; string input in ESI
; value in EAX
; CF set if none, clear if some
; ESI set past checked area
sign_dec_parse:
push ebx
push ecx
push edx
push edi
xor eax, eax
xor edi, edi
xor ecx, ecx ; neg flag
mov ebx, 10 ; base
cmp byte [esi], '-'
jne .no_minus
inc esi
mov cl, 1
.no_minus:
lodsb
sub al, '0'
js .no_input
cmp al, 9
jle .got_char
.no_input:
stc ; set CF
jmp .done
.loop:
xor eax,eax
lodsb
sub al, '0'
js .dec_done
cmp al, 9
jg .dec_done
.got_char:
xchg edi,eax
mul ebx
add edi,eax
jmp .loop
.dec_done:
test ecx, ecx
jz .not_neg
neg edi
.not_neg:
clc ; clear CF
.done:
mov eax,edi
pop edi
pop edx
pop ecx
pop ebx
ret
; modifies no regs
newline:
pushad
push 10
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, esp ; string
mov edx, 1 ; length
int 0x80
add esp, 4
popad
ret
; modifies no regs
space:
pushad
push 9
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, esp ; string
mov edx, 1 ; length
int 0x80
add esp, 4
popad
ret
; input in EAX, all regs unmodified
print_dec:
pushad ; save regs
; max 4294967296 is 10 chars
; round to nearest 32-bit boundary
sub esp, 12
; string in ECX, length in EDX
lea ecx, [esp+11] ; last possible byte
; check for 0
test eax, eax
jz .zero
mov ebx, 10 ; base 10
xor esi, esi ; counter
.div_shit:
xor edx, edx
; divide
div ebx
dec ecx ; next char
inc esi
; store
add dl, '0'
mov byte [ecx], dl
; check if done
test eax, eax
jnz .div_shit ; continue
mov edx, esi ; counter in edx
jmp .write
.zero:
mov byte [ecx], '0'
mov edx, 1 ; length
.write:
mov eax, 4 ; write
mov ebx, 1 ; stdout
int 0x80
add esp, 12 ; restore stack
popad ; restore regs
ret
; input in EAX, all regs unmodified
print_sign_dec:
pushad ; save regs
; range -2147483648 to 2147483647 is 11 chars
; round to nearest 32-bit boundary
sub esp, 12
; string in ECX, length in EDX
lea ecx, [esp+11] ; last possible byte
; check for 0, negative
xor ebp, ebp
test eax, eax
jz .zero
jns .positive
neg eax
mov ebp, 1
.positive:
mov ebx, 10 ; base 10
xor esi, esi ; counter
.div_shit:
xor edx, edx
; divide
div ebx
dec ecx ; next char
inc esi
; store
add dl, '0'
mov byte [ecx], dl
; check if done
test eax, eax
jnz .div_shit ; continue
mov edx, esi ; counter in edx
jmp .write
.zero:
mov byte [ecx], '0'
mov edx, 1 ; length
.write:
test ebp, ebp
jz .no_minus
dec ecx
inc edx
mov byte [ecx], '-'
.no_minus:
mov eax, 4 ; write
mov ebx, 1 ; stdout
int 0x80
add esp, 12 ; restore stack
popad ; restore regs
ret
; input in ESI, len in ECX, all regs unmodified
print_string:
pushad ; save regs
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov edx, ecx ; length
mov ecx, esi ; string
int 0x80
popad ; restore regs
ret
; input in AL, all regs unmodified
print_char:
pushad ; save regs
push eax
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov edx, 1 ; length
mov ecx, esp ; string
int 0x80
add esp, 4
popad ; restore regs
ret
; --- MACROS ---
%define len(x) x %+ .over - x
%macro p_string 1
push esi
push ecx
mov esi, %1
mov ecx, len(%1)
call print_string
pop ecx
pop esi
%endmacro