; CHKSUM.ASM by Erdogan Tan [ 10-6-2009 ]
; MS FAT & FAT32 File Systems
; Long Name (Long Directory Entries)
; 8 bit Checksum (CRC) Calculation Utility/Sample
; CHKSUM.COM 
; < masm chksum.asm, link /t chksum.asm >  or < ml /Zm /AT CHKSUM.ASM >

; TRDOS Project -> TRDOS.COM -> "longname <dosfilename>" command working
; TRDOS Kernel will use "proc_calculate_checksum"

code_seg        segment para public
                assume  cs:code_seg, ds:code_seg, ss:code_seg, es:code_seg

                org 100h

proc_main       proc far

start:
                mov si, offset 80h                      ; PSP command tail
                mov cl, byte ptr [ si ]
                or cl, cl                               
                jz short crc_filename_3                ; jump if zero

crc_filename_1:
                inc si
                mov al, byte ptr [ si ]
                cmp al, ' '                             ; is it SPACE ?
                jnz short crc_filename_2

                dec cl                                  
                jnz short crc_filename_1                  
                jmp short crc_filename_3

crc_filename_2:
              ; push ds
              ; pop  es
                mov di, offset DOS_File_Name
                call proc_convert_file_name
                mov si, offset DOS_File_Name
                call proc_calculate_checksum
                ; al = checksum value
                call proc_hex
                mov word ptr [str_checksum], ax
                mov si, offset Msg_Checksum
                call proc_printmsg
                int 20h

crc_filename_3:
                mov si, offset msg_no_filename
                call proc_printmsg

                int 20h

proc_main       endp

proc_printmsg   proc near
loc_print:          
		lodsb                           ; Load byte at DS:SI to AL
		and     AL,AL            
		je      short loc_return        ; If AL = 00h then return
		mov     AH,0Eh                  
		mov     BX,07h             
		int     10h                     ; BIOS Service func ( ah ) = 0Eh
						; Write char as TTY
						;AL-char BH-page BL-color
		jmp     short loc_print           
loc_return:
		retn

proc_printmsg   endp

proc_convert_file_name proc near
     ; INPUT -> DS:SI = Dot File Name Location
     ; INPUT -> ES:DI = Dir Entry Format File Name Location
     push di
     mov cx, 11
     mov al, 20h
     rep stosb
     pop di
     mov cx, 12
     mov al, 2Eh
     cmp byte ptr [SI], 2Eh
     je short pass_dot_space
loc_get_fchar:
     mov al, byte ptr [SI]
     cmp al, 61h
     jb  short pass_name_capitalize
     cmp al, 7Ah
     ja  short pass_name_capitalize
     and al, 0DFh
     mov byte ptr [SI], al
pass_name_capitalize:
     cmp al, 21h
     jb  short stop_convert_file
     cmp al, 2Eh
     jne short pass_dot_space
add_space:
     cmp cx, 4
     jna short inc_and_loop
     mov byte ptr [DI], 20h
     inc di
     dec cx
     jmp short add_space
pass_dot_space:
     mov byte ptr [DI], al
     inc di
inc_and_loop:
     inc si
     loop loc_get_fchar
stop_convert_file:
     retn
proc_convert_file_name endp

proc_calculate_checksum proc near

               ; INPUT DS:SI = 11 byte Dos File Name location
               ; (in DOS Directory Entry Format)

               ; © Erdogan Tan [ 10-6-2009 ]
               ; This 8086 assembly code is an original code
               ; which is adapted from C code in
               ; Microsoft FAT32 File System Specification
               ; Version 1.03, December 6, 2000
               ; Page 28

               xor al, al
               mov cx, 11
loc_next_sum:
               ror al, 1
               add al, byte ptr [si]
               inc si
               loop loc_next_sum

               ; al= 8 bit checksum (CRC) value

               retn

proc_calculate_checksum endp

proc_hex        proc    near

; 1998
                ; input -> AL = binary number to be converted
                ; output -> AH = First character of hex number
                ; output -> AL = Second character of hex number

                db 0D4h,10h                     ; Undocumented inst. AAM
						; AH = AL / 10h
						; AL = AL MOD 10h
		or AX,'00'                      ; Make it ZERO (ASCII) based

                xchg AH,AL 

; 1999
		cmp AL,'9'
		jna pass_cc_al
		add AL,7
pass_cc_al:
		cmp AH,'9'
		jna pass_cc_ah
		add AH,7
pass_cc_ah:

; 1998
		retn

proc_hex        endp

DOS_File_Name: db 12 dup(0)

msg_no_filename:
     db 7
     db "You must write a dos file name as command parameter!"
     db  0Dh, 0Ah
     db  "For example: < chksum filename.ext >"
     db  0Dh, 0Ah, 0

msg_checksum:
     db 7
     db "[ DOS File Name Checksum ] ¸ Erdogan Tan - 2009"
     db  0Dh, 0Ah
     db  "8 bit unsigned Checksum: "
str_checksum: dw  3030h
     db "h"
     db  0Dh, 0Ah, 0

code_seg ends

end start

