⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat32.inc

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 INC
📖 第 1 页 / 共 4 页
字号:
    ret

  nohdcache:

    add  esi,8
    add  edi,1
    loop hdreadcache

    popa

    call  wait_for_hd_idle

    push  esi edi eax ebx ecx edx

    cli

    xor   eax,eax
    mov   edx,[hdbase]
    add   edx,1
    mov   al,0
    out   dx,al
    add   edx,1
    mov   al,1
    out   dx,al
    add   edx,1
    mov   al,[esp+12]
    out   dx,al
    add   edx,1
    mov   al,[esp+13]
    out   dx,al
    add   edx,1
    mov   al,[esp+14]
    out   dx,al
    add   edx,1
    mov   al,[esp+15]
    and   al,1+2+4+8
    mov   bl,byte [hdid]
    add   al,bl
    add   al,128+64+32
    out   dx,al
    add   edx,1
    mov   al,20h
    out   dx,al

    sti

    call  wait_for_sector_buffer

    cmp   [hd_error],0
    jne   hd_read_error

    cli

    mov   edi,[esp+8]
    mov   ecx,256
    mov   edx,[hdbase]
    cld
    rep   insw

    sti

    mov   esi,[esp+8]      ; move sector to cache
    mov   ecx,512

    mov   edi,0            ; write if the cache is full
    call  write_cache

    call  find_empty_slot  ; ret in edi

    cmp   edi,-1
    jne   founds
    call  find_empty_read_slot  ; ret in edi
  founds:

    push  edi

    shl   edi,9
    add   edi,0x600000+65536
    cld
    rep   movsb            ; move data

    pop   edi

    imul  edi,8
    add   edi,0x600000
    mov   eax,[esp+12]
    mov   [edi],eax        ; cluster number

    mov   [edi+4],dword 1  ; hd read - mark as same as in hd

  not_to_cache:

    pop   edx ecx ebx eax edi esi
    ret




;****************************************************************
hd_write_new:
; eax = block
; ebx = pointer to memory

    push edi
    mov  edi,0 ; write cache if full
    call write_cache
    pop  edi

    ; check if the cache already has the cluster and overwrite it

    pusha

    mov  ecx,cache_max
    mov  esi,0x600000+8
    mov  edi,1

  hdwritecache:

    cmp  [esi+4],dword 0 ; if cache slot is empty
    je   not_in_cache_write

    cmp  [esi],eax       ; if the slot has the cluster
    jne  not_in_cache_write

    mov  [esi+4],dword 2 ; write - differs from hd

    shl  edi,9
    add  edi,0x600000+65536
    mov  esi,ebx
    mov  ecx,512
    cld
    rep  movsb

    popa
    ret

  not_in_cache_write:

    add  esi,8
    add  edi,1
    loop hdwritecache

    ; block not found in cache
    ; write the block to a new location

    call  find_empty_slot ; ret in edi

    cmp   edi,-1
    jne   foundsw
    call  find_empty_read_slot  ; ret in edi
  foundsw:

    push  edi

    imul edi,8
    add  edi,0x600000

    mov  [edi+0],eax
    mov  [edi+4],dword 2

    pop  edi

    shl  edi,9
    add  edi,0x600000+65536
    mov  esi,ebx
    mov  ecx,512
    cld
    rep  movsb
    popa
    ret


