summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/border.asm64
-rw-r--r--src/input.asm47
-rw-r--r--src/main.asm159
-rw-r--r--src/utils.asm114
4 files changed, 384 insertions, 0 deletions
diff --git a/src/border.asm b/src/border.asm
new file mode 100644
index 0000000..12774b6
--- /dev/null
+++ b/src/border.asm
@@ -0,0 +1,64 @@
+section .text
+    extern height
+    extern width
+    extern write_byte
+    global draw_border
+
+draw_upper_lower_line:
+    push rbx
+
+    mov rax, '+'
+    call write_byte
+
+    mov bl, byte [width]
+_01:mov rax, '-'
+    call write_byte
+    dec bl
+    cmp bl, 0
+    jnz _01
+
+    mov rax, '+'
+    call write_byte
+
+    mov rax, 10 ;newline
+    call write_byte
+
+    pop rbx
+    ret
+
+draw_left_right_lines:
+    push rbx
+
+    mov rax, '|'
+    call write_byte
+
+    mov bl, byte [width]
+_02:mov rax, 32 ;space
+    call write_byte
+    dec bl
+    cmp bl, 0
+    jnz _02
+
+    mov rax, '|'
+    call write_byte
+
+    mov rax, 10 ;newline
+    call write_byte
+     
+    pop rbx
+    ret
+
+draw_border:
+    push rbx
+
+    call draw_upper_lower_line
+    mov bl, byte [height]
+_03:call draw_left_right_lines
+    dec bl
+    cmp bl, 0
+    jnz _03
+
+    call draw_upper_lower_line
+
+    pop rbx
+    ret
diff --git a/src/input.asm b/src/input.asm
new file mode 100644
index 0000000..278b640
--- /dev/null
+++ b/src/input.asm
@@ -0,0 +1,47 @@
+section .bss
+    input_buffer resb 1
+
+section .text
+    global input
+    extern direction
+    extern exit
+
+input:
+    call read_input
+    call handle_input
+    ret
+
+handle_input:
+    mov al, byte [input_buffer]
+    cmp al, 'w'
+    je _input_up
+    cmp al, 's'
+    je _input_down
+    cmp al, 'a'
+    je _input_left
+    cmp al, 'd'
+    je _input_right
+    cmp al, 27 ; escape
+    je exit
+    ret
+
+_input_up:
+    mov byte [direction], 3
+    ret
+_input_down:
+    mov byte [direction], 1
+    ret
+_input_left:
+    mov byte [direction], 2
+    ret
+_input_right:
+    mov byte [direction], 0
+    ret
+
+read_input:
+    mov rax, 0           
+    mov rdi, 0           
+    mov rsi, input_buffer
+    mov rdx, 250          
+    syscall
+    ret
diff --git a/src/main.asm b/src/main.asm
new file mode 100644
index 0000000..170f6a2
--- /dev/null
+++ b/src/main.asm
@@ -0,0 +1,159 @@
+section .data
+
+    ; example messages for later
+    message1 db "Hello, World!", 0xA
+    msg_len1 equ $ - message1          
+    message2 db "Hello 2!", 0xA  
+    msg_len2 equ $ - message2
+    
+    ; array of snake - 1000 thousand bytes means max length is 500
+    ; x head is at snake[0]
+    ; y head is at snake[1]
+    snake TIMES 1000 db 0
+    snake_length dw 1
+
+    ; position of the fruit
+    fruit_x db 0
+    fruit_y db 0
+
+    ; direction of the snake:
+    ;   3
+    ; 2 x 0
+    ;   1
+    global direction
+    direction db 0
+
+    timespec dq 0 
+             dq 500000000
+
+section .rodata
+    ; width and height of the playable area
+    ; (without the borders)
+    global width
+    global height
+    width db 70
+    height db 30
+
+section .text
+    extern input
+    extern draw_border
+    extern write_byte
+    extern clear_screen
+    extern reset_cursor
+    extern move_cursor_right
+    extern move_cursor_down
+    extern hide_cursor
+    extern show_cursor
+    global _start 
+    global exit
+
+draw_snake:
+    push rbx
+    call reset_cursor
+    mov bh, byte [snake]
+    mov bl, byte [snake+1]
+
+_10:call move_cursor_right
+    dec bh
+    cmp bh, 0
+    jnz _10
+_11:call move_cursor_down
+    dec bl
+    cmp bl, 0
+    jnz _11
+
+    mov rax, 'x'
+    call write_byte
+
+    pop rbx
+    call reset_cursor
+    ret
+
+move_snake:
+    cmp byte [direction], 0
+    je _move_right
+    cmp byte [direction], 1
+    je _move_down
+    cmp byte [direction], 2
+    je _move_left
+    cmp byte [direction], 3
+    je _move_up
+    ret
+
+_move_right:
+    inc byte [snake]
+    ret
+_move_down:
+    inc byte [snake+1]
+    ret
+_move_left:
+    dec byte [snake]
+    ret
+_move_up:
+    dec byte [snake+1]
+    ret
+
+fruit_position:
+
+    ; x position
+    rdtsc
+    shr ax, 5
+    div byte [width]
+    mov byte [fruit_x], ah
+;; TODO
+    rdtsc
+    shr ax, 5
+    div byte [height]
+    mov byte [fruit_y], ah
+
+    ret
+
+draw_fruit:
+    push rbx
+    call reset_cursor
+    mov bh, byte [fruit_x]
+    mov bl, byte [fruit_y]
+
+_30:call move_cursor_right
+    dec bh
+    cmp bh, 0
+    jnz _30
+_31:call move_cursor_down
+    dec bl
+    cmp bl, 0
+    jnz _31
+
+    mov rax, '*'
+    call write_byte
+
+    pop rbx
+    call reset_cursor
+    ret
+
+_start:
+    call hide_cursor
+    mov byte [snake], 5
+    mov byte [snake+1], 5
+    call fruit_position
+
+main_loop:
+    call clear_screen
+    call draw_border
+    call draw_snake
+    call draw_fruit
+
+    mov rax, 35            
+    lea rdi, [timespec]   
+    xor rsi, rsi           
+    syscall
+
+    call input
+    call move_snake
+
+    jmp main_loop
+
+exit: ; exit syscall with return code 0
+    call show_cursor
+    mov rax, 60                     
+    xor rdi, rdi                    
+    syscall                         
diff --git a/src/utils.asm b/src/utils.asm
new file mode 100644
index 0000000..9281ed2
--- /dev/null
+++ b/src/utils.asm
@@ -0,0 +1,114 @@
+section .data
+    ; escape code for clearing the screen
+    clear db 0x1B, '[2J', 0x1B, '[H', 0
+    clear_len equ $ - clear 
+
+    ; cursor management
+    reset_cursor_code db 0x1B , '[H', 0
+    reset_cursor_len equ $ - reset_cursor_code
+    bottom_cursor db 0x1B , '[B', 0
+    bottom_cursor_len equ $ - bottom_cursor
+    right_cursor db 0x1B , '[C', 0
+    right_cursor_len equ $ - right_cursor
+
+    hide_cursor_code db 0x1B, '[', '?', '2', '5', 'l', 0  ; Escape sequence to hide the cursor
+    show_cursor_code db 0x1B, '[', '?', '2', '5', 'h', 0  ; Escape sequence to show the cursor
+
+section .bss
+    ; adress for syscall for write_byte wrapper
+    byte_to_write resb 1
+
+section .text
+    global write_byte
+    global clear_screen
+    global move_cursor_right
+    global move_cursor_down
+    global reset_cursor
+    global hide_cursor
+    global show_cursor
+
+hide_cursor:
+    push rdi
+    
+    mov rax, 1                      
+    mov rdi, 1                      
+    mov rsi, hide_cursor_code 
+    mov rdx, 6                
+    syscall                         
+
+    pop rdi
+    ret
+
+show_cursor:
+    push rdi
+    
+    mov rax, 1                      
+    mov rdi, 1                      
+    mov rsi, show_cursor_code 
+    mov rdx, 6                
+    syscall                         
+
+    pop rdi
+    ret
+
+reset_cursor:
+    push rdi
+    
+    mov rax, 1                      
+    mov rdi, 1                      
+    mov rsi, reset_cursor_code 
+    mov rdx, reset_cursor_len                
+    syscall                         
+
+    pop rdi
+    ret
+
+move_cursor_right:
+    push rdi
+
+    mov rax, 1
+    mov rdi, 1
+    mov rsi, right_cursor
+    mov rdx, right_cursor_len
+    syscall
+
+    pop rdi
+    ret
+
+move_cursor_down:
+    push rdi
+
+    mov rax, 1
+    mov rdi, 1
+    mov rsi, bottom_cursor
+    mov rdx, bottom_cursor_len
+    syscall
+
+    pop rdi
+    ret
+
+write_byte:
+    push rdi
+
+    mov byte [byte_to_write], al
+    mov rax, 1                      
+    mov rdi, 1                      
+    mov rsi, byte_to_write                
+    mov rdx, 1                
+    syscall                         
+
+    pop rdi
+    ret
+
+clear_screen:
+    push rdi
+
+    mov rax, 1                      
+    mov rdi, 1                      
+    mov rsi, clear                
+    mov rdx, clear_len                
+    syscall                         
+
+    pop rdi
+    ret
+