My Simple Operating system in Assembly

For programming questions that do not fit in the other forums.

Moderator:Moderators

Post Reply
Master
Posts:5
Joined:Wed May 26, 2010 5:08 pm
Location:Babol
Contact:
My Simple Operating system in Assembly

Post by Master » Thu Dec 27, 2012 5:37 pm

Hello . almost 2 and half years ago we tried to make a simple operating system for our system programming course using assembly.
This Website and its tutorials were huge help for us .
This is just a simple OS which only has FAT12 driver implemented .(The save function never got told in the tutorial ,so we write it ourselves :) )
Its been a week or two that a student is asking me about OS development , today i found the source code and I though it is good idea to let others benefit from my efforts as once you guys have done.so im posting it all here:
So here is the source whole source code (and the package concerning all tools needed for running it ) :)
I hope this little effort of mine is a help -be it tiny and small- to some one out there .
Again Thank you Mike for everything :P

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;   In the name of God     ;;   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        Kernel            ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;      SEYYED HOSSEIN HASAN POUR MATIKOLAEE     ;;
;;          MASTER.HURICANE@GMAIL.COM            ;;   
;;            HTTP://FORUM.USTMB.IR              ;;
;;Mazandaran University of Science And Technology;;
;;                  1388-89                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;     Code Segment (core)   ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODE    SEGMENT
    ASSUME CS:CODE
      
START: JMP BEGIN            ;JUMP TO START POINT OF EXECUTABLE CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;            MESSAGES                 ;;          
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NewLine            Db 10,13,0
 
 
GOD        DB    'IN THE NAME OF GOD',10,13,0
ME        DB    'SEYYED HOSSEIN HASAN POUR',10,13,0
WELCM    DB    'WELCOME TO KERNELX OPERATING SYSTEM',10,13,0
ENDMSG    DB    'WHEN YOU ARE READY TO REBOOT PRESS R',10,13,0
 
 
GETNAMEMSG    DB    10,13,'FILE NAME: ',0
MENUMSG        DB    10,13,'______________________________________',10,13
            DB    '     N:NEW  S:SAVE  L:LOAD  E:EXIT',10,13
            DB  '______________________________________',10,13,0    
FILESAVEMSG    DB    'FILE SAVED.',10,13,0
FILELOADMSG    DB    'FILE LOADED.',10,13,0
 
NOFREEFATMSG    DB    'ERROR: NO FREE FAT ENTRY IS FOUND.',10,13,0
NOFREEROOTMSG    DB    'ERROR: NO FREE ROOT ENTRY IS FOUND.',10,13,0
NOTHINGFOUND    DB    'ERROR: NO FREE FAT ENTRY IS FOUND',10,13,0
FILENOTFOUND    DB    'FILE COULD NOT BE FOUND IN ROOT DIRECTORY',10,13,0
FILEFOUND        DB    10,13,'FILE IS LOADED SUCCESSFULLY ',10,13,0
WriteFatIntoDisk    DB    'Writing Fat Into Disk',10,13,0
WriteRootIntoDisk    DB    'Writing Root Into Disk',10,13,0
ContinueMess    DB    10,13,'Press any Key to Contine...',10,13,0
NOFREEROOTENTRYFOUNDMSG  DB 'ERROR: NO FREE DIRECTORY ENTRY FOUND',10,13,0
 
MNMSG        DB    '<MENU ACTIVATED>     ',10,13,0
NOMENUMODE    DB    '      ',10,13,0
LDMSG        DB    '<LOAD ACTIVATED> ',10,13,0
SaveOperationMess        DB    '<Save Operation Is Done>       ',10,13,0
EXMSG        DB    '<EXIT ACTIVATED> ',10,13,0
WRMSG        DB    '<WRITING ACTIVATED>',10,13,0
 
 
STARTCLUSTER    DW 10
FREEFATENTRY1    DW 0000
FREEROOTENTRY    DW 0000
FTBUFFERADDRESS    DW 0  ;04000H ;~ 8400H
RTBUFFERADDRESS    DW 0  ;04000H ;~ 8400H
KRBUFFERADDRESS    DW 0
DATASECTOR        DW 33
ABSOLUTESECTOR    DB 0
ABSOLUTEHEAD    DB 0
ABSOLUTETRACK    DB 0
BPBROOTENTRIES    DW 224
CLUSTER            DW 0000H
 
 
;-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0
BPBBYTESPERSECTOR    DW 512
BPBSECTORSPERCLUSTER    DB 1    
BPBRESERVEDSECTORS    DW 1
BPBNUMBEROFFATS        DB 2
BPBTOTALSECTORS        DW 2880
BPBMEDIA            DB 0F0H            ;FA:IT IS A RAMDISK
                                         
BPBSECTORSPERFAT    DW 9
BPBSECTORSPERTRACK    DW 18
BPBHEADSPERCYLINDER    DW 2
BPBHIDDENSECTORS    DD 0
BPBTOTALSECTORSBIG    DD 0
BSDRIVENUMBER        DB 0H             ;0 ;HARDDISK
BSUNUSED            DB 0
 
;-0-0-0-0-0-0-0-0-0-0-00-0--0-0-0-0-0-0-0-0-0--0-0-0-0-0-0-0-0-0-0-
;--------------------------------------
TEXT        DB 512 DUP(0),10,13,0
STRLENGTH    DW 512
FILENAME    DB 8 DUP('s'),'SOS',0     ;'12345678TXT',0
Odd_Even_Fat DB 0
 
