ibis-os/print_util.asm
2024-07-24 22:51:08 +03:00

187 lines
3.2 KiB
NASM

%macro print_ch 1
push ax
mov al, %1
mov ah, 0x0e
int 0x10
pop ax
%endmacro
%macro cls 0
mov ax, 0x0600 ; AH=06 Scroll screen, AL=0 Clear screen
mov bh, 0x0F ; black bg, white fg
mov cx, 0x0000 ; x1=y1=0
mov dx, 0x5019 ; 89x25
int 0x10 ; Graphics services
%endmacro
print:
pusha
.loop:
mov al, [bx]
cmp al, 0
je .end ; go to end if char == 0
mov ah, 0x0e
int 0x10
add bx, 1
jmp .loop ; loop
.end:
popa
ret
print_nl:
pusha
mov ax, 0x0e0a
int 0x10
mov ax, 0x0e0d
int 0x10
popa
ret
println:
pusha
call print
mov ax, 0x0e0a
int 0x10
mov ax, 0x0e0d
int 0x10
popa
ret
print_hex_digit:
pusha
mov al, bl
mov bl, 0x0F
and al, bl ; Get rid of all but the last nibble
; If the value is >= 0xA, then we need to add to the alphabetical block of the ascii table
cmp al, 0x0A
jl .skip_alpha ; If the number is not at least 0xA, then skip this step
add al, 0x07 ; 'A' == 0x41, '0' == 0x30, 0x41 - 0x30 == 0x11
; Ignore ^^^^^^^ THIS ^^^^^^ actually.
; It works and i've not got a clue why. Oh well. Such is life.
.skip_alpha:
add al, 0x30 ; Add ASCII '0'
mov ah, 0x0e
int 0x10
popa
ret
print_hex:
pusha
mov ax, bx
shr bx, 12
call print_hex_digit
mov bx, ax
shr bx, 8
call print_hex_digit
mov bx, ax
shr bx, 4
call print_hex_digit
mov bx, ax
call print_hex_digit
popa
ret
print_bin:
pusha
mov cx, 0
.loop:
cmp cx, 16
je .end
test bx, 0x8000
jnz .one
push bx
mov bl, 0x02
mov ah, 0x0e
mov al, 0x30
int 0x10
pop bx
jmp .continue
.one:
push bx
mov bl, 0x03
mov ah, 0x0e
mov al, 0x31
int 0x10
pop bx
.continue:
shl bx, 1
add cx, 1
jmp .loop
.end:
popa
ret
print_uint:
pusha
mov ax, bx ; Move number into ax
mov bx, 0
.loop:
mov cx, 10
mov dx, 0 ; IMPORTANT: Division will not work unless the higher register is in a usable length
div cx ; Divide ax by cx (10), -> ax, rem -> dx
add dx, 0x30 ; Add ascii '0'
push dx ; Push that value
add bx, 1
cmp ax, 0 ; Continue looping as long as the quotient is not 0
jnz .loop
.print_loop:
sub bx, 1
pop ax ; 16-bit value
mov ah, 0x0e
;add al, 0x30
int 0x10
cmp bx, 0
jnz .print_loop
popa
ret
print_sint:
pusha
; Old (non-working method) used a copy of above with idiv. I think this way is smarter
test bx, 0x8000 ; Check sign-bit
jz .positive
print_ch '-'
neg bx
.positive:
call print_uint
popa
ret