0

I am trying to write a simple command system in x86 to run simple .COM files. This command system is designed to boot from a 720KB floppy. Here is the code:

[BITS 16]
[ORG 0x0000]      

mov ax, cs
mov ds, ax   
mov [drive_num], dl
mov [root_drive], dl
mov bx, load_msg
call str_prt
call new_line
xor cx, cx  
mov bx, art1
call str_prt
call new_line
mov bx, art2
call str_prt
call new_line
mov bx, art3
call str_prt
call new_line
mov bx, art4
call str_prt
call new_line
mov bx, art5
call str_prt
call new_line
mov bx, art6
call str_prt
call new_line
mov bx, art7
call str_prt
call new_line
call new_line
mov bx, welcome_msg
call str_prt
call new_line
mov bx, creator_msg
call str_prt
call new_line
mov bx, boot_msg
call str_prt
mov bx, disk
call str_prt
call disk_prop
call new_line

mov bx, [buffer]

call new_line

mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
mov al, '>'
int 0x10

loop:
xor ah, ah
int 0x16
call key_scan
jmp loop

%include "util.inc"

pro_com:
push bx
push ax
mov bx, buffer
mov al, [bx]
cmp al, 'h'
jne help_end
inc bx
mov al, [bx]
cmp al, 'e'
jne help_end
inc bx
mov al, [bx]
cmp al, 'l'
jne help_end
inc bx
mov al, [bx]
cmp al, 'p'
jne help_end
call com_help
jmp pro_end
help_end:
mov bx, buffer
mov al, [bx]
cmp al, 'd'
jne dir_end
inc bx
mov al, [bx]
cmp al, 'i'
jne dir_end
inc bx
mov al, [bx]
cmp al, 'r'
jne dir_end
call com_dir
jmp pro_end
dir_end:
mov bx, buffer
mov al, [bx]
cmp al, 'o'
jne open_end
inc bx
mov al, [bx]
cmp al, 'p'
jne open_end
inc bx
mov al, [bx]
cmp al, 'e'
jne open_end
inc bx
mov al, [bx]
cmp al, 'n'
jne open_end
call com_open
jmp pro_end
open_end:
mov bx, not_found
call str_prt
call new_line
pro_end:
pop ax
pop bx
ret

com_help:
push bx
call new_line
call draw_line
mov bx, dir_help
call str_prt
call new_line
call draw_line
call new_line
pop bx
ret

com_dir:
call new_line
push ax
push bx
push cx
push dx
call new_line
call draw_line
mov bx, drive_num
mov dl, [bx]
mov al, 0x01
mov ch, 0x00
mov cl, 0x01
mov dh, 0x00
com_dir_loop:
call read_dir
cmp cl, 0xff
je false1
inc cl
jmp com_dir_loop
false1:
cmp ch, 0xfe
je false2
inc ch
xor cl, cl
add cl, 0x01
jmp com_dir_loop
false2:
cmp dh, 0x01
je false3
xor cx, cx
add cl, 0x0f
inc dh
jmp com_dir_loop
false3:
call draw_line
call new_line
pop dx
pop cx
pop bx
pop ax 
ret

read_dir:
push ax
push bx
mov bx, 0x1000
mov es, bx
mov bx, 0xe00
;call screen_pause
;call disk_print
;call new_line
call read_disc
clc
mov bx, 0x0ff0
mov al, [bx]
cmp al, 'F'
jne read_dir_end
mov bx, 0x0ff1
call str_prt
call new_line
read_dir_end:
pop bx
pop ax 
mov bx, 0x1000
mov es, bx
ret


;---------------------------------------------------------------
;Construction zone

com_open:
push ax
push bx
push cx
push dx
call new_line
call draw_line
mov bx, drive_num
mov dl, [bx]
mov al, 0x01
mov ch, 0x00
mov cl, 0x01
mov dh, 0x00
com_open_loop:
call read_open
cmp cl, 0x09
je open_false1
inc cl
jmp com_open_loop
open_false1:
cmp ch, 0x4e
je open_false2
inc ch
xor cl, cl
add cl, 0x01
jmp com_open_loop
open_false2:
cmp dh, 0x01
je open_false3
xor cx, cx
add cl, 0x01
inc dh
jmp com_open_loop
open_false3:
call new_line
call draw_line
call new_line
pop dx
pop cx
pop bx
pop ax 
ret

read_open:
push cx
push ax
push bx
mov bx, 0x1000
mov es, bx
mov bx, 0xe00
call read_disc
clc

mov bx, buffer
add bx, 0x05
mov al, [0x0ff0]
cmp al, 'F'
jne read_open_end

mov al, [0x0ff1]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff2]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff3]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff4]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff5]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff6]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff7]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff8]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff9]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ffa]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ffb]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

clc
call 0x0e00
clc
call new_line
read_open_end:
mov bx, 0x1000
mov es, bx
pop bx
pop ax
pop cx 
ret


;---------------------------------------------------------------

buffer times 20 db 0
disk_buffer times 20 db 0

drive_num:
db 0
root_drive:
db 0

welcome_msg:
db 'Welcome to matriXos$'
creator_msg:
db 'Created by Vishnu Shankar.B$'
boot_msg:
db 'Booting command line interface...$'
not_found:
db '<Error>Command cannot be resolved! Use command "help"$'
dir_help:
db '    dir - Lists files in a drive$'
line:
db '==============================$'
art1:
db '                        __                     __   __                      $'
art2:
db '                       /\ \__           __    /\ \ /\ \                    $'
art3:
db '  ___ ___       __     \ \ ,_\   _ __  /\_\   \ `\`\/#/#     ___     ____  $'
art4:
db '/# __` __`\   /#__`\    \ \ \/  /\`#__\\/\ \   `\/ > <      / __`\  /#,__\ $'
art5:
db '/\ \/\ \/\ \ /\ \L\.\_   \ \ \_ \ \ \/  \ \ \     \/#/\`\  /\ \L\ \/\__, `\$'
art6:
db '\ \_\ \_\ \_\\ \__/.\_\   \ \__\ \ \_\   \ \_\    /\_\\ \_\\ \____/\/\____/$'
art7:
db ' \/_/\/_/\/_/ \/__/\/_/    \/__/  \/_/    \/_/    \/_/ \/_/ \/___/  \/___/ $'
load_msg:
db 'Successfully loaded operating system$'
disk:
db 'Disk properties: $'

jmp $
times 3584 - ($ - $$) db 0

Here is util.inc:

key_scan:
cmp al, 0x08
je back_space
cmp al, 0x0d
je enter
cmp cx, 0x0015 
je end
mov ah, 0x0e
int 0x10
mov bx, buffer
add bx, cx
mov [bx], al
inc cx
jmp end
back_space:
cmp cx, 0x00
je end
dec cx
mov ah, 0x0e
mov al, 0x08
int 0x10
mov al, 0x20
int 0x10
mov al, 0x08
int 0x10
jmp end
enter:
xor cx, cx
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
call pro_com
call clear_buffer
mov ah, 0x0e
mov al, '>'
int 0x10
end:
ret

clear_buffer:
push ax
push bx
push cx
mov bx, buffer
xor cx, cx
xor ax, ax
start:
cmp cx, 0x41
je end_buff
mov [bx], ax
inc bx
inc cx
jmp start
end_buff:
pop cx
pop bx
pop ax
ret

str_prt:
pusha
str:
mov ah, 0x0e
mov al, [bx]
cmp al, '$'
je str_end
int 0x10
add bx, 1
jmp str
str_end:
popa
ret

draw_line:
push ax
push bx
line_str:
mov bx, line
call str_prt
call new_line
pop bx
pop ax
ret

new_line:
push ax
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
pop ax
ret

read_disc:
mov ah, 0x02   
int 0x13   
ret

