Page 1 of 1

int 13h ext write is not working

Posted: Fri Jan 29, 2016 4:53 am
by ggodw000
I needed to write a code to read file into buffer and move the readbytes into sector 0 of drive 80h
everything works until I call the int13h 43h extended write which actually returns NC flag with AL=0,1 with AL=2 (write verify on) it rejects with AH=1, CF=1 just according to spec.
Now I read back with int13h 42h the same sector 0, but old data is still there. Which means the function returned OK but write did not take place.

The code below might have some convoluted jumps and redundant labels but that is because I removed all debugging macros and other stuff to make it easier to read. Anyone catch anything wrong? Thanks!

Code: Select all

data segment para public 'data'
fileName    db  "boot.bin$"
dosHdrBuffer db  512 dup (?)
mbrBuffer   db  512 dup (?)
filePointer dw  ?
readSize    dw  ?
data ends


;   open bootstrap file.

mainLab1:
    mov     ah, 3dh             ; (AH) = file open int 21h code.
    sub     al, al              ; (AL) = RO mode.
    mov     dx, DATA
    mov     ds, dx
    lea     dx, fileName        ; (DS:DX) = pointer to filename string.
    int     21h                 ; (AX) = file handle.
    jnc     mainLab2
    jmp     mainExit

;   read till the end or up to 1024 into buffer if FF pointer is successful.

mainLab2:
    mov     filePointer, ax     ; save file pointer.
    mov     ah, 3fh             ; (AH) = file read int 21h code.
    mov     bx, filePointer     ; (BX) = file pointer.
    mov     cx, 400h            ; (CX) = maximum of 1024 bytes.
    mov     dx, DATA
    mov     ds, dx
    lea     dx, dosHdrBuffer    ; (DS:DX) = 16:16 buffer to read into.
    int     21h                 ; (AX) = No. of bytes read if success.
    jnc     mainLab3
    jmp     mainExit

;   copy to disk 80h sector 0. Since the first 200h bytes of read is dosheader
;   we point the DS:SI to right after dosHeaderBuffer which is mbrBuffer
;   which itself is 512 bytes.

mainLab3:
    mov     readSize, ax        ; save read size.
    mov     dl, 80h             ; disk 0
    mov     si, DATA
    mov     ds, si
    lea     si, dap             ; (DS:SI) = SEG:OFF pointer to dap.

    mov     cx, 1               ; (CX) = No. of sectors.

    mov     di, DATA
    mov     es, di
    lea     di, mbrBuffer       ; (DS:SI) = SEG:OFF pointer to dap.

    M_PRINTF "\nData to write: "
    M_PRINTSTR_1616_NL es, di, 0, 040h

    mov     byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
    mov     byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
    mov     word ptr ds:[si+DAP_OFFSET_NO_SECTORS], cx

    mov     word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
    mov     word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es

    mov     dword ptr ds:[si+DAP_OFFSET_SECTOR_START], eax
    mov     dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.

    mov     ah, 43h             ; (AH) = fcn No. for extended disk write.
    sub     al, al              ; (AL) = close write check. Not sure what it means.
    int     13h                 ; (AH) = return code if error writing.
    jnc     mainLab4
    jmp     mainExit

;   open loading file.

mainLab4:

;   perform a sector 0 readback:

    mov     dl, 80h             ; disk 0

    mov     si, DATA
    mov     ds, si
    lea     si, dap             ; (DS:SI) = SEG:OFF pointer to dap.

;   prepare DAP area.

    mov     cx, 1               ; (CX) = No. of sectors.
    mov     di, DATA
    mov     es, di
    lea     di, mbrBuffer       ; (DS:SI) = SEG:OFF pointer to dap.

    mov     byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
    mov     byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
    mov     word ptr ds:[si+DAP_OFFSET_NO_SECTORS], cx

    mov     word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
    mov     word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es

    mov     dword ptr ds:[si+DAP_OFFSET_SECTOR_START], eax
    mov     dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.

    mov     ah, 42h             ; (AH) = fcn No. for extended disk read.
    int     13h                 ; (AH) = return code if error writing.
    jnc     mainLab5