OutPut_Bffer    DB    512 Dup(?),10,13,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;             FUNCTIONS              ;;     
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LBACHS:
        Push DX
        Push SI
        Push AX
       XOR DX, DX                      ; PREPARE DX:AX FOR OPERATION
       LEA SI, BPBSECTORSPERTRACK
       DIV WORD PTR[SI]                   ; CALCULATE
       INC DL                           ; ADJUST FOR SECTOR 0
       LEA SI, ABSOLUTESECTOR
       MOV BYTE PTR[SI], DL
       XOR DX, DX                       ; PREPARE DX:AX FOR OPERATION
       LEA SI,    BPBHEADSPERCYLINDER
       DIV WORD PTR[SI]                   ; CALCULATE
       LEA SI,    ABSOLUTEHEAD
       MOV BYTE PTR[SI], DL
       LEA SI,    ABSOLUTETRACK
       MOV BYTE PTR[SI], AL
        Pop AX
        Pop SI
        Pop DX
    RET
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     CONVERT CLUSTER TO LBA         ;;
;;LBA=(CLUSTER-2)*SECTORS PER CLUSTER ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLUSTERLBA:
       SUB    AX, 0002H                    ; ZERO BASE CLUSTER NUMBER
       MOV    CX,    00001H                    ;[BPBSECTORSPERCLUSTER]
       MUL   CX
       LEA   SI, DATASECTOR              ; BASE DATA SECTOR
       ADD   AX, WORD PTR[SI]            ; BASE DATA SECTOR
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;              GOTOXY                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GOTOXY:
        push AX
        push BX
        MOV AH,2
        MOV BH,0
        INT 10H
        pop bx
        pop ax
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;              GOTOXYAfterMenu                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GOTOXYAfterMenu:
        push AX
        push BX
        Push DX
        Mov DH,2
        Mov DL,6
        MOV AH,2
        MOV BH,0
        INT 10H
        Pop DX
        pop bx
        pop ax
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;             PUSHREGS                ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PUSHREGS:
       PUSH    AX
       PUSH    BX
       PUSH    CX
       PUSH    DX
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;             POPREGS                 ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
POPREGS:
    POP    DX
    POP    CX
    POP    BX
    POP    AX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;               FIX                   ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_FIX:
     ;MOV CX,07C00H
     ;MOV ES,CX   
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;               GetCh                 ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
GetCh:
        push AX   
        mov     ah, 00H
        int     16H                                ; await keypress
        Pop AX
        ;cmp        AL,    'r'
        ;jne        GetCh
Ret
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           CLEARSCREEN               ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLEARSCREEN:
    Push AX
    Push BX
    Push CX
    Push DX
       MOV AX, 0600H
       MOV BH, 07H
       MOV CX, 0000H
       MOV DX, 204FH
       INT 10H
    Pop AX
    Pop BX
    Pop CX
    Pop DX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;               DELAY                 ;;@@ 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY:
  CALL PUSHREGS
 
       MOV CX, 50
L1:       MOV DX, 10
L2:       DEC DX
       JNZ L2
       LOOP L1
 
  CALL POPREGS
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;              PUTC                   ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PUTC:
        push AX
        Push BX
       MOV AH, 0EH
       MOV BL, 07H
       MOV BH, 00H
       INT 10H
       Pop BX
       Pop AX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;              PUTS                   ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LEA SI, YOURTEXT
PUTS:
       push AX
       Push BX
PutL:  LODSB
       OR AL, AL
       JZ EXIT
       CALL PUTC
       JMP PutL
EXIT:
    Pop BX
    Pop AX
   RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;             GETNAME                 ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GETNAME:
        Push SI
        Push DX
        Push AX       
        ;CALL PRINT_MENU
        LEA SI, GETNAMEMSG
        CALL PUTS
        MOV DX,8
        LEA DI, FILENAME
    RD: MOV AH,00
        INT 16H 
        CALL PUTC
        MOV BYTE PTR[DI],AL
        INC DI
        DEC DX
        CMP DX,0
        JNZ RD
        Pop AX
        Pop DX
        Pop SI
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;            GETINPUT                 ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GETINPUT:
       ; MOV DH,6
       ; MOV DL,54
       ; CALL GOTOXY    
READAGAIN:
       MOV AH, 0                        ;READ KEY OPCODE
       INT 16H
       CALL PUTC
       CMP AL, 0                         ;SPECIAL FUNCTION?
       JZ READAGAIN                     ;IF SO, DON'T ECHO THIS KEYSTROKE
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           PRINT DIGIT               ;; 
;;           AX = DIGIT                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;========================================
;;  THIS STRING TERMINATED BY 0        ;;
;========================================
PRINTNUMBER:
           PUSH BX
        PUSH CX
        PUSH AX                            ; DIVIDEND
        PUSH DX
        Push SI
        MOV BX, 10                        ; DIVISOR
        MOV    CX,    0
    I2A:
        MOV DX, 0                        ; DON'T NEED DX (IN THIS CASE)
        DIV BX                            ; DX:AX PAIR IS IMPLIED SOURCE/DESTINATION
        MOV    DH,    0
        PUSH DX
        INC CX
        OR AX, 0                        ; OR INSTRUCTION MODIFIES FLAGS (LOOKING FOR
                                        ;AX=0, NOTHING MORE TO DIVIDE) 
        JNZ I2A                            ; JUMP IF NOT ZERO FLAG ENABLED 
    PL1:
        POP AX
        OR    AL, 30H
        MOV    AH,    0EH        
        INT    10H
        LOOP PL1    
         
        Pop SI
        POP DX
        POP AX
        POP CX
        POP BX
    RET                                     ; WE ARE DONE, SO RETURN
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;            READTEXT                 ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READTEXT:
       XOR DI,DI
       MOV CX , 512
       LEA SI,TEXT
READLOOP:
       MOV AH, 0                       ;READ KEY OPCODE
       INT 16H
       CMP AL, 0                       ;SPECIAL FUNCTION?
       JZ READLOOP                     ;IF SO, DON'T ECHO THIS KEYSTROKE
       CALL PUTC                       ;OTHERWISE PRINT IT ON SCREEN AND SAVE IT
       MOV BYTE PTR [SI], AL           ; SAVE IT INTO TEXT
       INC SI
       INC DI
       CMP CX,0
       JE GETOUT
       DEC CX
       CMP AL, 0DH                     ;CARRIAGE RETURN (ENTER)?
       JNE READLOOP
