Code: Select all
.
.
mov ah, 0x02
mov al, [0x7a00] ;1
mov cl, [0x7a01] ;1
mov dh, [0x7a02] ;31
mov dl, [drivedata] ;sets by bios
mov ch, [0x7a03] ;0
mov bx, [0x7a06] ;0
mov es, bx
mov bx, [0x7a04] ;0x7000
int 0x13
jnc diskreadnoerr
.
.
And yes, I tested using debug-prints and found that the CPU executes successfully upto int 0x13, then it doesn't come out. Doesn't go to error routine either. It stucks somewhere inside that routine.
I also tested by directly giving the arguments instead of reding it from memory, but still it didn't work. I have no idea why this is happening.
This is how I jumps back to real mode..
Code: Select all
.
.
lgdt [gdt_desc_16]
jmp 0x8:$+7
mov eax, cr0
and al, 0xfe
mov cr0, eax
jmp 0x0:bit_16_start
[bits 16]
bit_16_start:
mov ax, 0
mov ds, ax
mov ss, ax
mov fs, ax
mov es, ax
mov gs, ax
mov ax, 0x7900
mov sp, ax
mov bp, ax
.
.
Code: Select all
null_16: ;NULL gdt
dd 0x0
dd 0x0
gdt_code_16: ;code segment descriptor
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 00001111b
db 0x0
gdt_data_16: ;Data segment Descriptor
dw 0xffff
dw 0x0
db 0x0
db 10010010b ; 1 st flags , type flags
db 00001111b ; 2 nd flags , Limit ( bits 16 -19)
db 0x0
I can actually call some BIOS routines! I used 10h to reset video mode and used my own 16-bit subroutine to that prints strings using 10h and it all worked! Right until int 0x13!
Then I tried to reset disk using int 13h. But no even that didn't happen.
my modified code:
Code: Select all
[bits 16]
mov dl, 0x80
mov ah, 0
;int 0x13 ;doesn't work!
mov al, 3
mov ah, 0
int 0x10 ; works!
mov bx, checkdata
call print_bx ;also works!
mov al, [0x7a00]
mov cl, [0x7a01]
mov dh, [0x7a02]
mov dl, [drivedata]
mov ch, [0x7a03]
mov bx, [0x7a06]
mov es, bx
mov bx, [0x7a04]
mov ah, 0x02
int 0x13 ;doesn't work!