This repository has been archived by the owner on Apr 19, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shell.inc
177 lines (153 loc) · 3.24 KB
/
shell.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;
; Simplest shell
; DolphinOS (c) Dmytro Sirenko
; ___________________________________________________________________
%ifndef __SHELL_INC__
%define __SHELL_INC__
%include "stdio.inc"
%include "cmds.inc"
%include "debug.inc"
[section .text]
;; __________________________________________________________________
shell:
;; just shell
.shell_loop:
mov si, def_prompt
call print_string
call clear_cmdline
;; read commands
mov dx, cmdbuf
call read_string
;; parse it to arguments
call parse_cmdline
mov cx, internal_cmds_size
mov bx, internal_commands
.cmd_loop:
call cmdcmp
jne .next
call word [bx + INTCMDS_ENTRY_SIZE - 2]
jmp .shell_loop
.next:
add bx, INTCMDS_ENTRY_SIZE
loop .cmd_loop
mov si, m_unknown_cmd
call print_string
jmp .shell_loop
.exit:
retn
; ___________________________________________________________________
cmdcmp:
mov di, word [bx]
mov si, word [arg.n0]
.next:
cmpsb
jne .ret
mov al, byte [di]
test al, al
jnz .next
cmpsb
.ret:
retn
; ___________________________________________________________________
parse_cmdline:
;; divides cmdbuf string into words in-place, inserting 0 (endofline)
;; after each argument in command line, then writing up offsets of
;; arguments to [arg.n]
;; clear arg array
mov di, word arg
xor ax, ax
mov cx, MAX_ARGC
rep stosw
;;
xor bx, bx ;; args counter
mov di, word cmdbuf ;; iterator
.separator:
cmp byte [di], SEP_CHAR
jne .first_non_sep
mov byte [di], 0
inc di
jmp .separator
.first_non_sep:
; next argument
inc bl
;; is there no more than MAX_ARGC args?
cmp bl, MAX_ARGC
jg .end
; calculate offset of arg[bl]
mov si, bx
dec si ;; bx=1 for first arg, offs=0
shl si, 1 ;; word, 2 byte
add si, word arg
; remember offset of current argument
mov word [si], di
.non_sep:
;; whether the end reached
mov dl, byte [di]
test dl, dl
jz .end
mov al, SEP_CHAR ;; for comparison, won't be changed
;; test the next one
inc di
cmp byte [di], SEP_CHAR
je .separator
jmp .non_sep
.end:
mov byte [argc], bl
retn
; ___________________________________________________________________
clear_cmdline:
;; there may be additional actions, like saving cmdline in hist
xor al, al
mov cx, CMDBUF_SIZE
mov di, cmdbuf
rep stosb
retn
; ___________________________________________________________________
shell_exit:
pop ax ;; offset of return
mov si, m_sh_exiting
call print_string
mov ax, word shell.exit
push ax
retn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
MAX_ARGC equ 8
CMDBUF_SIZE equ 256
INTCMDS_ENTRY_SIZE equ 4
command_name:
.exit: db "exit", 0
.off: db "off", 0
.memdump: db "mem", 0
.args: db "args", 0
.cpu: db "cpu", 0
.egg: db "egg", 0
internal_commands:
.exit:
dw command_name.exit
dw shell_exit
.off:
dw command_name.off
dw turnoff
.memdump:
dw command_name.memdump
dw sh_mem_dump
.argsout:
dw command_name.args
dw dbg_show_args
.cpu:
dw command_name.cpu
dw dbg_cpu_state
.egg:
dw command_name.egg
dw dbg_something
internal_cmds_size equ ($ - internal_commands)/INTCMDS_ENTRY_SIZE
cmdbuf: times CMDBUF_SIZE db 0x00
argc: db MAX_ARGC ;; just to fill
arg:
%assign i 0
%rep MAX_ARGC
.n%[i]: dw ((i + '0') << 8) + 'A'
%assign i i+1
%endrep
%endif