GETOUT:
       LEA SI,STRLENGTH
       MOV WORD PTR[SI],DI
 RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         PRINT ON SCREEN             ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
View:
        push SI
        Push DI
        Push CX
        LEA SI,TEXT
        LEA DI,STRLENGTH
        MOV CX,WORD PTR [DI]
NEXTO :
        LODSB                                 ; COPIES [SI] TO AL , AND THEN INCREMENET SI BY ONE
        CALL PUTC
        LOOP NEXTO
        Pop CX
        Pop DI
        Pop SI
 RET
 
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         PRINT GOD TEXT              ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_GOD:    
       MOV DH,2                            ;SATR
       MOV DL,30                            ;SOTON
       CALL GOTOXY    
       LEA SI, GOD
       CALL PUTS    
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        PRINT WELCOME TEXT           ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_WELCOME:    
       MOV DH,3
       MOV DL,22
       CALL GOTOXY    
       LEA SI, WELCM
       CALL PUTS    
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          PRINT MY NAME              ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_ME:    
       MOV DH,4
       MOV DL,26
       CALL GOTOXY    
       LEA SI, ME
       CALL PUTS    
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           PRINT MENU                ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_MENU:
 
       LEA SI, MENUMSG
       CALL PUTS    
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        PRINT FILE NAME              ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRFNAME:
       LEA SI, FILENAME
       CALL PUTS
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        MENU ACTIVATED TEXT          ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_MNAC:
       MOV DH,5
       MOV DL,54
       CALL GOTOXY    
       LEA SI,MNMSG
       CALL PUTS
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          MENU DEACTIAVTED           ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_MNDAC:
        MOV DH,5
       MOV DL,54
       CALL GOTOXY    
       LEA SI, NOMENUMODE
       CALL PUTS    
 RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         SAVE DONE MESSAGE           ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SAVE_DONE:
       MOV DH,5
       MOV DL,54
       CALL GOTOXY    
       LEA SI, SaveOperationMess
       CALL PUTS    
 RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          LOAD ACTIAVTED             ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDAC:
       LEA SI, LDMSG
       CALL PUTS    
 RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         WRITE ACTIVATED             ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WRAC:
       LEA SI, WRMSG
       CALL PUTS
 RET
;=========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          EXIT ACTIVATED             ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXITACTIVATED:
        MOV DH,5
       MOV DL,54
       CALL GOTOXY    
       LEA SI, EXMSG
       CALL PUTS    
 RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         PRINT INITI TEXT            ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINTINT:
       CALL PRINT_GOD
       CALL PRINT_WELCOME
       CALL PRINT_ME
       CALL PRINT_MENU
RET
;=========================================
 
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ;;            FAT12 DRIVER             ;;
                            ;;                                     ;; 
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ;=========================================
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;            READ SECTOR()            ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                            
;;    READS A SERIES OF SECTORS        ;;
;;    CX=>NUMBER OF SECTORS TO READ    ;;
;;    AX=>STARTING SECTOR              ;;
;;    ES:BX=>BUFFER TO READ TO         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
W DB 'ERROR CANT READ',10,13,0
 
READSECTORS:
       MOV    DI, 0005H                      ; FIVE RETRIES FOR ERROR
SECTORLOOP:
       PUSH  AX
       PUSH  BX
       PUSH  CX
       CALL  LBACHS                      ; CONVERT STARTING SECTOR TO CHS
       MOV   AX, 0201H                     ; BIOS READ SECTOR (AH=02H) READ ONE SECTOR (AL=01H)
       LEA     SI,    ABSOLUTETRACK
       MOV   CH, BYTE PTR[SI]            ; TRACK
       LEA     SI,    ABSOLUTESECTOR
       MOV   CL, BYTE PTR[SI]             ; SECTOR
       LEA     SI,    ABSOLUTEHEAD
       MOV   DH, BYTE PTR[SI]            ; HEAD
       LEA     SI,    BSDRIVENUMBER
       MOV   DL, BYTE PTR[SI]             ; DRIVE
       INT   13H                         ; INVOKE BIOS
       JNC   SUCCESS                     ; TEST FOR READ ERROR
       XOR   AX, AX                      ; BIOS RESET DISK
       INT   13H                         ; INVOKE BIOS
       DEC   DI                           ; DECREMENT ERROR COUNTER
       POP   CX
       POP   BX
       POP   AX
       JNZ   SECTORLOOP                 ; ATTEMPT TO READ AGAIN
      
       LEA   SI, W                        ; PRINT ERROR AND EXIT
       CALL  PUTS 
       JMP   READ_ENDED
 
SUCCESS:
      POP   CX
      POP   BX
      POP   AX
      LEA    SI,    BPBBYTESPERSECTOR
      ADD   BX, WORD PTR[SI]            ; QUEUE NEXT BUFFER
      INC   AX                            ; QUEUE NEXT SECTOR      
      LOOP  READSECTORS                   ; READ NEXT SECTOR    
READ_ENDED:
   
      RET
 
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;    LOAD ROOT DIRECTORY INTO RAM     ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
RootLD         DB 10,13,'ROOT LOADED...',10,13,0
RootOffet    DB 'Offset(Dec)= ',0
RootSegment  DB 10,13,'Segment(Dec)= ',0
 
LDROOT:
        push AX
        push BX
        push CX
        push DX
        push SI
        mov AX,  2000H
        mov ES, AX
        MOV CX,14
        MOV AX,19
        LEA SI, RTBUFFERADDRESS
        MOV BX, WORD PTR[SI]
        CALL READSECTORS
 
 
        Lea    SI,    RootLD
        Call    Puts
        Lea    SI,    RootOffet
        Call    Puts
        LEA SI, RTBUFFERADDRESS
        Mov AX, WORD PTR[SI]
        Call PrintNumber
        Lea    Si,    RootSegment
        Call    Puts
        Push ES
        Pop AX
        Call PrintNumber
        Lea    Si,    NewLine
        Call    Puts
         
        pop SI
        pop DX
        pop CX
        pop BX
        pop AX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     SEARCH IN ROOT DIRECTORY        ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FreeRdMess DB 'Free RootDir/Start Cluster Number= ',0
