From c9ca1a9791218e8e4bb0d4accbc714b0aac3943e Mon Sep 17 00:00:00 2001 From: MutexRaceCondition Date: Sun, 6 Sep 2026 21:05:58 +0200 Subject: [PATCH] Integer division and square root --- src/errno.asm | 5 +++- src/imath.asm | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/errno.asm b/src/errno.asm index 5d06c89..cdd6dc2 100755 --- a/src/errno.asm +++ b/src/errno.asm @@ -16,12 +16,15 @@ ; ; handle error pub const OK = 0x0000 + pub const SCREEN_INVALID_MODE = 0x0001 pub const SCREEN_INVALID_WIDTH = 0x0003 pub const SCREEN_FB_TOO_SMALL = 0x0005 pub const SCREEN_OUTSIDE_FB = 0x0007 +pub const DIV_BY_ZERO = 0x01001 + pub const MAGIC_BAD = 0x8001 ; Extended error codes, these would require loading a 32 bit value. -pub const EXT_OK = 0x00000000 \ No newline at end of file +pub const EXT_OK = 0x00000000 diff --git a/src/imath.asm b/src/imath.asm index a246a2c..bf67a92 100644 --- a/src/imath.asm +++ b/src/imath.asm @@ -1,3 +1,82 @@ +include errno + +; (uint32_t, uint32_t) div(uint32_t, uint32_t); +; Divides two integers. +; +; Arguments: +; - r1: Dividend +; - r2: Divisor +; Results: +; - r1: Quotient +; - r2: Remainder +; Errors: +; - `ERR_DIV_BY_ZERO`: The divisor was `0`. +; +pub div: + cmp r2, 0 + je _div__by_0 + mov r4, r2 + mov r2, r1 + mov r3, 1 + cmp r1, 0 + jge _div__loop + mov r1, 1 + lsl r1, r1, 31 +_div__loop: + lsl r4, r4, 1 + lsl r3, r3, 1 +_div__loop_entry: + cmp r4, r1 + jb _div__loop + mov r1, 0 +_div__loop2: + cmp r2, r4 + jb _div__loop2_no + sub r2, r2, r4 + add r1, r1, r3 +_div__loop2_no: + lsr r4, r4, 1 + lsr r3, r3, 1 + cmp r3, 0 + jne _div__loop2 + mov flags, errno.OK + jmp r13 +_div__by_0: + mov flags, errno.DIV_BY_ZERO + jmp r13 + +; uint32_t sqrt(uint32_t); +; Calculates the integer square root. +; +; Arguments: +; - r1: The unsigned 32 bit value to take the square root of. +; Results: +; - r1: The square root of the input, rounded down. +; Clobbers: +; - r1 - r6 +; +pub sqrt: + mov r2, 0 + mov r3, 16 + mov r4, 0 + lsl r5, r3, 12 +_sqrt__loop: + lsl r6, r2, r3 + sub r3, r3, 1 + lsr r5, r5, 1 + lsl flags, r5, r3 + add r6, r6, flags + add r6, r6, r4 + cmp r6, r1 + ja _sqrt__test + or r2, r2, r5 + mov r4, r6 +_sqrt__test: + cmp r3, 0 + jne _sqrt__loop + mov r1, r2 + jmp r13 + ; Multiplies r1 and r2, returning the lower part of the result ; Arguments: ; r1 - The first value @@ -111,4 +190,4 @@ pub max: ; SHOULD BE INLINED and r2, r2, flags ; return x ^ ((x ^ y) & -(x < y)) xor r1, r1, r2 - jmp r13 \ No newline at end of file + jmp r13