flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > set an entry in fat12(memory buffer problem) |
Author |
|
baldr 26 Oct 2008, 05:45
abuashraf,
What is the value in ax before call setcluster? Code: org 0x100 ; Mark cluster 2 as bad mov di, 2 mov ax, 0xFF7 call fat12_set_cluster ; Mark cluster 3 as bad mov di, 3 mov ax, 0xFF7 call fat12_set_cluster ret fat12_set_cluster: ;;; di - cluster number ;;; ax - next cluster mov bx, di shr bx, 1 ;CF is set if cluster number odd lea di, [FAT12+bx+di] mov dx, 0xF000 jnc @f shl ax, 4 ;cluster number odd - adjust xor dx, 0xF00F @@: and dx, [di] or dx, ax mov [di], dx ret FAT12 db 0xF0, 0xFF, 0xFF db 0x03, 0xF0, 0xFF ;2 -> 3(EOF) |
|||
26 Oct 2008, 05:45 |
|
abuashraf 26 Oct 2008, 11:57
Ax holds the value of the free cluster number,
Code: call load_fat mov word[cluster],3 mov ax,word[cluster] x1: push es mov bx,0x100 ;fat table is loaded at (0x100:0x00) mov es,bx call getcluster ;get the next cluster of the file pop es cmp [cluster], 0x00 ;test for end of file je xxx inc ax jmp x1 xxx: mov word[cluster],ax ;save the cluster of the folder push es mov bx,0x100 ;fat table is loaded at (0x100:0x00) mov es,bx mov cx,0xFFF ;value which indecates that this cluster is the last in FAT chain mov word[value],cx mov bx,0x50 call setcluster pop es Code: ;-- ---------------------------------------------; ;returns next cluster of a specific file ; ;ax=starting cluster ; ;returns the cluster value in [cluster] ; ;assuming FAT is loaded at [100:0x50] ; ;-----------------------------------------------; getcluster: push cx dx bx mov cx, ax ;copy current cluster mov dx, ax ;copy current cluster shr dx, 0x0001 ;divide by two add cx, dx ;sum for (3/2) mov bx,0x50 ;address of fat table into memory add bx, cx ;index into FAT mov dx, WORD [es:bx] ;read two bytes from FAT(dx=old value) test ax, 0x0001 jnz .odd_ctr .even_ctr: and dx, 0000111111111111b ;take low twelve bits jmp .@.done .odd_ctr: shr dx, 0x0004 .@.done: mov WORD [cluster], dx ;store new cluster pop bx dx cx ret |
|||
26 Oct 2008, 11:57 |
|
baldr 29 Oct 2008, 12:26
abuashraf,
Just wrapped your code into .Com and debugged it… Nothing wrong, it successfully found free cluster 0x11D on my scratch floppy and updated corresponding FAT12 entry at 0x50+0x1AB with EOC mark. The only difference from your code was that mine set up es as ds+0x100 at the very beginning (100:50+1200 belongs to DOS, so I definitely will destroy something useful reading FAT there). |
|||
29 Oct 2008, 12:26 |
|
abuashraf 01 Nov 2008, 10:07
Thank you baldr very much for your help,and sorry I couldn't reply
faster because I was ill...any way,here's my whole make directory function,every time I execute it my os just hung,would you please take a look at it and tell me if there's any thing wrong: Code: md: push es ds call ffentry ;gets first free entry in the root directory save it in BX push bx call load_fat ;load fat table into memory at (0x100:0x50) mov word[cluster],3 mov ax,word[cluster] x1: push es mov bx,0x100 ;fat table is loaded at (0x100:0x00) mov es,bx call getcluster ;get the next cluster of the file pop es cmp [cluster], 0x00 ;test for end of file je xxx inc ax jmp x1 xxx: mov word[cluster],ax ;save the cluster of the folder push es mov bx,0x100 ;fat table is loaded at (0x100:0x00) mov es,bx mov cx,0xFFF ;value which indecates that this cluster is the last in FAT chain mov word[value],cx mov bx,0x50 call setcluster mov bx,0x100 ;write fat taable back to disk mov es,bx mov bx,0x50 ;at table is loaded into memory at (0x100:0x50) mov ax,1 ;the starting sector of fat table mov cx,9 ;fat table occupys 9 sectors call write_sectors ;call BIOS pop es xor ax,ax ;zero ax mov cx,ax ;zero cx mov dx,ax ;zero dx mov bx,0x500 ;set the buffer (es:bx) mov es,bx ;es=0x500,bx=0x50 mov bx,0x50 mov ax,19 ;first sector of the root directory mov cx,1 call read_sectors ;call bios xor ax,ax ;zero ax mov bx,ax ;zero bx mov si,ax ;zero di mov bx,0x500 mov ds,bx mov si,0x50 ;si points to the buffer pop bx ;get the first free entry add si,bx or byte [si+0x0b],0x10 ;make it directory mov ax,word[cluster] mov word [si+26],ax ;save the starting cluster mov cx,11 mov di,cname empty: ;pad folder name with spaces mov al,0x20 mov byte[di],al inc di loop empty call getname ;input folder name(user input) mov di,cname mov cx,11 cpyname: ;copy the folder name to the buffer mov al,byte[di] mov byte[si],al inc di inc si loop cpyname mov ax,0x500 ;write the buffer back to the disk mov es,ax mov ax,19 mov cx,1 mov bx,0x50 call write_sectors pop ds es ret Thank you very much. |
|||
01 Nov 2008, 10:07 |
|
baldr 03 Nov 2008, 20:48
abuashraf,
Hope you feel healthier today. You may add some debug output in your code to see where it hung. Stack seems to be balanced, but ffentry and getname functions are black boxes for me. ffentry function returns displacement from 0x500:0x50 or offset into segment 0x500 in bx? I.e. free root directory entry is at 500:bx or at 0x500:0x50+bx (as following code expects)? Are you sure that free root directory entry will be among the first 16? May be you should read entire root directory (14 sectors for standard 3.5" HD floppy). This md function will definitely invalidate FAT12 file system on floppy: desynchronised FAT copies, garbage as contents of just created subdirectory. And most of all: please clean up your code. There are many unnecessary instructions that add only confusion, with comments like ;zero ax that are superfluous at least. Carefully check segment registers' contents: in this fragment Code: mov bx,0x500 mov ds,bx mov si,0x50 ;si points to the buffer pop bx ;get the first free entry add si,bx or byte [si+0x0b],0x10 ;make it directory mov ax,word[cluster] mov word [si+26],ax ;save the starting cluster mov cx,11 mov di,cname empty: ;pad folder name with spaces mov al,0x20 mov byte[di],al inc di loop empty call getname ;input folder name(user input) mov di,cname mov cx,11 cpyname: ;copy the folder name to the buffer mov al,byte[di] mov byte[si],al inc di inc si loop cpyname Does getname ensure proper 8.3 padding? I.e. Code: 0123456789a
NAME EXT You must expect that only first byte of the free directory entry contains determined value, other 31 can be any garbage. Update all fields with meaningful values (or byte [si+0x0b],0x10 only sets "directory" bit, what about the rest?). |
|||
03 Nov 2008, 20:48 |
|
abuashraf 05 Nov 2008, 13:58
Hi baldr,thank you very much for your help,
and I'm really sorry about my confusing code,I'll try to make it more clean. Also about the ffentry,here it is: Code: ;-----------------------------------------------; ;returns first free entry of the root in bx ; ;searchs only in the first sector ; ;-----------------------------------------------; ffentry: push es ds mov ax,19 mov cx,1 ;read one sector mov bx,0x200 ;set the buffer (es:bx) mov es,bx ;es=0x200,bx=0x50 mov bx,0x50 call read_sectors mov bx,0x200 mov ds,bx mov si,0x50 ;si points to the buffer mov cx,16 ;number of root directory entries @@.loop: inc dx ;counts the entries,till we get free entry... test byte[si+0x0b],1 shl 3 ;is it a volume label? jnz .next cmp byte [si],0xE5 ;is it deleted file? je @del ;yes, cmp byte [si],0x00 ;is this the end of files/directories? je @del ;yes, add si,32 ;go to the next entry jmp @@.again ;continue looping @del: mov bx,dx ;save the first free entry number in bx jmp @@.quit ;quit .next: ;it is a volume label... add si,32 ;just go to the next entry @@.again: loop @@.loop ;continue looping! mov bx,00 ;no free space any more @@.quit: dec bx mov ax,bx ;entry number * 32 mov bx,32 mul bx mov bx,ax pop ds es ret in this code I'm looking for the first free entry only in the first sector of the root ,just for simplicity. Also here's the getname : Code: ;-----------------------------------------------; ;gets file/folder name from user ; ;store the name in cname ; ;whith converting it to capital letters ; ;-----------------------------------------------; getname: push si di ax bx ;push registers in the stack xor bx,bx mov di,bx mov si,bx ;make si equal to zero mov bx,cname .again: xor ah,ah ;gets input from the user int 16h cmp al,0x0D ;is it enter je .enter cmp al,0x20 ;is it spacebar? je .save ;yes,just save it... sub al,20h ;convert the letter to to caps .save: mov [bx + si],al ;save the char in the buffer (cname) inc si ;increament the pointer mov ah,0Eh ;print out the char int 10h jmp .again ;try to input more chars .enter: pop bx ax di si ;pop registers frmo the stack ret ;return! |
|||
05 Nov 2008, 13:58 |
|
baldr 05 Nov 2008, 18:55
abuashraf,
It will help me to help you if you provide complete sources. In order to compile the aforementioned test I have to write read_sectors by myself (it's not difficult, but my implementation almost surely is different from yours). write_sectors is just another example. I will not distribute your sources or any part thereof, I swear. By the way, your code use global variables for parameter passing every now and then. My opinion is that parameter passing should be done only through function's parameters, everything else is a side effect and should be avoided at any cost. |
|||
05 Nov 2008, 18:55 |
|
abuashraf 06 Nov 2008, 14:22
Hi baldr,thank you very much...
here's a complete file with all the functions you need,I'v been trying to solve my problem ,but till now I didn't find the bug ,I hope you could find the problem.and end my tragedy Thanx. |
|||
06 Nov 2008, 14:22 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.