write_cache:

    ; edi = 0 - write all only if the cache is full
    ; edi = 1 - write all

    pusha

    cmp  edi,0
    jne  no_check_for_full_cache

    mov  ecx,cache_max-15
    mov  esi,0x600000+8
    mov  edi,1

  cachel1:

    cmp  [esi+4],dword 2     ; if cache slot is different from hd
    jne  cachel2

    add  esi,8
    add  edi,1
    loop cachel1

    ; no empty slots found

    jmp  flush_cache

  cachel2:

    popa
    ret

  no_check_for_full_cache:


    ; edi = 1


  flush_cache:


    ; write difference ( 2 ) from cache to hd


    mov  ecx,cache_max
    mov  esi,0x600000+8
    mov  edi,1

  write_cache_more:

    cmp  [esi+4],dword 2 ; if cache slot is not different
    jne  does_not_need_writing

    mov  [esi+4],dword 1 ; same as in hd

    ; give parameters

    pusha

    mov  eax,[esi+0]  ; eax = cluster to write

    mov  ebx,edi
    imul ebx,512
    add  ebx,0x600000+65536

                      ; ebx = from memory position

    cmp  eax,[PARTITION_START]
    jb   danger
    cmp  eax,[PARTITION_END]
    ja   danger

    call  wait_for_hd_idle

    push  esi    ; [esp+12] +13 +14 +15
    push  eax    ; [esp+8]  +9  +10 +11
    push  ecx    ; [esp+4]  +5 +6 +7
    push  edx    ; [esp]    +1 +2 +3

    cli

    xor   eax,eax
    mov   edx,[hdbase]
    inc   edx
    out   dx,al
    inc   edx
    mov   al,1
    out   dx,al
    inc   edx
    mov   al,[esp+8]
    out   dx,al
    inc   edx
    mov   al,[esp+9]
    out   dx,al
    inc   edx
    mov   al,[esp+10]
    out   dx,al
    inc   edx
    mov   al,[esp+11]
    and   al,1+2+4+8
    add   al,byte [hdid]
    add   al,128+64+32
    out   dx,al
    inc   edx
    mov   al,30h
    out   dx,al

    sti

    call  wait_for_sector_buffer

    cmp   [hd_error],0
    jne   hd_write_error

    cli

    mov   esi,ebx
    mov   ecx,256
    mov   edx,[hdbase]
    cld
    rep outsw

    sti

    pop edx
    pop ecx
    pop eax
    pop esi

  danger:

    popa

  does_not_need_writing:

    add  esi,8
    add  edi,1
    dec  ecx
    jnz  write_cache_more

    popa
    ret


find_empty_slot:

    push eax ebx ecx edx esi

    mov  ecx,cache_max
    mov  esi,0x600000+8
    mov  edi,1

  search_for_empty:

    cmp  [esi+4],dword 0 ; if cache slot is empty
    je   found_empty_slot

    add  esi,8
    add  edi,1
    loop search_for_empty

    mov  edi,-1

    ; jmp  $ ; should not happen

  found_empty_slot:

    pop  esi edx ecx ebx eax

    ret


fat_search_start dd 0x0

find_empty_read_slot:

    push eax ebx ecx edx esi

  new_read_search:

    inc  dword [fat_search_start]
    cmp  [fat_search_start],cache_max-10
    jb   sok
    mov  [fat_search_start],0
  sok:

    mov  ecx,cache_max
    mov  esi,0x600000+8
    mov  edi,1

  search_for_empty_read:

    cmp  edi,[fat_search_start]
    jb   next_cache

    cmp  [esi+4],dword 1 ; if cache slot is used for reading
    je   found_empty_read_slot

  next_cache:

    add  esi,8
    add  edi,1
    loop search_for_empty_read

    mov  edi,1
    call write_cache

    mov  [fat_search_start],dword 0

    jmp  new_read_search

  found_empty_read_slot:

    pop  esi edx ecx ebx eax

    ret


hd_wait_timeout: dd 0x0


save_hd_wait_timeout:

    push  eax

    mov   eax,[0xfdf0]      
    add   eax,300           ; 3 sec timeout
    mov   [hd_wait_timeout],eax

    pop   eax

    ret


check_hd_wait_timeout:

    push  eax

    mov   eax,[hd_wait_timeout]
    cmp   [0xfdf0],eax
    jg    hd_timeout_error

    pop   eax

    ret


hd_timeout_str   db 'K : FS - HD timeout',13,10,0
hd_read_str      db 'K : FS - HD read error',13,10,0
hd_write_str     db 'K : FS - HD write error',13,10,0


hd_timeout_error:

    call  clear_hd_cache
    call  clear_application_table_status
    mov   esi,hd_timeout_str
    call  sys_msg_board_str
    jmp   $


hd_read_error:

    call  clear_hd_cache
    call  clear_application_table_status
    mov   esi,hd_read_str
    call  sys_msg_board_str
    jmp   $

