Page 1 of 1

int 13h - Read returning 0Ch Media type not found

Posted: Tue Dec 28, 2010 10:22 pm
by yadango
Hi, I've just started learning assembly language and I wrote some NASM code to create an 8-MB fixed-size VHD file, for which I load into VirtualBox to run my assembly. The first sector contains the boot sector, and the second sector just contains a bunch of data I'd like to load into 0x0000:0x7E00 and display a character dump of. My INT 0x13 function 0x02 sector read, for some reason, doesn't work even though I'm following the IBM ROM BIOS book to the letter on how to use it. It fails with AL receiving 0x0C, "Media type not found," even though I save the boot drive number given to me from the BIOS. It also doesn't read the data when I dd the VHD to USB and boot off of it, so it must be something silly I'm doing. :-)

Here's the code. Thanks for any help!
Steven

Code: Select all

;
; SECTOR #1
; nasm -f bin -o boot.vhd boot.asm
;
bits 16
org 0x7C00
start:

 ; set stack pointer ss:sp (stack segment:stack pointer)
 cli
 mov ax, 0x0000
 mov ss, ax
 mov sp, 0x7C00
 sti

 ; save drive number
 mov [boot_drive], dl
 
 ; set video mode to color text
 mov ah, 0x00
 mov al, 0x03
 int 10h
 
 ; read sector
 read_sector:
 
    ; reset disk
    mov ah, 0x00
    mov dl, [boot_drive]
    int 0x13
 
    ; read sector
    mov ah, 0x02         ; read sectors
    mov al, 0x01         ; number of sectors to read
    mov bx, 0x0000       ; read into 0x0000:0x7E00
    mov es, bx           ; read into 0x0000:0x7E00
    mov bx, 0x7E00       ; read into 0x0000:0x7E00
    mov dl, [boot_drive] ; read from hard drive
    mov dh, 0x00         ; head
    mov ch, 0x00         ; cylinder number lo (bits 0-7) cylinder number uses 10 bits for [0, 1024] cylinders
    mov cl, 0x00         ; cylinder number hi (bits 6-7)
    and cl, 0x02         ; set the sector number (bits 0-5) sector uses 6 bits for [1, 63] sectors
    int 0x13             ; execute read sector
    ;jc read_sector
 
 ; address to take hex dump
 mov si, 0x7E00
 mov byte[row], 0x00
 mov byte[col], 0x00
    
 ; for(;;) {
 begin_loop:
 
   ; termination check
   mov al, byte[row]
   mov bl, byte[max_row]
   cmp al, bl
   jae end_loop

   ; col = 0
   mov byte[col], 0x00
   
   ; for(;;) {
   begin_col_loop:

      ; if(!(col < max_col)) break;
      mov al, byte[col]
      mov bl, byte[max_col]
      cmp al, bl
      jae end_col_loop

      ; set cursor position
      mov dh, byte[row]
      mov dl, byte[col]
      mov bh, 0x00
      mov ah, 0x02
      int 10h

      ; display character   
      mov bh, 0x00
      mov bl, 0xE4
      mov cx, 0x01
      mov al, byte[si]
      mov ah, 0x09
      int 10h
      
      ; increment address
      inc si
      
      ; col++
      inc byte[col]
      
   ; }
   jmp begin_col_loop
   end_col_loop:

   ; row++
   inc byte[row]   

 ; }   
 jmp begin_loop
 end_loop:
   
 ; loop forever
 loop_forever:
 jmp loop_forever

 ; data
 row db 0x00
 col db 0x00
 max_row db 0x10
 max_col db 0x20
 boot_drive db 0x00
 
times 510 - ($ - $$) db 0
dw 0xAA55

;
; SECTOR #2
;
times 1022 - ($ - $$) db 0x41
dw 0xAA55

;
; HARD DISK DATA
;
times 0x00800000 - ($ - $$) db 0

;
; VHD FOOTER
;
dq 0x78697463656E6F63            ; 8-byte conectix cookie
dd 0x02000000                    ; 4-byte features (reserved)
dd 0x00000100                    ; 4-byte file format version
dq 0xFFFFFFFFFFFFFFFF            ; data offset for fixed disks
dd 0x17D06014                    ; time stamp
dd 0x656E6F6E                    ; creator application (none in ASCII)
dd 0x00000100                    ; creator version
dd 0x6B326957                    ; creator host OS (Windows)
dq 0x0000800000000000            ; original size (8 MB)
dq 0x0000800000000000            ; current size (8 MB)
dd 0x1104F000                    ; disk geometry (see below)
dd 0x02000000                    ; disk type (fixed hard disk)
dd 0x00000000                    ; checksum (skip)
dq 0x0123456789ABCDEF            ; unique identifier part 1
dq 0x0123456789ABCDEF            ; unique identifier part 2
db 0x00                          ; saved state
times 427 db 0                   ; reserved

; DISK GEOMETRY
; 0x00F0-04-11
; 240 cylinders
; 4 heads
; 17 sectors
; 512 bytes per sector
; 240*4*17*512 = bytes = 8355840 KB = 7 MB

Re: int 13h - Read returning 0Ch Media type not found

Posted: Wed Dec 29, 2010 1:01 am
by Combuster
Hint: What is DS pointing to?

Re: int 13h - Read returning 0Ch Media type not found

Posted: Wed Dec 29, 2010 9:18 am
by yadango
Hmmm... DS is 0x0000... time to think...
Thanks :)

Re: int 13h - Read returning 0Ch Media type not found