RTSCR:
        push SI
        push CX
        push DX
        push DI
        Push AX
        CALL  _FIX
        LEA   SI, BPBROOTENTRIES            ;224
        MOV   CX, WORD PTR[SI]            ; LOAD LOOP COUNTER >>CX = 224
        LEA   SI,RTBUFFERADDRESS
        MOV   DX, WORD PTR[SI]
        MOV   DI, DX                       ; LOCATE FIRST ROOT ENTRY(7C00:0200)
_LOOPR:
        push ds
        push es
        pop ds
        MOV   AL, BYTE PTR[DI]            ; TEST FOR ENTRY MATCH
        pop ds
        CMP   AL, 0;0E5H                    ;COMPARE [ DI ] WITH E5H TO SEE IF ITS AVAILABE 
        JE    FOUNDFREE                    ;
        CMP   AL, 0E5H
        JE    FOUNDFREE
        ADD   DI, 0020H                    ; QUEUE NEXT DIRECTORY ENTRY(ADD DI + 32)
        LOOP  _LOOPR                                        
        MOV   SI, OFFSET NOFREEROOTENTRYFOUNDMSG    ;IF NO FREE ENRTY IS FOUND PRINT ERROR MESSAGE AND EXIT
        CALL  PUTS
        JMP   ENDOK
 
FOUNDFREE:
        MOV   SI, OFFSET FREEROOTENTRY
        MOV   WORD PTR[SI], DI
        LEA SI,FreeRdMess
        CALL PUTS
        MOv AX, DI
        Call PrintNumber
        Lea    SI,NewLine
        Call    Puts
ENDOK:
    pop AX
    pop DI
    pop DX
    pop CX
    pop SI
 
       RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     SAVE NAME IN ROOT DIRECTORY     ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
SaveName DB 'FILE NAME IS SAVED IN ROOT',10,13,0
 
SAVE_NAME_INROOT:
    push AX
    push CX
    push SI
    push DI
    push DX
 
        LEA   SI, FREEROOTENTRY
        MOV   CX, WORD PTR[SI]            ; THE BEGINNING OF ROOT ENTRY       
        CLD                               ; INCREMENT SI AND DI IN EACH ITERATION
        MOV   DI, CX                      ; COPY THE FREE ROOT ENTRY ADDRESS INTO DI
        MOV   CX, 000BH                   ; ELEVEN CHARACTER NAME
        LEA   SI, FILENAME                ; FILENAME TO SAVE IN ROOT ENTRY
                                     ; 'REP MOVSB' COPIES CHARACTERS FROM DS:SI TO ES:DI.         
        REP   MOVSB                       ; COPY FILENAME INTO ROOT ENRTY 
                                     ; THE ABOVE STATEMENT REPEATES WITH REGARDS TO THE VALUE STORED IN CX
        ;--------- Copy Kernel for this file    
        LEA   SI, FREEROOTENTRY
        MOV   CX, WORD PTR[SI]
        Mov    DX, CX
        Mov BX, 11
        Add CX, 11
        Mov SI, CX
        Mov CX, 15
        Push DS
        Push ES
        Pop DS
    Att:Mov AL, Byte Ptr ES:[BX]
        Mov Byte Ptr ES:[SI], AL
        Inc    BX
        Inc    SI
        Loop Att
        MOV   CX, DX
        Add CX, 29
        Mov BX, CX
        Mov Byte Ptr ES:[BX], 1 ;Set Size of File        
        Pop DS
        LEA    SI, SaveName
        CALL  PUTS
    Pop DX
    Pop DI
    Pop SI
    Pop CX
    Pop AX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     SAVE START CLUSTER IN ROOT      ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SaveStartClusterMess DB 'START CLUSTER IS SAVED IN ROOT',10,13,0
 
SAVE_STARTCLUSTER_INROOT:
    push CX
    Push SI
    Push DI
    Push DX
        LEA   SI, FREEFATENTRY1
        MOV   CX, WORD PTR[SI]                  ; CX = FREE CLUSTER
        LEA   SI, FREEROOTENTRY
        Mov   DI, WORD PTR[SI] ;FREEROOTENTRY                ; THE BEGINNING OF FREE ROOT ENTRY
        Push DS
        Push ES
        Pop DS
        MOV   WORD PTR[DI + 001AH], CX         ; COPY THE CLUSTER IN THE 'START CLUSTER' FIELD IN ROOT ENTRY
        Pop DS   
 
        Lea    SI,    SaveStartClusterMess
        Call    Puts
 
        ; Lea SI, AfterPutNo
        ; Call Puts
      ; LEA SI, FREEROOTENTRY
      ; MOV BX, WORD PTR[SI]
        ; mov cx, 32
        ; LLL00:
            ; Push DS
            ; Push ES
            ; Pop DS
            ; Mov AL, Byte Ptr [BX]
            ; Pop DS
            ; MOv AH, 0
            ; Call PrintNumber
            ; Call GetCh
            ; Inc BX
            ; Loop LLL00
    Pop DX
    Pop DI
    Pop SI
    Pop CX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        SAVE STUFF TO ROOT           ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;SAVED NAME AND START CLUSTER IN ROOT ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
SAVE_IN_ROOT:
    CALL SAVE_STARTCLUSTER_INROOT
    CALL SAVE_NAME_INROOT
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           LOAD FAT                  ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
FatLoadMess DB 10,13,'FAT LOADED... ',10,13,0
FatOffset    DB 'Offset(Dec)= ',0
FatSegment    DB 10,13,'Segment(Dec)= ',0
 
