I need the total disk size in bytes to be displayed at startup, as well as some additional information.
I tried doing it this way, but the data displayed on the screen was completely wrong:
[BITS 16]
[ORG 7C00h]
start:
xor ax, ax
mov es, ax
mov ds, ax
mov ah, 08h
mov dl, 80h
int 13h
jc disk_error
mov [max_cylinder], ch
mov [max_cylinder+1], cl
mov [max_head], dh
and cl, 3Fh
mov [sectors_per_track], cl
call print_disk_info
jmp $
print_disk_info:
mov si, cylinder_msg
call print_string
mov ax, [max_cylinder]
call print_number
call print_newline
mov si, head_msg
call print_string
mov al, [max_head]
call print_number
call print_newline
mov si, sectors_msg
call print_string
mov al, [sectors_per_track]
call print_number
call print_newline
mov ax, [max_cylinder]
inc ax
mov bx, [max_head]
inc bx
mul bx
mov bx, [sectors_per_track]
mul bx
mov bx, 512
mul bx
mov si, size_msg
call print_string
call print_number
mov si, bytes_msg
call print_string
call print_newline
ret
print_number:
pusha
mov bx, 10
xor cx, cx
.convert_loop:
xor dx, dx
div bx
add dl, '0'
push dx
inc cx
test ax, ax
jnz .convert_loop
.print_loop:
pop ax
mov ah, 0x0E
int 0x10
loop .print_loop
popa
ret
print_string:
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x0F
.print_char:
lodsb
cmp al, 0
je .done
int 0x10
jmp .print_char
.done:
ret
print_newline:
mov ah, 0x0E
mov al, 0x0D
int 0x10
mov al, 0x0A
int 0x10
ret
disk_error:
mov si, disk_error_msg
call print_string
jmp $
max_cylinder dw 0
max_head db 0
sectors_per_track db 0
cylinder_msg db 'Cylinders: ', 0
head_msg db 'Heads: ', 0
sectors_msg db 'Sectors per track: ', 0
size_msg db 'Total disk size: ', 0
bytes_msg db ' bytes', 0
disk_error_msg db 'Disk error!', 0
times 510-($-$$) db 0
dw 0xAA55
the program writes that the size of my disk is 3584 bytes, although the disk size is actually 8kb
I would be very grateful if you could provide a code example.
mov [max_cylinder], ch
mov [max_cylinder+1], cl
This is not consistent with the description of the BIOS call, which says:
CH = low eight bits of maximum cylinder number
CL = maximum sector number (bits 5-0); high two bits of maximum cylinder number (bits 7-6)
So you need to shift cl
before storing in max_cylinder+1
.
I might write (not optimized):
mov [max_cylinder], ch
mov al, cl
shr cl, 6
mov [max_cylinder+1], cl
and al, 3fh
mov [sectors_per_track], al
If you don't have at least a 186, you'll need instead something like
mov bl, cl
mov cl, 6
shr bl, cl
mov [max_cylinder+1], bl
It was also noted in comments that you have things like
mov bx, [max_head]
where max_head
is a byte, not a word. You need to zero-extend it, which on 8086 is perhaps most simply done by
mov bl, [max_head]
xor bh, bh
There's the same issue with mov bx, [sectors_per_track]
just below.