hd_write_error:

    call  clear_hd_cache
    call  clear_application_table_status
    mov   esi,hd_write_str
    call  sys_msg_board_str
    jmp   $




wait_for_hd_idle:

    push  eax
    push  edx

    call  save_hd_wait_timeout

    mov   edx,[hdbase]
    add   edx,0x7
  wfhil1:

    call  check_hd_wait_timeout

    in    al,dx
    test  al,128
    jnz   wfhil1

    pop   edx
    pop   eax
    ret


wait_for_sector_buffer:

    push  eax edx

    mov   edx,[hdbase]
    add   edx,0x7

    call  save_hd_wait_timeout

  hdwait_sbuf:              ; wait for sector buffer to be ready

    call  check_hd_wait_timeout

    in    al,dx
    test  al,8
    jz    hdwait_sbuf

    mov   [hd_error],0

    cmp   [hd_setup],1      ; do not mark error for setup request
    je    buf_wait_ok

    test  al,1              ; previous command ended up with an error
    jz    buf_wait_ok
    mov   [hd_error],1

  buf_wait_ok:

    pop   edx eax

    ret



read_hd_file:
;-----------------------------------------------------------------
;
; Converting old reading function for hd-application start.
;
; IN:
;
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
; ebx - file lenght
; ecx - start 512 byte block number
; edx - number of blocks to read
; esi - pointer to return/work area (atleast 20 000 bytes)
;
; For new read function
;
; EAX   (PAR0)      pointer to file-name   PAR0
; ECX   (PAR1)      pointer to buffer      PAR1
; EBX   (PAR2)   vt file blocks to read    PAR2
; EDX   (PAR3)      pointer to path        PAR3
; ESI            vt first 512 block to read
; EDI               if 0 - return root
;--------------------------------------------------------------------------

     pusha
     mov  esi,eax
     mov  edi,startpath
     mov  ecx,250
     cld
     rep  movsb
     popa

     mov  eax,startpath
     add  eax,ebx
     sub  eax,12
     mov  [eax],byte 0
     mov  eax,startpath

     push eax ebx ecx edx esi

     pop  ecx ; pointer to buffer
     add  ecx,1024
     pop  ebx ; number of blocks to read
     pop  esi ; first block to read
     dec  esi
     pop  eax ; file length
     pop  edx ; pointer to path

     mov  edi,12

     add  eax,edx
     sub  eax,12
     inc  eax

     call file_read

     ret

startpath: times 255 db 0

;***********************
;*         Start       *
;* Mario79 edited code *
;*  correct free mem   *
;*     change 1.6      *
;***********************
hd_write_new_sys:
; eax = block
; ebx = pointer to memory
   
    cmp  eax,[PARTITION_START]
    jb   danger_1
    cmp  eax,[PARTITION_END]
    ja   danger_1
   
    call  wait_for_hd_idle
   
    push  esi    ; [esp+12] +13 +14 +15
    push  eax    ; [esp+8]  +9  +10 +11
    push  ecx    ; [esp+4]  +5 +6 +7
    push  edx    ; [esp]    +1 +2 +3
   
    cli
   
    xor   eax,eax
    mov   edx,[hdbase] 
    inc   edx
    out   dx,al
    inc   edx
    mov   al,1 
    out   dx,al
    inc   edx
    mov   al,[esp+8] 
    out   dx,al
    inc   edx
    mov   al,[esp+9]
    out   dx,al
    inc   edx
    mov   al,[esp+10]
    out   dx,al
    inc   edx
    mov   al,[esp+11]
    and   al,1+2+4+8
    add   al,byte [hdid]
    add   al,128+64+32
    out   dx,al
    inc   edx
    mov   al,31h 
    out   dx,al

    sti

hdwait_write:
    in    al,dx
    and   al,128
    jnz    hdwait_write

    cli

    mov   esi,ebx
    mov   ecx,256
    mov   edx,[hdbase]

    cld
    rep outsw
   
    sti

    pop edx
    pop ecx
    pop eax
    pop esi
danger_1:
    ret   
;***********************
;*          End        *
;* Mario79 edited code *
;*  correct free mem   *
;*     change 1.6      *
;***********************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -