flat assembler
Message board for the users of flat assembler.

Index > OS Construction > How do I write to a disk using Int 13h?

Author
Thread Post new topic Reply to topic
ralc



Joined: 13 Mar 2008
Posts: 4
ralc 13 Mar 2008, 03:58
I am finding the flasmassembler website very helpful . Thanks to all.

I need some help with using 13h for writing /reading to/from disk. I am writing a small rudimentary operating system. Presently it does not do anything more than boots, loads the kernel, prints to the display several messages (help, about, etc) and echos user keyboard input to the display. Now I am working to write user input data to the disk (floppy) and being able to read it back.
To (hopefully) keep the kernel free from mistakes, I have been writing modules as com files for testing. When one works I further test it by compiling a binary file, temporarily using it as the kernel. If all goes well, the module is then incorporated into the real kernel.
I wrote the code to write to the disk (you can see that I am using Emu8086 includes). The com file does write to sector 72, but the user input string does not appear at the beginning of sector 72. Instead the user input string starts at sector 72, 9100,06 (it is likely I have the notation wrong, I am new to this). Overcome with a feeling of success, partial success is heady stuff, I compiled a binary file. It appears that the binary file writes to the disk, but it writes garbage.



; Code
; Write user input string to Sector 72

org 100h
include 'emu8086.inc'
jmp start

msg_01 db "- ", 0 ; The prompt
; Buffer size is set at 80 characters
buffer db " "
size = $ - offset buffer ; declare constant

start:
lea SI, msg_01
call print_string

; get string into ds:di
lea di, buffer ; buffer offset.
mov dx, size ; buffer size.
call get_string

putc 0Dh
putc 10 ; next line.

; print using macro:
print "< "

; print string in ds:si using procedure:
mov si, di
call print_string

; wait for any key...
mov ax, 0
int 16h

; INT 13h / AH = 02h - read disk sectors into memory.
; INT 13h / AH = 03h - write disk sectors.
;WRITE
mov AL, 1 ; AL = number of sectors to read/write (must be > zero)
MOv CH, 2 ; CH = cylinder number (0..79).
MOV CL, 1 ; CL = sector number (1..18).
mov DH, 0 ; DH = head number (0..1).
MOV DL, 0 ; DL = drive number
Mov AH, 03h
INT 13h
DEFINE_GET_STRING
DEFINE_PRINT_STRING

ret
end



Why are there such different results between the com file and the binary file? Where am I going wrong? Your good help is greatly appreciated.
Post 13 Mar 2008, 03:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 13 Mar 2008, 04:07
You need to set es:bx to point to the data that you want to write to the disk.
Post 13 Mar 2008, 04:07
View user's profile Send private message Visit poster's website Reply with quote
ralc



Joined: 13 Mar 2008
Posts: 4
ralc 27 Mar 2008, 20:47
Thank you. I think that I have it mostly worked out.
This is what I have now:

;=============================================
; 'write to sector 72
write_command:
call clear_screen
mov CX, 3
reset_disk:
MOV AH,00h ; Reset disk system 3 times, as recommended
INT 13h
loope reset_disk:

lea di, write_buffer
call get_string

mov BX, DI
mov ES:[BX], BX
mov AL, 1 ; AL = number of sectors to read/write (must be nonzero)
MOv CH, 2 ; CH = cylinder number (0..79).
MOV CL, 1 ; CL = sector number (1..18).
mov DH, 0 ; DH = head number (0..1).
MOV DL, 0 ; DL = drive number
Mov AH, 03h
INT 13h
putc 0Dh
putc 10 ; next line.
jmp processed
;=============================================

It writes to sector 72. It works fine, except it does not write the first two characters. It looks as tho I need to shift something. That is not my primary concern at the moment.

What I am working on now is reading from the disk. I have tried (what I thought) reserving the code from the write proceedure and came up with this:

;====================================================
; this is suppose to read from sector 72
read_command:
call clear_screen
mov CX, 3
reset_read_disk:
MOV AH,00h ; Reset disk system 3 times, as recommended
INT 13h
loope reset_read_disk
mov BX, DI
mov es, bx
mov AL, 1 ; AL = number of sectors to read/write (must be nonzero)
MOv CH, 2 ; CH = cylinder number (0..79).
MOV CL, 1 ; CL = sector number (1..18).
mov DH, 0 ; DH = head number (0..1).
MOV DL, 0 ; DL = drive number

Mov AH, 02h ; Read
INT 13h
putc 0Dh
putc 10 ; next line.

gotoxy 0, 1
mov SI, SI; Tried also: mov SI,BX;mov SI,es;mov SI,DI
call print_string

;wait for any key...
mov ax, 0
int 16h

jmp processed ; END Read
;====================================================

This does not seem to read from anything, at least it does not read anything to the dispaly. Where did I make the wrong turn? Thank you.
Post 27 Mar 2008, 20:47
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 27 Mar 2008, 21:51
ralc wrote:
mov es, bx
You need to set ES to your source/target memory segment and set BX to your source/target memory offset.
Post 27 Mar 2008, 21:51
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 27 Mar 2008, 22:09
note that on some machines, the offset in bx shall be 0, otherwise, it don't work.
and be carefull to don't cross a 64k boundary during the read/write/verify.
it may cause a dma overrun. then, the best is to write your own floppy driver.

i prefer to read sectors one by one, and if error, retry at least 3 times.
it is slow, but it's better.

something fun:
you post a question about floppy the day i buy new ones. and i think i have the same problems as you.
if i try to write over 16K on the floppy, it don't works, the same for reads.
Post 27 Mar 2008, 22:09
View user's profile Send private message Visit poster's website Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 28 Mar 2008, 04:57
ralc: My boot sector example may help you. It loads a secondary binary file to memory and jumps to it. The example also shows how to handle es:bx.

http://board.flatassembler.net/topic.php?t=6529

regards,
Mac2004
Post 28 Mar 2008, 04:57
View user's profile Send private message Reply with quote
roboman



Joined: 03 Dec 2006
Posts: 122
Location: USA
roboman 28 Mar 2008, 14:57
I've also got an example on my page that might help. A little program that formats a dish using the bios, then writes the boot sector with the bios int 13. 'ForDex' at http://home.comcast.net/~dexos/
Post 28 Mar 2008, 14:57
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.