Compare commits
19 Commits
5b56f6bcb6
..
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 719bc17fcd | |||
| 5c91ace69b | |||
| 872c842e7c | |||
| a6a7debf2e | |||
| 57987228b0 | |||
| 83d3f3ac5a | |||
| 45c6d0eb83 | |||
| 670a6a2602 | |||
| e70b9ac765 | |||
| 6112537e9b | |||
| 3e59f36d4e | |||
| f26553e7c7 | |||
| db00e98b4c | |||
| b449c66a66 | |||
| 7dc5237c3e | |||
| 7fd699ea38 | |||
| b5c539a3a2 | |||
| ce343ff9db | |||
| d6ee106682 |
@@ -0,0 +1,17 @@
|
|||||||
|
name: build_test
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: arch
|
||||||
|
steps:
|
||||||
|
- name: fix package cache
|
||||||
|
run: rm -fr /var/cache/pacman/pkg/* && pacman -Syy archlinux-keyring --needed --noconfirm && pacman-key --init && pacman-key --populate archlinux
|
||||||
|
- name: get dependencies
|
||||||
|
run: pacman -Sy nodejs make nasm binutils --needed --noconfirm
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: make -j$(nproc)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<img src="https://git.pupes.org/repo-avatars/e4ede9d30f070c9e191eace5a88dcaa40434b9cadf60204122fab5a83aec9a9f" alt="logo of ParaDocs" width="196"></img>
|
||||||
|
[](https://git.pupes.org/PoliEcho/asm-game-of-life/actions?workflow=build_test.yaml)
|
||||||
|
# AMD64 Assembly Game of life
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
> AMD64 Linux Kernel
|
||||||
|
### Build only
|
||||||
|
> nasm
|
||||||
|
> ld
|
||||||
|
> make
|
||||||
|
|
||||||
|
## Download
|
||||||
|
#### TODO: add releases link
|
||||||
|
|
||||||
|
## Build
|
||||||
|
```shell
|
||||||
|
make
|
||||||
|
```
|
||||||
+35
-2
@@ -14,6 +14,8 @@ section .bss
|
|||||||
simulation_running: RESB 1
|
simulation_running: RESB 1
|
||||||
|
|
||||||
next_frame_ptr: RESQ 1
|
next_frame_ptr: RESQ 1
|
||||||
|
section .data
|
||||||
|
extern simulation_speed
|
||||||
|
|
||||||
section .rodata
|
section .rodata
|
||||||
clear: db ESC_CHAR, "[2J", 0
|
clear: db ESC_CHAR, "[2J", 0
|
||||||
@@ -24,8 +26,9 @@ section .rodata
|
|||||||
|
|
||||||
home_cursor: db ESC_CHAR, "[H", 0
|
home_cursor: db ESC_CHAR, "[H", 0
|
||||||
|
|
||||||
statusbar: db ESC_CHAR, "[32;100m", "Use arrow keys to move cursor, enter to invert cell j/k to change simulation speed, p to simulation", 0
|
statusbar: db ESC_CHAR, "[32;100m", "Use arrow keys to move cursor, enter to invert cell j/k to change simulation speed, p to simulation. Frame Delay multiplier:", 0
|
||||||
START_STOP_pos: equ $-statusbar-17
|
statusbarLen: equ $-statusbar
|
||||||
|
START_STOP_pos: equ statusbarLen-42
|
||||||
|
|
||||||
|
|
||||||
start_str: db "START", 0
|
start_str: db "START", 0
|
||||||
@@ -49,6 +52,7 @@ extern string_copy
|
|||||||
extern memory_set
|
extern memory_set
|
||||||
extern memory_copy
|
extern memory_copy
|
||||||
extern alloc
|
extern alloc
|
||||||
|
extern unsigned_int_to_ascii
|
||||||
|
|
||||||
global init_gameboard
|
global init_gameboard
|
||||||
init_gameboard:
|
init_gameboard:
|
||||||
@@ -95,6 +99,7 @@ print_game_ui:
|
|||||||
push rdi
|
push rdi
|
||||||
add rdi, [gameboard_size]
|
add rdi, [gameboard_size]
|
||||||
sub di, [term_cols]
|
sub di, [term_cols]
|
||||||
|
push rdi
|
||||||
add rdi, START_STOP_pos
|
add rdi, START_STOP_pos
|
||||||
|
|
||||||
mov cl, [simulation_running]
|
mov cl, [simulation_running]
|
||||||
@@ -107,6 +112,34 @@ print_game_ui:
|
|||||||
.end_simulation_running_check:
|
.end_simulation_running_check:
|
||||||
call string_copy
|
call string_copy
|
||||||
|
|
||||||
|
pop rdi
|
||||||
|
add rdi, statusbarLen
|
||||||
|
|
||||||
|
movss xmm0, [simulation_speed]
|
||||||
|
|
||||||
|
cvttss2si rsi, xmm0
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
call unsigned_int_to_ascii
|
||||||
|
pop rdi
|
||||||
|
add rdi, rax
|
||||||
|
|
||||||
|
mov byte [rdi], '.'
|
||||||
|
inc rdi
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
cvtsi2ss xmm1, rax
|
||||||
|
|
||||||
|
subss xmm0, xmm1; get only value after decimal point
|
||||||
|
mov rax, 10
|
||||||
|
cvtsi2ss xmm1, rax
|
||||||
|
|
||||||
|
mulss xmm0, xmm1
|
||||||
|
cvttss2si rsi, xmm0; get first decimal point as int
|
||||||
|
|
||||||
|
call unsigned_int_to_ascii; rdi already set
|
||||||
|
|
||||||
|
|
||||||
pop rdi
|
pop rdi
|
||||||
call print_str
|
call print_str
|
||||||
|
|
||||||
|
|||||||
+28
-12
@@ -15,6 +15,10 @@ section .bss
|
|||||||
section .data
|
section .data
|
||||||
cursor_rows: dw 1
|
cursor_rows: dw 1
|
||||||
cursor_cols: dw 1
|
cursor_cols: dw 1
|
||||||
|
|
||||||
|
|
||||||
|
global simulation_speed
|
||||||
|
simulation_speed dd 1.0
|
||||||
section .rodata
|
section .rodata
|
||||||
extern reset
|
extern reset
|
||||||
|
|
||||||
@@ -25,6 +29,8 @@ section .rodata
|
|||||||
|
|
||||||
cursor_color: db ESC_CHAR, "[45m", 0
|
cursor_color: db ESC_CHAR, "[45m", 0
|
||||||
|
|
||||||
|
speed_multiplier dd 50.0
|
||||||
|
|
||||||
arrow_switch_statement:
|
arrow_switch_statement:
|
||||||
dq handle_user_input.arrow_up
|
dq handle_user_input.arrow_up
|
||||||
dq handle_user_input.arrow_down
|
dq handle_user_input.arrow_down
|
||||||
@@ -63,7 +69,10 @@ handle_user_input:; main loop of the program
|
|||||||
mov word [r12+4], POLLIN
|
mov word [r12+4], POLLIN
|
||||||
mov rdi, r12
|
mov rdi, r12
|
||||||
mov rsi, 1; only one file descriptor is provided
|
mov rsi, 1; only one file descriptor is provided
|
||||||
mov rdx, 50; no timeout. maybe use this for final sleep but run if user inputs something TODO
|
movss xmm0, [speed_multiplier]
|
||||||
|
movss xmm1, [simulation_speed]
|
||||||
|
mulss xmm0, xmm1; callculate sleep lenght
|
||||||
|
cvttss2si rdx, xmm0; truncate and copy to rdx
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
test rax, rax; SYS_POLL returns 0 when no change happens within timeout
|
test rax, rax; SYS_POLL returns 0 when no change happens within timeout
|
||||||
@@ -179,7 +188,13 @@ handle_user_input:; main loop of the program
|
|||||||
cmp al, 'j'
|
cmp al, 'j'
|
||||||
jne .check_k
|
jne .check_k
|
||||||
|
|
||||||
; TODO implement simulation speed
|
movss xmm0, [simulation_speed]
|
||||||
|
mov eax, 0x3DCCCCCD; 0.1f
|
||||||
|
vmovd xmm1, eax
|
||||||
|
|
||||||
|
addss xmm0, xmm1
|
||||||
|
; wont check for overflows since the user would need be crazy to reach that number
|
||||||
|
movss [simulation_speed], xmm0
|
||||||
|
|
||||||
jmp .end_input_handling
|
jmp .end_input_handling
|
||||||
|
|
||||||
@@ -187,7 +202,17 @@ handle_user_input:; main loop of the program
|
|||||||
cmp al, 'k'
|
cmp al, 'k'
|
||||||
jne .check_q
|
jne .check_q
|
||||||
|
|
||||||
; TODO implement simulation speed
|
movss xmm0, [simulation_speed]
|
||||||
|
mov eax, 0x3DCCCCCD; 0.1f
|
||||||
|
vmovd xmm1, eax
|
||||||
|
|
||||||
|
subss xmm0, xmm1
|
||||||
|
|
||||||
|
ucomiss xmm0, xmm1; check if number is smaller than 0.1
|
||||||
|
jb .end_input_handling
|
||||||
|
movss [simulation_speed], xmm0
|
||||||
|
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
.check_q:
|
.check_q:
|
||||||
cmp al, 'q'
|
cmp al, 'q'
|
||||||
@@ -206,15 +231,6 @@ handle_user_input:; main loop of the program
|
|||||||
mov r13b, 1
|
mov r13b, 1
|
||||||
.dont_step:
|
.dont_step:
|
||||||
|
|
||||||
%ifdef COMMENT
|
|
||||||
lea rdi, [multipurpuse_buf]
|
|
||||||
mov qword [multipurpuse_buf], 0
|
|
||||||
mov qword [multipurpuse_buf+8], 50000000; 50ms
|
|
||||||
mov rax, SYS_NANOSLEEP
|
|
||||||
mov rsi, 0
|
|
||||||
syscall
|
|
||||||
%endif
|
|
||||||
|
|
||||||
test r13b, r13b
|
test r13b, r13b
|
||||||
jz .main_loop
|
jz .main_loop
|
||||||
call print_game_ui
|
call print_game_ui
|
||||||
|
|||||||
+47
-1
@@ -20,6 +20,8 @@ section .bss
|
|||||||
extern cursor_rows
|
extern cursor_rows
|
||||||
extern cursor_cols
|
extern cursor_cols
|
||||||
|
|
||||||
|
global running_in_tty
|
||||||
|
running_in_tty: RESB 1
|
||||||
|
|
||||||
section .rodata
|
section .rodata
|
||||||
extern resetLen
|
extern resetLen
|
||||||
@@ -27,6 +29,8 @@ section .rodata
|
|||||||
hide_cursor: db ESC_CHAR, "[?25l", 0
|
hide_cursor: db ESC_CHAR, "[?25l", 0
|
||||||
show_cursor: db ESC_CHAR, "[?25h", 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
|
section .text
|
||||||
extern print_str
|
extern print_str
|
||||||
extern unsigned_int_to_ascii
|
extern unsigned_int_to_ascii
|
||||||
@@ -58,11 +62,50 @@ _start:
|
|||||||
|
|
||||||
; handle args
|
; handle args
|
||||||
pop rcx; get argc (number of arguments)
|
pop rcx; get argc (number of arguments)
|
||||||
|
pop rax; get rid of program name arugument
|
||||||
cmp rcx, 1
|
cmp rcx, 1
|
||||||
jle .no_arguments_provided
|
jle .no_arguments_provided
|
||||||
; TODO hanndle arguments
|
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:
|
.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
|
call init_alloc
|
||||||
|
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
@@ -95,6 +138,8 @@ _start:
|
|||||||
|
|
||||||
call disable_canonical_mode_and_echo
|
call disable_canonical_mode_and_echo
|
||||||
|
|
||||||
|
call print_game_ui
|
||||||
|
|
||||||
call handle_user_input
|
call handle_user_input
|
||||||
|
|
||||||
call reset_terminal
|
call reset_terminal
|
||||||
@@ -102,6 +147,7 @@ _start:
|
|||||||
lea rdi, [show_cursor]
|
lea rdi, [show_cursor]
|
||||||
call print_str
|
call print_str
|
||||||
|
|
||||||
|
.exit_program:
|
||||||
mov rax, SYS_EXIT
|
mov rax, SYS_EXIT
|
||||||
mov rdi, 0 ; return code
|
mov rdi, 0 ; return code
|
||||||
syscall
|
syscall
|
||||||
|
|||||||
Reference in New Issue
Block a user