-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshell.asm
229 lines (180 loc) · 8.06 KB
/
shell.asm
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
;=========================
; SHELL
;=========================
[bits 16]
[org 0x8000] ;tell NASM the code is running shell at address 0x0000_8000
%define BOOTSECTOR_ADDRESS 0x7c0
%define FILES_ADDRESS 0x7E00
%define FILES_ADDR_OFFSET 8
%define THEME_ADDR 0x8200 ; physical memory address to load THEME at from sector 6
%define THEME_UPDATE 0x0045 ; local offset of THEME_ADDR used for far call to update theme
%define ENTER_KEY 0x1c
%define BACKSPACE_KEY 0x0e
;init segment register
mov ax, 0
mov ds, ax ;set data segment
mov es, ax ;set extra segment
mov ss, ax ;set stack segment
mov bp, BOOTSECTOR_ADDRESS ;set stack base pointer
mov sp, bp ;set stack pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;main OS loop
shell_loop:
call THEME_ADDR:THEME_UPDATE ; update color scheme
;print the user prompt
mov si, new_line
call print_string
mov si, user_prompt
call print_string
;reset user input
mov di, user_input ;point DESTINATION INDEX register to user_iput variable adress
mov al, 0 ;al is used by stosb
times 20 stosb ; store zeros at di and then inc di
mov di, user_input
.next_byte:
mov ah, 0x00 ;BIOS code to read keyboard
int 0x16 ;read a single keystroke from the keyboard
cmp ah, ENTER_KEY ; is ENTER pressed
;je shell_loop
je .search ;search game by name
cmp ah, BACKSPACE_KEY ; is BACKSPACE pressed
je .erase_char
stosb ;store key that has been pressed into user_input
mov ah, 0x0e ;BIOS teletype code
int 0x10 ;echo typed character
jmp .next_byte ;read next key from user
.erase_char:
;erasing in shell
mov ah, 0x03 ;BIOS code for getting cursor position
int 0x10 ;get cursor position
cmp dl, 3 ;cursor column to far left
je .next_byte ;if so dont erase any more
mov ah, 0x0e ;teletype mode eanabled
mov al, 8 ; ASCII code for '\b'
int 0x10 ;move cursor 1 step back
mov ah, 0x0e ;teletype mode eanabled
mov al, 0 ; ASCII code for empty char
int 0x10 ;move cursor 1 step back
mov ah, 0x0e ;teletype mode eanabled
mov al, 8 ; ASCII code for '\b'
int 0x10 ;move cursor 1 step back
;erasing from user_input variable
mov al, 0 ;AL is used by stosb
dec di ;go one position back
stosb ;replace with al and inc di
dec di ;do one position back (again)
jmp .next_byte ;process next byte
.search:
call search_file
jmp shell_loop
;search file procedure
search_file:
cmp byte [user_input], 0 ;check first byte user has entered
je .return
mov bx, 0 ;file name index
mov dl, 3 ;sector of first executable on USB or flsh drive
.next_game:
mov ax, FILES_ADDRESS;[file_list + bx]
add ax, bx
;cmp ax, no_file
;je .no_file_found
mov di, end_file
call compare_strings ;compare user_input with file name
cmp cl, 1 ;if user input matches file name execute the file
je .no_file_found ;execute binary coresponding to the file name and sector (dl)
mov ax, FILES_ADDRESS;[file_list + bx]
add ax, bx
add bx, FILES_ADDR_OFFSET ;point bx to the next filename
inc dl ;point to next sector associated to the file name
mov di, user_input
call compare_strings ;compare user_input with file name
cmp cl, 1 ;if user input matches file name execute the file
je execute ;execute binary coresponding to the file name and sector (dl)
jmp .next_game
.no_file_found:
mov si, new_line
call print_string
mov si, error_no_file
call print_string
.return: ret
;String comparison
;DI => scasb compares value stored in DI which is 's' with 's' stored in AX reg and then inc. DI if DF is 0
; v
;addr. 1: s|n|a|o|0| user input
;addr. 2: s|n|a|k|e|0| file name
; ^
;SI => lodsb loads value stored at SI to AX and then inc. SI if DF is 0
compare_strings:
cld ;clear direction flag to use later
;mov di, user_input ;point DI to target input
mov si, ax ;point SI to source string
.next_byte:
lodsb ;init AX = to where SI points to
scasb ;compare the value of whre DI is pointing at
jne .return_false
cmp al, 0 ;if reach term 0 at the end
je .return_true
jmp .next_byte
.return_true:
mov cl, 1
ret
.return_false:
mov cl, 0
ret
;procedure execute boot sector game/file
execute:
mov ax, BOOTSECTOR_ADDRESS ;init the segment
mov es, ax ;init extra segment register
mov bx, 0 ;init local offset
mov cl, dl ;select sector (4) from USB/HDD
call read_sector ;read sector
mov si, new_line
call print_string
jmp BOOTSECTOR_ADDRESS:0x0000 ;jump to the shell
;procedure to print a string
print_string:
cld ;clear directional flag
mov ah, 0x0e ;enable teletype output for int 0x10 BIOS call
.next_char:
lodsb ;read next byte from (e)si and the inc si
cmp al, 0 ;match the '/000' termnating char of a string
je .return
int 0x10 ;assuming ah = 0x0e int 0x10 will print a single char
jmp .next_char
.return: ret
;procedure to read a single sector from USB/HDD
read_sector:
mov ah, 0x02 ;BIOS code for read from storage device
mov al, 1 ;how many sectors to read
mov ch, 0 ;specify celinder
mov dh, 0 ;specify head
mov dl, 0x80 ;specify HDD code
int 0x13 ;read the sector from USB/HDD
jc .error
ret
.error:
mov si, error_message
call print_string ;print error_message
jmp $ ;stuck here forever (infinite loop)
;mesages
error_message db 'Failed to read sector from HDD/USB', 10, 13, 0
error_no_file db 'Command not found!',0;, 10, 13, 0
;variables
;intro db 'Welcome to RockOS! Type "list" to list the avaiable games ', 10, 13, 0
user_prompt db ' > ', 0
user_input times 20 db 0
new_line db 10, 13
end_file db 0, 0, 0, 0, 0, 0, 0, 0
;no_file dw 0
;file_list dw FILES_ADDRESS ;list
; dw FILES_ADDRESS + FILES_ADDR_OFFSET ;info
; dw FILES_ADDRESS + 2 * FILES_ADDR_OFFSET ;clear
; dw FILES_ADDRESS + 3 * FILES_ADDR_OFFSET ;theme
; dw FILES_ADDRESS + 4 * FILES_ADDR_OFFSET ;clock
; dw FILES_ADDRESS + 5 * FILES_ADDR_OFFSET ;snake
; dw FILES_ADDRESS + 6 * FILES_ADDR_OFFSET ;mines
; dw FILES_ADDRESS + 7 * FILES_ADDR_OFFSET ;pong
; dw FILES_ADDRESS + 8 * FILES_ADDR_OFFSET ;reboot
; dw no_file
;temp vars
times 512 - ($ - $$) db 0 ;fill trailing zeros to get exacly 512 bytes long binary file