diff --git a/Makefile b/Makefile index 16e59af..c94c983 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NASM = nasm LD = ld -NASM_FLAGS := -felf64 -Isrc -Ox -Ov -w+all +NASM_FLAGS := -felf64 -Isrc -Ox -Ov -w+all -w-reloc-abs-dword -w-reloc-rel-dword LD_FLAGS := --strip-all DEBUG_LD_FLAGS := -g diff --git a/src/drawing.asm b/src/drawing.asm index 738bdd4..3436be6 100644 --- a/src/drawing.asm +++ b/src/drawing.asm @@ -13,6 +13,8 @@ section .bss global simulation_running simulation_running: RESB 1 + next_frame_ptr: RESQ 1 + section .rodata clear: db ESC_CHAR, "[2J", 0 reset: db ESC_CHAR, "[0m", 0 @@ -32,6 +34,7 @@ section .text extern print_str extern string_copy extern memory_set +extern alloc global init_gameboard init_gameboard: @@ -51,6 +54,7 @@ init_gameboard: pop rdx pop rdi add rdi, rdx; get pointer to last char on screen + push rdx push rdi add rdi, ESC_chars_compensation_Len lea rsi, [reset] @@ -63,6 +67,9 @@ init_gameboard: lea rsi, [statusbar] call string_copy + pop rdi + call alloc + mov [next_frame_ptr], rax ret global print_game_ui @@ -90,4 +97,71 @@ print_game_ui: call print_str + ret + +%macro check_if_hashtag 1 + cmp r8, %1 + jl +7 + cmp r9, %1 + ja +5 + mov r11b, [%1] + cmp r11b, '#' + jne +2 + inc dl +%endmacro + +global step_simulation: +step_simultion: + mov rdi, [next_frame_ptr]; destination + mov rsi, [gameboard_ptr]; source + mov rcx, [gameboard_size]; number of iterations + + mov r8, rsi; store lowest address posible so we are not checking out of bounds + mov r9, rsi + add r9, rcx; store higest address posible so we are not checking out of bounds + + mov r10, [term_cols] + ;mov r11, [term_rows] this register has been confiscated since i cannot use ah because of error: cannot use high byte register in rex instruction + + xor rax, rax; this shouldn't be needed but just to be sure + xor r11, r11 + xor rdx, rdx; we will use dl as # counter + .for_every_column_on_gameboard: + mov al, [rdi]; NOTE to self if i need extra register i can shift this to ah and free up r11 + + + inc rdi + check_if_hashtag rdi + dec rdi + + check_if_hashtag rdi-1 + + + add rdi, r10 + + check_if_hashtag rdi + + inc rdi + check_if_hashtag rdi + dec rdi + + check_if_hashtag rdi-1 + + sub rdi, r10 + + + sub rdi, r10 + check_if_hashtag rdi + + inc rdi + check_if_hashtag rdi + dec rdi + + check_if_hashtag rdi-1 + + add rdi, r10 + + + ; TODO create jump table + ret diff --git a/src/str.asm b/src/str.asm index 6f83b2c..91ae360 100644 --- a/src/str.asm +++ b/src/str.asm @@ -141,3 +141,65 @@ memory_set:; takes destination in rdi, byte in sil and lenght in rdx .true_function_exit: mov rax, r9; return pointer to memory area same as memset in libc ret + + + + + + + +global memory_copy: +memory_copy:; takes destination in rdi, source in rsi and lenght in rdx + ; first check if value is 16 byte alligned + + mov r9, rdi + + cmp rdx, 16 + jnl .write_16_or_more_bytes + mov rcx, rdx + jmp .write_less_than_16_bytes + .write_16_or_more_bytes: + mov rax, rdi; move destination to rax + and rax, 0xF; offset is stored in rax + + + test al, al; check if resault is 0 + jz .addr_is_16_Byte_alligned + + + mov cl, 16 + sub cl, al; now offset to first higher 16 byte alligned address is stored in r8 + movzx rcx, cl; remove ani posible garbage + + + .write_less_than_16_bytes: + sub rdx, rcx; we will write these bytes now + + rep movsb + + .addr_is_16_Byte_alligned: + mov r10, rdx + shr r10, 4; set it to how many 128bit(16Byte) chunk we need + test r10, r10; check if we need to write aditional 16 bytes at all + jz .function_exit + + .move_16_bytes: + movdqa xmm8, [rsi] + movdqa [rdi], xmm8 + add rdi, 16 + add rsi, 16 + sub rdx, 16 + + cmp rdx, 16; test if rdx is less than 16 + jge .move_16_bytes + + .function_exit: + + test rdx, rdx; test if rdx is 0 + jz .true_function_exit + movzx rcx, dl + jmp .write_less_than_16_bytes + + .true_function_exit: + mov rax, r9; return pointer to memory area same as memset in libc + ret