LDFAT:
        Push AX
        Push CX
        Push BX
        Push DX
        Push SI
        Mov AX, 2000H
        Mov    ES, AX          
        MOV CX,9
        MOV AX,1
        LEA SI,FTBUFFERADDRESS
        MOV BX,  WORD PTR[SI]       
        CALL    READSECTORS
 
        ;CALL    GOTOXYAfterMenu
        Lea    SI, FatLoadMess
        Call    Puts
        Lea    SI, FatOffset
        Call    Puts
        LEA SI,FTBUFFERADDRESS
        MOV BX,  WORD PTR[SI]       
        Mov    AX, BX   
        Call PrintNumber
         
        Lea    SI, FatSegment
        Call    Puts
        Push ES
        Pop AX       
        Call PrintNumber
 
        Lea    SI, NewLine
        Call    Puts
 
        Pop SI
        Pop DX
        Pop BX
        Pop CX
        Pop AX
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     FIND FREE CLUSTE IN FAT         ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
FreeFatMess DB ' Free Cluster In FAT Is Found',0AH,0DH,0
FreeFatNo DB ' Free Cluster In FAT =  ',0
 
FINDFREEFAT:
        Push CX
        MOV   CX,0FEDH                    ;NUMBER OF CLUSTERS TO SEARCH
        PUSH  CX
        Mov   AX, 2000H
        Mov     ES, AX
READNEXT:
        LEA   SI, STARTCLUSTER
        MOV   AX, WORD PTR[SI]            ; IDENTIFY CURRENT CLUSTER
        MOV   CX, AX                      ; COPY CURRENT CLUSTER
        MOV   DX, AX                      ; COPY CURRENT CLUSTER
        SHR   DX, 0001H                   ; DIVIDE BY TWO
        ADD CX, DX                      ; SUM FOR (3/2)
        LEA DI, FTBUFFERADDRESS
        MOV BX, WORD PTR[DI]            ; LOCATION OF FAT IN MEMORY
        ADD BX, CX                      ; INDEX INTO FAT *
        Push DS
        Push ES
        Pop DS
        MOV DX, WORD PTR[BX]            ; READ TWO BYTES FROM FAT
        Pop DS
    ;-------------------    
        TEST AX, 0001H
        jz     EVEN_CLUSTER
    ODD_CLUSTER:     
        Lea SI, Odd_Even_Fat
        Mov Byte Ptr[SI],1
        mov    CL,    4     
        shr     dx, CL                      ; take high twelve bits
        jmp     _DONE    
    EVEN_CLUSTER:
        Lea SI, Odd_Even_Fat
        Mov Byte Ptr[SI],0
        and  dx, 0000111111111111b        ; take low twelve bits
   _DONE:
        CMP DX, 0000H               ;TEST FOR BEIGN FREE 
        JNE  NEXTONE                ;IF NOT GO CHECK THE NEXT ONE
        LEA SI, STARTCLUSTER           ;THIS MEANS THE CURRENT CLUSTER WAS FREE 
        MOV DX,WORD PTR[SI]           ; SO GET ITS NUMBER         
        LEA SI, FREEFATENTRY1          ; AND SAVE IT IN ANOTHER VARIABLE 
        MOV WORD PTR[SI], DX        ;COPY OUR FREE CLUSTER NUMBER IN VARIABLE
        Mov AX, DX
        JMP FINISH
NEXTONE:
        LEA SI, STARTCLUSTER
        MOV AX, WORD PTR[SI]
        INC AX
        MOV WORD PTR [SI], AX
        POP CX                       ;RESTORE HOW MANY CLUSTERS REMAINED TO SEARCH
        DEC CX
        push cx                       ;DECREASE IT BY ONE 
        CMP CX,0                     ;FINISHED ALREADY? 
        JE NOTFOUND                  ;NO MORE SEARCHING , PRINT ERROR AND EXIT 
        JMP READNEXT                 ;IF NOT GO READ ONE MORE . 
NOTFOUND:
        pop cx
        LEA SI, NOTHINGFOUND 
        CALL PUTS
        LEA SI, FREEFATENTRY1
        MOV WORD PTR[SI], 0 
        Pop CX
RET
FINISH:         
        pop cx          
        Lea SI, Odd_Even_Fat        ; IF cluster No is Odd  THEN we must save  Right Shift of  Cluster No
        Mov AL, Byte Ptr[SI]    ; Else if cluster No is Odd we must save Left Shift of  Cluster No
        Mov AH,0
        Push DS
        Push ES
        Pop DS
        Cmp AX, 0
        Je  _Even
        MOV Byte PTR[BX+1], 0FFH
        Mov CL, Byte Ptr[BX]
        OR    CL,0F0H
        Mov Byte PTR[BX], CL
        Jmp __Done
_Even:  MOV WORD PTR[BX], 0FFFH     ; BECAUSE OURFILE IS ONLY ONE CLUSTER, THEN WE SPECIFY END OF FILE HERE
__Done: Pop DS
;--------------------------
        Lea    SI,    FreeFatMess
        Call    Puts
        Lea    SI,    FreeFatNo
        Call    Puts
        LEA SI, FREEFATENTRY1
        Mov AX, WORD PTR[SI]
        Call PrintNumber
        Lea    Si,    NewLine
        Call    Puts
 
        Pop CX    
         
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;       FIND AND LOAD FILE            ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LoadFileMess    DB    10,13,'File Loading... ',10,13,0
FileStartCluster DB 'Start Cluster of File= ',0
LoddFileFatOffset    DB 'Load Offset(Dec)= ',0
LoddFileFatSegment    DB 10,13,'Load Segment(Dec)= ',0
 
 
FINDNLOAD:
        Lea    SI,LoadFileMess
        Call    Puts
    ;  CALL _FIX                        ; LEA SI, BPBROOTENTRIES
       MOV CX, 224                      ; WORD PTR[SI]; LOAD LOOP COUNTER
       LEA SI,RTBUFFERADDRESS           ; LOCATE FIRST ROOT ENTRY(X:0200)
       MOV DX, WORD PTR[SI]
       MOV DI, DX              