mainLab5:
    M_PRINTF "\nReadback success. "
    M_PRINTSTR_1616_NL es, di, 0, 040h

    jmp     mainExit

Here is the return output, i putout first 40h bytes of the blob to be written (first hex printout) and after that read back the same sector (second hex printout). Like I said earlier, none of the INT call returned CF and worked OK, except the int 13h 43h write just did not take place.

Code: Select all


Success opening file (fileHandle), reading: 0005
Read success (No. of bytes): 0238
Data to write:

0701:0209:  B2 80 BE 00 7E 8E DE 2B : F6 C6 04 10 C6 44 01 00
0701:0219:  C7 44 02 00 00 C7 44 04 : 00 80 C7 44 06 00 00 66
0701:0229:  89 44 08 66 C7 44 0C 00 : 00 00 00 B4 42 CD 13 2B
0701:0239:  F6 8E DE BE 00 80 FF 24 : 00 00 00 00 00 00 00 00
Success writing sector 0. Readback test:
Readback success.


0701:0209:  33 C0 8E D0 BC 00 7C 8E : C0 8E D8 BE 00 7C BF 00
0701:0219:  06 B9 00 02 FC F3 A4 50 : 68 1C 06 CB FB B9 04 00
0701:0229:  BD BE 07 80 7E 00 00 7C : 0B 0F 85 0E 01 83 C5 10
0701:0239:  E2 F1 CD 18 88 56 00 55 : C6 46 11 05 C6 46 10 00


Re: int 13h ext write is not working

Posted: Fri Jan 29, 2016 5:19 am
by Octocontrabass
ggodw000 wrote:sector 0

Code: Select all

    mov     dword ptr ds:[si+DAP_OFFSET_SECTOR_START], eax
Are you sure?

Re: int 13h ext write is not working

Posted: Fri Jan 29, 2016 6:43 pm
by ggodw000
thanks, that was stupid mistake. made sure i banged up my head against the wall too.

Re: int 13h ext write is not working

Posted: Sun Jan 31, 2016 5:45 pm
by ggodw000
okay, lot of progress, i tried to make my executable bootable directly from MBR.
Here is what I did:
created small boot.bin file. Since this is DOS exec, I used file offset 08h to zero into start of file (bypass dos header). However since I ordered the segment as STA, DATA, CODE, it points to STA segment. I ordered CODE, STA, DATA so that offset 08h will point to CODE. Compile worked too with this arrangement.

Another rawcopy.exe (similar to linux dd) will do a raw copy of this file to sector 0 (mbr) starting from its CODE segment, so that BIOS will execute this bootloader.

Another file EXP.EXE is the actual program to that bootloader will jump into. I did same manipulation as boot.bin described above but it will copy file content starting from CODE segment into sector 1 and so on.

All these file are copied to bootable FDD and create another HDD1 to which it will do a raw copy.

Bootloader at sector 0, will copy about 64K worth of sectors starting from sector 1 into 0000:8000h and jumps to it.

I verified that all sectors were written correctly, by booting to another HDD2 with Windows installed and used RW utility to check the HDD1's sectors and disassembly of first few bytes of sector 0 and sector 1 to verify.

However when I boot from HDD1, BIOS error message says: "FATAL: Could not read from the boot medium! System halted."
hmm that does not look right to me. Not sure why it is complaining. Time for may be AMD SimNow.

My understanding was that BIOS (legacy) will copy sector 0 of first bootable HDD to 0:7c00 and will start executing. Assuming it did, something has gone wrong and execution looks like went back to BIOS and that is why it is displaying.

For debugging on AMD Simnow, I placed jmp $ instruction at the very beginning of boot.bin code segment and fired up SimNow but it says "Reboot and select proper Boot device".

Looks like simnow is not recognizing HDD1. I mapped another HDD2 to Simnow with bootable Windows still not booting. So task seem to remains: figure out why AMD Simnow is not booting from HDD, (FDD works).

Re: int 13h ext write is not working

Posted: Mon Feb 01, 2016 3:49 am
by ggodw000
update on this one: turns out i was erasing partition table, decided to keep it and only update the MBR with 512-64 bytes. Boot works now. Still unsure why BIOS does behave differently based on whether partition table is present or not, i will just leave this million dollar question and move on. thx every1!