Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4840 → Rev 4842

/programs/shell.inc
0,0 → 1,507
; PRIVATE FIELDS
 
__shell.buf__ rd 1
__shell.name__ rb 16
__shell.str__ rb 16
 
;-----------------------------------
; a = 0
;-----------------------------------
 
macro clear a {
xor a, a
}
 
;-----------------------------------
; if a == b then c
;-----------------------------------
 
macro cmpe a, b, c {
cmp a, b
je c
}
 
;-----------------------------------
; if a != b then c
;-----------------------------------
 
macro cmpne a, b, c {
cmp a, b
jne c
}
 
;-----------------------------------
; Shell`s initialization
; without arguments
;-----------------------------------
 
shell.init:
pusha
 
; Get PID
mov eax, 68
mov ebx, 11
int 64
 
mov eax, 68
mov ebx, 12
mov ecx, 1024
int 64
 
mov esi, eax
 
mov eax, 9
mov ebx, esi
mov ecx, -1
int 64
 
mov eax, dword [esi + 30]
mov [@pid], eax
 
mov eax, 68
mov ebx, 13
mov ecx, esi
int 64
 
; Convert PID to STR
mov eax, [@pid]
mov ebx, 10
clear ecx
@@:
clear edx
div ebx
push edx
inc ecx
cmpne eax, 0, @b
 
mov ebx, __shell.name__
@@:
pop eax
add al, "0"
mov [ebx], al
inc ebx
loop @b
 
; Add postfix
mov [ebx + 0], dword "-SHE"
mov [ebx + 4], word "LL"
mov [ebx + 6], byte 0
 
; Open buffer
mov eax, 68
mov ebx, 22
mov ecx, __shell.name__
mov edx, 4096
mov esi, 101b
int 64
 
mov [__shell.buf__], eax
 
mov eax, 5
mov ebx, 5
int 64
 
popa
ret
 
;-----------------------------------
; Wait answer from shell
;
; INPUT:
; edi - shell-buffer
;-----------------------------------
 
shell.wait:
pusha
 
@@:
mov eax, 5
mov ebx, 1
int 64
 
cmpne [edi], byte 0, @b
 
popa
ret
 
;-----------------------------------
; Exit from shell
; without arguments
;-----------------------------------
 
shell.destroy:
pusha
 
mov edi, [__shell.buf__]
mov [edi], byte 1
call shell.wait
 
mov eax, 68
mov ebx, 23
mov ecx, __shell.name__
int 64
 
popa
ret
 
;-----------------------------------
; Print char to shell
;
; INPUT:
; al - char
;-----------------------------------
 
shell.print_char:
pusha
 
mov edi, [__shell.buf__]
mov [edi], byte 2
mov [edi + 1], al
call shell.wait
 
popa
ret
 
;-----------------------------------
; Print string to shell
;
; INPUT:
; eax - string
;-----------------------------------
 
shell.print_string:
pusha
 
mov edi, [__shell.buf__]
mov [edi], byte 3
inc edi
 
@@:
mov bl, [eax]
mov [edi], bl
inc edi
inc eax
cmpne [eax], byte 0, @b
 
mov [edi], byte 0
mov edi, [__shell.buf__]
call shell.wait
 
popa
ret
 
;-----------------------------------
; Print number to shell
;
; INPUT:
; eax - number
;-----------------------------------
 
shell.print_num:
pusha
 
mov ecx, eax
and ecx, 1 shl 31
cmpe ecx, 0, @f
mov [__shell.str__], "-"
not eax
inc eax
 
@@:
mov ebx, 10
clear ecx
@@:
clear edx
div ebx
push edx
inc ecx
cmpne eax, 0, @b
 
mov ebx, __shell.str__
inc ebx
 
@@:
pop eax
add al, "0"
mov [ebx], al
inc ebx
loop @b
 
mov [ebx], byte 0
mov eax, __shell.str__
cmpe [eax], byte "-", @f
inc eax
@@:
call shell.print_string
 
popa
ret
 
;-----------------------------------
; Get char from shell
;
; OUTPUT:
; al - char
;-----------------------------------
 
shell.get_char:
push ebx ecx edx esi edi
 
mov edi, [__shell.buf__]
mov [edi], byte 4
call shell.wait
mov al, [edi + 1]
 
pop edi esi edx ecx ebx
ret
 
;-----------------------------------
; Get string from shell
;
; INPUT:
; eax - addres of memory for str
;-----------------------------------
 
shell.get_string:
pusha
 
mov edi, [__shell.buf__]
mov [edi], byte 5
call shell.wait
 
inc edi
@@:
mov bl, [edi]
mov [eax], bl
inc eax
inc edi
cmpne [edi], byte 0, @b
 
mov [eax], byte 0
 
popa
ret
 
;-----------------------------------
; Get number from shell
;
; OUTPUT:
; eax - number
;-----------------------------------
 
shell.get_num:
push ebx ecx edx esi edi
 
mov eax, __shell.str__
call shell.get_string
 
mov ebx, eax
clear eax
clear edi
cmpne [ebx], byte "-", @f
mov edi, 1
inc ebx
 
@@:
sub [ebx], byte "0"
imul eax, 10
add al, [ebx]
inc ebx
cmpne [ebx], byte 10, @b
 
cmpe edi, 0, @f
not eax
inc eax
 
@@:
pop edi esi edx ecx ebx
ret
 
 
;-----------------------------------
; Clear shell
; without arguments
;-----------------------------------
 
shell.clear:
pusha
 
mov edi, [__shell.buf__]
mov [edi], byte 6
call shell.wait
 
popa
ret
 
;-----------------------------------
; Print char to shell
;
; INPUT:
; arg1 - char
;-----------------------------------
 
macro shpc [char] {
push eax
mov al, char
call shell.print_char
pop eax
}
 
;-----------------------------------
; Go to new line in shell
; without arguments
;-----------------------------------
 
macro shln {
shpc 10
shpc 13
}
 
;-----------------------------------
; Print string to shell
;
; INPUT:
; arg1 - string
;-----------------------------------
 
macro shps [string] {
local ..string, ..label
jmp ..label
..string db string, 0
..label:
 
push eax
mov eax, ..string
call shell.print_string
pop eax
}
 
;-----------------------------------
; Print string to shell
;
; INPUT:
; arg1 - addres of string
;-----------------------------------
 
macro shpsa [addr] {
push eax
mov eax, addr
call shell.print_string
pop eax
}
 
;-----------------------------------
; Print number to shell
;
; INPUT:
; arg1 - number
;-----------------------------------
 
macro shpn [num] {
push eax
mov eax, num
call shell.print_num
pop eax
}
 
 
;-----------------------------------
; Get char from shell
;
; OUTPUT:
; al - char
;-----------------------------------
 
macro shgc {
call shell.get_char
}
 
;-----------------------------------
; Get string from shell
;
; INPUT:
; arg1 - addres of memory for str
;-----------------------------------
 
macro shgs [addr] {
mov eax, addr
call shell.get_string
}
 
;-----------------------------------
; Get number from shell
;
; INPUT:
; arg1 - addres of memory for num
;-----------------------------------
 
macro shgn [addr] {
push eax
call shell.get_num
mov [addr], eax
pop eax
}
 
 
;-----------------------------------
; Wait any char from shell
; without arguments
;-----------------------------------
 
macro shw {
push eax
call shell.get_char
pop eax
}
 
;-----------------------------------
; Clear shell
; without arguments
;-----------------------------------
 
macro shc {
call shell.clear
}
 
;-----------------------------------
; Choice
;
; INPUT:
; arg1 - question
; arg2 - asnwers
;
; OUTPUT:
; al - answer
;-----------------------------------
 
macro shchs str, chs {
local ..loop1, ..loop2, ..chs, ..start, ..res
jmp ..start
..chs db chs, 0
..start:
push ebx
 
shps str, " ["
shpsa ..chs
shps "]: "
 
..loop1:
call shell.get_char
 
mov ebx, ..chs
..loop2:
cmpe al, [ebx], ..res
inc ebx
cmpe [ebx], byte 0, ..loop1
jmp ..loop2
 
..res:
mov al, [ebx]
call shell.print_char
shln
 
mov eax, ebx
sub eax, ..chs
 
pop ebx
}