_LOOP:
       PUSH CX
       PUSH DI
       MOV  CX, 000BH                 ; ELEVEN CHARACTER NAME
       LEA  SI, FILENAME              ; FILENAME TO FIND
       CLD
       REP  CMPSB                     ; TEST FOR ENTRY MATCH
       POP   DI
       POP   CX                               ;COMPARE ES:DI AND DS:SI FOR CX CHARACTER(BYRE)
       JE    LOAD_FAT
       ADD   DI, 0020H                ; QUEUE NEXT DIRECTORY ENTRY
       LOOP  _LOOP
       JMP   DIDNTFIND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;LOAD FAT;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOAD_FAT:
        Mov    AX, 2000H
        Mov    ES,    AX       
        MOV  DX, WORD PTR ES:[DI + 001AH]   ; DX= STARTING CLUSTER OF FILE(BYTE 26 AND 27)
        LEA SI, CLUSTER
        MOV  WORD PTR[SI], DX           ; FILE'S FIRST CLUSTER
        LEA DI , FTBUFFERADDRESS
        MOV  BX, WORD PTR[DI]           ; READ FAT INTO MEMORY (X:C200)
        MOV  CX, 9
        MOV  AX,1
        CALL READSECTORS        
        Lea    SI,LoddFileFatOffset
        Call    Puts
        LEA DI , FTBUFFERADDRESS
        MOV  AX, WORD PTR[DI]         
        Call PrintNumber
        Lea    SI,LoddFileFatSegment
        Call    Puts
        MOV  AX, ES        
        Call PrintNumber
        Lea    SI, NewLine
        Call    Puts
        Lea    SI,FileStartCluster
        Call    Puts
        LEA SI, CLUSTER
        MOV  AX, WORD PTR[SI]
        Call PrintNumber
        Lea    SI, NewLine
        Call    Puts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;READ FILE INTO MEMORY(X:OFFSET FILE)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      Lea BX, OutPut_Bffer                 ;DESTINATION FOR FILE
      PUSH BX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;       LOAD FILE INTO RAM         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOAD_IMAGE: 
        LEA SI, CLUSTER
        MOV AX, WORD PTR[SI]               ; CLUSTER TO READ
        POP BX                              ; BUFFER TO READ INTO
        CALL CLUSTERLBA                       ; CONVERT CLUSTER TO LBA: GET SECTOR NUMBER
        MOV CX, 1                            ;[BPBSECTORSPERCLUSTER=1]: SECTORS TO BE READ 
        Push ES
        Push DS
        Pop ES
        CALL READSECTORS        
        Pop ES      
        ;PUSH BX
        ;JMP  ENDK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;          
;;    COMPUTE NEXT CLUSTER           ;;  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       LEA SI, CLUSTER
       MOV AX, WORD PTR[SI]            ; IDENTIFY CURRENT CLUSTER
       MOV CX, AX                       ; COPY CURRENT CLUSTER
       MOV DX, AX                      ; COPY CURRENT CLUSTER
       SHR DX, 0001H                   ; DIVIDE BY TWO
       ADD CX, DX                      ; SUM FOR (3/2)
       LEA DI, FTBUFFERADDRESS         ; LOCATION OF FAT IN MEMORY
       MOV BX, WORD PTR[DI]                                   
       ADD BX, CX                      ; INDEX INTO FAT
       MOV DX, WORD PTR ES:[BX]            ; READ TWO BYTES FROM FAT
       TEST AX, 0001H
       JNZ  _ODD_CLUSTER          
_EVEN_CLUSTER:     
       AND DX, 0000111111111111B        ; TAKE LOW TWELVE BITS
       JMP _DONE_
_ODD_CLUSTER:
       MOV CL, 4     
       SHR DX, CL                         ; TAKE HIGH TWELVE BITS      
_DONE_:     
        LEA    SI, CLUSTER
        MOV WORD PTR[SI], DX              ; STORE NEW CLUSTER
        CMP  DX, 0FF0H                     ; TEST FOR END OF FILE
        JB   LOAD_IMAGE    
        MOV  SI, OFFSET FILEFOUND             
        CALL PUTS 
        JMP  ENDK
DIDNTFIND:
       MOV SI, OFFSET FILENOTFOUND
       CALL PUTS
ENDK:
        Lea SI, OutPut_Bffer
        Call Puts
        Lea SI,    ContinueMess
        Call Puts
        Call GetCh
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;            SAVE FILE                ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;=====================================;;
;;        FOR TEXT FILE ONLY           ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;====================================================================================
;MOV CX, 1            ; NUMBER OF SECTORS IN TOTAL TO BE WRITTEN TO THE HARD DISK   =
;MOV BX,OFFSET TEXT   ; WRITE THESE BYTES TO DISK                                   =
;LEA SI,FREEFATENTRY1 ; COPY THIS CLUSTER INTO AX , FOR BEING CONVERTED TO LBA      = 
;MOV AX,WORD PTR[SI]                                                                =
;CALL CLUSTERLBA      ; CONVERT THIS CLUSTER TO LBA ( STORES THE RESULT IN AX )     =
;====================================================================================              
 
WRITE_DONEMSG DB 'WRITTING WAS SUCCESSFUL',10,13,0
CANT_WRITEMSG DB 'ERROR: WRITTING FAILED',0
 
SAVEFILE:
 
        ;mov ax,50
        mov cx ,1
        mov bx, offset  text
        push ds
        pop es
WRITENEXT:                                         
       MOV DI, 0005H                    ; FIVE RETRIES FOR ERROR