disk_prop:
push ax
push bx
push cx
push dx
mov dl, [drive_num]
mov ah, 0x08
mov bx, 0x0000
mov es, bx
mov di, bx
int 0x13
call hex_print
mov cx, dx
call hex_print
mov bx, 0x1000
mov es, bx
pop dx
pop cx
pop bx
pop ax
ret

disk_print:
push cx
mov cx, ax
call hex_print
pop cx
call hex_print
push cx
mov cx, dx
call hex_print
pop cx
ret

hex_print:
push ax
push cx
mov ah, 0x0e
mov al, '0'
int 0x10
mov al, 'x'
int 0x10
hex_print_start:
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
hex_print_end:
pop cx
pop ax
ret

hex_map:
cmp al, 0x00
jne zero_end
mov al, '0'
ret
zero_end:
cmp al, 0x10
jne one_end
mov al, '1'
ret
one_end:
cmp al, 0x20
jne two_end
mov al, '2'
ret
two_end:
cmp al, 0x30
jne three_end
mov al, '3'
ret
three_end:
cmp al, 0x40
jne four_end
mov al, '4'
ret
four_end:
cmp al, 0x50
jne five_end
mov al, '5'
ret
five_end:
cmp al, 0x60
jne six_end
mov al, '6'
ret
six_end:
cmp al, 0x70
jne seven_end
mov al, '7'
ret
seven_end:
cmp al, 0x80
jne eight_end
mov al, '8'
ret
eight_end:
cmp al, 0x90
jne nine_end
mov al, '9'
ret
nine_end:
cmp al, 0xa0
jne a_end
mov al, 'A'
ret
a_end:
cmp al, 0xb0
jne b_end
mov al, 'B'
ret
b_end:
cmp al, 0xc0
jne c_end
mov al, 'C'
ret
c_end:
cmp al, 0xd0
jne d_end
mov al, 'D'
ret
d_end:
cmp al, 0xe0
jne e_end
mov al, 'E'
ret
e_end:
cmp al, 0xf0
jne f_end
mov al, 'F'
ret
f_end:
ret

screen_pause:
push ax
xor ax, ax
int 0x16
pop ax
ret

This works fine in bochs emulator. I want this to run from a flash drive. So I wrote a function, disk_prop in util.inc. This function is called in the beginning of the program in comandsys.asm (line 40-44). This function calls ah = 0x08, int 0x13 and prints the values in cx and then in dx registers in hex so that I can get number of sectors, heads, cylinders in my flash drive. I ran this program in my laptop, found out the number of sectors, cylinders, tracks in my flash drive then I changed com_dir function in comandsys.asm correspondingly. com_dir function is supposed to print strings that begin with letter 'F' at "End" of each sector. After changing I booted my laptop through my flash drive, but com_dir function prints garbage!.
Can sombody tell me what is wrong?
Thanks in advance!
For my Bootloader, click on this stack overflow question
Note: Ignore "under construction zone"

Community
  • 1
  • 1
RainingComputers
  • 554
  • 6
  • 17
  • Can you tell us what _CX_ and _DX_ are showing when you boot from your USB? – Michael Petch Jan 01 '16 at 14:10
  • @MichaelPetch cx: 0xffff, dx: 0x0f02. I am using a 8GB flash drive. – RainingComputers Jan 01 '16 at 14:18
  • That doesn't look anywhere close to what an 8GB USB drive should be returning. Are you sure? 0x0f02 looks wrongs. 0f for heads? Maybe ff? – Michael Petch Jan 01 '16 at 14:35
  • 1
    Have you read the documentation for int 13h/08h? Take a look here: http://www.ctyme.com/intr/rb-0621.htm . One of the issues is that you have incorrectly decoded _CX_ and _DX_. Part of the cylinder number is made up of the upper 2 bits of _CL_ . The sector number is only the lower 6 bits of _CL_. The largest sector number is 63 (0x3f) 1-63. Cylinders can be a maximum of 1023 (0x3ff) 0-1023. Heads are 8bits so can be as high as 255 (0xff) 0-255. – Michael Petch Jan 01 '16 at 14:42
  • @MichaelPetch I restarted my computer using my flash drive. This might make sense: cx:0xcaff dx:fe02. Also the function counts heads from zero. So there are ff heads. – RainingComputers Jan 01 '16 at 14:44
  • @MichaelPetch I will read that. – RainingComputers Jan 01 '16 at 14:44
  • My comment says `Heads are 8bits so can be as high as 255 (0xff) 0-255` . I didn't mention that most BIOSes will report a maximum 0xfe to remain compatible with older BIOSes that had a bug. However I have seen the occasional BIOS actually return 0xff but they are far and few between, and the last one I saw was probably in the 1980s. – Michael Petch Jan 01 '16 at 14:49
  • @MichaelPetch my BIOS returns 0xfe! – RainingComputers Jan 01 '16 at 14:53
  • That is why I asked you to check your numbers for _CX_ and _DX_ and then you produced a completely different set of numbers from what you first posted (which look reasonable). – Michael Petch Jan 01 '16 at 14:58
  • `cx:0xcaff dx:fe02` Looks reasonable for a USB drive that is about 8gb. If you review that link and do the math that is 971 Cylinders * 255 heads * 63 sectors = 15,537,942 sectors * 512 = 7,955,426,304 bytes – Michael Petch Jan 01 '16 at 15:13
  • @MichaelPetch I changed com_dir to read 0x1-0x3f sectors(1-63) and 0x0 - 0xff cylinders (0 - 256). It still prints garbage... – RainingComputers Jan 01 '16 at 15:18
  • @MichaelPetch Accidentally started discussion....apologies.. – RainingComputers Jan 01 '16 at 15:23
  • If you read that link. The upper 2 bits of _CL_ are actually the upper 2 bits of the cylinder number (cylinders are a 10 bit number, not an 8 bit one). CH is the lower 8 bits of the cylinder. *CH* =0xca=0b11001010. If you take the upper 2 bits from *CL* which is 0b11 you would end up with a maximum cylinder of 0b1111001010 . So cylinders on your drive go from 0b0000000000 to 0b1111001010 which is a total of 971 cylinders. The bottom 6 bits of _CL_ are 0b111111 so sectors run from 1-63, and heads max at 0xfe which is 0-254 (or 255 heads). – Michael Petch Jan 01 '16 at 15:24
  • @MichaelPetch changed to read 63 sectors and 256 cylinders and 2 heads. still prints garbage.... – RainingComputers Jan 01 '16 at 15:27
  • 1
    2 heads? 256 cylinders? huh? You clearly aren't reading what I am saying and you clearly haven't looked at how the bits are packed into _CX_ and _DX_ that was provided at the link I gave you. You then need to set up the parameters to the READ properly to int 0x13/ah=02h is documented here: http://www.ctyme.com/intr/rb-0607.htm . Notice that you need to properly pack the 10 bit cylinder number into _CX_ along with the sector number. Problem is that you are not properly iterating through the Cylinders/Heads/Sectors properly, AND you aren't setting up the parameters properly for the read. – Michael Petch Jan 01 '16 at 15:32
  • I once told you in a previous question of yours that you really should consider looking at creating an LBA to CHS conversion routine. I gave you a link to the equations. You might want to take my advice on that. You'd probably save yourself a lot of headaches. – Michael Petch Jan 01 '16 at 15:34
  • @MichaelPetch Sorry for being such a dork......Now I understand.. – RainingComputers Jan 01 '16 at 15:36
  • If you are going to go down this route then you might want to look at this recent Stackoverflow answer: http://stackoverflow.com/a/34521208/3857942 . It literally loops through all the CHS retrieved from Get Geometry call and handles the packing of the data and then makes a call to read each sector. – Michael Petch Jan 01 '16 at 15:37
  • @MichaelPetch Thanks a lot, I will rewrite my com_dir function.... – RainingComputers Jan 01 '16 at 15:41

0 Answers0