157 lines
3.0 KiB
NASM
157 lines
3.0 KiB
NASM
%include "symbols.asm"
|
|
|
|
|
|
|
|
section .bss
|
|
global multipurpuse_buf
|
|
multipurpuse_buf: RESB 16
|
|
|
|
global term_rows
|
|
term_rows: RESW 1
|
|
global term_cols
|
|
term_cols: RESW 1
|
|
|
|
global gameboard_ptr
|
|
gameboard_ptr: RESQ 1
|
|
|
|
global gameboard_size
|
|
gameboard_size: RESQ 1
|
|
|
|
extern cursor_rows
|
|
extern cursor_cols
|
|
|
|
global running_in_tty
|
|
running_in_tty: RESB 1
|
|
|
|
section .rodata
|
|
extern resetLen
|
|
|
|
hide_cursor: db ESC_CHAR, "[?25l", 0
|
|
show_cursor: db ESC_CHAR, "[?25h", 0
|
|
|
|
help_text: db "asm-game-of-life [args]",0xA,"-h display this help menu",0xA,"Controls:",0xA,"use arrow keys to move around",0xA,"ENTER to invert cell",0xA,"p to START/STOP simulation",0xA,"k to increase simulation speed",0xA,"j to decrese simulation speed",0xA, 0
|
|
|
|
section .text
|
|
extern print_str
|
|
extern unsigned_int_to_ascii
|
|
extern init_alloc
|
|
extern alloc
|
|
|
|
extern init_gameboard
|
|
extern print_game_ui
|
|
|
|
extern handle_user_input
|
|
|
|
extern disable_canonical_mode_and_echo
|
|
extern reset_terminal
|
|
|
|
global _start
|
|
_start:
|
|
; get terminal dimensions
|
|
mov rax, SYS_IOCTL
|
|
mov rdi, STDOUT
|
|
mov rsi, TIOCGWINSZ
|
|
lea rdx, [multipurpuse_buf]
|
|
syscall
|
|
|
|
mov word ax, [multipurpuse_buf]; rows are stored at offset 0
|
|
mov [term_rows], ax
|
|
|
|
mov word ax, [multipurpuse_buf+2]; cols are stored at offset 2
|
|
mov [term_cols], ax
|
|
|
|
; handle args
|
|
pop rcx; get argc (number of arguments)
|
|
pop rax; get rid of program name arugument
|
|
cmp rcx, 1
|
|
jle .no_arguments_provided
|
|
dec rcx
|
|
.handle_arg:
|
|
pop rax
|
|
mov word di, [rax]
|
|
|
|
cmp di, 0x682D; check if -h was passed
|
|
jne .next_arg
|
|
lea rdi, [help_text]
|
|
call print_str
|
|
jmp .exit_program
|
|
|
|
.next_arg:
|
|
dec rcx
|
|
test rcx, rcx
|
|
jnz .handle_arg
|
|
|
|
.no_arguments_provided:
|
|
|
|
|
|
pop rax; get rid of null termination of argv
|
|
; handle enviroment vars
|
|
|
|
.handle_env:
|
|
pop rax
|
|
test rax, rax; test if we reached end of envs
|
|
jz .no_envs
|
|
|
|
mov dword edi, [rax]
|
|
cmp edi, 0x4D524554; check for "TERM" inverted becose endiannes
|
|
jne .handle_env
|
|
mov qword rdi, [rax+5]; remove the TERM= part this should never segfault since there sould allwas be other data behind enviroment vars and i dont mind garbage
|
|
mov rsi, 0xffffffffff
|
|
and rdi, rsi
|
|
mov rsi, 0x78756e696c
|
|
cmp rdi, rsi; check for "linux"
|
|
jne .no_envs
|
|
mov byte [running_in_tty], 1
|
|
|
|
.no_envs:
|
|
|
|
|
|
call init_alloc
|
|
|
|
xor rax, rax
|
|
xor rcx, rcx
|
|
|
|
mov ax, [term_rows]
|
|
mov cx, [term_cols]
|
|
mul rcx
|
|
mov rdi, rax
|
|
mov qword [gameboard_size], rax
|
|
inc rdi; addition byte for NULL BYTE
|
|
lea rax, [resetLen]
|
|
add rdi, rax
|
|
add rdi, ESC_chars_compensation_Len
|
|
call alloc
|
|
mov [gameboard_ptr], rax; stores pointer to gameboard array
|
|
call init_gameboard
|
|
|
|
; make stdin non-blocking in case polling somehow fails, or am i stupid
|
|
mov rax, SYS_FCNTL
|
|
mov rdi, STDIN
|
|
mov rsi, F_SETFL
|
|
mov rdx, O_NONBLOCK
|
|
syscall
|
|
|
|
lea rdi, [hide_cursor]
|
|
call print_str
|
|
|
|
call print_game_ui
|
|
|
|
call disable_canonical_mode_and_echo
|
|
|
|
call print_game_ui
|
|
|
|
call handle_user_input
|
|
|
|
call reset_terminal
|
|
|
|
lea rdi, [show_cursor]
|
|
call print_str
|
|
|
|
.exit_program:
|
|
mov rax, SYS_EXIT
|
|
mov rdi, 0 ; return code
|
|
syscall
|
|
|
|
|
|
|