WRITELOOP:
;   CALL PUSHREGS
       PUSH  AX
       PUSH  BX
       PUSH  CX
       CALL LBACHS                      ; CONVERT LBA TO CHS
       MOV AX, 0301H                    ; BIOS WRITE SECTOR (AH=03H) WRITE ONE SECTOR (AL=01H)
       LEA SI, ABSOLUTETRACK
       MOV CH, BYTE PTR[SI]             ; TRACK
       LEA SI, ABSOLUTESECTOR
       MOV CL, BYTE PTR[SI]                ; SECTOR
       LEA SI, ABSOLUTEHEAD
       MOV DH, BYTE PTR[SI]             ; HEAD
       LEA SI, BSDRIVENUMBER
       MOV   DL, Byte PTR[SI]                    ; HARD DRIVE
       INT   13H                        ; INVOKE BIOS
       JNC   WRITE_DONE                 ; TEST FOR WRITE ERROR
 
       XOR   AX, AX                      ; BIOS RESET DISK
       INT   13H                         ; INVOKE BIOS
           
       ;CALL RESET_HARD                  ; RESETS HARD DRIVE DRIVER
 ;  CALL POPREGS
       POP   CX
       POP   BX
       POP   AX
       DEC   DI                         ; DECREMENT ERROR COUNTER
       JNZ   WRITELOOP                  ; ATTEMPT TO WRITE AGAIN
 
       LEA SI, CANT_WRITEMSG            ; PRINT ERROR AND EXIT
       CALL PUTS 
       JMP WRITE_ENDED
 
WRITE_DONE:
       LEA SI, WRITE_DONEMSG                
       CALL PUTS 
       POP   CX
       POP   BX
       POP   AX                          ; CHECK TO SEE IF WE WROTE ALL NEEDED SECTORS         
;  CALL POPREGS                          ; THIS LINE MAKES IT CLEAR THAT , WE WRITE ANOTHER SECTOR
                                         ; OR NO, WE ARE DONE HERE, THE NUMBER OF SECTORS TO WRIE 
                                         ; IS LOCATED IN CX. 
       LEA SI, BPBBYTESPERSECTOR
       ADD BX, WORD PTR[SI]                 ; QUEUE NEXT BUFFER
       INC AX                            ; QUEUE NEXT SECTOR
       LOOP WRITENEXT                    ; IF WE HAVE MORE SECTORS TO WRITE, GO WRITE THE NEXT ONE
 
WRITE_ENDED:
 
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;       RESET HARD DISK DRIVER        ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RESET_HARD:
 
    ; CALL PUSHREGS
       push CX
       Push  AX
        
       MOV CX,5
            
RESETHHD:
       CMP CX,0
       JE  EXT
       MOV AH,00H           ; RESET FUNCTION 
       MOV AL,00H           ; HARD DISK TO BE RESET
       INT 13H              ; RESET 
       DEC CX
       JC  RESETHHD         ; IF ANYTHING WENT WRONG TRY AGAIN 
 
EXT:
    pop ax
    pop cx
    ; CALL POPREGS
RET
;========================================
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SAVE FAT OR ROOT DIRECTORY ON DISK  ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;   BEFORE CALLING THIS FUNCTION      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          FOR FAT  ONLY              ;; 
;;          MOV CX, 18                 ;; 
;;          MOV AX,1                   ;;
;;          MOV BX,[FTBUFFERADDRESS]   ;;  
;=======================================
;;          FOR ROOT ONLY              ;;
;;          MOV CX,14                  ;; 
;;          MOV AX,19                  ;;
;;          MOV BX,[RTBUFFERADDRESS]   ;; 
;=======================================
;TEXT DB 512 DUP(0),0
;ABSOLUTETRACK
;ABSOLUTESECTOR
;ABSOLUTEHEAD
 
DUMP_DONEMSG DB 'DUMPP_SUCCESSFUL ',10,13,0
CANT_DUMPMSG DB 'ERROR: DUMPP_FAILED',10,13,0
Dup_ Db '.',0
Dup__ Db '-',0
DUMPONDISK:
DUMPNEXT:                                           
       MOV DI, 0005H                     ; FIVE RETRIES FOR ERROR
DUMPLOOP:      
      lea si, Dup_
      Call  PutS
       PUSH  AX
       PUSH  BX
       PUSH  CX
        
        ; push AX
        ; push CX
         ; Mov DI, 0
         ; Mov CX, 20
; lll:  
       ; Mov AL, ES:[BX+DI]
      ; Mov AH, 0
      ; Call PrintNumber
      ; lea SI, Dup__
      ; Call Puts
      ; Inc DI
      ; Call GetCh
      ; Loop lll
      ; Pop CX
      ; Pop AX
       
       
       CALL LBACHS                       ; CONVERT LBA TO CHS
       MOV AX, 0301H                     ; BIOS WRITE SECTOR (AH=03H) WRITE ONE SECTOR (AL=01H)
       LEA SI, ABSOLUTETRACK
       MOV CH, BYTE PTR[SI]              ; TRACK
       LEA SI, ABSOLUTESECTOR
       MOV CL, BYTE PTR[SI]                 ; SECTOR
       LEA SI, ABSOLUTEHEAD
       MOV DH, BYTE PTR[SI]              ; HEAD
       LEA   SI, BSDRIVENUMBER
       MOV DL, Byte PTR[SI]                 ; HARD DRIVE
       INT 13H                           ; INVOKE BIOS
       JNC DUMP_DONE                     ; TEST FOR WRITE ERROR
       XOR   AX, AX                      ; BIOS RESET DISK
       INT   13H                         ; INVOKE BIOS
      ; CALL RESET_HARD                   ; RESETS HARD DRIVE DRIVER
                                  ; DECREMENT ERROR COUNTER
       POP   CX
       POP   BX
       POP   AX      
       DEC DI
       JNZ DUMPLOOP                      ; ATTEMPT TO WRITE AGAIN
       LEA SI, CANT_DUMPMSG              ; PRINT ERROR AND EXIT
       CALL PUTS 
       JMP DUMP_ENDED