Posted: Wed Dec 29, 2010 10:35 pm
by yadango
And I have thought for a day and have failed ha ha ha. This is making me feel stupid lol. Apparently, from the VirtualBox logs, it's trying to read from iSector=0x9b7be0. Computing this is obviously more complicated than just es*0x10 + bx. How does the BIOS get from what I wrote to 0x9b7be0?
Thanks,
Steven

Code: Select all

00:00:03.883 PIIX3 ATA: LUN#0: disk read error (rc=VERR_INVALID_PARAMETER iSector=0x9b7be0 cSectors=0x1)
00:00:03.884 Guest Log: BIOS: int13_harddisk: function 02, error 02 !

Re: int 13h - Read returning 0Ch Media type not found

Posted: Thu Dec 30, 2010 2:51 pm
by yadango
Wow, finally got it to work. Boy do I feel stupid ha ha ha looking for errors in all the wrong places. Besides zeroing the stack segment registers, I had:

Code: Select all

    mov cl, 0x00         ; cylinder number hi (bits 6-7)
    and  cl, 0x02         ; set the sector number (bits 0-5) sector uses 6 bits for [1, 63] sectors
    int 0x13             ; execute read sector
should have been

Code: Select all

    mov cl, 0x00         ; cylinder number hi (bits 6-7)
    or  cl, 0x02         ; set the sector number (bits 0-5) sector uses 6 bits for [1, 63] sectors
    int 0x13             ; execute read sector
:lol: I see A's now.

Code: Select all

;
; SECTOR #1
; nasm -f bin -o boot.vhd boot.asm
;
bits 16
[org 0x7C00]

jmp 0x0000:start
start:

 ; disable interrupts
 cli
 
    ; set stack pointer ss:sp (0x0000:0x7C00)
    xor ax, ax
    mov ss, ax
    mov sp, 0x7C00
    
    ; zero stack segment registers
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
        
 ; enable interrupts
 sti

 ; save drive number
 mov [boot_drive], dl

 ; set video mode to color text
 mov ah, 0x00
 mov al, 0x03
 int 10h
 
 ; read sector
 read_sector:
 
    ; reset disk
    mov ah, 0x00
    mov al, 0x00
    mov dl, [boot_drive]
    int 0x13
    
    ; read sector
    mov ah, 0x02         ; read sectors
    mov al, 0x01         ; number of sectors to read
    mov bx, 0x0000       ; read into ds:0x7E00
    mov es, bx           ; read into ds:0x7E00
    mov bx, 0x7E00       ; read into ds:0x7E00
    mov dl, [boot_drive] ; read from hard drive
    mov dh, 0x00         ; head
    mov ch, 0x00         ; cylinder number lo (bits 0-7) cylinder number uses 10 bits for [0, 1024] cylinders
    mov cl, 0x00         ; cylinder number hi (bits 6-7)
    or  cl, 0x02         ; set the sector number (bits 0-5) sector uses 6 bits for [1, 63] sectors
    int 0x13             ; execute read sector
    jc read_sector

 ; address to take hex dump
 mov si, 0x7E00
 mov byte[row], 0x00
 mov byte[col], 0x00
    
 ; for(;;) {
 begin_loop:
 
   ; termination check
   mov al, byte[row]
   mov bl, byte[max_row]
   cmp al, bl
   jae end_loop

   ; col = 0
   mov byte[col], 0x00
   
   ; for(;;) {
   begin_col_loop:

      ; if(!(col < max_col)) break;
      mov al, byte[col]
      mov bl, byte[max_col]
      cmp al, bl
      jae end_col_loop

      ; set cursor position
      mov dh, byte[row]
      mov dl, byte[col]
      mov bh, 0x00
      mov ah, 0x02
      int 10h

      ; display character
      mov bh, 0x00
      mov bl, 0xE4
      mov cx, 0x01
      mov al, byte[ds:si]
      mov ah, 0x09
      int 10h
      
      ; increment address
      inc si
      
      ; col++
      inc byte[col]
      
   ; }
   jmp begin_col_loop
   end_col_loop:

   ; row++
   inc byte[row]   

 ; }   
 jmp begin_loop
 end_loop:
   
 ; loop forever
 loop_forever:
 jmp loop_forever
 
 ; data
 row db 0x00
 col db 0x00
 max_row db 0x10
 max_col db 0x20
 boot_drive db 0x00
 
times 510 - ($ - $$) db 0
dw 0xAA55

;
; SECTOR #2
;
times 1022 - ($ - $$) db 0x41
dw 0xAA55

;
; HARD DISK DATA
;
times 0x00800000 - ($ - $$) db 0

;
; VHD FOOTER
;
dq 0x78697463656E6F63            ; 8-byte conectix cookie
dd 0x02000000                    ; 4-byte features (reserved)
dd 0x00000100                    ; 4-byte file format version
dq 0xFFFFFFFFFFFFFFFF            ; data offset for fixed disks
dd 0x17D06014                    ; time stamp
dd 0x656E6F6E                    ; creator application (none in ASCII)
dd 0x00000100                    ; creator version
dd 0x6B326957                    ; creator host OS (Windows)
dq 0x0000800000000000            ; original size (8 MB)
dq 0x0000800000000000            ; current size (8 MB)
dd 0x1104F000                    ; disk geometry (see below)
dd 0x02000000                    ; disk type (fixed hard disk)
dd 0x00000000                    ; checksum (skip)
dq 0x0123456789ABCDEF            ; unique identifier part 1
dq 0x0123456789ABCDEF            ; unique identifier part 2
db 0x00                          ; saved state
times 427 db 0                   ; reserved

; DISK GEOMETRY
; 0x00F0-04-11
; 240 cylinders
; 4 heads
; 17 sectors
; 512 bytes per sector
; 240*4*17*512 = bytes = 8355840 KB = 7 MB