diff --git a/kernel/trunk/sec_loader/trunk/boot/after_win/build.bat b/kernel/trunk/sec_loader/trunk/boot/after_win/build.bat new file mode 100644 index 0000000000..5419e0d687 --- /dev/null +++ b/kernel/trunk/sec_loader/trunk/boot/after_win/build.bat @@ -0,0 +1,2 @@ +@fasm -m 65535 kordldr.win.asm kordldr.win +@pause \ No newline at end of file diff --git a/kernel/trunk/sec_loader/trunk/boot/build.bat b/kernel/trunk/sec_loader/trunk/boot/build.bat new file mode 100644 index 0000000000..00039e5053 --- /dev/null +++ b/kernel/trunk/sec_loader/trunk/boot/build.bat @@ -0,0 +1,16 @@ +echo off +cls +echo ** bulding after win loader ** +@fasm -m 65535 after_win/kordldr.win.asm after_win/kordldr.win +echo ============================== +echo ** building first loader for cd/dvd ** +@fasm -m 65535 cdfs/bootsect.asm cdfs/bootsect.bin +echo ============================== +echo ** building first loader for fat12/fat16 ** +@fasm -m 65535 fat1x/bootsect.asm fat1x/bootsect.bin +@fasm -m 65535 fat1x/kordldr.f1x.asm fat1x/kordldr.f1x +echo ============================== +echo ** building firs loader for fat32 ** +@fasm -m 65535 fat32/bootsect.asm fat32/bootsect.bin +@fasm -m 65535 fat32/kordldr.f1x.asm fat32/kordldr.f1x +@pause diff --git a/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.asm b/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.asm index a9ccb863aa..4d03989b37 100644 --- a/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.asm +++ b/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.asm @@ -24,792 +24,792 @@ ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;***************************************************************************** - jmp far 0:real_start + jmp far 0:real_start ; special text org $+0x7C00 real_start: ; initialize - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov es, ax - cld - sti - mov [bootdrive], dl + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov es, ax + cld + sti + mov [bootdrive], dl ; check LBA support - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err - cmp bx, 0AA55h - jnz err - test cl, 1 - jz err + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cl, 1 + jz err_ ; get file system information ; scan for Primary Volume Descriptor - db 66h - push 10h-1 - pop eax + db 66h + push 10h-1 + pop eax pvd_scan_loop: - mov cx, 1 - inc eax - mov bx, 0x1000 - call read_sectors - jnc @f + mov cx, 1 + inc eax + mov bx, 0x1000 + call read_sectors + jnc @f fatal_read_err: - mov si, aReadError -err: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ + mov si, aReadError +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ @@: - push ds - pop es - cmp word [bx+1], 'CD' - jnz pvd_scan_loop - cmp word [bx+3], '00' - jnz pvd_scan_loop - cmp byte [bx+5], '1' - jnz pvd_scan_loop + push ds + pop es + cmp word [bx+1], 'CD' + jnz pvd_scan_loop + cmp word [bx+3], '00' + jnz pvd_scan_loop + cmp byte [bx+5], '1' + jnz pvd_scan_loop ; we have found ISO9660 descriptor, look for type - cmp byte [bx], 1 ; Primary Volume Descriptor? - jz pvd_found - cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? - jnz pvd_scan_loop + cmp byte [bx], 1 ; Primary Volume Descriptor? + jz pvd_found + cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? + jnz pvd_scan_loop ; Volume Descriptor Set Terminator reached, no PVD found - fatal error - mov si, no_pvd - jmp err + mov si, no_pvd + jmp err_ pvd_found: - add bx, 80h - mov ax, [bx] - mov [lb_size], ax + add bx, 80h + mov ax, [bx] + mov [lb_size], ax ; calculate number of logical blocks in one sector - mov ax, 800h - cwd - div word [bx] - mov [lb_per_sec], ax + mov ax, 800h + cwd + div word [bx] + mov [lb_per_sec], ax ; get location of root directory - mov di, root_location - movzx eax, byte [bx+1Dh] - add eax, [bx+1Eh] - stosd + mov di, root_location + movzx eax, byte [bx+1Dh] + add eax, [bx+1Eh] + stosd ; get memory size - int 12h - mov si, nomem_str - cmp ax, 71000h / 400h - jb err - shr ax, 1 - sub ax, 60000h / 800h - mov [size_rest], ax - mov [free_ptr], 60000h / 800h + int 12h + mov si, nomem_str + cmp ax, 71000h / 400h + jb err_ + shr ax, 1 + sub ax, 60000h / 800h + mov [size_rest], ax + mov [free_ptr], 60000h / 800h ; load path table ; if size > 62K => it's very strange, avoid using it ; if size > (size of cache)/2 => avoid using it too - mov ecx, [bx+4] - cmp ecx, 0x10000 - 0x800 - ja nopathtable - shr ax, 1 - cmp ax, 0x20 - jae @f - shl ax, 11 - cmp cx, ax - ja nopathtable + mov ecx, [bx+4] + cmp ecx, 0x10000 - 0x800 + ja nopathtable + shr ax, 1 + cmp ax, 0x20 + jae @f + shl ax, 11 + cmp cx, ax + ja nopathtable @@: ; size is ok, try to load it - mov [pathtable_size], cx - mov eax, [bx+12] - xor edx, edx - div dword [lb_per_sec] - imul dx, [bx] - mov [pathtable_start], dx - add cx, dx - call cx_to_sectors - xor bx, bx - push 6000h - pop es - call read_sectors - jc nopathtable + mov [pathtable_size], cx + mov eax, [bx+12] + xor edx, edx + div dword [lb_per_sec] + imul dx, [bx] + mov [pathtable_start], dx + add cx, dx + call cx_to_sectors + xor bx, bx + push 6000h + pop es + call read_sectors + jc nopathtable ; path table has been loaded - inc [use_path_table] - sub [size_rest], cx - add [free_ptr], cx + inc [use_path_table] + sub [size_rest], cx + add [free_ptr], cx nopathtable: ; init cache - mov ax, [size_rest] - mov [cache_size], ax - mov ax, [free_ptr] - mov [cache_start], ax + mov ax, [size_rest] + mov [cache_size], ax + mov ax, [free_ptr] + mov [cache_start], ax ; load secondary loader - mov di, secondary_loader_info - call load_file - test bx, bx - jnz noloader + mov di, secondary_loader_info + call load_file + test bx, bx + jnz noloader ; set registers for secondary loader - mov ah, [bootdrive] - mov al, 'c' - mov bx, 'is' - mov si, callback - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 + mov ah, [bootdrive] + mov al, 'c' + mov bx, 'is' + mov si, callback + jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 noloader: - mov si, aKernelNotFound - jmp err + mov si, aKernelNotFound + jmp err_ read_sectors: ; es:bx = pointer to data ; eax = first sector ; cx = number of sectors - pushad - push ds + pushad + push ds do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F + push ax + push cx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F @@: ; create disk address packet on the stack ; dq starting LBA - db 66h - push 0 - push eax + db 66h + push 0 + push eax ; dd buffer - push es - push bx + push es + push bx ; dw number of blocks to transfer (no more than 0x7F) - push cx + push cx ; dw packet size in bytes - push 10h + push 10h ; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [cs:bootdrive] - mov ah, 42h - int 13h - jc diskreaderr + push ss + pop ds + mov si, sp + mov dl, [cs:bootdrive] + mov ah, 42h + int 13h + jc diskreaderr ; restore stack - add sp, 10h + add sp, 10h ; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 7 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popad - ret + movzx esi, cx + mov ax, es + shl cx, 7 + add ax, cx + mov es, ax + pop cx + pop ax + add eax, esi + sub cx, si + jnz do_read_sectors + pop ds + popad + ret diskreaderr: - add sp, 10h + 2*2 - pop ds - popad - stc + add sp, 10h + 2*2 + pop ds + popad + stc out_string.ret: - ret + ret out_string: ; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz .ret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string + lodsb + test al, al + jz .ret + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string -aNoLBA db 'The drive does not support LBA!',0 -aReadError db 'Read error',0 -no_pvd db 'Primary Volume Descriptor not found!',0 -nomem_str db 'No memory',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 +aNoLBA db 'The drive does not support LBA!',0 +aReadError db 'Read error',0 +no_pvd db 'Primary Volume Descriptor not found!',0 +nomem_str db 'No memory',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 load_file: ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found ; out: dx:ax = file size (0xFFFFFFFF if file not found) ; parse path to the file - lea si, [di+6] - mov eax, [cs:root_location] - cmp [cs:use_path_table], 0 - jz parse_dir + lea si, [di+6] + mov eax, [cs:root_location] + cmp [cs:use_path_table], 0 + jz parse_dir ; scan for path in path table - push di - push 6000h - pop es - mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table - mov dx, 1 ; dx = number of current entry in path table, start from 1 - mov cx, [cs:pathtable_size] + push di + push 6000h + pop es + mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table + mov dx, 1 ; dx = number of current entry in path table, start from 1 + mov cx, [cs:pathtable_size] pathtable_newparent: - mov bx, dx ; bx = number of current parent in path table: root = 1 + mov bx, dx ; bx = number of current parent in path table: root = 1 scan_path_table_e: - call is_last_component - jnc path_table_scanned + call is_last_component + jnc path_table_scanned scan_path_table_i: - cmp word [es:di+6], bx - jb .next - ja path_table_notfound - call test_filename1 - jc .next + cmp word [es:di+6], bx + jb .next + ja path_table_notfound + call test_filename1 + jc .next @@: - lodsb - cmp al, '/' - jnz @b - jmp pathtable_newparent + lodsb + cmp al, '/' + jnz @b + jmp pathtable_newparent .next: ; go to next entry - inc dx - movzx ax, byte [es:di] - add ax, 8+1 - and al, not 1 - add di, ax - sub cx, ax - ja scan_path_table_i + inc dx + movzx ax, byte [es:di] + add ax, 8+1 + and al, not 1 + add di, ax + sub cx, ax + ja scan_path_table_i path_table_notfound: - pop di - mov ax, -1 - mov dx, ax - mov bx, 2 ; file not found - ret + pop di + mov ax, -1 + mov dx, ax + mov bx, 2 ; file not found + ret path_table_scanned: - movzx eax, byte [es:di+1] - add eax, [es:di+2] - pop di + movzx eax, byte [es:di+1] + add eax, [es:di+2] + pop di parse_dir: ; eax = logical block, ds:di -> information structure, ds:si -> file name ; was the folder already read? - push di ds - push cs - pop ds - mov [cur_desc_end], 2000h - mov bx, cachelist + push di ds + push cs + pop ds + mov [cur_desc_end], 2000h + mov bx, cachelist .scan1: - mov bx, [bx+2] - cmp bx, cachelist - jz .notfound - cmp [bx+4], eax - jnz .scan1 + mov bx, [bx+2] + cmp bx, cachelist + jz .notfound + cmp [bx+4], eax + jnz .scan1 .found: ; yes; delete this item from the list (the following code will append this item to the tail) - mov di, [bx] - push word [bx+2] - pop word [di+2] - mov di, [bx+2] - push word [bx] - pop word [di] - mov di, bx - jmp .scan + mov di, [bx] + push word [bx+2] + pop word [di+2] + mov di, [bx+2] + push word [bx] + pop word [di] + mov di, bx + jmp .scan .notfound: ; no; load first sector of the folder to get its size - push eax - push si - mov si, 1 - call load_phys_sector_for_lb_force - mov bx, si - pop si - pop eax - jnc @f + push eax + push si + mov si, 1 + call load_phys_sector_for_lb_force + mov bx, si + pop si + pop eax + jnc @f ; read error - return .readerr: - pop ds + pop ds .readerr2: - pop di - mov ax, -1 - mov dx, ax - mov bx, 3 - ret + pop di + mov ax, -1 + mov dx, ax + mov bx, 3 + ret @@: ; first item of the folder describes the folder itself ; do not cache too big folders: size < 64K and size <= (total cache size)/2 - cmp word [bx+12], 0 - jnz .nocache - mov cx, [cache_size] ; cx = cache size in sectors - shr cx, 1 ; cx = (cache size)/2 - cmp cx, 0x20 - jae @f - shl cx, 11 - cmp [bx+10], cx - ja .nocache + cmp word [bx+12], 0 + jnz .nocache + mov cx, [cache_size] ; cx = cache size in sectors + shr cx, 1 ; cx = (cache size)/2 + cmp cx, 0x20 + jae @f + shl cx, 11 + cmp [bx+10], cx + ja .nocache @@: ; we want to cache this folder; get space for it - mov cx, [bx+10] - call cx_to_sectors - jnz .yescache + mov cx, [bx+10] + call cx_to_sectors + jnz .yescache .nocache: - push dword [bx+10] - pop dword [cur_nocache_len] - call lb_to_sector - push ds - pop es - pop ds + push dword [bx+10] + pop dword [cur_nocache_len] + call lb_to_sector + push ds + pop es + pop ds .nocache_loop: - push eax - mov dx, 1800h - call scan_for_filename_in_sector - mov cx, dx - pop eax - jnc .j_scandone - sub cx, bx - sub word [es:cur_nocache_len], cx - sbb word [es:cur_nocache_len+2], 0 - jb .j_scandone - ja @f - cmp word [es:cur_nocache_len], 0 - jz .j_scandone + push eax + mov dx, 1800h + call scan_for_filename_in_sector + mov cx, dx + pop eax + jnc .j_scandone + sub cx, bx + sub word [es:cur_nocache_len], cx + sbb word [es:cur_nocache_len+2], 0 + jb .j_scandone + ja @f + cmp word [es:cur_nocache_len], 0 + jz .j_scandone @@: - mov cx, 1 - inc eax - push es - mov bx, 1000h - call read_sectors - pop es - jc .readerr2 - jmp .nocache_loop + mov cx, 1 + inc eax + push es + mov bx, 1000h + call read_sectors + pop es + jc .readerr2 + jmp .nocache_loop .j_scandone: - jmp .scandone + jmp .scandone .yescache: - push bx - mov bx, [cachelist.head] + push bx + mov bx, [cachelist.head] .freeloop: - cmp cx, [size_rest] - jbe .sizeok + cmp cx, [size_rest] + jbe .sizeok @@: ; if we are here: there is not enough free space, so we must delete old folders' data ; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). ; one loop iteration: delete data of one folder - pusha - mov dx, [bx+10] - mov es, dx ; es = segment of folder data to be deleted - xor di, di - mov ax, [bx+8] - add ax, 0x7FF - rcr ax, 1 - shr ax, 10 - push ax - shl ax, 11-4 ; get number of paragraphs in folder data to be deleted - mov cx, [cache_size] - add cx, [cache_start] - push ds - push ax - add ax, dx - mov ds, ax - pop ax - shl cx, 11-4 - sub cx, dx ; cx = number of paragraphs to be moved - push si - xor si, si + pusha + mov dx, [bx+10] + mov es, dx ; es = segment of folder data to be deleted + xor di, di + mov ax, [bx+8] + add ax, 0x7FF + rcr ax, 1 + shr ax, 10 + push ax + shl ax, 11-4 ; get number of paragraphs in folder data to be deleted + mov cx, [cache_size] + add cx, [cache_start] + push ds + push ax + add ax, dx + mov ds, ax + pop ax + shl cx, 11-4 + sub cx, dx ; cx = number of paragraphs to be moved + push si + xor si, si ; move cx paragraphs from ds:si to es:di to get free space in the end of cache @@: - sub cx, 1000h - jbe @f - push cx - mov cx, 8000h - rep movsw - mov cx, ds - add cx, 1000h - mov ds, cx - mov cx, es - add cx, 1000h - mov es, cx - pop cx - jmp @b + sub cx, 1000h + jbe @f + push cx + mov cx, 8000h + rep movsw + mov cx, ds + add cx, 1000h + mov ds, cx + mov cx, es + add cx, 1000h + mov es, cx + pop cx + jmp @b @@: - add cx, 1000h - shl cx, 3 - rep movsw - pop si - pop ds + add cx, 1000h + shl cx, 3 + rep movsw + pop si + pop ds ; correct positions in cache for existing items - mov cx, 80h - mov di, 8400h + mov cx, 80h + mov di, 8400h .correct: - cmp [di+10], dx - jbe @f - sub [di+10], ax + cmp [di+10], dx + jbe @f + sub [di+10], ax @@: - add di, 12 - loop .correct + add di, 12 + loop .correct ; some additional space is free now - pop ax - add [size_rest], ax - sub [free_ptr], ax + pop ax + add [size_rest], ax + sub [free_ptr], ax ; add cache item to the list of free items - mov dx, [bx] - mov ax, [free_cache_item] - mov [bx], ax - mov [free_cache_item], bx - mov bx, dx + mov dx, [bx] + mov ax, [free_cache_item] + mov [bx], ax + mov [free_cache_item], bx + mov bx, dx ; current iteration done - popa - jmp .freeloop + popa + jmp .freeloop .sizeok: - mov [cachelist.head], bx - mov word [bx+2], cachelist + mov [cachelist.head], bx + mov word [bx+2], cachelist ; allocate new item in cache - mov di, [free_cache_item] - test di, di - jz .nofree - push word [di] - pop [free_cache_item] - jmp @f + mov di, [free_cache_item] + test di, di + jz .nofree + push word [di] + pop [free_cache_item] + jmp @f .nofree: - mov di, [last_cache_item] - add [last_cache_item], 12 + mov di, [last_cache_item] + add [last_cache_item], 12 @@: - pop bx - push si di -; mov [di+4], eax ; start of folder - scasd - stosd - push ax - mov ax, [free_ptr] - shl ax, 11-4 - mov [di+10-8], ax - mov es, ax - pop ax - add [free_ptr], cx - sub [size_rest], cx + pop bx + push si di +; mov [di+4], eax ; start of folder + scasd + stosd + push ax + mov ax, [free_ptr] + shl ax, 11-4 + mov [di+10-8], ax + mov es, ax + pop ax + add [free_ptr], cx + sub [size_rest], cx ; read folder data ; first sector is already in memory, 0000:bx - pusha - mov cx, [bx+10] - mov [di+8-8], cx ; folder size in bytes - mov si, bx - xor di, di - mov cx, 0x1800 - sub cx, si - rep movsb - pop ax - push di - popa + pusha + mov cx, [bx+10] + mov [di+8-8], cx ; folder size in bytes + mov si, bx + xor di, di + mov cx, 0x1800 + sub cx, si + rep movsb + pop ax + push di + popa ; read rest of folder - mov esi, dword [lb_per_sec] - add eax, esi - dec si - not si - and ax, si - mov si, word [bx+10] - mov bx, di - pop di - sub si, bx - jbe @f - mov [cur_limit], esi - call read_many_bytes - pop si - jnc .scan - jmp .readerr + mov esi, dword [lb_per_sec] + add eax, esi + dec si + not si + and ax, si + mov si, word [bx+10] + mov bx, di + pop di + sub si, bx + jbe @f + mov [cur_limit], esi + call read_many_bytes + pop si + jnc .scan + jmp .readerr @@: - pop si + pop si .scan: ; now we have required cache item; append it to the end of list - mov bx, [cachelist.tail] - mov [cachelist.tail], di - mov [di+2], bx - mov word [di], cachelist - mov [bx], di + mov bx, [cachelist.tail] + mov [cachelist.tail], di + mov [di+2], bx + mov word [di], cachelist + mov [bx], di ; scan for given filename - mov es, [di+10] - mov dx, [di+8] - pop ds - xor bx, bx - call scan_for_filename_in_sector + mov es, [di+10] + mov dx, [di+8] + pop ds + xor bx, bx + call scan_for_filename_in_sector .scandone: - push cs - pop es - mov bx, 2000h - cmp bx, [es:cur_desc_end] - jnz filefound + push cs + pop es + mov bx, 2000h + cmp bx, [es:cur_desc_end] + jnz filefound j_notfound: - jmp path_table_notfound + jmp path_table_notfound filefound: @@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b @@: - mov cl, [es:bx+8] - test al, al - jz @f + mov cl, [es:bx+8] + test al, al + jz @f ; parse next component of file name - test cl, 2 ; directory? - jz j_notfound - mov eax, [es:bx] - pop di - jmp parse_dir + test cl, 2 ; directory? + jz j_notfound + mov eax, [es:bx] + pop di + jmp parse_dir @@: - test cl, 2 ; directory? - jnz j_notfound ; do not allow read directories as regular files + test cl, 2 ; directory? + jnz j_notfound ; do not allow read directories as regular files ; ok, now load the file - pop di - les bx, [di] - call normalize - movzx esi, word [di+4] ; esi = limit in 4K blocks - shl esi, 12 ; esi = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, 2000h + pop di + les bx, [di] + call normalize + movzx esi, word [di+4] ; esi = limit in 4K blocks + shl esi, 12 ; esi = limit in bytes + push cs + pop ds + mov [cur_limit], esi + mov di, 2000h loadloop: - and [cur_start], 0 + and [cur_start], 0 .loadnew: - mov esi, [cur_limit] - mov eax, [cur_start] - add esi, eax - mov [overflow], 1 - sub esi, [di+4] - jb @f - xor esi, esi - dec [overflow] + mov esi, [cur_limit] + mov eax, [cur_start] + add esi, eax + mov [overflow], 1 + sub esi, [di+4] + jb @f + xor esi, esi + dec [overflow] @@: - add esi, [di+4] ; esi = number of bytes to read - mov [cur_start], esi - sub esi, eax - jz .loadcontinue - xor edx, edx - div dword [lb_size] ; eax = number of logical blocks to skip, - mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block - cmp byte [di+10], 0 - jnz .interleaved - add eax, [di] + add esi, [di+4] ; esi = number of bytes to read + mov [cur_start], esi + sub esi, eax + jz .loadcontinue + xor edx, edx + div dword [lb_size] ; eax = number of logical blocks to skip, + mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block + cmp byte [di+10], 0 + jnz .interleaved + add eax, [di] ; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - jc .readerr3 + call read_many_bytes.with_first + jc .readerr3 .loadcontinue: - mov [cur_chunk], di - add di, 11 - cmp di, [cur_desc_end] - jae @f - cmp [cur_limit], 0 - jnz loadloop + mov [cur_chunk], di + add di, 11 + cmp di, [cur_desc_end] + jae @f + cmp [cur_limit], 0 + jnz loadloop @@: - mov bx, [overflow] + mov bx, [overflow] .calclen: ; calculate length of file - xor ax, ax - xor dx, dx - mov di, 2000h + xor ax, ax + xor dx, dx + mov di, 2000h @@: - add ax, [di+4] - adc dx, [di+6] - add di, 11 - cmp di, [cur_desc_end] - jb @b - ret + add ax, [di+4] + adc dx, [di+6] + add di, 11 + cmp di, [cur_desc_end] + jb @b + ret .interleaved: - mov [cur_unit_limit], esi - push esi + mov [cur_unit_limit], esi + push esi ; skip first blocks - movzx ecx, byte [di+9] ; Unit Size - movzx esi, byte [di+10] ; Interleave Gap - add si, cx - mov edx, [di] + movzx ecx, byte [di+9] ; Unit Size + movzx esi, byte [di+10] ; Interleave Gap + add si, cx + mov edx, [di] @@: - sub eax, ecx - jb @f - add edx, esi - jmp @b + sub eax, ecx + jb @f + add edx, esi + jmp @b @@: - add ecx, eax ; ecx = number of logical blocks to skip - lea eax, [ecx+edx] ; eax = first logical block - pop esi + add ecx, eax ; ecx = number of logical blocks to skip + lea eax, [ecx+edx] ; eax = first logical block + pop esi .interleaved_loop: ; get number of bytes in current file unit - push eax - movzx eax, byte [di+9] - sub ax, cx - imul eax, dword [lb_size] - cmp eax, esi - ja .i2 + push eax + movzx eax, byte [di+9] + sub ax, cx + imul eax, dword [lb_size] + cmp eax, esi + ja .i2 .i1: - xchg esi, eax + xchg esi, eax .i2: - pop eax - sub [cur_unit_limit], esi - push eax + pop eax + sub [cur_unit_limit], esi + push eax ; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - pop eax - jnc @f + call read_many_bytes.with_first + pop eax + jnc @f .readerr3: - mov bx, 3 - jmp .calclen + mov bx, 3 + jmp .calclen @@: - mov esi, [cur_unit_limit] - test esi, esi - jz .loadcontinue - movzx ecx, byte [di+9] ; add Unit Size - add cl, byte [di+10] ; add Interleave Gap - adc ch, 0 - add eax, ecx - xor cx, cx - mov [first_byte], cx - jmp .interleaved_loop + mov esi, [cur_unit_limit] + test esi, esi + jz .loadcontinue + movzx ecx, byte [di+9] ; add Unit Size + add cl, byte [di+10] ; add Interleave Gap + adc ch, 0 + add eax, ecx + xor cx, cx + mov [first_byte], cx + jmp .interleaved_loop cx_to_sectors: - add cx, 7FFh - rcr cx, 1 - shr cx, 10 - ret + add cx, 7FFh + rcr cx, 1 + shr cx, 10 + ret is_last_component: ; in: ds:si -> name ; out: CF set <=> current component is not last (=> folder) - push si + push si @@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b - stc + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + stc @@: - pop si - ret + pop si + ret test_filename1: ; in: ds:si -> filename, es:di -> path table item ; out: CF set <=> no match - pusha - mov cl, [es:di] - add di, 8 - jmp test_filename2.start + pusha + mov cl, [es:di] + add di, 8 + jmp test_filename2.start test_filename2: ; in: ds:si -> filename, es:bx -> directory item ; out: CF set <=> no match - pusha - mov cl, [es:bx+32] - lea di, [bx+33] + pusha + mov cl, [es:bx+32] + lea di, [bx+33] .start: - mov ch, 0 + mov ch, 0 @@: - lodsb - test al, al - jz .test1 - cmp al, '/' - jz .test1 - call toupper - mov ah, al - mov al, [es:di] - call toupper - inc di - cmp al, ah - loopz @b - jnz .next1 + lodsb + test al, al + jz .test1 + cmp al, '/' + jz .test1 + call toupper + mov ah, al + mov al, [es:di] + call toupper + inc di + cmp al, ah + loopz @b + jnz .next1 ; if we have reached this point: current name is done - lodsb - test al, al - jz .ret - cmp al, '/' - jz .ret + lodsb + test al, al + jz .ret + cmp al, '/' + jz .ret ; if we have reached this point: current name is done, but input name continues ; so they do not match - jmp .next1 + jmp .next1 .test1: ; if we have reached this point: input name is done, but current name continues ; "filename.ext;version" in ISO-9660 represents file "filename.ext" ; "filename." and "filename.;version" are also possible for "filename" - cmp byte [es:di], '.' - jnz @f - inc di - dec cx - jz .ret + cmp byte [es:di], '.' + jnz @f + inc di + dec cx + jz .ret @@: - cmp byte [es:di], ';' - jnz .next1 - jmp .ret + cmp byte [es:di], ';' + jnz .next1 + jmp .ret .next1: - stc + stc .ret: - popa - ret + popa + ret toupper: ; in: al=symbol ; out: al=symbol in uppercase - cmp al, 'a' - jb .ret - cmp al, 'z' - ja .ret - sub al, 'a'-'A' + cmp al, 'a' + jb .ret + cmp al, 'z' + ja .ret + sub al, 'a'-'A' .ret: - ret + ret scan_for_filename_in_sector: ; in: ds:si->filename, es:bx->folder data, dx=limit ; out: CF=0 if found - push bx + push bx .loope: - push bx + push bx .loop: - cmp bx, dx - jae .notfound - cmp byte [es:bx], 0 - jz .loopd - test byte [es:bx+25], 4 ; ignore files with Associated bit - jnz .next - call test_filename2 - jc .next - push ds es di - push es - pop ds - push cs - pop es - mov di, [es:cur_desc_end] - movzx eax, byte [bx+1] - add eax, [bx+2] - stosd ; first logical block - mov eax, [bx+10] - stosd ; length - mov al, [bx+25] - stosb ; flags - mov ax, [bx+26] - stosw ; File Unit size, Interleave Gap size - mov [es:cur_desc_end], di - cmp di, 3000h - pop di es ds - jae .done - test byte [es:bx+25], 80h - jz .done + cmp bx, dx + jae .notfound + cmp byte [es:bx], 0 + jz .loopd + test byte [es:bx+25], 4 ; ignore files with Associated bit + jnz .next + call test_filename2 + jc .next + push ds es di + push es + pop ds + push cs + pop es + mov di, [es:cur_desc_end] + movzx eax, byte [bx+1] + add eax, [bx+2] + stosd ; first logical block + mov eax, [bx+10] + stosd ; length + mov al, [bx+25] + stosb ; flags + mov ax, [bx+26] + stosw ; File Unit size, Interleave Gap size + mov [es:cur_desc_end], di + cmp di, 3000h + pop di es ds + jae .done + test byte [es:bx+25], 80h + jz .done .next: - add bl, [es:bx] - adc bh, 0 - jmp .loop + add bl, [es:bx] + adc bh, 0 + jmp .loop .loopd: - mov ax, bx - pop bx + mov ax, bx + pop bx @@: - add bx, [cs:lb_size] - jz .done2 - cmp bx, ax - jb @b - jmp .loope + add bx, [cs:lb_size] + jz .done2 + cmp bx, ax + jb @b + jmp .loope .notfound: - stc + stc .done: - pop bx + pop bx .done2: - pop bx - ret + pop bx + ret lb_to_sector: - xor edx, edx - div dword [lb_per_sec] - ret + xor edx, edx + div dword [lb_per_sec] + ret load_phys_sector_for_lb_force: ; in: eax = logical block, ds=0 @@ -819,206 +819,206 @@ load_phys_sector_for_lb_force: ; out: CF=1 if read error ; destroys cx ; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector - call lb_to_sector - or si, dx - jnz @f - mov si, 1800h - jmp .done + call lb_to_sector + or si, dx + jnz @f + mov si, 1800h + jmp .done @@: - mov si, 1000h - imul dx, [lb_size] - add si, dx - mov cx, 1 - push es bx - push ds - pop es - mov bx, 1000h - call read_sectors - pop bx es - inc eax + mov si, 1000h + imul dx, [lb_size] + add si, dx + mov cx, 1 + push es bx + push ds + pop es + mov bx, 1000h + call read_sectors + pop bx es + inc eax .done: - ret + ret normalize: ; in: es:bx = far pointer ; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) - push ax bx - mov ax, es - shr bx, 4 - add ax, bx - mov es, ax - pop bx ax - and bx, 0x0F - ret + push ax bx + mov ax, es + shr bx, 4 + add ax, bx + mov es, ax + pop bx ax + and bx, 0x0F + ret read_many_bytes: - and [first_byte], 0 + and [first_byte], 0 read_many_bytes.with_first: ; read esi bytes from logical block dx:ax to buffer es:bx ; out: CF=1 <=> disk error - push di + push di ; load first physical sector - push bx si - mov si, [first_byte] - call load_phys_sector_for_lb_force - jnc @f - pop si bx + push bx si + mov si, [first_byte] + call load_phys_sector_for_lb_force + jnc @f + pop si bx .ret: - pop di - ret + pop di + ret @@: - add si, [first_byte] - mov ecx, 1800h - sub cx, si - mov ebx, esi - pop bx - sub ebx, ecx - jnc @f - add cx, bx - xor ebx, ebx + add si, [first_byte] + mov ecx, 1800h + sub cx, si + mov ebx, esi + pop bx + sub ebx, ecx + jnc @f + add cx, bx + xor ebx, ebx @@: - pop di - sub [cur_limit], ecx - rep movsb - mov esi, ebx - mov bx, di - call normalize + pop di + sub [cur_limit], ecx + rep movsb + mov esi, ebx + mov bx, di + call normalize ; load other physical sectors ; read esi bytes from physical sector eax to buffer es:bx - test esi, esi - jz .ret - push esi - add esi, 0x7FF - and si, not 0x7FF - cmp esi, [cur_limit] - jbe .okplace + test esi, esi + jz .ret + push esi + add esi, 0x7FF + and si, not 0x7FF + cmp esi, [cur_limit] + jbe .okplace .noplace: - sub esi, 800h + sub esi, 800h .okplace: - shr esi, 11 ; si = number of sectors - mov cx, si - jz @f - call read_sectors + shr esi, 11 ; si = number of sectors + mov cx, si + jz @f + call read_sectors @@: - pop esi - jc .ret - movzx ecx, cx - add eax, ecx - shl ecx, 11 - sub [cur_limit], ecx - sub esi, ecx - jc .big - jz .nopost - push bx es - push ds - pop es - mov bx, 1000h - mov cx, 1 - call read_sectors - pop es di - jc .ret2 - mov cx, si - mov si, 1000h - sub word [cur_limit], cx - sbb word [cur_limit+2], 0 - rep movsb - mov bx, di - call normalize + pop esi + jc .ret + movzx ecx, cx + add eax, ecx + shl ecx, 11 + sub [cur_limit], ecx + sub esi, ecx + jc .big + jz .nopost + push bx es + push ds + pop es + mov bx, 1000h + mov cx, 1 + call read_sectors + pop es di + jc .ret2 + mov cx, si + mov si, 1000h + sub word [cur_limit], cx + sbb word [cur_limit+2], 0 + rep movsb + mov bx, di + call normalize .nopost: - clc + clc .ret2: - pop di - ret + pop di + ret .big: - mov ax, es - sub ax, 80h - mov es, ax - add bx, 800h - add bx, si - call normalize - sub [cur_limit], esi - jmp .nopost + mov ax, es + sub ax, 80h + mov es, ax + add bx, 800h + add bx, si + call normalize + sub [cur_limit], esi + jmp .nopost ; Callback function for secondary loader callback: ; in: ax = function number; only function 1 is defined for now - dec ax - jz callback_readfile - dec ax - jz callback_continueread - stc ; unsupported function - retf + dec ax + jz callback_readfile + dec ax + jz callback_continueread + stc ; unsupported function + retf callback_readfile: ; function 1: read file ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error ; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file - clc ; function is supported - retf + call load_file + clc ; function is supported + retf callback_continueread: ; function 2: continue to read file ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) ; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error ; out: dx:ax = file size - les bx, [di] - call normalize - movzx esi, word [di+4] ; si = limit in 4K blocks - shl esi, 12 ; bp:si = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, [cur_chunk] - call loadloop.loadnew - clc ; function is supported - retf + les bx, [di] + call normalize + movzx esi, word [di+4] ; si = limit in 4K blocks + shl esi, 12 ; bp:si = limit in bytes + push cs + pop ds + mov [cur_limit], esi + mov di, [cur_chunk] + call loadloop.loadnew + clc ; function is supported + retf secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 align 2 cachelist: -.head dw cachelist -.tail dw cachelist -free_cache_item dw 0 -last_cache_item dw 0x8400 +.head dw cachelist +.tail dw cachelist +free_cache_item dw 0 +last_cache_item dw 0x8400 -use_path_table db 0 -bootdrive db ? +use_path_table db 0 +bootdrive db ? align 2 -lb_size dw ? ; Logical Block size in bytes - dw 0 ; to allow access dword [lb_size] -lb_per_sec dw ? ; Logical Blocks per physical sector - dw 0 ; to allow access dword [lb_per_sec] -free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) -size_rest dw ? ; free space in cache (in blocks) -cache_size dw ? -cache_start dw ? -pathtable_size dw ? -pathtable_start dw ? -root_location dd ? -cur_desc_end dw ? -cur_nocache_len dd ? -cur_limit dd ? -cur_unit_limit dd ? -overflow dw ? -cur_chunk dw ? -first_byte dw ? -cur_start dd ? +lb_size dw ? ; Logical Block size in bytes + dw 0 ; to allow access dword [lb_size] +lb_per_sec dw ? ; Logical Blocks per physical sector + dw 0 ; to allow access dword [lb_per_sec] +free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) +size_rest dw ? ; free space in cache (in blocks) +cache_size dw ? +cache_start dw ? +pathtable_size dw ? +pathtable_start dw ? +root_location dd ? +cur_desc_end dw ? +cur_nocache_len dd ? +cur_limit dd ? +cur_unit_limit dd ? +overflow dw ? +cur_chunk dw ? +first_byte dw ? +cur_start dd ? -;times 83FEh-$ db 0 - db 43h +;times 83FEh-$ db 0 + db 43h ; just to make file 2048 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' + db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - dw 0xAA55 ; this is not required for CD, but to be consistent... + dw 0xAA55 ; this is not required for CD, but to be consistent... diff --git a/kernel/trunk/sec_loader/trunk/boot/cdfs/build.bat b/kernel/trunk/sec_loader/trunk/boot/cdfs/build.bat new file mode 100644 index 0000000000..93b242702f --- /dev/null +++ b/kernel/trunk/sec_loader/trunk/boot/cdfs/build.bat @@ -0,0 +1,2 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@pause \ No newline at end of file diff --git a/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.asm b/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.asm index 67e87ace11..772829f065 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.asm +++ b/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.asm @@ -25,254 +25,254 @@ ;***************************************************************************** use_lba = 0 - org 0x7C00 - jmp start - nop + org 0x7C00 + jmp start + nop ; FAT parameters, BPB ; note: they can be changed at install, replaced with real values ; these settings are for most typical 1.44M floppies - db 'KOLIBRI ' ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db 1 -BPB_RsvdSecCnt dw 1 -BPB_NumFATs db 2 -BPB_RootEntCnt dw 0xE0 - dw 2880 ; BPB_TotSec16 - db 0xF0 ; BPB_Media -BPB_FATSz16 dw 9 -BPB_SecPerTrk dw 18 -BPB_NumHeads dw 2 -BPB_HiddSec dd 0 - dd 0 ; BPB_TotSec32 -BS_DrvNum db 0 - db 0 ; BS_Reserved1 - db ')' ; BS_BootSig - dd 12344321h ; BS_VolID + db 'KOLIBRI ' ; BS_OEMName, ignored + dw 200h ; BPB_BytsPerSec +BPB_SecsPerClus db 1 +BPB_RsvdSecCnt dw 1 +BPB_NumFATs db 2 +BPB_RootEntCnt dw 0xE0 + dw 2880 ; BPB_TotSec16 + db 0xF0 ; BPB_Media +BPB_FATSz16 dw 9 +BPB_SecPerTrk dw 18 +BPB_NumHeads dw 2 +BPB_HiddSec dd 0 + dd 0 ; BPB_TotSec32 +BS_DrvNum db 0 + db 0 ; BS_Reserved1 + db ')' ; BS_BootSig + dd 12344321h ; BS_VolID filename: - db 'KORD.OS ' ; BS_VolLab - db 'FAT12 ' ; BS_FilSysType + db 'KORD.OS ' ; BS_VolLab + db 'FAT12 ' ; BS_FilSysType ; Used memory map: -; 8000:0000 - current directory -; 9000:0000 - root directory data [cached] +; 8000:0000 - current directory +; 9000:0000 - root directory data [cached] start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - mov [bp+BS_DrvNum-0x7C00], dl + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov bp, sp + cld + sti + mov [bp+BS_DrvNum-0x7C00], dl if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err - cmp bx, 0AA55h - jnz err - test cx, 1 - jz err + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cx, 1 + jz err_ else - mov ah, 8 - int 13h - jc @f ; on error, assume that BPB geometry is valid - mov al, dh - mov ah, 0 - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx + mov ah, 8 + int 13h + jc @f ; on error, assume that BPB geometry is valid + mov al, dh + mov ah, 0 + inc ax + mov [bp+BPB_NumHeads-0x7C00], ax + and cx, 3Fh + mov [bp+BPB_SecPerTrk-0x7C00], cx @@: end if ; get FAT parameters - xor bx, bx - mov al, [bp+BPB_NumFATs-0x7C00] - mov ah, 0 - mul [bp+BPB_FATSz16-0x7C00] - add ax, [bp+BPB_RsvdSecCnt-0x7C00] - adc dx, bx - push dx - push ax ; root directory start = dword [bp-4] - mov cx, [bp+BPB_RootEntCnt-0x7C00] - add cx, 0xF - rcr cx, 1 - shr cx, 3 ; cx = size of root directory in sectors - add ax, cx - adc dx, bx - push dx - push ax ; data start = dword [bp-8] + xor bx, bx + mov al, [bp+BPB_NumFATs-0x7C00] + mov ah, 0 + mul [bp+BPB_FATSz16-0x7C00] + add ax, [bp+BPB_RsvdSecCnt-0x7C00] + adc dx, bx + push dx + push ax ; root directory start = dword [bp-4] + mov cx, [bp+BPB_RootEntCnt-0x7C00] + add cx, 0xF + rcr cx, 1 + shr cx, 3 ; cx = size of root directory in sectors + add ax, cx + adc dx, bx + push dx + push ax ; data start = dword [bp-8] ; load start of root directory (no more than 0x2000 bytes = 0x10 sectors) - cmp cx, 0x10 - jb @f - mov cx, 0x10 + cmp cx, 0x10 + jb @f + mov cx, 0x10 @@: - mov ax, [bp-4] - mov dx, [bp-2] - push 0x9000 - pop es - call read_sectors - add word [bp-4], cx ; dword [bp-4] = start of non-cached root data - adc word [bp-2], bx + mov ax, [bp-4] + mov dx, [bp-2] + push 0x9000 + pop es + call read_sectors + add word [bp-4], cx ; dword [bp-4] = start of non-cached root data + adc word [bp-2], bx ; load kordldr.f12 - mov si, main_loader - call lookup_in_root_dir - jc noloader - test byte [es:di+11], 10h ; directory? - jz kordldr_ok + mov si, main_loader + call lookup_in_root_dir + jc noloader + test byte [es:di+11], 10h ; directory? + jz kordldr_ok noloader: - mov si, aLoaderNotFound -err: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ + mov si, aLoaderNotFound +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ kordldr_ok: - mov ax, [es:di+26] ; get file cluster - mov bx, 0x7E00 - xor cx, cx - mov es, cx - sub ax, 2 - jc noloader - push bx ; save return address: bx = 7E00 - mov cl, [bp+BPB_SecsPerClus-0x7C00] - mul cx + mov ax, [es:di+26] ; get file cluster + mov bx, 0x7E00 + xor cx, cx + mov es, cx + sub ax, 2 + jc noloader + push bx ; save return address: bx = 7E00 + mov cl, [bp+BPB_SecsPerClus-0x7C00] + mul cx ; fall through - 'ret' in read_sectors will return to 7E00 read_sectors2: ; same as read_sectors, but dx:ax is relative to start of data - add ax, [bp-8] - adc dx, [bp-6] + add ax, [bp-8] + adc dx, [bp-6] read_sectors: ; ss:bp = 0:7C00 ; es:bx = pointer to data ; dx:ax = first sector ; cx = number of sectors - pusha - add ax, word [bp+BPB_HiddSec-0x7C00] - adc dx, word [bp+BPB_HiddSec+2-0x7C00] + pusha + add ax, word [bp+BPB_HiddSec-0x7C00] + adc dx, word [bp+BPB_HiddSec+2-0x7C00] if use_lba - push ds + push ds do_read_sectors: - push ax - push cx - push dx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F + push ax + push cx + push dx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F @@: ; create disk address packet on the stack ; dq starting LBA - push 0 - push 0 - push dx - push ax + push 0 + push 0 + push dx + push ax ; dd buffer - push es - push bx + push es + push bx ; dw number of blocks to transfer (no more than 0x7F) - push cx + push cx ; dw packet size in bytes - push 10h + push 10h ; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp+BS_DrvNum-0x7C00] - mov ah, 42h - int 13h - mov si, aReadError - jc err + push ss + pop ds + mov si, sp + mov dl, [bp+BS_DrvNum-0x7C00] + mov ah, 42h + int 13h + mov si, aReadError + jc err_ ; restore stack - add sp, 10h + add sp, 10h ; increase current sector & buffer; decrease number of sectors - mov si, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop dx - pop cx - pop ax - add ax, si - adc dx, 0 - sub cx, si - jnz do_read_sectors - pop ds - popa - ret + mov si, cx + mov ax, es + shl cx, 5 + add ax, cx + mov es, ax + pop dx + pop cx + pop ax + add ax, si + adc dx, 0 + sub cx, si + jnz do_read_sectors + pop ds + popa + ret else do_read_sectors: - pusha - pop di - push bx + pusha + pop di + push bx ; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx - mov si, ax - xchg ax, dx - xor dx, dx - div [bp+BPB_SecPerTrk-0x7C00] - push ax - mov ax, si - div [bp+BPB_SecPerTrk-0x7C00] - mov bx, dx ; bx=sector-1 - pop dx + mov si, ax + xchg ax, dx + xor dx, dx + div [bp+BPB_SecPerTrk-0x7C00] + push ax + mov ax, si + div [bp+BPB_SecPerTrk-0x7C00] + mov bx, dx ; bx=sector-1 + pop dx ; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] + div [bp+BPB_NumHeads-0x7C00] ; number of sectors: read no more than to end of track - push bx - sub bx, [bp+BPB_SecPerTrk-0x7C00] - neg bx - cmp cx, bx - jbe @f - mov cx, bx + push bx + sub bx, [bp+BPB_SecPerTrk-0x7C00] + neg bx + cmp cx, bx + jbe @f + mov cx, bx @@: - pop bx + pop bx - inc bx + inc bx ; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - mov di, cx - mov dh, dl - mov dl, [bp+BS_DrvNum-0x7C00] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 + mov di, cx + mov dh, dl + mov dl, [bp+BS_DrvNum-0x7C00] + shl ah, 6 + mov ch, al + mov al, cl + mov cl, bl + or cl, ah + pop bx + mov si, 3 + mov ah, 2 @@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err + push ax + int 13h + jnc @f + xor ax, ax + int 13h ; reset drive + pop ax + dec si + jnz @b + mov si, aReadError + jmp err_ @@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push di - popa - add ax, di - adc dx, 0 - sub cx, di - jnz do_read_sectors - popa - ret + pop ax + mov ax, es + mov cx, di + shl cx, 5 + add ax, cx + mov es, ax + push di + popa + add ax, di + adc dx, 0 + sub cx, di + jnz do_read_sectors + popa + ret end if scan_for_filename: @@ -282,111 +282,111 @@ scan_for_filename: ; out: if found: CF=0, ZF=1, es:di -> directory entry ; out: if not found, but continue required: CF=1 and ZF=0 ; out: if not found and zero item reached: CF=1 and ZF=1 - xor di, di - push cx + xor di, di + push cx sloop: - cmp byte [es:di], 0 - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone + cmp byte [es:di], 0 + jz snotfound + test byte [es:di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmpsb + popa + jz sdone scont: - add di, 0x20 - loop sloop - inc cx ; clear ZF flag + add di, 0x20 + loop sloop + inc cx ; clear ZF flag snotfound: - stc + stc sdone: - pop cx + pop cx lrdret: - ret + ret lookup_in_root_dir: ; ss:bp = 0:7C00 ; in: ds:si -> 11-bytes FAT name ; out: if found: CF=0, es:di -> directory entry ; out: if not found: CF=1 - mov cx, [bp+BPB_RootEntCnt-0x7C00] - push cx + mov cx, [bp+BPB_RootEntCnt-0x7C00] + push cx ; first, look in root directory cache - push 0x9000 - pop es - test ch, ch - jz @f - mov cx, 0x100 + push 0x9000 + pop es + test ch, ch + jz @f + mov cx, 0x100 @@: - mov ax, [bp-4] - mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory + mov ax, [bp-4] + mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory lrdloop: - call scan_for_filename - pop bx - jz lrdret - sub bx, cx - mov cx, bx - stc - jz lrdret + call scan_for_filename + pop bx + jz lrdret + sub bx, cx + mov cx, bx + stc + jz lrdret ; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries - push cx - cmp ch, 0x8 - jb @f - mov cx, 0x800 + push cx + cmp ch, 0x8 + jb @f + mov cx, 0x800 @@: - push 0x8000 - pop es - push cx - push es - xor bx, bx - add cx, 0xF - shr cx, 4 - call read_sectors - pop es - add ax, cx - adc dx, bx - pop cx - jmp lrdloop + push 0x8000 + pop es + push cx + push es + xor bx, bx + add cx, 0xF + shr cx, 4 + call read_sectors + pop es + add ax, cx + adc dx, bx + pop cx + jmp lrdloop out_string: ; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz lrdret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string + lodsb + test al, al + jz lrdret + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string -aReadError db 'Read error',0 +aReadError db 'Read error',0 if use_lba -aNoLBA db 'The drive does not support LBA!',0 +aNoLBA db 'The drive does not support LBA!',0 end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F1X' +aLoaderNotFound db 'Loader not found',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 +main_loader db 'KORDLDR F1X' if use_lba - db 0 ; make bootsector 512 bytes in length + db 0 ; make bootsector 512 bytes in length end if ; bootsector signature - dw 0xAA55 + dw 0xAA55 ; display offsets of all procedures used by kordldr.f12.asm macro show [procedure] { - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 + bits = 16 + display `procedure,' = ' + repeat bits/4 + d = '0' + procedure shr (bits - %*4) and 0Fh + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 } -show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err, noloader +show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader diff --git a/kernel/trunk/sec_loader/trunk/boot/fat1x/build.bat b/kernel/trunk/sec_loader/trunk/boot/fat1x/build.bat new file mode 100644 index 0000000000..17c30cac18 --- /dev/null +++ b/kernel/trunk/sec_loader/trunk/boot/fat1x/build.bat @@ -0,0 +1,3 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@fasm -m 65535 kordldr.f1x.asm kordldr.f1x +@pause \ No newline at end of file diff --git a/kernel/trunk/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm b/kernel/trunk/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm index 7589677890..6f2348ae69 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm +++ b/kernel/trunk/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm @@ -24,47 +24,47 @@ ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;***************************************************************************** - org 0x7E00 + org 0x7E00 ; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here ; ss:bp = 0:7C00 virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? -BPB_TotSec16 dw ? - db ? ; BPB_Media -BPB_FATSz16 dw ? -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? -BPB_TotSec32 dd ? -BS_DrvNum db ? -fat_type db ? ; this is BS_Reserved1, - ; we use it to save FS type: 0=FAT12, 1=FAT16 - db ? ; BS_BootSig -num_sectors dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 3 ; BS_FilSysType, first 3 bytes -read_sectors dw ? -read_sectors2 dw ? -lookup_in_root_dir dw ? -scan_for_filename dw ? -err dw ? -noloader dw ? -cachelimit dw ? -filesize: ; will be used to save file size - rb 5 ; BS_FilSysType, last 5 bytes + rb 3 ; BS_jmpBoot + rb 8 ; BS_OEMName, ignored + dw ? ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? +BPB_TotSec16 dw ? + db ? ; BPB_Media +BPB_FATSz16 dw ? +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? +BPB_TotSec32 dd ? +BS_DrvNum db ? +fat_type db ? ; this is BS_Reserved1, + ; we use it to save FS type: 0=FAT12, 1=FAT16 + db ? ; BS_BootSig +num_sectors dd ? ; BS_VolID +; rb 11 ; BS_VolLab +; rb 3 ; BS_FilSysType, first 3 bytes +read_sectors dw ? +read_sectors2 dw ? +lookup_in_root_dir dw ? +scan_for_filename dw ? +err_ dw ? +noloader dw ? +cachelimit dw ? +filesize: ; will be used to save file size + rb 5 ; BS_FilSysType, last 5 bytes ; following variables are located in the place of starting code; ; starting code is no more used at this point -sect_per_clus dw ? -cur_cluster dw ? -next_cluster dw ? -flags dw ? -cur_delta dd ? +sect_per_clus dw ? +cur_cluster dw ? +next_cluster dw ? +flags dw ? +cur_delta dd ? end virtual ; procedures from boot sector @@ -83,213 +83,213 @@ chs_scan_for_filename = 7D4Eh chs_err = 7CB1h chs_noloader = 7CAEh - push ax cx ; save our position on disk - push ss - pop es + push ax cx ; save our position on disk + push ss + pop es ; determine version of bootsector (LBA vs CHS) -; mov [read_sectors], chs_read_sectors -; mov [read_sectors2], chs_read_sectors2 -; mov [lookup_in_root_dir], chs_lookup_in_root_dir -; mov [scan_for_filename], chs_scan_for_filename -; mov [err], chs_err -; mov [noloader], chs_noloader - lea di, [read_sectors] - mov si, chs_proc_addresses - mov cx, 6*2 - cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' - jz @f - add si, cx -; mov [read_sectors], lba_read_sectors -; mov [read_sectors2], lba_read_sectors2 -; mov [lookup_in_root_dir], lba_lookup_in_root_dir -; mov [scan_for_filename], lba_scan_for_filename -; mov [err], lba_err -; mov [noloader], lba_noloader +; mov [read_sectors], chs_read_sectors +; mov [read_sectors2], chs_read_sectors2 +; mov [lookup_in_root_dir], chs_lookup_in_root_dir +; mov [scan_for_filename], chs_scan_for_filename +; mov [err], chs_err +; mov [noloader], chs_noloader + lea di, [read_sectors] + mov si, chs_proc_addresses + mov cx, 6*2 + cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' + jz @f + add si, cx +; mov [read_sectors], lba_read_sectors +; mov [read_sectors2], lba_read_sectors2 +; mov [lookup_in_root_dir], lba_lookup_in_root_dir +; mov [scan_for_filename], lba_scan_for_filename +; mov [err], lba_err +; mov [noloader], lba_noloader @@: - rep movsb - mov cl, [BPB_SecsPerClus] - mov [sect_per_clus], cx - xor bx, bx + rep movsb + mov cl, [BPB_SecsPerClus] + mov [sect_per_clus], cx + xor bx, bx ; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jae @f + int 12h ; ax = size of available base memory in Kb + sub ax, 94000h / 1024 + jae @f nomem: - mov si, nomem_str - jmp [err] + mov si, nomem_str + jmp [err_] @@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 + shr ax, 3 + mov [cachelimit], ax ; size of cache - 1 ; get type of file system - FAT12 or FAT16? ; calculate number of clusters - mov ax, [BPB_TotSec16] - xor dx, dx - test ax, ax - jnz @f - mov ax, word [BPB_TotSec32] - mov dx, word [BPB_TotSec32+2] + mov ax, [BPB_TotSec16] + xor dx, dx + test ax, ax + jnz @f + mov ax, word [BPB_TotSec32] + mov dx, word [BPB_TotSec32+2] @@: - sub ax, [bp-8] ; dword [bp-8] = first data sector - sbb dx, [bp-6] - jb j_noloader - div [sect_per_clus] + sub ax, [bp-8] ; dword [bp-8] = first data sector + sbb dx, [bp-6] + jb j_noloader + div [sect_per_clus] ; ax = number of clusters ; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes - mov [fat_type], ch - cmp ax, 0xFF5 - jb init_fat12 - inc [fat_type] + mov [fat_type], ch + cmp ax, 0xFF5 + jb init_fat12 + inc [fat_type] init_fat16: ; no sectors loaded - mov di, 0x8200 - xor ax, ax - mov cx, 0x100/2 - rep stosw - jmp init_fat_done + mov di, 0x8200 + xor ax, ax + mov cx, 0x100/2 + rep stosw + jmp init_fat_done init_fat12: ; read FAT - push 0x6000 - pop es - mov ax, [BPB_RsvdSecCnt] - mov cx, [BPB_FATSz16] - cmp cx, 12 - jb @f - mov cx, 12 + push 0x6000 + pop es + mov ax, [BPB_RsvdSecCnt] + mov cx, [BPB_FATSz16] + cmp cx, 12 + jb @f + mov cx, 12 @@: - xor dx, dx - call [read_sectors] + xor dx, dx + call [read_sectors] init_fat_done: ; if cluster = sector, we need to read second part of our file ; (bootsector loads only first cluster of kordldr.f1x) - pop cx ax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub ax, [bp-8] - inc ax - inc ax ; ax = first cluster of kordldr.f12 - call get_next_cluster - jc @f + pop cx ax ; restore our position on disk + cmp cx, 1 + ja kordldr_full + sub ax, [bp-8] + inc ax + inc ax ; ax = first cluster of kordldr.f12 + call get_next_cluster + jc @f j_noloader: - jmp [noloader] + jmp [noloader] @@: - dec ax - dec ax - push 0x800 - pop es - call [read_sectors2] + dec ax + dec ax + push 0x800 + pop es + call [read_sectors2] kordldr_full: ; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err] - jz @f - mov si, aKernelNotFound - jmp bx + mov di, secondary_loader_info + call load_file + test bx, bx + mov bx, [err_] + jz @f + mov si, aKernelNotFound + jmp bx @@: ; for subsequent calls to callback function, hook error handler -; mov byte [bx], 0xE9 ; 'jmp' opcode -; mov ax, hooked_err - 3 -; sub ax, bx -; mov word [bx+1], ax +; mov byte [bx], 0xE9 ; 'jmp' opcode +; mov ax, hooked_err - 3 +; sub ax, bx +; mov word [bx+1], ax ; push hooked_err / ret - mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) - mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) + mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) + mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) ; set registers for secondary loader - mov ah, [BS_DrvNum] - mov al, 'f' - test ah, ah - jns @f - sub ah, 80h - mov al, 'h' + mov ah, [BS_DrvNum] + mov al, 'f' + test ah, ah + jns @f + sub ah, 80h + mov al, 'h' @@: - mov bx, '12' - cmp [fat_type], 0 - jz @f - mov bh, '6' + mov bx, '12' + cmp [fat_type], 0 + jz @f + mov bh, '6' @@: - mov si, callback ; ds:si = far pointer to callback procedure - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 + mov si, callback ; ds:si = far pointer to callback procedure + jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 -nomem_str db 'No memory',0 +nomem_str db 'No memory',0 chs_proc_addresses: - dw chs_read_sectors - dw chs_read_sectors2 - dw chs_lookup_in_root_dir - dw chs_scan_for_filename - dw chs_err - dw chs_noloader + dw chs_read_sectors + dw chs_read_sectors2 + dw chs_lookup_in_root_dir + dw chs_scan_for_filename + dw chs_err + dw chs_noloader lba_proc_addresses: - dw lba_read_sectors - dw lba_read_sectors2 - dw lba_lookup_in_root_dir - dw lba_scan_for_filename - dw lba_err - dw lba_noloader + dw lba_read_sectors + dw lba_read_sectors2 + dw lba_lookup_in_root_dir + dw lba_scan_for_filename + dw lba_err + dw lba_noloader get_next_cluster: ; in: ax = cluster ; out: if there is next cluster: CF=1, ax = next cluster ; out: if there is no next cluster: CF=0 - push si - cmp [fat_type], 0 - jnz gnc16 + push si + cmp [fat_type], 0 + jnz gnc16 ; for FAT12 - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 + push ds + push 0x6000 + pop ds + mov si, ax + shr si, 1 + add si, ax + test al, 1 + lodsw + jz @f + shr ax, 4 @@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret + and ax, 0xFFF + cmp ax, 0xFF7 + pop ds si + ret ; for FAT16 gnc16: ; each sector contains 200h bytes = 100h FAT entries ; so ah = # of sector, al = offset in sector - mov si, ax - mov ah, 0 - shr si, 8 + mov si, ax + mov ah, 0 + shr si, 8 ; calculate segment for this sector of FAT table ; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) ; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x8200+si], ah ; sector already loaded? - jnz @f + push es + push si + shl si, 5 + add si, 0x6000 + mov es, si + pop si + cmp byte [ss:0x8200+si], ah ; sector already loaded? + jnz @f ; load corresponding sector - pusha - push es - xor bx, bx - mov ax, [BPB_RsvdSecCnt] - xor dx, dx - add ax, si - adc dx, bx - mov cx, 1 ; read 1 sector - call [read_sectors] - pop es - popa + pusha + push es + xor bx, bx + mov ax, [BPB_RsvdSecCnt] + xor dx, dx + add ax, si + adc dx, bx + mov cx, 1 ; read 1 sector + call [read_sectors] + pop es + popa @@: - mov si, ax - add si, si -; mov ax, [es:si] - lods word [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret + mov si, ax + add si, si +; mov ax, [es:si] + lods word [es:si] + pop es + cmp ax, 0xFFF7 + pop si + ret if $ > 0x8000 error 'get_next_cluster must fit in first sector of kordldr.f1x!' @@ -298,370 +298,370 @@ end if load_file: ; in: ss:bp = 0:7C00 ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found ; out: dx:ax = file size (0xFFFFFFFF if file not found) - xor ax, ax ; start from root directory - mov dx, -1 - mov word [filesize], dx - mov word [filesize+2], dx ; initialize file size with invalid value - lea si, [di+6] + xor ax, ax ; start from root directory + mov dx, -1 + mov word [filesize], dx + mov word [filesize+2], dx ; initialize file size with invalid value + lea si, [di+6] parse_dir_loop: ; convert name to FAT name - push di - push ax - push ss - pop es + push di + push ax + push ss + pop es ; convert ASCIIZ filename to FAT name - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 + mov di, filename + push di + mov cx, 8+3 + mov al, ' ' + rep stosb + pop di + mov cl, 8 ; 8 symbols per name + mov bl, 1 nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' + lodsb + test al, al + jz namedone + cmp al, '/' + jz namedone + cmp al, '.' + jz namedot + dec cx + js badname + cmp al, 'a' + jb @f + cmp al, 'z' + ja @f + sub al, 'a'-'A' @@: - stosb - jmp nameloop + stosb + jmp nameloop namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop + inc bx + jp badname + add di, cx + mov cl, 3 + jmp nameloop +badname: ; do not make direct js/jp to notfound_pop: + ; this generates long forms of conditional jumps and results in longer code + jmp notfound_pop namedone: ; scan directory - pop ax ; ax = cluster of directory or 0 for root - push ds - push si - push es - pop ds - mov si, filename ; ds:si -> filename in FAT style - test ax, ax - jnz lookup_in_notroot_dir + pop ax ; ax = cluster of directory or 0 for root + push ds + push si + push es + pop ds + mov si, filename ; ds:si -> filename in FAT style + test ax, ax + jnz lookup_in_notroot_dir ; for root directory, use the subroutine from bootsector - call [lookup_in_root_dir] - jmp lookup_done + call [lookup_in_root_dir] + jmp lookup_done lookup_in_notroot_dir: ; for other directories, read a folder sector-by-sector and scan ; first, try to use the cache - push ds - push cs - pop ds - mov bx, [cachelimit] - add bx, bx - mov di, foldcache_mark + push ds + push cs + pop ds + mov bx, [cachelimit] + add bx, bx + mov di, foldcache_mark @@: - mov dx, [foldcache_clus+di-foldcache_mark+bx] - cmp dx, ax - jz cacheok - test dx, dx - jz cacheadd ; the cache has place for new entry - dec bx - dec bx - jns @b + mov dx, [foldcache_clus+di-foldcache_mark+bx] + cmp dx, ax + jz cacheok + test dx, dx + jz cacheadd ; the cache has place for new entry + dec bx + dec bx + jns @b ; the folder is not present in the cache, so add it ; the cache is full; find the oldest entry and replace it with the new one - mov dx, [cachelimit] + mov dx, [cachelimit] @@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b + inc bx + inc bx + cmp word [di+bx], dx ; marks have values 0 through [cachelimit] + jnz @b cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - mov [foldcache_clus+di-foldcache_mark+bx], ax - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet + or word [di+bx], 0xFFFF ; very big value, it will be changed soon + mov [foldcache_clus+di-foldcache_mark+bx], ax + and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet cacheok: ; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di + mov dx, [di+bx] + mov cx, [foldcache_size+di-foldcache_mark+bx] + mov di, [cachelimit] + add di, di cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 + cmp [foldcache_mark+di], dx + adc [foldcache_mark+di], 0 + dec di + dec di + jns cacheupdate + and [foldcache_mark+bx], 0 ; done, bx contains (position in cache)*2 - pop ds -; mov dx, bx -; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 -; add dx, 0x9200 - lea dx, [bx+0x92] - xchg dl, dh - mov es, dx - jcxz not_in_cache - call [scan_for_filename] - jz lookup_done + pop ds +; mov dx, bx +; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 +; add dx, 0x9200 + lea dx, [bx+0x92] + xchg dl, dh + mov es, dx + jcxz not_in_cache + call [scan_for_filename] + jz lookup_done not_in_cache: ; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry + mov bx, cx + shr bx, 4 + shl cx, 5 + mov di, cx ; es:di -> free space in cache entry ; external loop: scan clusters folder_next_cluster: ; internal loop: scan sectors in cluster - mov cx, [sect_per_clus] - push ax - dec ax - dec ax - mul cx - add ax, [bp-8] - adc dx, [bp-6] ; dx:ax = absolute sector + mov cx, [sect_per_clus] + push ax + dec ax + dec ax + mul cx + add ax, [bp-8] + adc dx, [bp-6] ; dx:ax = absolute sector folder_next_sector: ; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call [read_sectors] + dec bx + jns folder_skip_sector + push cx + push es di + push 0x8000 + pop es + xor bx, bx + mov cx, 1 + push es + call [read_sectors] ; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - push si di - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - pop di si + pop ds + pop di es + cmp di, 0x2000 ; ...if there is free space, of course + jae @f + push si di + mov cx, 0x100 + xor si, si + rep movsw + mov di, es + shr di, 8 + add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache + pop di si @@: - push es - push 0x8000 - pop es - push cs - pop ds - mov cx, 0x10 - call [scan_for_filename] - pop es - pop cx - jz lookup_done_pop + push es + push 0x8000 + pop es + push cs + pop ds + mov cx, 0x10 + call [scan_for_filename] + pop es + pop cx + jz lookup_done_pop folder_skip_sector: - inc ax - jnz @f - inc dx + inc ax + jnz @f + inc dx @@: - loop folder_next_sector - pop ax ; ax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push ax + loop folder_next_sector + pop ax ; ax = current cluster + call get_next_cluster + jc folder_next_cluster + stc + push ax lookup_done_pop: - pop ax + pop ax lookup_done: - pop si - pop ds + pop si + pop ds ; CF=1 <=> failed - jnc found + jnc found notfound: - pop di - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret + pop di + mov bx, 2 ; file not found + mov ax, 0xFFFF + mov dx, ax ; invalid file size + ret notfound_pop: - pop ax - jmp notfound + pop ax + jmp notfound found: - mov ax, [es:di+26] ; get cluster - test byte [es:di+11], 10h ; directory? - jz regular_file - cmp byte [si-1], 0 - jz notfound ; don't read directories as a regular files + mov ax, [es:di+26] ; get cluster + test byte [es:di+11], 10h ; directory? + jz regular_file + cmp byte [si-1], 0 + jz notfound ; don't read directories as a regular files ; ok, we have found a directory and the caller requested a file into it - pop di - jmp parse_dir_loop ; restart with new cluster in ax + pop di + jmp parse_dir_loop ; restart with new cluster in ax regular_file: - cmp byte [si-1], 0 - jnz notfound ; file does not contain another files + cmp byte [si-1], 0 + jnz notfound ; file does not contain another files ; ok, we have found a regular file and the caller requested it ; save file size - mov dx, [es:di+28] - mov [filesize], dx - mov dx, [es:di+30] - mov [filesize+2], dx - pop di - mov si, [di+4] - shl si, 3 - push si ; [ds:di+4] = limit in 4K blocks - les bx, [di] ; es:bx -> buffer + mov dx, [es:di+28] + mov [filesize], dx + mov dx, [es:di+30] + mov [filesize+2], dx + pop di + mov si, [di+4] + shl si, 3 + push si ; [ds:di+4] = limit in 4K blocks + les bx, [di] ; es:bx -> buffer clusloop: ; ax = first cluster, top of stack contains limit in sectors - mov si, ax ; remember current cluster - xor cx, cx ; cx will contain number of consecutive clusters - mov word [cur_delta], cx - mov word [cur_delta+2], cx - mov di, ax + mov si, ax ; remember current cluster + xor cx, cx ; cx will contain number of consecutive clusters + mov word [cur_delta], cx + mov word [cur_delta+2], cx + mov di, ax clusfind: - inc di - inc cx - call get_next_cluster - jnc clusread - cmp ax, di - jz clusfind - stc + inc di + inc cx + call get_next_cluster + jnc clusread + cmp ax, di + jz clusfind + stc clusread: - pop di ; limit in sectors - push ax ; save next cluster - pushf ; save flags + pop di ; limit in sectors + push ax ; save next cluster + pushf ; save flags ; read cx clusters, starting from si ; calculate number of sectors - xchg ax, cx - mul [sect_per_clus] + xchg ax, cx + mul [sect_per_clus] ; dx:ax = number of sectors; compare with limit - mov word [num_sectors], ax - mov word [num_sectors+2], dx - jmp @f + mov word [num_sectors], ax + mov word [num_sectors+2], dx + jmp @f continue_load_file: - les bx, [di] ; es:bx -> buffer - mov di, [di+4] ; ds:di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov ax, word [num_sectors] - mov dx, word [num_sectors+2] - mov si, [cur_cluster] - push [next_cluster] - push [flags] - or ax, dx - jz nextclus + les bx, [di] ; es:bx -> buffer + mov di, [di+4] ; ds:di = limit in 4K blocks + shl di, 3 ; now di = limit in sectors + mov ax, word [num_sectors] + mov dx, word [num_sectors+2] + mov si, [cur_cluster] + push [next_cluster] + push [flags] + or ax, dx + jz nextclus @@: - test dx, dx - jnz clusdecrease - push dx ; limit was not exceeded - cmp ax, di - jbe @f - pop ax + test dx, dx + jnz clusdecrease + push dx ; limit was not exceeded + cmp ax, di + jbe @f + pop ax clusdecrease: - push 1 ; limit was exceeded - mov ax, di + push 1 ; limit was exceeded + mov ax, di @@: - sub di, ax ; calculate new limit - sub word [num_sectors], ax - sbb word [num_sectors+2], 0 + sub di, ax ; calculate new limit + sub word [num_sectors], ax + sbb word [num_sectors+2], 0 ; calculate starting sector - xchg ax, cx - lea ax, [si-2] - mul [sect_per_clus] - add ax, word [cur_delta] - adc dx, word [cur_delta+2] - add word [cur_delta], cx - adc word [cur_delta+2], 0 + xchg ax, cx + lea ax, [si-2] + mul [sect_per_clus] + add ax, word [cur_delta] + adc dx, word [cur_delta+2] + add word [cur_delta], cx + adc word [cur_delta+2], 0 ; read - call [read_sectors2] - pop dx + call [read_sectors2] + pop dx ; next cluster? nextclus: - popf - pop ax - mov [cur_cluster], si - mov [next_cluster], ax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue + popf + pop ax + mov [cur_cluster], si + mov [next_cluster], ax + pushf + pop [flags] + jnc @f ; no next cluster => return + mov dl, 1 ; dh=0 in any case + test di, di + jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded + push di + jmp clusloop ; all is ok, continue hooked_err: - mov sp, 7C00h-12-2 ; restore stack - mov dx, 3 ; return: read error + mov sp, 7C00h-12-2 ; restore stack + mov dx, 3 ; return: read error @@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret + mov bx, dx + mov ax, [filesize] + mov dx, [filesize+2] + ret ; Callback function for secondary loader callback: ; in: ax = function number; only functions 1 and 2 are defined for now ; save caller's stack - mov dx, ss - mov cx, sp + mov dx, ss + mov cx, sp ; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-8 - mov bp, 7C00h - push dx - push cx + xor si, si + mov ss, si + mov sp, 7C00h-8 + mov bp, 7C00h + push dx + push cx ; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret + stc ; unsupported function + dec ax + jz callback_readfile + dec ax + jnz callback_ret ; function 2: continue loading file ; can be called only after function 1 returned value bx=1 (only part of file was loaded) ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) ; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error ; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ + call continue_load_file + jmp callback_ret_succ callback_readfile: ; function 1: read file ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error ; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file + call load_file callback_ret_succ: - clc ; function is supported + clc ; function is supported callback_ret: ; restore caller's stack - pop cx - pop ss - mov sp, cx + pop cx + pop ss + mov sp, cx ; return to caller - retf + retf secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 -foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache -foldcache_mark rw 7 -foldcache_size rw 7 -filename rb 11 +foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache +foldcache_mark rw 7 +foldcache_size rw 7 +filename rb 11 if $ > 0x8200 error: table overwritten end if diff --git a/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.asm b/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.asm index 1106275e9e..3dbee88653 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.asm +++ b/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.asm @@ -25,232 +25,232 @@ ;***************************************************************************** use_lba = 0 - org 0x7C00 - jmp start - nop + org 0x7C00 + jmp start + nop ; FAT parameters, BPB ; they must be changed at install, replaced with real values - rb 8 ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? - dw ? ; BPB_FSInfo -BPB_BkBootSec dw ? - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID - rb 11 ; BS_VolLab - rb 8 ; + rb 8 ; BS_OEMName, ignored + dw 200h ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? + dw ? ; BPB_TotSec16 + db ? ; BPB_Media + dw ? ; BPB_FATSz16 = 0 for FAT32 +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? + dd ? ; BPB_TotSec32 +BPB_FATSz32 dd ? +BPB_ExtFlags dw ? + dw ? ; BPB_FSVer +BPB_RootClus dd ? + dw ? ; BPB_FSInfo +BPB_BkBootSec dw ? + rb 12 ; BPB_Reserved +BS_DrvNum db ? + db ? ; BS_Reserved1 + db ? ; BS_BootSig + dd ? ; BS_VolID + rb 11 ; BS_VolLab + rb 8 ; -curseg dw 0x8000 +curseg dw 0x8000 start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - push dx ; byte [bp-2] = boot drive + xor ax, ax + mov ss, ax + mov sp, 0x7C00 + mov ds, ax + mov bp, sp + cld + sti + push dx ; byte [bp-2] = boot drive if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err - cmp bx, 0AA55h - jnz err - test cl, 1 - jz err + mov ah, 41h + mov bx, 55AAh + int 13h + mov si, aNoLBA + jc err_ + cmp bx, 0AA55h + jnz err_ + test cl, 1 + jz err_ else - mov ah, 8 - int 13h - jc @f - movzx ax, dh - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx + mov ah, 8 + int 13h + jc @f + movzx ax, dh + inc ax + mov [bp+BPB_NumHeads-0x7C00], ax + and cx, 3Fh + mov [bp+BPB_SecPerTrk-0x7C00], cx @@: end if ; get FAT parameters - xor bx, bx - movzx eax, [bp+BPB_NumFATs-0x7C00] - mul [bp+BPB_FATSz32-0x7C00] - movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] - push ecx ; FAT start = dword [bp-6] - add eax, ecx - push eax ; data start = dword [bp-10] - ;push dword -1 ; dword [bp-14] = current sector for FAT cache - db 66h - push -1 ; dword [bp-14] = current sector for FAT cache - mov eax, [bp+BPB_RootClus-0x7C00] - mov si, main_loader - call lookup_in_dir - jnc kordldr_ok + xor bx, bx + movzx eax, [bp+BPB_NumFATs-0x7C00] + mul [bp+BPB_FATSz32-0x7C00] + movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] + push ecx ; FAT start = dword [bp-6] + add eax, ecx + push eax ; data start = dword [bp-10] + ;push dword -1 ; dword [bp-14] = current sector for FAT cache + db 66h + push -1 ; dword [bp-14] = current sector for FAT cache + mov eax, [bp+BPB_RootClus-0x7C00] + mov si, main_loader + call lookup_in_dir + jnc kordldr_ok noloader: - mov si, aLoaderNotFound -err: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ + mov si, aLoaderNotFound +err_: + call out_string + mov si, aPressAnyKey + call out_string + xor ax, ax + int 16h + int 18h + jmp $ kordldr_ok: - mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) - mov ax, [es:di+26] ; loword(eax) = loword(cluster) - mov es, bx ; es = 0 - mov bx, 0x7E00 - push bx ; save return address: bx = 7E00 + mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) + mov ax, [es:di+26] ; loword(eax) = loword(cluster) + mov es, bx ; es = 0 + mov bx, 0x7E00 + push bx ; save return address: bx = 7E00 ; fall through - 'ret' in read_cluster will return to 7E00 read_cluster: ; ss:bp = 0:7C00 ; es:bx = pointer to data ; eax = cluster - sub eax, 2 - movzx ecx, [bp+BPB_SecsPerClus-0x7C00] - mul ecx + sub eax, 2 + movzx ecx, [bp+BPB_SecsPerClus-0x7C00] + mul ecx read_sectors2: ; same as read_sectors32, but eax is relative to start of data - add eax, [bp-10] + add eax, [bp-10] read_sectors32: ; ss:bp = 0:7C00 ; es:bx = pointer to data ; eax = first sector ; cx = number of sectors ; some high words of 32-bit registers are destroyed! - pusha - add eax, [bp+BPB_HiddSec-0x7C00] + pusha + add eax, [bp+BPB_HiddSec-0x7C00] if use_lba - push ds + push ds do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F + push ax + push cx + cmp cx, 0x7F + jbe @f + mov cx, 0x7F @@: ; create disk address packet on the stack ; dq starting LBA - push 0 - push 0 - push eax + push 0 + push 0 + push eax ; dd buffer - push es - push bx + push es + push bx ; dw number of blocks to transfer (no more than 0x7F) - push cx + push cx ; dw packet size in bytes - push 10h + push 10h ; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp-2] - mov ah, 42h - int 13h - mov si, aReadError - jc err + push ss + pop ds + mov si, sp + mov dl, [bp-2] + mov ah, 42h + int 13h + mov si, aReadError + jc err_ ; restore stack - add sp, 10h + add sp, 10h ; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popa - ret + movzx esi, cx + mov ax, es + shl cx, 5 + add ax, cx + mov es, ax + pop cx + pop ax + add eax, esi + sub cx, si + jnz do_read_sectors + pop ds + popa + ret else do_read_sectors: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx + pusha + pop edi ; loword(edi) = di, hiword(edi) = si + push bx ; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp+BPB_SecPerTrk-0x7C00] - xor edx, edx - div esi - mov bx, dx ; bx=sector-1 + movzx esi, [bp+BPB_SecPerTrk-0x7C00] + xor edx, edx + div esi + mov bx, dx ; bx=sector-1 ; eax -> dx:ax - push eax - pop ax - pop dx + push eax + pop ax + pop dx ; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] + div [bp+BPB_NumHeads-0x7C00] ; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si + sub si, bx + cmp cx, si + jbe @f + mov cx, si @@: - inc bx + inc bx ; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp-2] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 + movzx edi, cx + mov dh, dl + mov dl, [bp-2] + shl ah, 6 + mov ch, al + mov al, cl + mov cl, bl + or cl, ah + pop bx + mov si, 3 + mov ah, 2 @@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err + push ax + int 13h + jnc @f + xor ax, ax + int 13h ; reset drive + pop ax + dec si + jnz @b + mov si, aReadError + jmp err_ @@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz do_read_sectors - popa - ret + pop ax + mov ax, es + mov cx, di + shl cx, 5 + add ax, cx + mov es, ax + push edi + popa + add eax, edi + sub cx, di + jnz do_read_sectors + popa + ret end if lookup_in_dir: @@ -259,100 +259,100 @@ lookup_in_dir: ; in: bx = 0 ; out: if found: CF=0, es:di -> directory entry ; out: if not found: CF=1 -; push 0x8000 -; pop es +; push 0x8000 +; pop es ; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000 - mov es, [bp-7C00h + curseg] - push es - push eax - call read_cluster - mov ax, es - cmp ah, 82h - jb @f - mov ax, 8200h + mov es, [bp-7C00h + curseg] + push es + push eax + call read_cluster + mov ax, es + cmp ah, 82h + jb @f + mov ax, 8200h @@: - mov [bp-7C00h + curseg], ax - pop eax - pop es + mov [bp-7C00h + curseg], ax + pop eax + pop es ; scan for filename - shl cx, 4 - xor di, di + shl cx, 4 + xor di, di sloop: - cmp byte [es:di], bl - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone + cmp byte [es:di], bl + jz snotfound + test byte [es:di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmpsb + popa + jz sdone scont: - add di, 0x20 - loop sloop + add di, 0x20 + loop sloop ; next cluster - push 0x6000 - pop es - push es ax - shr eax, 7 - cmp eax, [bp-14] - mov [bp-14], eax - jz @f - add eax, [bp-6] - mov cx, 1 - call read_sectors32 + push 0x6000 + pop es + push es ax + shr eax, 7 + cmp eax, [bp-14] + mov [bp-14], eax + jz @f + add eax, [bp-6] + mov cx, 1 + call read_sectors32 @@: - pop di es - and di, 0x7F - shl di, 2 - and byte [es:di+3], 0x0F - mov eax, [es:di] - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - jb lookup_in_dir + pop di es + and di, 0x7F + shl di, 2 + and byte [es:di+3], 0x0F + mov eax, [es:di] + ;and eax, 0x0FFFFFFF + cmp eax, 0x0FFFFFF7 + jb lookup_in_dir snotfound: - stc + stc sdone: - ret + ret out_string: ; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz sdone - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string + lodsb + test al, al + jz sdone + mov ah, 0Eh + mov bx, 7 + int 10h + jmp out_string -aReadError db 'Read error',0 +aReadError db 'Read error',0 if use_lba -aNoLBA db 'The drive does not support LBA!',0 +aNoLBA db 'The drive does not support LBA!',0 end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F32' +aLoaderNotFound db 'Loader not found',0 +aPressAnyKey db 13,10,'Press any key...',13,10,0 +main_loader db 'KORDLDR F32' - db 56h + db 56h ; just to make file 512 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' + db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' ; bootsector signature - dw 0xAA55 + dw 0xAA55 ; display offsets of all procedures used by kordldr.f12.asm macro show [procedure] { - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 + bits = 16 + display `procedure,' = ' + repeat bits/4 + d = '0' + procedure shr (bits - %*4) and 0Fh + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 } -show read_sectors32, read_sectors2, err, noloader +show read_sectors32, read_sectors2, err_, noloader diff --git a/kernel/trunk/sec_loader/trunk/boot/fat32/build.bat b/kernel/trunk/sec_loader/trunk/boot/fat32/build.bat new file mode 100644 index 0000000000..267c29375b --- /dev/null +++ b/kernel/trunk/sec_loader/trunk/boot/fat32/build.bat @@ -0,0 +1,3 @@ +@fasm -m 65535 bootsect.asm bootsect.bin +@fasm -m 65535 kordldr.f32.asm kordldr.f32 +@pause \ No newline at end of file diff --git a/kernel/trunk/sec_loader/trunk/boot/fat32/kordldr.f32.asm b/kernel/trunk/sec_loader/trunk/boot/fat32/kordldr.f32.asm index 95889de5c9..9913b442bf 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat32/kordldr.f32.asm +++ b/kernel/trunk/sec_loader/trunk/boot/fat32/kordldr.f32.asm @@ -24,264 +24,264 @@ ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;***************************************************************************** - org 0x7E00 + org 0x7E00 ; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here ; ss:bp = 0:7C00 ; ds = 0 virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? + rb 3 ; BS_jmpBoot + rb 8 ; BS_OEMName, ignored + dw ? ; BPB_BytsPerSec +BPB_SecsPerClus db ? +BPB_RsvdSecCnt dw ? +BPB_NumFATs db ? +BPB_RootEntCnt dw ? + dw ? ; BPB_TotSec16 + db ? ; BPB_Media + dw ? ; BPB_FATSz16 = 0 for FAT32 +BPB_SecPerTrk dw ? +BPB_NumHeads dw ? +BPB_HiddSec dd ? + dd ? ; BPB_TotSec32 +BPB_FATSz32 dd ? +BPB_ExtFlags dw ? + dw ? ; BPB_FSVer +BPB_RootClus dd ? filesize: - dw ? ; BPB_FSInfo - dw ? ; BPB_BkBootSec - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 5 ; BS_FilSysType, first 5 bytes -read_sectors32 dw ? -read_sectors2 dw ? -err dw ? -noloader dw ? -cachelimit dw ? -fatcachehead rw 2 -fatcacheend dw ? - rb 3 ; BS_FilSysType, last 3 bytes -curseg dw ? -num_sectors dd ? -cur_cluster dd ? -next_cluster dd ? -flags dw ? -cur_delta dd ? + dw ? ; BPB_FSInfo + dw ? ; BPB_BkBootSec + rb 12 ; BPB_Reserved +BS_DrvNum db ? + db ? ; BS_Reserved1 + db ? ; BS_BootSig + dd ? ; BS_VolID +; rb 11 ; BS_VolLab +; rb 5 ; BS_FilSysType, first 5 bytes +read_sectors32 dw ? +read_sectors2 dw ? +err_ dw ? +noloader dw ? +cachelimit dw ? +fatcachehead rw 2 +fatcacheend dw ? + rb 3 ; BS_FilSysType, last 3 bytes +curseg dw ? +num_sectors dd ? +cur_cluster dd ? +next_cluster dd ? +flags dw ? +cur_delta dd ? end virtual ; procedures from boot sector ; LBA version lba_read_sectors2 = 7CD6h lba_err = 7CAAh -lba_noloader = 7CA7h ; = lba_err - 3 +lba_noloader = 7CA7h ; = lba_err - 3 ; CHS version chs_read_sectors2 = 7CD2h chs_err = 7CA6h -chs_noloader = 7CA3h ; = chs_err - 3 +chs_noloader = 7CA3h ; = chs_err - 3 - push eax cx ; save our position on disk + push eax cx ; save our position on disk ; determine version of bootsector (LBA vs CHS) - mov [read_sectors2], chs_read_sectors2 - mov bx, chs_err - mov [err], bx -; mov [noloader], chs_noloader - cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version - jz @f - add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 - add [err], lba_err - chs_err -; mov [noloader], lba_noloader + mov [read_sectors2], chs_read_sectors2 + mov bx, chs_err + mov [err_], bx +; mov [noloader], chs_noloader + cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version + jz @f + add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 + add [err_], lba_err - chs_err +; mov [noloader], lba_noloader @@: - xor bx, bx + xor bx, bx ; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 92000h / 1024 - jae @f + int 12h ; ax = size of available base memory in Kb + sub ax, 92000h / 1024 + jae @f nomem: - mov si, nomem_str - jmp [err] + mov si, nomem_str + jmp [err_] @@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 - mov es, bx + shr ax, 3 + mov [cachelimit], ax ; size of cache - 1 + mov es, bx ; no folders in cache yet - mov di, foldcache_clus - mov cx, 8*4/2 + 1 - xor ax, ax - rep stosw + mov di, foldcache_clus + mov cx, 8*4/2 + 1 + xor ax, ax + rep stosw ; bootsector code caches one FAT sector, [bp-14], in 6000:0000 ; initialize our (more advanced) FAT caching from this - mov di, 8400h - mov cx, di - lea si, [fatcachehead] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [fatcacheend], di ; first free item = 8400h - stosw ; 'next cached sector' link - stosw ; 'prev cached sector' link - mov eax, [bp-14] - stosd ; first sector number in cache - test eax, eax - js @f - mov [si], cx ; 'first cached sector' link = 8400h - mov [si+2], cx ; 'next cached sector' link = 8400h - mov [fatcacheend], di ; first free item = 8406h + mov di, 8400h + mov cx, di + lea si, [fatcachehead] + mov [si], si ; no sectors in cache: + mov [si+2], si ; 'prev' & 'next' links point to self + mov [fatcacheend], di ; first free item = 8400h + stosw ; 'next cached sector' link + stosw ; 'prev cached sector' link + mov eax, [bp-14] + stosd ; first sector number in cache + test eax, eax + js @f + mov [si], cx ; 'first cached sector' link = 8400h + mov [si+2], cx ; 'next cached sector' link = 8400h + mov [fatcacheend], di ; first free item = 8406h @@: ; if cluster = sector, we need to read second part of our file ; (bootsector loads only first cluster of kordldr.f32) - pop cx eax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub eax, [bp-10] - inc eax - inc eax ; eax = first cluster of kordldr.f32 - call get_next_cluster - jc @f -; jmp [noloader] - mov ax, [err] - sub ax, 3 - jmp ax + pop cx eax ; restore our position on disk + cmp cx, 1 + ja kordldr_full + sub eax, [bp-10] + inc eax + inc eax ; eax = first cluster of kordldr.f32 + call get_next_cluster + jc @f +; jmp [noloader] + mov ax, [err_] + sub ax, 3 + jmp ax @@: - dec eax - dec eax - push 0x800 - pop es - call [read_sectors2] + dec eax + dec eax + push 0x800 + pop es + call [read_sectors2] kordldr_full: ; bootsector code has read some data of root directory to 8000:0000 ; initialize our folder caching from this - mov eax, [BPB_RootClus] - mov [foldcache_clus], eax - mov cx, [curseg] - mov ax, 8000h - sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) - shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) - mov [foldcache_size], cx - shl cx, 4 - push ds - mov ds, ax - push 0x9000 - pop es - xor si, si - xor di, di - rep movsw - pop ds + mov eax, [BPB_RootClus] + mov [foldcache_clus], eax + mov cx, [curseg] + mov ax, 8000h + sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) + shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) + mov [foldcache_size], cx + shl cx, 4 + push ds + mov ds, ax + push 0x9000 + pop es + xor si, si + xor di, di + rep movsw + pop ds ; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err] - jz @f - mov si, aKernelNotFound - jmp bx + mov di, secondary_loader_info + call load_file + test bx, bx + mov bx, [err_] + jz @f + mov si, aKernelNotFound + jmp bx @@: ; for subsequent calls to callback function, hook error handler ; push hooked_err / ret - mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) + mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) ; set registers for secondary loader - mov ah, [bp-2] ; drive id - mov al, 'f' - btr ax, 15 - jnc @f - mov al, 'h' + mov ah, [bp-2] ; drive id + mov al, 'f' + btr ax, 15 + jnc @f + mov al, 'h' @@: - mov bx, '32' - mov si, callback - jmp far [si+secondary_loader_info-callback] + mov bx, '32' + mov si, callback + jmp far [si+secondary_loader_info-callback] -nomem_str db 'No memory',0 +nomem_str db 'No memory',0 cluster2sector: - sub eax, 2 + sub eax, 2 clustersz2sectorsz: - movzx ecx, [BPB_SecsPerClus] - mul ecx - ret + movzx ecx, [BPB_SecsPerClus] + mul ecx + ret get_next_cluster: ; in: eax = cluster ; out: if there is next cluster: CF=1, eax = next cluster ; out: if there is no next cluster: CF=0 - push di bx - push ds - push ss - pop ds - push ax - shr eax, 7 + push di bx + push ds + push ss + pop ds + push ax + shr eax, 7 ; eax = FAT sector number; look in cache - mov di, 8400h + mov di, 8400h .cache_lookup: - cmp di, [fatcacheend] - jae .not_in_cache - scasd - scasd - jnz .cache_lookup + cmp di, [fatcacheend] + jae .not_in_cache + scasd + scasd + jnz .cache_lookup .in_cache: - sub di, 8 + sub di, 8 ; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si - jmp @f + push si + mov si, [di] + mov bx, [di+2] + mov [si+2], bx + mov [bx], si + pop si + jmp @f .not_in_cache: ; cache miss ; cache is full? - mov di, [fatcacheend] - cmp di, 8C00h - jnz .cache_not_full + mov di, [fatcacheend] + cmp di, 8C00h + jnz .cache_not_full ; yes, delete the oldest entry - mov di, [fatcachehead] - mov bx, [di] - mov [fatcachehead], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append + mov di, [fatcachehead] + mov bx, [di] + mov [fatcachehead], bx + push word [di+2] + pop word [bx+2] + jmp .cache_append .cache_not_full: ; no, allocate new sector - add [fatcacheend], 8 + add [fatcacheend], 8 .cache_append: ; read FAT - mov [di+4], eax - push es - pushad - lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM - shl cx, 9-3 - mov es, cx - xor bx, bx - mov cx, 1 - add eax, [bp-6] ; FAT start - sub eax, [bp-10] - call [read_sectors2] - popad - pop es + mov [di+4], eax + push es + pushad + lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM + shl cx, 9-3 + mov es, cx + xor bx, bx + mov cx, 1 + add eax, [bp-6] ; FAT start + sub eax, [bp-10] + call [read_sectors2] + popad + pop es @@: ; add new sector to the end of list - mov bx, di - xchg bx, [fatcachehead+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx + mov bx, di + xchg bx, [fatcachehead+2] + push word [bx] + pop word [di] + mov [bx], di + mov [di+2], bx ; get requested item - lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-3 - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop ds - pop bx di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret + lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] + pop di + and di, 0x7F + shl di, 2 + shl ax, 9-3 + mov ds, ax + and byte [di+3], 0x0F + mov eax, [di] + pop ds + pop bx di + ;and eax, 0x0FFFFFFF + cmp eax, 0x0FFFFFF7 + ret if $ > 0x8000 error 'get_next_cluster must fit in first sector of kordldr.f32!' @@ -290,286 +290,286 @@ end if load_file: ; in: ss:bp = 0:7C00 ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found ; out: dx:ax = file size (0xFFFFFFFF if file not found) - mov eax, [BPB_RootClus] ; start from root directory - or dword [filesize], -1 ; initialize file size with invalid value - lea si, [di+6] + mov eax, [BPB_RootClus] ; start from root directory + or dword [filesize], -1 ; initialize file size with invalid value + lea si, [di+6] parse_dir_loop: ; convert name to FAT name - push di - push ax - push ss - pop es + push di + push ax + push ss + pop es ; convert ASCIIZ filename to FAT name filename equ bp - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 + mov di, filename + push di + mov cx, 8+3 + mov al, ' ' + rep stosb + pop di + mov cl, 8 ; 8 symbols per name + mov bl, 1 nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' + lodsb + test al, al + jz namedone + cmp al, '/' + jz namedone + cmp al, '.' + jz namedot + dec cx + js badname + cmp al, 'a' + jb @f + cmp al, 'z' + ja @f + sub al, 'a'-'A' @@: - stosb - jmp nameloop + stosb + jmp nameloop namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop + inc bx + jp badname + add di, cx + mov cl, 3 + jmp nameloop +badname: ; do not make direct js/jp to notfound_pop: + ; this generates long forms of conditional jumps and results in longer code + jmp notfound_pop namedone: ; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si + pop ax ; eax = cluster of directory + ; high word of eax is preserved by operations above + push ds + push si ; read a folder sector-by-sector and scan ; first, try to use the cache - push ss - pop ds - mov di, foldcache_mark - xor bx, bx - mov cx, [cachelimit] + push ss + pop ds + mov di, foldcache_mark + xor bx, bx + mov cx, [cachelimit] @@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz cacheok - test edx, edx - jz cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - jns @b + lea si, [di+bx] + mov edx, dword [foldcache_clus+si-foldcache_mark+bx] + cmp edx, eax + jz cacheok + test edx, edx + jz cacheadd ; the cache has place for new entry + inc bx + inc bx + dec cx + jns @b ; the folder is not present in the cache, so add it ; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [cachelimit] + mov bx, -2 + mov dx, [cachelimit] @@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b - lea si, [di+bx] + inc bx + inc bx + cmp word [di+bx], dx ; marks have values 0 through [cachelimit] + jnz @b + lea si, [di+bx] cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - mov dword [foldcache_clus+si-foldcache_mark+bx], eax + or word [di+bx], 0xFFFF ; very big value, it will be changed soon + and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet + mov dword [foldcache_clus+si-foldcache_mark+bx], eax cacheok: ; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di + mov dx, [di+bx] + mov cx, [foldcache_size+di-foldcache_mark+bx] + mov di, [cachelimit] + add di, di cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 + cmp [foldcache_mark+di], dx + adc [foldcache_mark+di], 0 + dec di + dec di + jns cacheupdate + and [foldcache_mark+bx], 0 ; done, bx contains (position in cache)*2 - ;mov dx, bx - ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 - ;add dx, 0x9000 - lea dx, [bx + 0x90] - xchg dl, dh - mov ds, dx - mov si, filename ; ss:si -> filename in FAT style - call scan_for_filename - jz lookup_done + ;mov dx, bx + ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 + ;add dx, 0x9000 + lea dx, [bx + 0x90] + xchg dl, dh + mov ds, dx + mov si, filename ; ss:si -> filename in FAT style + call scan_for_filename + jz lookup_done ; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry + mov bx, cx + shr bx, 4 + shl cx, 5 + mov di, cx ; es:di -> free space in cache entry ; external loop: scan clusters folder_next_cluster: ; internal loop: scan sectors in cluster - push eax - call cluster2sector + push eax + call cluster2sector folder_next_sector: ; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - push eax - call [read_sectors2] - pop eax + dec bx + jns folder_skip_sector + push cx + push es di + push 0x8000 + pop es + xor bx, bx + mov cx, 1 + push es + push eax + call [read_sectors2] + pop eax ; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache - popa + pop ds + pop di es + cmp di, 0x2000 ; ...if there is free space, of course + jae @f + pusha + mov cx, 0x100 + xor si, si + rep movsw + mov di, es + shr di, 8 + add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache + popa @@: - push es - mov cl, 0x10 ; ch=0 at this point - call scan_for_filename - pop es - pop cx - jz lookup_done_pop + push es + mov cl, 0x10 ; ch=0 at this point + call scan_for_filename + pop es + pop cx + jz lookup_done_pop folder_skip_sector: - inc eax - loop folder_next_sector - pop eax ; eax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push eax + inc eax + loop folder_next_sector + pop eax ; eax = current cluster + call get_next_cluster + jc folder_next_cluster + stc + push eax lookup_done_pop: - pop eax + pop eax lookup_done: - pop si + pop si ; CF=1 <=> failed - jnc found - pop ds + jnc found + pop ds notfound: - pop di + pop di notfound2: - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret + mov bx, 2 ; file not found + mov ax, 0xFFFF + mov dx, ax ; invalid file size + ret notfound_pop: - pop ax - jmp notfound + pop ax + jmp notfound found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop di - jz regular_file - cmp byte [si-1], 0 - jz notfound2 ; don't read directories as regular files + mov eax, [di+20-2] + mov edx, [di+28] + mov ax, [di+26] ; get cluster + test byte [di+11], 10h ; directory? + pop ds + pop di + jz regular_file + cmp byte [si-1], 0 + jz notfound2 ; don't read directories as regular files ; ok, we have found a directory and the caller requested a file into it - jmp parse_dir_loop ; restart with new cluster in ax + jmp parse_dir_loop ; restart with new cluster in ax regular_file: - cmp byte [si-1], 0 - jnz notfound2 ; file does not contain another files + cmp byte [si-1], 0 + jnz notfound2 ; file does not contain another files ; ok, we have found a regular file and the caller requested it ; save file size - mov [filesize], edx - mov si, [di+4] ; [ds:di+4] = limit in 4K blocks - shl si, 3 - push si - les bx, [di] ; es:bx -> buffer + mov [filesize], edx + mov si, [di+4] ; [ds:di+4] = limit in 4K blocks + shl si, 3 + push si + les bx, [di] ; es:bx -> buffer clusloop: ; eax = first cluster, top of stack contains limit in sectors - mov esi, eax ; remember current cluster - xor ecx, ecx ; ecx will contain number of consecutive clusters - mov [cur_delta], ecx - mov edi, eax + mov esi, eax ; remember current cluster + xor ecx, ecx ; ecx will contain number of consecutive clusters + mov [cur_delta], ecx + mov edi, eax clusfind: - inc edi - inc ecx - call get_next_cluster - jnc clusread - cmp eax, edi - jz clusfind - stc + inc edi + inc ecx + call get_next_cluster + jnc clusread + cmp eax, edi + jz clusfind + stc clusread: - pop di ; limit in sectors - movzx edi, di - push eax ; save next cluster - pushf ; save flags + pop di ; limit in sectors + movzx edi, di + push eax ; save next cluster + pushf ; save flags ; read cx clusters, starting from si ; calculate number of sectors - xchg eax, ecx - call clustersz2sectorsz - mov [num_sectors], eax - jmp @f + xchg eax, ecx + call clustersz2sectorsz + mov [num_sectors], eax + jmp @f continue_load_file: - les bx, [di] ; es:bx -> buffer - movzx edi, word [di+4] ; di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov eax, [num_sectors] - mov esi, [cur_cluster] - push [next_cluster] - push [flags] - test eax, eax - jz nextclus + les bx, [di] ; es:bx -> buffer + movzx edi, word [di+4] ; di = limit in 4K blocks + shl di, 3 ; now di = limit in sectors + mov eax, [num_sectors] + mov esi, [cur_cluster] + push [next_cluster] + push [flags] + test eax, eax + jz nextclus @@: ; eax = number of sectors; compare with limit - cmp eax, edi - seta dl - push dx ; limit was exceeded? - jbe @f - mov eax, edi + cmp eax, edi + seta dl + push dx ; limit was exceeded? + jbe @f + mov eax, edi @@: - sub di, ax ; calculate new limit - sub [num_sectors], eax - mov [cur_cluster], esi + sub di, ax ; calculate new limit + sub [num_sectors], eax + mov [cur_cluster], esi ; calculate starting sector - push ax - xchg eax, esi - call cluster2sector - pop cx - add eax, [cur_delta] - add [cur_delta], ecx + push ax + xchg eax, esi + call cluster2sector + pop cx + add eax, [cur_delta] + add [cur_delta], ecx ; read - call [read_sectors2] - pop dx + call [read_sectors2] + pop dx ; next cluster? nextclus: - popf - pop eax - mov [next_cluster], eax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue + popf + pop eax + mov [next_cluster], eax + pushf + pop [flags] + jnc @f ; no next cluster => return + mov dl, 1 ; dh=0 in any case + test di, di + jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded + push di + jmp clusloop ; all is ok, continue hooked_err: - mov sp, 7C00h-14-2 ; restore stack - mov dx, 3 ; return: read error + mov sp, 7C00h-14-2 ; restore stack + mov dx, 3 ; return: read error @@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret + mov bx, dx + mov ax, [filesize] + mov dx, [filesize+2] + ret scan_for_filename: ; in: ss:si -> 11-bytes FAT name @@ -579,94 +579,94 @@ scan_for_filename: ; out: if found: CF=0, ZF=1, es:di -> directory entry ; out: if not found, but continue required: CF=1 and ZF=0 ; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz snoent + push ds + pop es + xor di, di + push cx + jcxz snoent sloop: - cmp byte [di], bh - jz snotfound - test byte [di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz sdone + cmp byte [di], bh + jz snotfound + test byte [di+11], 8 ; volume label? + jnz scont ; ignore volume labels + pusha + mov cx, 11 + repz cmps byte [ss:si], byte [es:di] + popa + jz sdone scont: - add di, 0x20 - loop sloop + add di, 0x20 + loop sloop snoent: - inc cx ; clear ZF flag + inc cx ; clear ZF flag snotfound: - stc + stc sdone: - pop cx + pop cx lrdret: - ret + ret ; Callback function for secondary loader callback: ; in: ax = function number; only functions 1 and 2 are defined for now ; save caller's stack - mov dx, ss - mov cx, sp + mov dx, ss + mov cx, sp ; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-10 - mov bp, 7C00h - push dx - push cx + xor si, si + mov ss, si + mov sp, 7C00h-10 + mov bp, 7C00h + push dx + push cx ; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret + stc ; unsupported function + dec ax + jz callback_readfile + dec ax + jnz callback_ret ; function 2: continue loading file ; can be called only after function 1 returned value bx=1 (only part of file was loaded) ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) ; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error ; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ + call continue_load_file + jmp callback_ret_succ callback_readfile: ; function 1: read file ; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name +; dw:dw address +; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) +; ASCIIZ name ; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error ; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file + call load_file callback_ret_succ: - clc ; function is supported + clc ; function is supported callback_ret: ; restore caller's stack - pop cx - pop ss - mov sp, cx + pop cx + pop ss + mov sp, cx ; return to caller - retf + retf secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 + dw 0, 0x1000 + dw 0x30000 / 0x1000 + db 'kord/loader',0 +aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 ;if $ > 0x8200 ;error 'total size of kordldr.f32 must not exceed 1024 bytes!' ;end if -;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache -;foldcache_mark dw 0 -; rw 7 -;foldcache_size rw 8 -foldcache_clus rd 8 -foldcache_mark rw 8 -foldcache_size rw 8 +;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache +;foldcache_mark dw 0 +; rw 7 +;foldcache_size rw 8 +foldcache_clus rd 8 +foldcache_mark rw 8 +foldcache_size rw 8