move assembly files into src directory

This commit is contained in:
2026-09-03 20:32:40 +02:00
parent 6ff1a43c32
commit 7c49c5212e
6 changed files with 0 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
@0x10000 ; Example address until we get a proper memory map for this
; Shift conversion table
; It stores the mapping from value 32-127 of the ASCII table to their shifted equivalents (both ways) in the standard US keyboard layout
; e.g. 1 -> !
U8 32 ; Space -> Space
U8 49 ; ! -> 1
U8 39 ; " -> '
U8 51 ; # -> 3
U8 52 ; $ -> 4
U8 53 ; % -> 5
U8 55 ; & -> 7
U8 34 ; ' -> "
U8 57 ; ( -> 9
U8 48 ; ) -> 0
U8 56 ; * -> 8
U8 61 ; + -> =
U8 60 ; , -> <
U8 95 ; - -> _
U8 62 ; . -> >
U8 63 ; / -> ?
U8 41 ; 0 -> )
U8 33 ; 1 -> !
U8 64 ; 2 -> @
U8 35 ; 3 -> #
U8 36 ; 4 -> $
U8 37 ; 5 -> %
U8 94 ; 6 -> ^
U8 38 ; 7 -> &
U8 42 ; 8 -> *
U8 40 ; 9 -> (
U8 59 ; : -> ;
U8 58 ; ; -> :
U8 44 ; < -> ,
U8 43 ; = -> +
U8 46 ; > -> .
U8 47 ; ? -> /
U8 50 ; @ -> 2
U8 97 ; A -> a
U8 98 ; B -> b
U8 99 ; C -> c
U8 100; D -> d
U8 101; E -> e
U8 102; F -> f
U8 103; G -> g
U8 104; H -> h
U8 105; I -> i
U8 106; J -> j
U8 107; K -> k
U8 108; L -> l
U8 109; M -> m
U8 110; N -> n
U8 111; O -> o
U8 112; P -> p
U8 113; Q -> q
U8 114; R -> r
U8 115; S -> s
U8 116; T -> t
U8 117; U -> u
U8 118; V -> v
U8 119; W -> w
U8 120; X -> x
U8 121; Y -> y
U8 122; Z -> z
U8 123; [ -> {
U8 124; \ -> |
U8 125; ] -> }
U8 125; ^ -> 6
U8 45 ; _ -> -
U8 126; ` -> ~
U8 65 ; a -> A
U8 66 ; b -> B
U8 67 ; c -> C
U8 68 ; d -> D
U8 69 ; e -> E
U8 70 ; f -> F
U8 71 ; g -> G
U8 72 ; h -> H
U8 73 ; i -> I
U8 74 ; j -> J
U8 75 ; k -> K
U8 76 ; l -> L
U8 77 ; m -> M
U8 78 ; n -> N
U8 79 ; o -> O
U8 80 ; p -> P
U8 81 ; q -> Q
U8 82 ; r -> R
U8 83 ; s -> S
U8 84 ; t -> T
U8 85 ; u -> U
U8 86 ; v -> V
U8 87 ; w -> W
U8 88 ; x -> X
U8 89 ; y -> Y
U8 90 ; z -> Z
U8 91 ; { -> [
U8 92 ; | -> \
U8 93 ; } -> ]
U8 96 ; ~ -> `
+77
View File
@@ -0,0 +1,77 @@
; Returns the index of the first element matching the provided predicate function (or -1 if not found)
; Arguments:
; r1 - The array pointer
; r2 - The array length (number of items)
; r3 - The stride (size of one item) - either 1, 2 or 4 (bytes)
; r4 - The predicate
; r5 - Predicate context
; Result:
; r1 - The index of the first element matching the provided predicate function (or -1 if not found)
; Clobbers: r2, r3, r4, r5, r6, + what the predicate clobbers
; Info:
; The predicate function should follow the stdlib calling convention
; The predicate receives two arguments (the value and the predicate context) and should return either a zero when the value is not the one we search for
; , or any other result if it is the searched-for item.
pub find_index:
push r12 ; We will store the predicate pointer here
push r11 ; We will store the current pointer here
push r10 ; We will store the stride here
push r9 ; We will store the final address here
push r8 ; We will store the mask here
mov r12, r4
mov r11, r1
mov r10, r3
mov r9, r2
lsr r6, r3, 1 ; We turn the stride into a byte shift
lsl r9, r9, r6 ; We calculate bytes left
add r9, r9, r1 ; We add the start address to get the final address
push r13 ; We save up the return address because we will provide our own to the predicate
push r1 ; We need the array pointer to calculate the item index
counter r13
add r13, r13, 52 ; Point to just after the predicate call - we can set this up now so we don't waste loop cycles
nand r8, zr, zr ; We create a mask of 0xFFFFFFFF
mov r6, 4
sub r6, r6, r3 ; We create a "negative stride", e.g. 4 -> 0, 2 -> 2, 1 -> 3
lsl r6, r6, 3
lsr r8, r8, r6 ; We shift the mask by the negative stride to obtain the proper mask for a value
; e.g. stride 4 -> mask is 0xFFFFFFFF
; stride 2 -> mask is 0x0000FFFF
; stride 1 -> mask is 0x000000FF
push r5 ; We save the predicate context on the stack
find_index_loop:
load_32 r1, [r11] ; We load the element
and r1, r1, r8 ; We mask it to handle stride 2 and 1 cases
load_32 r2, [sp] ; We load the predicate context into r2
jmp r12 ; We call the predicate
cmp r1, zr
jne find_index_found_item ; If we found the item, we jump out
; If we didn't, move to next item
add r11, r11, r10 ; We add the stride to the pointer
cmp r11, r9 ; We compare with the final address
jne find_index_loop ; If we did not reach the end we jump back into the loop
find_index_not_found:
add sp, sp, 8 ; The predicate context and old array pointer are not useful
pop r13 ; We get our return address
nand r1, zr, zr ; We put -1 in r1
jmp find_index_postamble
find_index_found_item:
add sp, sp, 4 ; The predicate context is not useful
pop r1 ; We get the array pointer
pop r13 ; We get our return address
sub r1, r11, r1 ; We calculate the bytes from the start
lsr r10, r10, 1 ; We shift the stride to get the amount to shift the bytes for
lsr r1, r1, r10 ; We shift to get the index of the item
find_index_postamble:
pop r8
pop r9
pop r10
pop r11
pop r12
jmp r13 ; Return
+94
View File
@@ -0,0 +1,94 @@
pub rotate_left:
; (r1 >> r2) | (r1 << (32 - r2))
sub r3, zr, r2
add r3, r3, 32
lsr r3, r1, r3
lsl r1, r1, r2
or r1, r1, r3
jmp r13
pub rotate_right:
; (r1 << r2) | (r1 >> (32 - r2))
sub r3, zr, r2
add r3, r3, 32
lsl r3, r1, r3
lsr r1, r1, r2
or r1, r1, r3
jmp r13
pub clz:
; special case
mov r4, 0
; since we start the loop by shifting r2 load twice the value we need
mov r2, 32
mov r3, r1
; divide and conquer algorithm
clz_loop:
; next finer step
lsr r2, r2, 1
; abort if there is no finer step
cmp r2, 0
je clz_end
; see if there are still some 1 bits left with this additional shift
lsr r3, r3, r2
add r4, r4, r2
cmp r3, 0
jne clz_loop
; undo shift if it resulted in zero
sub r4, r4, r2
lsr r3, r1, r4
jmp clz_loop
clz_end:
; we calculated the position of the last 1 from the least significant side
; inverse is what we want (position of last 0 from most significant side)
mov r1, 31
sub r1, r1, r4
jmp r13
pub popc:
mov r2, 0x0101 ; load mask of 0x01010101
lsl r2, r2, 16
or r2, r2, 0x0101
mov r3, 8 ; bits in byte
mov r4, 0 ; pop count of each byte
popc_loop:
and r5, r1, r2 ; extract least significant bit of byte
add r4, r4, r5
lsr r1, r1, 1 ; cycle through bits
sub r3, r3, 1
cmp r3, 0
jg popc_loop
; sum up bytes
lsr r2, r4, 8
add r4, r4, r2
lsr r2, r4, 16
add r4, r4, r2
and r1, r4, 0xFF ; mask out end result in lowest byte
jmp r13
; Calculates the parity of the value provided in the r1 register
; i.e. 0 means even bits set, 1 means odd bits set
; Based on Stanford's BitHacks
; Clobbers r2
pub parity:
; v ^= v >> 16;
lsr r2, r1, 16
xor r1, r1, r2
; v ^= v >> 8;
lsr r2, r1, 8
xor r1, r1, r2
; v ^= v >> 4;
lsr r2, r1, 4
xor r1, r1, r2
; v &= 0xf;
and r1, r1, 0x0F
; return (0x6996 >> v) & 1;
mov r2, 0x6996
lsr r1, r2, r1
and r1, r1, 0x01
jmp r13
+69
View File
@@ -0,0 +1,69 @@
; Reads a line from the keyboard and fills the specified buffer with it
; Does not support Shift or any other special keys
; Arguments:
; r1 - pointer to the buffer
; Result:
; r1 - pointer to the same buffer
; Clobbers: r2, r3, r4, r5, r6, r7
pub read_line:
mov r6, 1
lsl r6, r6, 16
sub r6, r6, 32 ; Calculating the address to the shift LUT
mov r2, 0 ; Storing the shift status here
mov r4, 0 ; Storing the last key here, so we don't repeat the same key
mov r3, r1 ; The pointer to after the last character
read_line_keyloop:
keyboard r5
cmp r5, r4
je read_line_keyloop ; If the current key is same as previous, we loop
mov r4, r5 ; Storing current key as previous
cmp r5, 0x120 ; Is the key renderable or special?
jb read_line_special ; If the key was special, we handle it separately
xor r5, r5, 0x100 ; Clearing the "down" bit
cmp r2, zr ; Checking for shift status
je read_line_store ; If shift is up, we skip conversion
;;; converting from shift-down to shift-up keys
add r7, r6, r5 ; Calculating the index of the shift conversion
load_8 r5, [r7] ; Loading the shifted value
;;;
read_line_store:
store_8 [r3], r5 ; Else, we store the key in the buffer
add r3, r3, 1 ; We advance forward
; TODO: Writeback
jmp read_line_keyloop
read_line_special:
cmp r5, 13 ; Was the key Backspace?
je read_line_backspace ; If yes we need to move one character back
cmp r5, 10 ; Was the key Enter?
je read_line_finished ; If so, we're finished
and r5, r5, 0x1FB ; Mask out the left/right shift direction bit
cmp r5, 0x110 ; Was the key Shift Down?
and flags, flags, 0x1 ; We care only about equality bit
or r2, r2, flags ; If shift was down before, it still is. If it was pressed now, it is down now
cmp r5, 0x010 ; Was the key Shift Up?
and flags, flags, 0x1 ; We care only about equality bit
xor flags, flags, 0x1 ; We invert it, i.e. "if it's not up"
and r2, r2, flags ; The shift can be kept down if it's not currently up
jmp read_line_keyloop ; If no special handling, we loop back
read_line_backspace:
cmp r3, r1 ; Compare the current pointer to start of buffer
je read_line_keyloop ; If we are at the start, we loop
sub r3, r3, 1 ; We move back one character
; TODO: Writeback
jmp read_line_keyloop
read_line_finished:
store_8 [r3], zr ; We store null at the end so the string is finished
jmp r13
+83
View File
@@ -0,0 +1,83 @@
; Multiplies r1 and r2, returning the lower part of the result
; Arguments:
; r1 - The first value
; r2 - The second value
; Result:
; r1 - The lower 32 bits of the result
; Clobbers: r2, r3, r4, r5
pub mul_low:
mov r3, 0 ; result
mov r4, 31 ; loop counter
mul_low_loop:
asr r5, r2, 31
and r5, r5, r1
lsl r5, r5, r4
add r3, r3, r5
lsl r2, r2, 1
sub r4, r4, 1
cmp r4, 0
jge mul_low_loop
mov r1, r3
jmp r13
; Calculates the absolute value of the value provided in the r1 register
; Arguments:
; r1 - The value for which we want the absolute value
; Result:
; r1 - The calculated absolute value
; Clobbers: r2
; Info: Based on Stanford's BitHacks
pub abs: ; SHOULD BE INLINED
; mask = v >> 31
asr r2, r1, 31
; v + mask
add r1, r1, r2
; return (v + mask) ^ mask
xor r1, r1, r2
jmp r13
; Calculates the minimum value of the two values provided in the r1 and r2 registers
; Arguments:
; r1 - The first value
; r2 - The second value
; Result:
; r1 - The smaller value
; Clobbers: Nothing
; Info: Based on Stanford's BitHacks
pub min: ; SHOULD BE INLINED
; x < y
cmp r1, r2
lsr flags, flags, 2
; -(x < y)
neg flags, flags
; x ^ y
xor r1, r1, r2
; (x ^ y) & -(x < y)
and r1, r1, flags
; return y ^ ((x ^ y) & -(x < y))
xor r1, r2, r1
jmp r13
; Calculates the maximum value of the two values provided in the r1 and r2 registers
; Arguments:
; r1 - The first value
; r2 - The second value
; Result:
; r1 - The smaller value
; Clobbers: r2
; Info: Based on Stanford's BitHacks
pub max: ; SHOULD BE INLINED
; x < y
cmp r1, r2
lsr flags, flags, 2
; -(x < y)
neg flags, flags
; x ^ y
xor r2, r1, r2
; (x ^ y) & -(x < y)
and r2, r2, flags
; return x ^ ((x ^ y) & -(x < y))
xor r1, r1, r2
jmp r13
+7
View File
@@ -0,0 +1,7 @@
pub include bit
pub include imath
pub include array
pub include console
; Needs to be last!
pub include LUTs