;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; lib.asm, for DOS. ;; ;; Written by, Sohail QAYUM Malik ;; ;; Assemble it with MASM. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .MODEL SMALL, C, OS_DOS, NEARSTACK .DOSSEG .DATA flag word 0000h .CODE ;Access a sector for reading or writing purposes. accessSectors PROC NEAR push bp mov bp, sp push es push bx ;Get the far address of the buffer and update ES:BX mov ax, [bp + 6] mov es, ax mov bx, [bp + 4] ;Get the cylinder number and the sector number for the CX mov cx, [bp + 0ah] ;Get the head and the drive number for the DX mov dx, [bp + 0ch] ;Get the service number and the number of sectors to read. mov ax, [bp + 8] int 13h pop bx pop es mov sp, bp pop bp retn accessSectors ENDP ;Routine borrowed from the Linux source file "bootsect.s" . numberToAscii PROC NEAR push bp mov bp, sp push cx push dx push ax mov dx, [bp + 4] mov cx, 4 numberToAscii_0: db 0c1h, 0c2h, 4h ;Since some I'm unable to ;assemble this instruction ;"rol dx, 04h". ;God knows whats wrong with ;this MASM, may be I'm doing ;some thing wrong you know. mov ax, 0e0fh and al, dl add al, 90h daa adc al, 40h daa int 10h loop numberToAscii_0 pop ax pop dx pop cx mov sp, bp pop bp retn numberToAscii ENDP readFATEntries PROC NEAR push bp mov bp, sp mov dx, [bp + 8] ;CX now has the number ;of FAT entries each ;entry is 12bits wide ;here cx has the ;number of groups of 2 ;FAT entries. mov ax, [bp + 0ah] ;Initial value of link mov flag, ax mov ax, [bp + 6] mov es, ax mov si, 3 _soni_A0_: push dx mov bx, [bp + 4] mov ax, es:[bx + si] and ax, 0fffh cmp si, flag jne _mov_0 mov flag, 0001h _mov_0: push si push ax call near ptr evaluateFATEntry pop ax pop si mov bx, [bp + 4] add si, 1 mov ax, es:[bx + si] and ax, 0fff0h db 0c1h, 0e8h, 04h ;shr ax, 4 cmp si, flag jne _mov_1 mov flag, 0001h _mov_1: push si push ax call near ptr evaluateFATEntry pop ax pop si add si, 2 pop dx sub dx, 1 cmp dx, 0 jnz _soni_A0_ mov sp, bp pop bp retn readFATEntries ENDP makeCHS PROC NEAR push bp mov bp, sp mov ax, [bp + 4] ;The link. add ax, [bp + 6] ;The reserved sectors. xor dx, dx ;The intention is.... ;AX:DX/BX mov bx, 36 ;Sectors per cylinder. cmp ax, bx ;Now see if sectors are ;equal to sectors in a single ; cylinder. jne _GO_BIG_5 ;No they are not equal. ;Yes they are equal. mov dh, 0 ;DH should be the cylinder 0 mov dl, 12h ;DL is the sector number. mov ah, 1 ;AH is head. mov al, 0 jmp _GO_BIG_3 _GO_BIG_5: ;The division to be performed.... ;DX:AX/BX.... div bx ;NOTE: after the division the DX has the remainder, ; and the AX has the quotient.... ; So now we atleast have the cylinder number 'n' in AX. ; cmp dx, 0 ;See if remander is 0 jne _GO_BIG_1 ;No it is not zero. xchg ax, dx ;Yes it is zero DX = cylinder and ;AX is remainder. ;DX should have a bits[8-0f] = cylinder and bits[0-7] are ;sector number.... db 0c1h, 0e2h, 08h ;shl dx, 8 mov dl, 01h ;AX should have bits[8-0f] the head and bits[0-7] should be 0. mov ax, 0 jmp _GO_BIG_3 _GO_BIG_1: ;NOTE: after the division the DX has the remainder, ; and the AX has the quotient.... ; So now we atleast have the cylinder number 'n' in AX. ; cmp dx, 12h ;See if remainder is the last sector ;on this track in AX. jne _GO_BIG_2 ;No it is not. xchg ax, dx ;Yes it is, so now the AX has the ;remainder and the DX is the cylinder. ;OR.... ;DX = cylinder and AX is reminder. ;DX should have a bits[8-0f] = cylinder and bits[0-7] are ;sector number.... db 0c1h, 0e2h, 08h ;shl dx, 8 mov dl, 12h ;AX should have bits[8-0f] the head and bits[0-7] should be 0. mov ax, 0 jmp _GO_BIG_3 _GO_BIG_2: ;NOTE: after the division the DX has the remainder, ; and the AX has the quotient.... ; So now we atleast have the cylinder number 'n' in AX. ; cmp dx, 12h jb _GO_BIG_4 ;See if remainder is below 18 sectors. xchg ax, dx ;No it is no below.... ;So now DX has the cylinder and ;and AX has the sectors. ;Operation to be performed here.... ;AX/bl, mov bl, 18 div bl ;NOTE AL = head number, ; AH = sector number. ;SO now DX is the cylinder number and the AL is the head ;and the AH is sector number. db 0c1h, 0e2h, 08h ;shl dx, 8 mov dl, ah mov ah, al mov al, 0 jmp _GO_BIG_3 _GO_BIG_4: ;NOTE: after the division the DX has the remainder, ; and the AX has the quotient.... ; So now we atleast have the cylinder number 'n' in AX. ; xchg ax, dx ;So now DX has the cylinder and ;and AX has the sectors. ;DX should have a bits[8-0f] = cylinder and bits[0-7] are ;sector number.... db 0c1h, 0e2h, 08h ;shl dx, 8 mov dl, al mov ax, 0 _GO_BIG_3: mov sp, bp pop bp retn makeCHS ENDP EXTERNDEF evaluateFATEntry:NEAR PUBLIC flag END EXTERNDEF numberToAscii:NEAR EXTERNDEF accessSectors:NEAR EXTERNDEF readFATEntries:NEAR EXTERNDEF makeCHS:NEAR