; ============================================================================= ; ; Litos8 system disk (logical disk) ; ; ============================================================================= ; Limitations: Sector size must be 512 bytes. Partition size is max. 2 GB. ; File system FAT12 or FAT16. ; ----------------------------------------------------------------------------- ; Exported user functions (18): ; SDiskGetNum - get number of valid system disks ; SDiskGetDesc - get system disk descriptor ; SDiskGetInfo - get system disk info TEXT ; SDiskGetAllInfo - get system all disks info TEXT ; SDiskReadSect - read cached sector ; SDDCheck - check system disk device ; SDDSize - get system disk size ; SDDRead - read from system disk device ; SDDWrite - write to system disk device ; SDiskCheckSize - check system disk size ; SDiskReload - reload system disk ; SDiskMediaDesc - get system disk default media descriptor ; DefFATType - get default FAT type ; DefRootSize - get default root directory size ; DefClustSize - get default cluster size ; SDiskDefPar - get default parameters of system disk ; GetClustNum - calculate number of clusters ; BuildBoot - build BOOT sector parameter table ; ----------------------------------------------------------------------------- CODEINIT_SECTION ; ----------------------------------------------------------------------------- ; INIT: Initialize system disk driver ; ----------------------------------------------------------------------------- ; ------------- prepare BDD table SDiskInit: mov si,BDDTab ; SI <- table of BDD descriptors mov cx,[BDDNum] ; CX <- number of BIOS disks jcxz SDiskInit8 ; no BIOS disk ; ------------- push registers SDiskInit2: push si ; push SI (BDD descriptor) push cx ; push CX (disk counter) ; ------------- skip invalid floppy disks cmp byte [si+BDD_Disk],10h ; floppy disk? jb short SDiskInit4 ; floppy disk is OK cmp byte [SDDLastDisk],2 ; check minimal disks jae short SDiskInit4 ; number of disks is OK mov byte [SDDLastDisk],2 ; skip invalid floppy disks ; ------------- load system disks for this BDD SDiskInit4: xor cx,cx ; CX <- 0, start sector LOW xor di,di ; DI <- 0, start sector HIGH mov [SDDExtStart],cx ; extended start sector LOW mov [SDDExtStart+2],di ; extended start sector HIGH mov ax,[si+BDD_SectNum] ; AX <- number of sectors LOW mov dx,[si+BDD_SectNum+2] ; DX <- number of sectors HIGH call SDiskAdd ; add system disk ; ------------- pop registers pop cx ; pop CX (disk counter) pop si ; ------------- next BDD descriptor add si,BDD_size ; SI <- next BDD descriptor loop SDiskInit2 ; next disk SDiskInitRet: SDiskInit8: ret ; ----------------------------------------------------------------------------- ; INIT: Add system disk ; ----------------------------------------------------------------------------- ; INPUT: SI = BDD Bios disk descriptor ; DX:AX = number of sectors ; DI:CX = absolute start sector ; DESTROYS: All. ; ----------------------------------------------------------------------------- ; ------------- check number of disks SDiskAdd: cmp byte [si+BDD_Disk],RAMDISK ; RAM disk? je short SDiskAdd1 ; RAM disk is reserved cmp byte [SDDLastDisk],SDISK_MAX-1 ; check number of disks jae short SDiskInitRet ; no available descriptor ; ------------- skip RAW memory disk cmp byte [si+BDD_Disk],MEMDISK ; memory disk? je short SDiskInitRet ; skip memory disk ; ------------- check disk size SDiskAdd1: mov bp,ax ; BP <- number of sectors LOW or bp,dx ; check disk size jz short SDiskInitRet ; invalid disk size ; ------------- prepare SDD descriptor -> BX mov bx,SDDTab + SDD_size*(SDISK_MAX-1) ; BX <- last disk cmp byte [si+BDD_Disk],RAMDISK ; RAM disk? je short SDiskAdd2 ; RAM disk xchg ax,bx ; BX <- push AX mov al,SDD_size ; AL <- size of SDD descriptor mul byte [SDDLastDisk]; AX <- offset of last SDD descriptor add ax,SDDTab ; AX <- address of SDD descriptor xchg ax,bx ; BX <- SDD descriptor, AX <- pop AX ; ------------- initialize descriptor SDiskAdd2: mov [bx+SDD_BDD],si ; BDD descriptor mov [bx+SDD_StartSect],cx ; start sector LOW mov [bx+SDD_StartSect+2],di ; start sector HIGH push ax ; push AX push dx ; push DX mov al,SDISK_MAX-1 ; AL <- RAM disk cmp byte [si+BDD_Disk],RAMDISK ; RAM disk? je short SDiskAdd23 ; RAM disk mov al,[SDDLastDisk] ; AL <- last disk SDiskAdd23: mov [bx+SDD_FlagsDisk],al ; AL <- system disk call GetDateTimeUnix ; get date and time in Unix format mov [bx+SDD_LastTime],ax ; set last access time mark pop dx ; pop DX pop ax ; pop AX ; ------------- removable disk, use default descriptor test byte [si+BDD_Flags],BDDF_Removable ; removable media? jz short SDiskAdd3 ; not removable media or byte [bx+SDD_FlagsDisk],SDDF_Removable ; removable flag call SDiskInitDef ; initialize default parameters jmp SDiskAdd8 ; ------------- read boot sector DX:AX -> SI SDiskAdd3: xchg ax,cx ; AX <- start LOW, CX <- number LOW xchg dx,di ; DX <- start HIGH, DI <- number HIGH push bx ; push BX mov bx,si ; BX <- BDD descriptor call BDiskReadSect ; read sector pop bx ; pop BX jc short SDiskAdd9 ; error ; ------------- check signature cmp word [si+1feh],0aa55h ; check signature jne short SDiskAdd9 ; invalid boot sector ; ------------- load system disk parameters call SDiskLoad ; load system disk parameters jnc short SDiskAdd7 ; disk is valid ; ------------- prepare to load partitions mov bp,1beh ; BP <- first partition mov bx,[bx+SDD_BDD] ; BX <- BDD descriptor ; ------------- push registers SDiskAdd5: push ax ; push AX (start sector LOW) push dx ; push DX (start sector HIGH) push bx ; push BX (BDD descriptor) push bp ; push BP (partition offset) push word [SDDExtStart] ; push extended start sector LOW push word [SDDExtStart+2] ; push extended start sector HIGH ; ------------- get partition start sector -> DI:CX lea si,[si+bp] ; SI <- partition descriptor xchg bx,si ; BX <- partition, SI <- BDD descriptor ; ------------- start sector of this partition -> CX:DI mov cx,[bx+8] ; CX <- start sector LOW mov di,[bx+10] ; DI <- start sector HIGH cmp bp,1beh ; primary partition? je short SDiskAdd52 ; yes, primary partition mov ax,[SDDExtStart] ; AX <- extended start sector LOW mov dx,[SDDExtStart+2] ; DX <- extended start sector HIGH SDiskAdd52: add cx,ax ; CX <- absolute start sector LOW adc di,dx ; DI <- absolute start sector HIGH jc short SDiskAdd6 ; invalid partition ; ------------- get partition size -> DX:AX mov ax,[bx+12] ; AX <- number of sectors LOW mov dx,[bx+14] ; DX <- number of sectors HIGH mov bp,cx ; BP <- start sector LOW or bp,di ; BP <- valid start sector? jz short SDiskAdd6 ; invalid start sector ; ------------- prepare extended start sector (only main partition) cmp word [SDDExtStart],byte 0 ; check start sectr LOW jne short SDiskAdd54 ; it is already set cmp word [SDDExtStart+2],byte 0 ; check start sectr HIGH jne short SDiskAdd54 ; it is already set mov [SDDExtStart],cx ; extended start sector LOW mov [SDDExtStart+2],di ; extended start sector HIGH ; ------------- add system disk SDiskAdd54: call SDiskAdd ; add system disk ; ------------- pop registers SDiskAdd6: pop word [SDDExtStart+2] ; pop extended start sector HIGH pop word [SDDExtStart] ; pop extended start sector LOW pop bp ; pop BP (partition offset) pop bx ; pop BX (BDD descriptor) pop dx ; pop DX (start sector HIGH) pop ax ; pop AX (start sector LOW) ; ------------- shift to next partition add bp,byte 16 ; BP <- next partition cmp bp,1feh ; end of boot record? jae short SDiskAdd9 ; end of boot record ; ------------- reload boot sector DX:AX -> SI call BDiskReadSect ; read sector jnc short SDiskAdd5 ; load next partition SDiskAdd9: ret ; ------------- increase number of system disks SDiskAdd7: or byte [bx+SDD_FlagsDisk],SDDF_Valid ; disk is valid SDiskAdd8: mov si,[bx+SDD_BDD] ; SI <- BDD descriptor cmp byte [si+BDD_Disk],RAMDISK ; RAM disk? je short SDiskAdd82 ; RAM disk inc byte [SDDLastDisk] ; increase number of disks SDiskAdd82: inc byte [SDDNum] ; increase number of valid disks ret CODE_SECTION ; ----------------------------------------------------------------------------- ; Initialize system disk parameters to default values ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = number of sectors ; BX = pointer to SDD descriptor ; NOTES: SDD_StartSect must be set to partition start sector. ; SDD_BDD must be set to BDD descriptor. ; ----------------------------------------------------------------------------- ; ------------- push registers SDiskInitDef: push ax ; push AX push cx ; push CX push dx ; push DX push di ; push DI ; ------------- get default parameters xor cx,cx ; default parameters xor di,di ; default root size call SDiskDefPar ; get default parameters ; ------------- set base entries and byte [bx+SDD_FlagsDisk],~SDDF_FormMask ; clear format or [bx+SDD_FlagsDisk],ch ; set file format mov [bx+SDD_SectClust],cl ; sectors per cluster mov byte [bx+SDD_FatNum],2 ; number of FAT tables mov word [bx+SDD_ResSect],1 ; reserved sectors mov [bx+SDD_RootEntries],di ; number of root entries ; ------------- total number of sectors mov [bx+SDD_SectNum],ax ; total number of sectors LOW mov [bx+SDD_SectNum+2],dx ; total number of sectors HIGH ; ------------- cluster size push cx ; push CX (FAT type and cluster size) mov ch,cl ; CH <- sectors per cluster mov cl,0 shl cx,1 ; CX <- cluster size mov [bx+SDD_ClustSize],cx ; cluster size ; ------------- number of root sectors add di,15 ; round up mov cl,4 shr di,cl ; DI <- root sectors mov [bx+SDD_RootSect],di ; number of root sectors pop cx ; pop CX (FAT type and cluster size) ; ------------- sectors per one FAT table stc ; include boot sector sbb ax,di ; subtract root and boot sectors sbb dx,byte 0 ; borrow push di ; push DI (root sectors) push ax ; push AX push dx ; push DX call GetClustNum ; get number of clusters -> AX xor dx,dx ; DX <- 0 mov di,ax ; DI <- number of clusters cmp ch,SDDF_FAT16 ; FAT16 ? je short SDiskInitDef4 ; yes shr di,1 ; DI <- number of clusters / 2 inc di ; round up SDiskInitDef4: add ax,di ; AX <- number of clusters *2 or *1.5 adc dx,byte 0 ; DX <- overflow add ax,511 ; round up to sector adc dx,byte 0 mov al,ah mov ah,dl ; AX <- FAT bytes / 256 shr ax,1 ; AX <- number of FAT sectors mov [bx+SDD_FatSect],ax ; sectors per one FAT table xchg ax,di ; DI <- sectors per one FAT table pop dx ; pop DX pop ax ; pop AX ; ------------- number of clusters shl di,1 ; DI <- sectors per 2 FAT tables sub ax,di ; subtract FAT sectors sbb dx,byte 0 ; borrow call GetClustNum ; get number of clusters mov [bx+SDD_ClustNum],ax ; number of clusters pop cx ; pop CX (root sectors) ; ------------- root start sector mov ax,[bx+SDD_StartSect] ; AX <- start sectors LOW mov [bx+SDD_HiddenSect],ax ; hidden sectors LOW mov dx,[bx+SDD_StartSect+2] ; DX <- start sectors HIGH mov [bx+SDD_HiddenSect+2],dx ; hidden sectors HIGH inc di ; DI <- sectors per 2 FAT + boot sector add ax,di ; add FAT and BOOT adc dx,byte 0 ; carry mov [bx+SDD_RootStart],ax ; root start sector LOW mov [bx+SDD_RootStart+2],dx ; root start sector HIGH ; ------------- data start sector add ax,cx ; add ROOT sectors adc dx,byte 0 ; carry mov [bx+SDD_ClustStart],ax ; data start sector LOW mov [bx+SDD_ClustStart+2],dx ; data start sector HIGH ; ------------- random serial disk number call RandDWord ; get random dword mov [bx+SDD_Serial],ax ; serial LOW mov [bx+SDD_Serial+2],dx ; serial HIGH ; ------------- media descriptor call SDiskMediaDesc ; get media descriptor mov [bx+SDD_MediaDesc],al ; media descriptor ; ------------- pop registers pop di ; pop DI pop dx ; pop DX pop cx ; pop CX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Load system disk parameters from BOOT sector ; ----------------------------------------------------------------------------- ; INPUT: BX = pointer to SDD descriptor ; SI = pointer to BOOT sector ; OUTPUT: CY = invalid system disk ; NOTES: SDD_StartSect must be set to partition start sector. ; ----------------------------------------------------------------------------- ; ------------- push registers SDiskLoad: push ax ; push AX push cx ; push CX push dx ; push DX push di ; push DI ; ------------- check extension signature cmp byte [si+BOOT_Signature],BOOTSIGN ; check signature jne short SDiskLoad82 ; invalid disk ; ------------- check sector size cmp word [si+BOOT_SectSize],SECTSIZE ; check sector size jne short SDiskLoad82 ; invalid disk ; ------------- load cluster size mov al,[si+BOOT_ClustSize] ; AL <- sectors per cluster or al,al ; check cluster size jz short SDiskLoad82 ; invalid cluster size mov ah,al ; AH <- number of sectors per cluster mov [bx+SDD_SectClust],al ; number of sectors per cluster SDiskLoad1: shr al,1 ; cluster size / 2 jnc short SDiskLoad1 ; next test jnz short SDiskLoad82 ; invalid cluster size shl ax,1 ; AX <- cluster size in bytes jc short SDiskLoad82 ; 64 KB cluster size is invalid mov [bx+SDD_ClustSize],ax ; cluster size ; ------------- reserved sectors (boot) mov ax,[si+BOOT_Reserved] ; AX <- reserved sectors cmp ax,byte 16 ; check value ja short SDiskLoad82 ; invalid reserved sectors mov [bx+SDD_ResSect],ax ; reserved sectors ; ------------- number of FAT tables mov al,[si+BOOT_FATNum] ; AL <- number of FAT tables or al,al ; check minimal value jz short SDiskLoad82 ; invalid FAT tables cmp al,4 ; check maximal value ja short SDiskLoad82 ; invalid FAT tables mov [bx+SDD_FatNum],al ; number of FAT tables ; ------------- number of ROOT entries mov ax,[si+BOOT_RootSize] ; AX <- number of root entries cmp ax,byte 4 ; check minimal value jb short SDiskLoad82 ; invalid root mov [bx+SDD_RootEntries],ax ; number of root entries mov cl,4 ; CL <- number of shifts add ax,15 ; round up shr ax,cl ; AX <- number of root sectors mov [bx+SDD_RootSect],ax ; number of root sectors ; ------------- total number of sectors xor dx,dx ; DX <- 0 mov ax,[si+BOOT_SectNumW] ; AX <- number of sectors WORD or ax,ax ; number of sectors WORD = 0 ? jnz short SDiskLoad2 ; number of sectors is OK mov ax,[si+BOOT_SectNum] ; AX <- number of sectors LOW mov dx,[si+BOOT_SectNum+2] ; DX <- number of sectors HIGH SDiskLoad2: cmp dx,byte 40h ; check max. number of sectors (2 GB) jbe short SDiskLoad22 ; number of sectors is OK SDiskLoad82: jmp SDiskLoad8 ; invalid disk SDiskLoad22: mov [bx+SDD_SectNum],ax ; number of sectors LOW mov [bx+SDD_SectNum+2],dx ; number of sectors HIGH ; ------------- media descriptor mov al,[si+BOOT_MediaDesc] ; AL <- media descriptor mov [bx+SDD_MediaDesc],al ; media descriptor ; ------------- FAT size mov ax,[si+BOOT_FATSize] ; AX <- number of sectors per FAT or ax,ax ; check minimal FAT size jz short SDiskLoad82 ; FAT size is OK cmp ah,1 ; check maximal FAT size (256) ja short SDiskLoad82 ; invalid FAT size mov [bx+SDD_FatSect],ax ; number of sectors per FAT ; ------------- hidden sectors mov ax,[si+BOOT_Hidden] ; AX <- hidden sectors LOW mov [bx+SDD_HiddenSect],ax ; hidden sectors LOW mov ax,[si+BOOT_Hidden+2] ; AX <- hidden sectors HIGH mov [bx+SDD_HiddenSect+2],ax ; hidden sectors HIGH ; ------------- serial mov ax,[si+BOOT_Serial] ; AX <- serial LOW mov [bx+SDD_Serial],ax ; serial LOW mov ax,[si+BOOT_Serial+2] ; AX <- serial HIGH mov [bx+SDD_Serial+2],ax ; serial HIGH ; ------------- FAT system cmp word [si+BOOT_FatName],"FA" ; check FAT 1 jne short SDiskLoad82 ; invalid file system cmp word [si+BOOT_FatName+2],"T1" ; check FAT 2 jne short SDiskLoad82 ; invalid file system mov al,SDDF_FAT12 ; AL <- FAT12 cmp word [si+BOOT_FatName+4],"2 " ; check FAT 3 je short SDiskLoad3 ; FAT12 cmp word [si+BOOT_FatName+4],"6 " ; check FAT 3 jne short SDiskLoad82 ; invalid disk mov al,SDDF_FAT16 ; AL <- FAT16 SDiskLoad3: and byte [bx+SDD_FlagsDisk],~SDDF_FormMask ; clear format or byte [bx+SDD_FlagsDisk],al ; set file format ; ------------- root start sector mov al,[bx+SDD_FatNum] ; AL <- number of FAT tables cbw ; AX <- number of FAT tables mul word [bx+SDD_FatSect] ; DX:AX <- sectors per FATs add ax,[bx+SDD_ResSect] ; add number of boot sectors adc dx,byte 0 ; carry mov cx,ax ; CX <- FAT and boot LOW mov di,dx ; DI <- FAT and boot HIGH add ax,[bx+SDD_StartSect] ; add start sectors LOW adc dx,[bx+SDD_StartSect+2] ; add start sectors HIGH mov [bx+SDD_RootStart],ax ; root start sector LOW mov [bx+SDD_RootStart+2],dx ; root start sector HIGH ; ------------- data start sector add ax,[bx+SDD_RootSect] ; add number of root sectors adc dx,byte 0 ; carry mov [bx+SDD_ClustStart],ax ; data start sector LOW mov [bx+SDD_ClustStart+2],dx ; data start sector HIGH ; ------------- number of clusters mov ax,[bx+SDD_SectNum] ; AX <- number of sectors LOW mov dx,[bx+SDD_SectNum+2] ; DX <- number of sectors HIGH sub ax,cx ; subtract FAT and boot LOW sbb dx,di ; subtract FAT and boot HIGH jc short SDiskLoad8 ; invalid disk size sub ax,[bx+SDD_RootSect] ; subtract root sectors sbb dx,byte 0 ; borrow jc short SDiskLoad8 ; invalid disk size mov cl,[bx+SDD_SectClust] ; CL <- sectors per cluster call GetClustNum ; get number of clusters jc short SDiskLoad8 ; overflow or ax,ax ; minimal clusters jz short SDiskLoad8 ; invalid disk cmp ax,FAT16_NUM ; FAT16 max. clusters ja short SDiskLoad8 ; overflow mov cx,ax ; CX <- number of clusters test byte [bx+SDD_FlagsDisk],SDDF_FAT16 ; FAT16? jnz short SDiskLoad4 ; FAT16 cmp ax,FAT12_NUM ; FAT12 max. clusters ja short SDiskLoad8 ; overflow shr cx,1 ; CX <- number of clusters / 2 inc cx ; round up SDiskLoad4: mov [bx+SDD_ClustNum],ax ; number of clusters ; ------------- check FAT size xor dx,dx ; DX <- 0 add ax,cx ; AX <- number of clusters *2 or *1.5 adc dx,byte 0 ; carry add ax,511 ; round up to sector adc dx,byte 0 mov al,ah mov ah,dl ; AX <- FAT bytes / 256 shr ax,1 ; AX <- number of FAT sectors cmp ax,[bx+SDD_FatSect] ; check number of sectors ja short SDiskLoad8 ; invalid FAT size ; ------------- disk is valid or byte [bx+SDD_FlagsDisk],SDDF_Valid ; disk is valid jmp short SDiskLoad9 ; ------------- error, reset disk parameters SDiskLoad8: and byte [bx+SDD_FlagsDisk],~SDDF_Valid ; clear valid flag stc ; set error flag ; ------------- pop registers SDiskLoad9: pop di ; pop DI pop dx ; pop DX pop cx ; pop CX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Reload system disk ; ----------------------------------------------------------------------------- ; INPUT: BX = pointer to SDD descriptor ; OUTPUT: CY = error ; NOTES: Loads SDD of removable disk if needed. ; ----------------------------------------------------------------------------- ; ------------- check if it is removable disk SDiskReload: test byte [bx+SDD_FlagsDisk],SDDF_Removable ; removable? jz short SDiskReload9 ; not removable media ; ------------- push registers push ax ; push AX push dx ; push DX push si ; push SI ; ------------- get time delta -> AX call GetDateTimeUnix ; get date and time in Unix format sub ax,[bx+SDD_LastTime] ; AX <- interval add [bx+SDD_LastTime],ax ; shift last time ; ------------- invalid disk is loaded immediately test byte [bx+SDD_FlagsDisk],SDDF_Valid ; valid format? jz short SDiskReload2 ; uknown disk format ; ------------- check last access time cmp ax,byte 3 ; check interval cmc ; NC = short interval jnc short SDiskReload8 ; disk is valid ; ------------- mark disk as invalid SDiskReload2: and byte [bx+SDD_FlagsDisk],~SDDF_Valid ; clear valid flag ; ------------- read boot sector mov ax,[bx+SDD_StartSect] ; AX <- start sector LOW mov dx,[bx+SDD_StartSect+2] ; DX <- start sector HIGH call SDiskReadSect ; read sector jc short SDiskReload8 ; read error ; ------------- check signature cmp word [si+1feh],0aa55h ; check signature stc ; set error flag jne short SDiskReload8 ; invalid boot sector ; ------------- load system disk parameters call SDiskLoad ; load system disk parameters ; ------------- pop registers SDiskReload8: pop si ; pop SI pop dx ; pop DX pop ax ; pop AX SDiskReload9: ret ; ----------------------------------------------------------------------------- ; Get system disk default media descriptor ; ----------------------------------------------------------------------------- ; INPUT: BX = pointer to SDD descriptor ; OUTPUT: AL = default media descriptor ; ----------------------------------------------------------------------------- ; ------------- push registers SDiskMediaDesc: push cx ; push CX push si ; push SI ; ------------- get BDD descriptor -> SI mov si,[bx+SDD_BDD] ; SI <- BDD descriptor ; ------------- get drive type -> CH mov ch,[si+BDD_Flags] ; CH <- BDD flags and ch,BDDF_TypeMask ; CH <- drive type ; ------------- hard disk ; F8: HDD mov al,0f8h ; AL <- HDD descriptor cmp ch,BDDF_HardDisk ; hard disk ? je short SDiskMediaDesc8 ; hard disk ; ------------- check disk size >= 5 MB cmp word [bx+SDD_SectNum+2],byte 0 ; check disk size HIGH jne short SDiskMediaDesc8 ; disk is too big mov cx,[bx+SDD_SectNum] ; CX <- disk size LOW cmp ch,28h ; check disk size LOW jae short SDiskMediaDesc8 ; disk is loo big ; ------------- floppy 2.88 MB, 1.44 MB ; F0: 2.88MB C=80 H=2 S=36 ; 1.44MB C=80 H=2 S=18 mov al,0f0h ; AL <- floppy 2.88 MB, 1.44 MB cmp ch,0ah ; check disk size LOW, 1.3 MB jae short SDiskMediaDesc8 ; disk is > 1.3 MB ; ------------- floppy disk descriptor ; FF: 320KB C=40 H=2 S=8 ; FE: 160KB C=40 H=1 S=8 ; FD: 360KB C=40 H=2 S=9 ; FC: 180KB C=40 H=1 S=9 ; FB: 640KB C=80 H=2 S=8 ; FA: 320KB C=80 H=1 S=8 ; F9: 720KB C=80 H=2 S=9 ; 1.2MB C=80 H=2 S=15 mov al,0f8h ; AL <- base descriptor cmp byte [si+BDD_Heads],1 ; 1 side? jbe short SDiskMediaDesc2 ; 1 side or al,B0 ; set 2 sides flag SDiskMediaDesc2:cmp byte [si+BDD_SectTrack],8 ; 8 sectors per track? ja short SDiskMediaDesc3 ; more than 8 sectors or al,B1 ; set 8 sectors flag SDiskMediaDesc3:cmp byte [si+BDD_Cylinders],60 ; 40 cylinders? jae short SDiskMediaDesc4 ; more than 40 cylinders or al,B2 ; set 40 cylinders flag SDiskMediaDesc4:cmp al,0f8h ; reserved media type? jne SDiskMediaDesc8 ; media type is OK inc ax ; AL <- change to 0f9h ; ------------- pop registers SDiskMediaDesc8:pop si ; pop SI pop cx ; pop CX ret ; ----------------------------------------------------------------------------- ; Check system disk size ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors (5..400000h) ; OUTPUT: CY = error, invalid disk size ( < 2.5 KB or > 2 GB) ; ----------------------------------------------------------------------------- ; ------------- check minimum disk size (sectors: BOOT, FAT1, FAT2, ROOT, DATA) SDiskCheckSize: or dx,dx ; check disk size HIGH jnz short SDiskCheckSize2 ; disk size is OK cmp ax,5 ; minimum disk size jb short SDiskCheckSize6 ; invalid disk size ; ------------- check maximum disk size (2 GB, i.e. 400000h of 512 sectors) SDiskCheckSize2:cmp dx,byte 40h ; check 2 GB HIGH, use 512 B sectors jne short SDiskCheckSize4 ; not 2 GB cmp ax,byte 1 ; check 2 GB LOW SDiskCheckSize4:cmc ; CY = invalid disk size SDiskCheckSize6:ret ; ----------------------------------------------------------------------------- ; Get default FAT type ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors (5..400000h) ; OUTPUT: CH = default FAT type (SDDF_FAT12, SDDF_FAT16) ; ----------------------------------------------------------------------------- DefFATType: mov ch,SDDF_FAT16 ; CH <- FAT16 or dx,dx ; check number of sectors jnz short DefFATType9 ; large disk cmp ax,5000h ; check 10 MB LOW jae short DefFATType9 ; >= 10 MB, use FAT16 mov ch,SDDF_FAT12 ; CH <- FAT12 DefFATType9: ret ; ----------------------------------------------------------------------------- ; Get default root directory size ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors (5..400000h) ; OUTPUT: DI = number of root directory entries (16,32,112,224,448,512) ; ----------------------------------------------------------------------------- ; ------------- size >= 5 MB (hard disk, FAT16), use 32 sectors, 512 entries DefRootSize: mov di,32*SECTDIRNUM ; DI <- 32 sectors, 512 entries or dx,dx ; check disk size HIGH jnz short DefRootSize8 ; size >= 5 MB cmp ah,28h ; check 5 MB jae short DefRootSize8 ; size >= 5 MB ; ------------- size >= 2 MB (2.88 MB), use 28 sectors, 448 entries mov di,28*SECTDIRNUM ; DI <- 28 sectors, 448 entries cmp ah,10h ; check 2 MB jae short DefRootSize8 ; size >= 2 MB ; ------------- size >= 1 MB (1.2 MB, 1.44 MB), use 14 sectors, 224 entries shr di,1 ; DI <- 14 sectors, 224 entries cmp ah,8 ; check 1 MB jae short DefRootSize8 ; size >= 1 MB ; ------------- size >= 340 KB (360 KB, 720 KB), use 7 sectors, 112 entries shr di,1 ; DI <- 7 sectors, 112 entries cmp ax,2a8h ; check 340 KB jae short DefRootSize8 ; size > 340 KB ; ------------- size >= 128 KB (180 KB, 320 KB), use 4 sectors, 64 entries mov di,4*SECTDIRNUM ; DI <- 4 sectors, 64 entries or ah,ah ; check 128 KB jnz short DefRootSize8 ; size > 128 KB ; ------------- size >= 64 KB, use 2 sectors, 32 entries shr di,1 ; DI <- 2 sectors, 32 entries or al,al ; check 64 KB js short DefRootSize8 ; size > 64 KB ; ------------- size < 64 KB, use 1 sector, 16 entries shr di,1 ; DI <- 1 sector, 16 entries DefRootSize8: ret ; ----------------------------------------------------------------------------- ; Get default cluster size ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors ; FAT12: 5..40000h, FAT16: 5..400000h ; CH = FAT type (SDDF_FAT12, SDDF_FAT16) ; DI = number of root directory entries (1..0ffffh) ; OUTPUT: CL = sectors per cluster (1,2,4,8,16,32,64) ; ----------------------------------------------------------------------------- ; Cluster size must be power of 2 and < 65K -> max. cluster size is 32KB. ; ; Cluster size (sectors per cluster): ; FAT12: ; 0..127 KB: 1 ; 128..999 KB: 2 (FDD 360 KB, 720 KB) ; 1..1.9 MB: 1 (FDD 1.2 MB, 1.4 MB) ; 2..3.9 MB: 2 (FDD 2.88 MB) ; 4..7 MB: 4 ; 8..15 MB: 8 ; 16..31 MB: 16 ; 32..63 MB: 32 ; 64..127 MB: 64 ; FAT16: ; 0..255 KB: 1 ; 256 KB..1.9 MB: 8 ; 2..3.9 MB: 4 ; 4..7 MB: 2 ; 8..31 MB: 1 ; 32..63 MB: 2 ; 64..127 MB: 4 ; 128..255 MB: 8 ; 256..511 MB: 16 ; 512..1023 MB: 32 ; 1024..2047 MB: 64 ; ------------- push registers DefClustSize: push ax ; push AX push dx ; push DX push di ; push DI ; ------------- decrease disk size by root directory sectors xchg ax,di ; AX <- number of root entries add ax,SECTDIRNUM-1 ; AX <- round up rcr ax,1 ; AX <- /2 shr ax,1 shr ax,1 shr ax,1 ; AX <- number of root sectors xchg ax,di ; DI <- number of root sectors sub ax,di ; subtract root sectors LOW sbb dx,byte 0 ; borrow mov cl,1 ; CL <- 1, minimal cluster size jc short DefClustSize9 ; error ; ------------- prepare table -> DI mov di,FAT12ClustSize-5 ; DI <- FAT12 table cmp ch,SDDF_FAT12 ; FAT12? je short DefClustSize2 ; FAT12 mov di,FAT16ClustSize-5 ; DI <- FAT16 table ; ------------- find cluster size -> CL DefClustSize2: add di,byte 5 ; DI <- shift table pointer mov cl,[di] ; CL <- number of sectors cmp dx,[di+3] ; compare disk size HIGH jne short DefClustSize4 cmp ax,[di+1] ; compare disk size LOW DefClustSize4: jb short DefClustSize2 ; next table entry ; ------------- pop registers DefClustSize9: pop di ; pop DI pop dx ; pop DX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Get default parameters of system disk ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors ; FAT12: 5..40000h, FAT16: 5..400000h ; CL = sectors per cluster (1,2,4,8,16,32,64; 0=auto) ; CH = FAT type (SDDF_FAT12, SDDF_FAT16; 0=auto) ; DI = number of root directory entries (1..0ffffh, 0=auto) ; OUTPUT: Default parameters ; ----------------------------------------------------------------------------- ; ------------- FAT type SDiskDefPar: or ch,ch ; unknown FAT type? jnz short SDiskDefPar2 ; FAT type is OK call DefFATType ; default FAT type ; ------------- number of root directory entries SDiskDefPar2: or di,di ; unknown root directory entries? jnz short SDiskDefPar4 ; root size is OK call DefRootSize ; default root directory entries ; ------------- sectors per cluster SDiskDefPar4: or cl,cl ; unknown sectors per cluster? jnz short SDiskDefPar6 ; cluster size is OK call DefClustSize ; default cluster size SDiskDefPar6: ret ; ----------------------------------------------------------------------------- ; Calculate number of clusters ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = data sectors (without boot, root and FATs) ; CL = sectors per cluster (1,2,4,8,16,32,64) ; OUTPUT: AX = number of clusters (0..0ffffh) ; CY = overflow (number of clusters > 64K) ; ----------------------------------------------------------------------------- ; ------------- push registers GetClustNum: push bx ; push BX push cx ; push CX push dx ; push DX ; ------------- get number of clusters -> DX:AX mov ch,0 ; CX <- sectors per cluster xchg ax,bx ; BX <- data sectors LOW xchg ax,dx ; AX <- data sectors HIGH xor dx,dx ; DX <- 0 div cx ; AX <- clusters HIGH, DX <- rest xchg ax,bx ; AX <- sectors LOW,BX <- clusters HIGH div cx ; AX <- clusters LOW ; ------------- check overflow or bx,bx ; overflow? jz short GetClustNum4 ; no overflow or ax,byte -1 ; AX <- -1, limit to 0ffffh stc ; set error flag ; ------------- pop registers GetClustNum4: pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Build BOOT sector parameter table ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = total number of disk sectors ; FAT12: 5..40000h, FAT16: 5..400000h ; CL = sectors per cluster (1,2,4,8,16,32,64; 0=auto) ; CH = FAT type (SDDF_FAT12, SDDF_FAT16; 0=auto) ; DI = number of root directory entries (1..0ffffh, 0=auto) ; SI = pointer to BOOT sector (BOOTHEAD structure) ; OUTPUT: Default parameters ; NOTES: Fills up these entries: BOOT_OEM_Ident, BOOT_SectSize, ; BOOT_ClustSize, BOOT_Reserved, BOOT_RootSize, ; BOOT_SectNumW, BOOT_FATSize, BOOT_SectNum, ; BOOT_Signature, BOOT_Serial, BOOT_FatName ; ----------------------------------------------------------------------------- ; ------------- get default parameters BuildBoot: call SDiskDefPar ; get default parameters ; ------------- push registers push ax ; push AX push dx ; push DX push di ; push DI ; ------------- fill up boot table mov word [si+BOOT_OEM_Ident],"LI" ; OEM ident. 1 mov word [si+BOOT_OEM_Ident+2],"TO" ; OEM ident. 2 mov word [si+BOOT_OEM_Ident+4],"S8" ; OEM ident. 3 mov word [si+BOOT_OEM_Ident+6]," 1" ; OEM ident. 4 mov word [si+BOOT_SectSize],SECTSIZE ; sector size mov [si+BOOT_ClustSize],cl ; sectors per cluster mov word [si+BOOT_Reserved],1 ; reserved sectors mov [si+BOOT_RootSize],di ; number of root entries mov byte [si+BOOT_Signature],BOOTSIGN ; signature ; ------------- number of sectors and word [si+BOOT_SectNumW],byte 0 ; number of sectors WORD mov [si+BOOT_SectNum],ax ; number of sectors LOW mov [si+BOOT_SectNum+2],dx ; number of sectors HIGH or dx,dx ; number of sectors >= 64K ? jnz short BuildBoot2 ; disk is >= 64K sectors mov [si+BOOT_SectNumW],ax ; number of sectors WORD mov [si+BOOT_SectNum],dx ; clear number of sectors LOW ; ------------- subtract boot and root -> DX:AX BuildBoot2: add di,15 ; round up root size shr di,1 shr di,1 shr di,1 shr di,1 ; DI <- sectors per root inc di ; include BOOT sector sub ax,di ; subtract boot and root sbb dx,byte 0 ; borrow jnc short BuildBoot4 ; disk size is OK xor ax,ax ; AX <- 0, limit disk size xor dx,dx ; DX <- 0 ; ------------- get FAT size BuildBoot4: call GetClustNum ; get number of clusters -> AX xor dx,dx ; DX <- 0 mov di,ax ; DI <- number of clusters cmp ch,SDDF_FAT16 ; FAT16 ? je short BuildBoot6 ; yes shr di,1 ; DI <- number of clusters / 2 inc di ; round up BuildBoot6: add ax,di ; AX <- number of clusters *2 or *1.5 adc dx,byte 0 ; DX <- overflow add ax,511 ; round up to sector adc dx,byte 0 mov al,ah mov ah,dl ; AX <- FAT bytes / 256 shr ax,1 ; AX <- number of FAT sectors mov [si+BOOT_FATSize],ax ; sectors per one FAT table ; ------------- random serial disk number call RandDWord ; get random dword mov [si+BOOT_Serial],ax ; serial LOW mov [si+BOOT_Serial+2],dx ; serial HIGH ; ------------- FAT name mov word [si+BOOT_FatName],"FA" mov word [si+BOOT_FatName+2],"T1" mov word [si+BOOT_FatName+4],"2 " mov word [si+BOOT_FatName+6]," " cmp ch,SDDF_FAT12 ; FAT12 ? je short BuildBoot8 ; yes mov byte [si+BOOT_FatName+4],"6" ; FAT16 ; ------------- pop registers BuildBoot8: pop di ; pop DI pop dx ; pop DX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Get number of valid system disks ; ----------------------------------------------------------------------------- ; OUTPUT: AL = number of system disks (0..16) ; ----------------------------------------------------------------------------- SDiskGetNum: mov al,[SDDNum] ret ; ----------------------------------------------------------------------------- ; Get system disk descriptor ; ----------------------------------------------------------------------------- ; INPUT: AL = disk number (0...) ; OUTPUT: BX = pointer to SDD descriptor (or NULL on CY error) ; CY = error, invalid disk number (returns BX = NULL) ; ----------------------------------------------------------------------------- SDiskGetDesc: cmp al,SDISK_MAX ; check disk number jae short SDiskGetDesc6 ; error, invalid disk xchg ax,bx ; BX <- push AX mov al,SDD_size ; AL <- descriptor size mul bl ; AX <- offset of descriptor add ax,SDDTab ; AX <- SDD address xchg ax,bx ; AX <- pop AX, BX <- SDD address cmp word [bx+SDD_BDD],byte 1 ; check BDD descriptor jnc SDiskGetDesc8 ; disk is OK SDiskGetDesc6: xor bx,bx ; BX <- 0 stc ; set error flag SDiskGetDesc8: ret ; ----------------------------------------------------------------------------- ; Get system disk info TEXT ; ----------------------------------------------------------------------------- ; INPUT: AL = system disk number (0...) ; OUTPUT: BX = pointer to TEXT structure (NULL on memory error) ; CY = disk or memory error (BX = NULL) ; NOTES: Returned text should be destroyed using TextFree. ; ----------------------------------------------------------------------------- ; ------------- push registers SDiskGetInfo: push ax ; push AX push cx ; push CX push dx ; push DX push si ; push SI push di ; push DI ; ------------- get system disk descriptor -> DI call SDiskGetDesc ; get disk descriptor jnc short SDiskGetInfo0 SDiskGetInfo99: jmp SDiskGetInfo9 ; invalid disk SDiskGetInfo0: mov di,bx ; DI <- disk descriptor ; ------------- create TEXT -> BX xchg ax,bx ; BL <- disk call TextNewEmpty ; create new text xchg ax,bx ; BX <- TEXT structure, AL <- disk jc short SDiskGetInfo99 ; memory error ; ------------- disk name add al,"A" ; AL <- disk name call TextAddChar ; add disk name ; ------------- BIOS number mov ax,SDTextBIOS ; ": BIOS=" call TextAddText ; add text mov si,[di+SDD_BDD] ; SI <- BDD descriptor mov al,[si+BDD_Disk] ; AL <- disk call TextAddHByte ; add disk HEX number ; ------------- FAT format mov ax,SDTextFAT12 ; FAT12 test byte [di+SDD_FlagsDisk],SDDF_FAT12 ; FAT12 ? jnz short SDiskGetInfo2 ; FAT 12 mov ax,SDTextFAT16 ; FAT16 SDiskGetInfo2: call TextAddText ; add text ; ------------- disk size call TextAddSpc ; add space mov al,[di+SDD_SectClust] ; AL <- sectors per cluster cbw ; AX <- sectors per cluster mul word [di+SDD_ClustNum] ; DX:AX <- disk size call TextAddDiskSize ; add disk size ; ------------- number of clusters mov ax,SDTextClust ; AX <- text "clust=" call TextAddText ; add text mov ax,[di+SDD_ClustNum] ; AX <- number of clusters call TextAddWord ; add number of clusters mov al,"x" call TextAddChar ; add "x" character mov al,[di+SDD_SectClust] ; AL <- sectors per cluster shr al,1 ; 1 sector? jnc short SDiskGetInfo3 ; no mov ax,512 call TextAddWord ; add "512" jmp short SDiskGetInfo4 SDiskGetInfo3: call TextAddByte ; add cluster size mov al,"K" call TextAddChar ; add "K" char SDiskGetInfo4: mov al,"B" call TextAddChar ; add "B" char ; ------------- ROOT entries mov ax,SDTextRoot ; AX <- text "root=" call TextAddText ; add text mov ax,[di+SDD_RootEntries] ; AX <- root entries call TextAddWord ; add root entries ; ------------- FAT size mov ax,SDTextFAT ; AX <- text "FAT=" call TextAddText ; add text mov al,[di+SDD_FatNum] ; AL <- number of FAT tables call TextAddByte ; add number mov al,"x" call TextAddChar ; add "x" character mov ax,[di+SDD_FatSect] ; AX <- number of FAT sectors call TextAddWord ; add number ; ------------- start sector mov ax,SDTextStart ; AX <- text "start=" call TextAddText ; add text mov ax,[di+SDD_StartSect] ; AX <- start sector LOW mov dx,[di+SDD_StartSect+2] ; DX <- start sector HIGH call TextAddDWord ; add number ; ------------- pop registers clc ; clear error flag SDiskGetInfo9: pop di ; pop DI pop si ; pop SI pop dx ; pop DX pop cx ; pop CX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Get system all disks info TEXT ; ----------------------------------------------------------------------------- ; OUTPUT: BX = pointer to TEXT structure (NULL on memory error) ; CY = memory error (BX = NULL) ; NOTES: Returned text should be destroyed using TextFree. ; ----------------------------------------------------------------------------- ; ------------- push registers SDiskGetAllInfo:push ax ; push AX push dx ; push DX ; ------------- create TEXT call TextNewEmpty ; create new text xchg bx,ax ; BX <- TEXT structure jc short SDiskGetAllInf9 ; memory error ; ------------- total number of disks mov ax,SDTextDiskNum ; AX <- text "System disks=" call TextAddText ; add text "System disks=" mov al,[SDDNum] ; AL <- total number of disks call TextAddByte ; add total number of disks call TextAddNewLine ; add new line ; ------------- add disc descriptors mov al,0 ; AL <- disk index SDiskGetAllInf2:push ax ; push AX mov dx,bx ; DX <- TEXT descriptor call SDiskGetInfo ; get disk info xchg ax,bx ; AX <- disk TEXT mov bx,dx ; BX <- TEXT descriptor jc short SDiskGetAllInf6 ; error call TextAddText ; add text xchg ax,bx ; AX <- TEXT, BX <- disk TEXT call TextFree ; free disk TEXT xchg ax,bx ; BX <- TEXT call TextAddNewLine ; add new line SDiskGetAllInf6:pop ax ; pop AX inc ax ; increase disk index cmp al,SDISK_MAX ; next disk? jb short SDiskGetAllInf2 ; get next disk ; ------------- pop registers clc ; clear error flag SDiskGetAllInf9:pop dx ; pop DX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Read cached sector (into SectBuf) ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = absolute sector (0..) ; BX = pointer to SDD descriptor ; OUTPUT: SI = sector buffer SectBuf ; CY = operation error ; ----------------------------------------------------------------------------- SDiskReadSect: push bx ; push BX mov bx,[bx+SDD_BDD] ; BX <- BDD descriptor call BDiskReadSect ; read cached sector pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Check system disk device ; ----------------------------------------------------------------------------- ; INPUT: BL = system disk (0..) ; OUTPUT: CY = invalid system disk ; ----------------------------------------------------------------------------- SDDCheck: push ax ; push AX push bx ; push BX xchg ax,bx ; AL <- system disk number call SDiskGetDesc ; get SDD descriptor pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Get system disk size ; ----------------------------------------------------------------------------- ; INPUT: BL = system disk (0..) ; OUTPUT: DX:AX = media size (0 on error) ; CY = invalid system disk (DX:AX = 0) ; ----------------------------------------------------------------------------- SDDSize: push bx ; push BX xchg ax,bx ; AL <- system disk number xor dx,dx ; DX <- 0 call SDiskGetDesc ; get SDD descriptor mov ax,dx ; AX <- 0 jc short SDDSize4 ; error, invalid disk mov ah,[bx+SDD_SectNum] ; AX <- number of sectors * 256 mov dx,[bx+SDD_SectNum+1] ; DX <- number of sectors HIGH shl ax,1 ; AX <- size LOW rcl dx,1 ; DX <- size HIGH clc ; clear error flag SDDSize4: pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Read from system disk device ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = current sector offset ; BL = system disk (0..1) ; CX = number of sectors ; DI = destination buffer ; OUTPUT: CY = error (CX > 0) ; CX = remaining sectors (or CX = 0 if no error NC) ; ----------------------------------------------------------------------------- ; ------------- push registers 1 SDDRead: push bx ; push BX ; ------------- get SDD descriptor -> BX push ax ; push AX xchg ax,bx ; AL <- system disk number call SDiskGetDesc ; get SDD descriptor pop ax ; pop AX jc short SDDRead9 ; invalid disk ; ------------- push registers 2 push ax ; push AX push dx ; push DX push di ; push DI ; ------------- change to absolute sector -> DX:AX add ax,[bx+SDD_StartSect] ; AX <- absolute sector LOW adc dx,[bx+SDD_StartSect+2] ; DX <- absolute sector HIGH ; ------------- read data from disk mov bx,[bx+SDD_BDD] ; BX <- BDD descriptor call BDiskRead ; read sectors jc short SDDRead6 ; error xor cx,cx ; CX <- 0, data OK ; ------------- pop registers SDDRead6: pop di ; pop DI pop dx ; pop DX pop ax ; pop AX SDDRead9: pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Write to system disk device ; ----------------------------------------------------------------------------- ; INPUT: DX:AX = current sector offset ; BL = system disk (0..1) ; CX = number of sectors ; DI = source buffer ; OUTPUT: CY = error (CX > 0) ; CX = remaining sectors (or CX = 0 if no error NC) ; ----------------------------------------------------------------------------- ; ------------- push registers 1 SDDWrite: push bx ; push BX ; ------------- get SDD descriptor -> BX push ax ; push AX xchg ax,bx ; AL <- system disk number call SDiskGetDesc ; get SDD descriptor pop ax ; pop AX jc short SDDWrite9 ; invalid disk ; ------------- push registers 2 push ax ; push AX push dx ; push DX push di ; push DI ; ------------- change to absolute sector -> DX:AX add ax,[bx+SDD_StartSect] ; AX <- absolute sector LOW adc dx,[bx+SDD_StartSect+2] ; DX <- absolute sector HIGH ; ------------- write data to disk mov bx,[bx+SDD_BDD] ; BX <- BDD descriptor call BDiskWrite ; write sectors jc short SDDWrite6 ; error xor cx,cx ; CX <- 0, data OK ; ------------- pop registers SDDWrite6: pop di ; pop DI pop dx ; pop DX pop ax ; pop AX SDDWrite9: pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Constant data ; ----------------------------------------------------------------------------- CONST_SECTION ; ------------- FAT12 default number of sectors per cluster ; Max. 4078 clusters, FAT size max. 12 sectors FAT12ClustSize: db 64 ; 64..127 MB: 64 dd FAT12_NUM*32 + 1 + 2*FAT12_FATSECT ; 130521 (63.7 MB) db 32 ; 32..63 MB: 32 dd FAT12_NUM*16 + 1 + 2*FAT12_FATSECT ; 65273 (31.9 MB) db 16 ; 16..31 MB: 16 dd FAT12_NUM*8 + 1 + 2*FAT12_FATSECT ; 32648 (15.9 MB) db 8 ; 8..15 MB: 8 dd FAT12_NUM*4 + 1 + 2*FAT12_FATSECT ; 16337 (8 MB) db 4 ; 4..7 MB: 4 dd FAT12_NUM*2 + 1 + 2*FAT12_FATSECT ; 8181 (4 MB) db 2 ; 2..3.9 MB: 2 dd FAT12_NUM + 1 + 2*FAT12_FATSECT ; 4103 (2 MB) db 1 ; 1..1.9 MB: 1 dd 2048 ; (1 MB) db 2 ; 128..999 KB: 2 dd 256 ; (128 KB) db 1 ; 0..127 KB: 1 dd 0 ; ------------- FAT16 default number of sectors per cluster ; Max. 65518 clusters, FAT size max. 256 sectors FAT16ClustSize: db 64 ; 1024..2047 MB: 64 dd FAT16_NUM*32 + 1 + 2*FAT16_FATSECT ; 2097089 (1024 MB) db 32 ; 512..1023 MB: 32 dd FAT16_NUM*16 + 1 + 2*FAT16_FATSECT ; 1048801 (512 MB) db 16 ; 256..511 MB: 16 dd FAT16_NUM*8 + 1 + 2*FAT16_FATSECT ; 524657 (256 MB) db 8 ; 128..255 MB: 8 dd FAT16_NUM*4 + 1 + 2*FAT16_FATSECT ; 262585 (128 MB) db 4 ; 64..127 MB: 4 dd FAT16_NUM*2 + 1 + 2*FAT16_FATSECT ; 131549 (64 MB) db 2 ; 32..63 MB: 2 dd FAT16_NUM + 1 + 2*FAT16_FATSECT ; 66031 (32 MB) db 1 ; 8..31 MB: 1 dd 16384 ; (8 MB) db 2 ; 4..7 MB: 2 dd 8192 ; (4 MB) db 4 ; 2..3.9 MB: 4 dd 4096 ; (2 MB) db 8 ; 256 KB..1.9 MB: 8 dd 512 ; (256 KB) db 1 ; 0..255 KB: 1 dd 0 ; ------------- system disk info texts SDTextDiskNum: CTEXT "System disks=" SDTextBIOS: CTEXT ": (" SDTextFAT12: CTEXT "h) FAT12" SDTextFAT16: CTEXT "h) FAT16" SDTextClust: CTEXT " clust=" SDTextRoot: CTEXT " root=" SDTextFAT: CTEXT " FAT=" SDTextStart: CTEXT " start=" ; ----------------------------------------------------------------------------- ; Uninitialised data ; ----------------------------------------------------------------------------- DATA_SECTION ; ------------- System disks descriptors align 4, resb 1 SDDTab: resb SDD_size * SDISK_MAX ; disk descriptors SDDNum: resw 1 ; number of valid system disks SDDLastDisk: resw 1 ; index of last system disk + 1 SDDExtStart: resd 1 ; initialize - extended start sector