DUMP_DONE:
                                         ;CHECK TO SEE IF WE WROTE ALL NEEDED SECTORS         
    ;CALL POPREGS                        ;THIS LINE MAKES IT CLEAR THAT , WE WRITE ANOTHER SECTOR
                                         ;OR NO, WE ARE DONE HERE, THE NUMBER OF SECTORS TO WRIE 
      POP  CX
      POP  BX
      POP  AX                           ;IS LOCATED IN CX. 
      LEA SI, BPBBYTESPERSECTOR
      ADD BX, WORD PTR[SI]               ; QUEUE NEXT BUFFER
      INC AX                             ; QUEUE NEXT SECTOR
      LOOP  DUMPNEXT                     ; GO DUMP THE NEXT SECTOR ON HARD
      LEA SI, DUMP_DONEMSG                
      CALL PUTS 
DUMP_ENDED:
 
        ;mov ax,1
        ;mov cx,1
             
        ;Push ES
        ;Push DS
        ;Pop ES
        ;lea bx,text
        ;call READSECTORS
        ;CALL View        
        ;Pop ES
        ;Call GetCh        
 
 
RET
;========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           TRACKER                   ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
X DB 'REACHED HERE ',10,13,0
_X:
       MOV   DH,15
       MOV   DL,15
       CALL  GOTOXY
       LEA   SI, X
       CALL  PUTS
       CALL  GETCH
RET
got:
push DX
mov dh,18
     mov dl,25
     call gotoxy
     pop dx
     ret
                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;;            MAIN FUNCTION            ;; 
                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;=======================================;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;            BEGIN                    ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BEGIN:
        CLI
        Pop AX
        Mov AH, 0
        Lea SI, BSDRIVENUMBER
        Mov Byte PTR[SI], AL
        MOV AX, 01000H                      ; CODE SEGMENT TA 6000H
        MOV DS, AX
        MOV ES, AX
        STI
MENUF:
        CALL CLEARSCREEN
        Mov DH,1
        Mov DL,1
        Call GOTOXY
        CALL PRINT_MENU
        CALL GETINPUT
        CMP AL,'N'
        JE NEWF
        CMP AL,'S'
        JE SAVEF
        CMP AL,'L'
        JNE  Next ;
        Jmp LOADF
Next:    CMP AL,'E'
        JNE ee
        MOv ah,0
        int 19H
  ee:  JMP MENUF
NEWF:
      CALL CLEARSCREEN
      CALL WRAC
WRITEF:
        ;CALL PRFNAME
        CALL READTEXT
        JMP MENUF
;==================================================================================
SAVEF:
        CALL GETNAME                    ;
;----------------------------------------------------------------------------------      
        CALL LDFAT                            ; LOAD FAT
        CALL FINDFREEFAT                   ; SEARCH FOR FRRE CLUSTER & SAVE IN VARIABLE & SPECIFY END OF FILE 
        Lea    SI,    WriteFatIntoDisk
        Call    Puts
        MOV CX,9                           ; NUMBER OF SECTORS IN TOTAL TO BE WRITTEN TO THE HARD DISK
        ;MOV CX,1                           ; NUMBER OF SECTORS IN TOTAL TO BE WRITTEN TO THE HARD DISK
        LEA SI, FTBUFFERADDRESS            ; THE ADDRESS OF FAT LOADED IN MEMORY 
        MOV BX, WORD PTR[SI]
        Mov Ax,2000H
        Mov ES, AX
        MOV AX,1                           ; START OF FAT ON DISK             
        CALL DUMPONDISK                     ; WRITE BACK FAT TO HARD/FLOPPY DISK
        Lea SI,    ContinueMess
        Call Puts
        Call GetCh
;----------------------------------------------------------------------------------      
        ;Call CLEARSCREEN
        CALL LDROOT                         ; LOAD ROOT DIRECTORY 
        CALL RTSCR                         ; SEARCH FOR FREE ENTRY 
        CALL SAVE_IN_ROOT                     ; SAVE START CLUSTER IN ROOT DIRECTORY & ;SAVE FILE NAME IN ROOT DIRECTORY
        Lea    SI,    WriteRootIntoDisk
        Call    Puts
        Mov Ax,2000H
        Mov ES, AX
        LEA SI,RTBUFFERADDRESS             ; THE ADDRESS OF ROOT LOADED IN MEMORY  
        MOV BX, WORD PTR[SI]
        MOV CX,14                          ; NUMBER OF SECTORS IN TOTAL TO BE WRITTEN TO THE HARD DISK
        MOV AX,19                          ; START OF ROOT ON DISK 
        CALL DUMPONDISK                     ; WRITE BACK ROOT TO HARD /FLOPPY DISK
        Lea SI,    ContinueMess
        Call Puts
        Call GetCh
;----------------------------------------------------------------------------------      
        ;Call CLEARSCREEN                                 ; FOR TEXT FILE ONLY ;
        LEA SI, FREEFATENTRY1
        MOV AX, WORD PTR[SI] ;200
        CALL CLUSTERLBA
        CALL SAVEFILE
;-----------------------------------------------------------------------------------
        LEA SI, SaveOperationMess
        CALL PUTS    
        CALL GETCH
        JMP MENUF       
;===================================================================================      
LOADF:                           ;CALL CLEARSCREEN 
        CALL CLEARSCREEN 
        CALL LDAC
        CALL PRINTINT
        CALL GETNAME 
        CALL LDROOT
        CALL FINDNLOAD                     ;LOADFILE
        JMP MENUF                            ;WRITEF     
;===================================================================================
EXITP:
      CALL EXITACTIVATED
      mov ah,0
RB:   INT 19H                            ; BOOT COMPUTER
 
CODE    ENDS
        END
Regards
Hossein
Attachments
Operating System in Assembly.zip
(161.05KiB)Downloaded 2770 times
Regards
Seyyed Hossein Hasan Pour Matikolaee
ustmb.ir

pathos
Moderator
Posts:97
Joined:Thu Jan 10, 2008 6:43 pm
Location:USA

Re: My Simple Operating system in Assembly

Post by pathos » Thu Jan 03, 2013 2:37 pm

Thanks! I look forward to checking it out.

Post Reply