Bug fixes; first beginnings of FAT16 support
authorhpa <hpa>
Tue, 3 Feb 1998 10:16:14 +0000 (10:16 +0000)
committerhpa <hpa>
Tue, 3 Feb 1998 10:16:14 +0000 (10:16 +0000)
ldlinux.asm
syslinux.asm

index 1946f6e..c628056 100644 (file)
@@ -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
index 84e5ef4..f0e0261 100644 (file)
@@ -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 <drive>:', 0Dh, 0Ah, '$'
+msg_unfair:    db 'Usage: syslinux <drive>:', 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