From cef0fd80434153eee525e9bf385511499fe9eeeb Mon Sep 17 00:00:00 2001 From: hpa Date: Tue, 3 Feb 1998 10:16:14 +0000 Subject: [PATCH] Bug fixes; first beginnings of FAT16 support --- ldlinux.asm | 70 ++++++++++++++++++++++++++++++++++++-------------------- syslinux.asm | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 113 insertions(+), 31 deletions(-) diff --git a/ldlinux.asm b/ldlinux.asm index 1946f6e..c628056 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -426,8 +426,8 @@ debugentrypt: mov al,[bsFATs] ; Number of FATs jmpc kaboom ; If the floppy init failed ; (too far to be above the mov) - cbw ; Clear AH - mul byte [bsFATsecs] ; Get the size of the FAT area + cbw ; Clear AH (we WILL have < 128 FATs) + mul word [bsFATsecs] ; Get the size of the FAT area add ax,[bsHidden1] ; Add hidden sectors adc dx,[bsHidden2] add ax,[bsResSectors] ; And reserved sectors (why two?) @@ -451,23 +451,25 @@ debugentrypt: add bx,trackbuf-31 mov [EndofDirSec],bx ; End of a single directory sector - add [DataArea1],ax ; Now we have the location of the - adc word [DataArea2],byte 0 ; first data cluster + add [DataArea1],ax + adc word [DataArea2],byte 0 + + pop dx ; Reload root directory starting point + pop ax ; ; Now the fun begins. We have to search the root directory for ; LDLINUX.SYS and load the first sector, so we have a little more ; space to have fun with. Then we can go chasing through the FAT. ; Joy!! ; -sd_nextsec: pop dx - pop ax - push ax +sd_nextsec: push ax push dx mov bx,trackbuf + push bx call getonesec - mov si,trackbuf + pop si sd_nextentry: cmp byte [si],0 ; Directory high water mark -jz_kaboom: jz kaboom + je kaboom mov di,ldlinux_sys mov cx,11 push si @@ -477,6 +479,8 @@ jz_kaboom: jz kaboom add si,byte 32 ; Distance to next cmp si,[EndofDirSec] jb sd_nextentry + pop dx + pop ax add ax,byte 1 adc dx,byte 0 dec word [DirScanCtr] @@ -496,16 +500,16 @@ kaboom: pop word [si+2] sti int 19h ; And try once more to boot... -norge: jmp short norge ; If int 19h returned... oh boy... +norge: jmp short norge ; If int 19h returned; this is the end ; ; found_it: now we compute the location of the first sector, then ; load it and JUMP (since we're almost out of space) ; -found_it: pop ax - pop ax +found_it: ; Note: we actually leave two words on the stack here + ; (who cares?) mov al,[bsSecPerClust] - cbw ; We won't have 128 sec/cluster + xor ah,ah mov bp,ax ; Load an entire cluster mov bx,[si+26] ; First cluster push bx ; Remember which cluster it was @@ -515,13 +519,14 @@ found_it: pop ax add ax,[DataArea1] adc dx,[DataArea2] mov bx,ldlinux_magic + push bx call getlinsec mov si,bs_magic - mov di,ldlinux_magic - mov cx,[magic_len] + pop di + mov cx,magic_len repe cmpsb ; Make sure that the bootsector - jne kaboom - jmp ldlinux_ent ; matches LDLINUX.SYS + jne kaboom ; matches LDLINUX.SYS + jmp ldlinux_ent ; ; writestr: write a null-terminated string to the console ; @@ -583,8 +588,8 @@ gls_lasttrack: push ax ; Cylinder # push cx mov cl,6 ; Because IBM was STOOPID - shl ah,cl ; and thought 8 bits was enough - ; then thought 10 bits was enough... + shl ah,cl ; and thought 8 bits were enough + ; then thought 10 bits were enough... pop cx ; Sector # inc cx ; Sector numbers are 1-based or cl,ah @@ -825,11 +830,12 @@ gfs_return: ret ; Sets CF on return if end of file. ; nextcluster: - push bx - mov bx,si ; Multiply by 3/2 - shr bx,1 +nextcluster_fat12: + push ax + mov ax,si ; Multiply by 3/2 + shr ax,1 pushf ; CF now set if odd - add si,bx + add si,ax mov si,[FAT+si] popf jnc nc_even @@ -841,9 +847,23 @@ nc_even: and si,0FFFh cmp si,0FF0h ; Clears CF if at end of file cmc ; But we want it SET... - pop bx + pop ax nc_return: ret +nextcluster_fat16: + push ax + push es + mov ax,(fat_seg >> 12) + shl si,1 + adc ax,byte 0 + mov es,ax + mov si,[es:si] + cmp si,0FFF0h + cmc + pop es + pop ax + ret + ; ; Debug routine ; @@ -2044,7 +2064,7 @@ load_last: mov si,trackbuf dir_test_name: cmp byte [si],0 ; Directory high water mark je dir_return ; Failed - test byte [si+11],010h ; Check it really is a file + test byte [si+11],018h ; Check it really is a file jnz dir_not_this push di push si diff --git a/syslinux.asm b/syslinux.asm index 84e5ef4..f0e0261 100644 --- a/syslinux.asm +++ b/syslinux.asm @@ -19,8 +19,8 @@ ; absolute 0080h -psp_cmdlen resb 1 -psp_cmdline resb 127 +psp_cmdlen: resb 1 +psp_cmdline: resb 127 section .text org 0100h @@ -48,7 +48,7 @@ cmdscan1: jcxz bad_usage ; End of command line? mov [DriveNo],al ; Save away drive index section .bss -DriveNo resb 1 +DriveNo: resb 1 section .text ; @@ -78,13 +78,14 @@ bad_usage: mov dx,msg_unfair int 21h section .data -msg_unfair db 'Usage: syslinux :', 0Dh, 0Ah, '$' +msg_unfair: db 'Usage: syslinux :', 0Dh, 0Ah, '$' section .text ; ; Parsed the command line OK, now get to work ; got_cmdline: ; BUG: check sector size == 512 + ; Use INT 21h:32h mov bx,SectorBuffer mov al,[DriveNo] @@ -100,9 +101,61 @@ got_cmdline: ; BUG: check sector size == 512 mov di,BootSector+11 mov cx,51 ; Superblock = 51 bytes rep movsb ; Copy the superblock +; +; Writing LDLINUX.SYS +; + ; 1. If the file exists, strip its attributes and delete + + xor cx,cx ; Clear attributes + mov dx,ldlinux_sys_str + mov ax,4301h ; Set file attributes + int 21h + + mov dx,ldlinux_sys_str + mov ah,41h ; Delete file + int 21h + + section .data +ldlinux_sys_str: db 'LDLINUX.SYS', 0 + + section .text + + ; 2. Create LDLINUX.SYS and write data to it + + mov dx,ldlinux_sys_str + xor cx,cx ; Normal file + mov ah,3Ch ; Create file + int 21h + jc file_write_error + mov [FileHandle],ax + + mov bx,ax + mov cx,ldlinux_size + mov dx,LDLinuxSYS + mov ah,40h ; Write data + int 21h + jc file_write_error + cmp ax,ldlinux_size + jne file_write_error + + mov bx,[FileHandle] + mov ah,3Eh ; Close file + int 21h + + section .bss +FileHandle: resw 1 + + section .text - ; Write LDLINUX.SYS here (*before* writing boot sector) + ; 3. Set the readonly flag on LDLINUX.SYS + mov dx,ldlinux_sys_str + mov cx,1 ; Read only + mov ax,4301h ; Set attributes + int 21h +; +; Writing boot sector +; mov bx,BootSector mov cx,1 ; One sector xor dx,dx ; Absolute sector 0 @@ -115,13 +168,22 @@ all_done: mov ax,4C00h ; Exit good status disk_read_error: disk_write_error: - mov ax,4C01h +file_write_error: + mov dx,msg_bummer + mov ah,09h ; Write string int 21h + mov ax,4C01h ; Exit error status + int 21h + + section .data +msg_bummer: db 'Disk write error', 0Dh, 0Ah, '$' + section .data align 4, db 0 BootSector: incbin "bootsect.bin" LDLinuxSYS: incbin "ldlinux.sys" +ldlinux_size: equ $-LDLinuxSYS section .bss alignb 4 -- 2.7.4