Guest User

Untitled

a guest
Jul 23rd, 2021
123
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Use16
  2. org 0x7C00
  3.  
  4. TTY_WIDTH   equ 80
  5. TTY_HEIGHT  equ 25
  6.  
  7. FAT     equ 0x1000
  8. ROOT    equ 0x3000
  9. SBOOT   equ 0x8000
  10.  
  11. jmp start
  12.     db 0
  13.     BS_OEMName      db '        '
  14.     BPB_BytsPerSec  dw 0x200                ; байт в секторе
  15.     BPB_SecPerClus  db 1                    ; секторов в кластере
  16.     BPB_RsvdSecCnt  dw 1
  17.     BPB_NumFATs     db 2                    ; число таблиц FAT
  18.     BPB_RootEntCnt  dw 0x00E0               ; число записей в корневом дереве
  19.     BPB_TotSec16    dw 0x0B40
  20.     BPB_Media       db 0xF0
  21.     BPB_FATSz16     dw 9                    ; размер FAT в секторах
  22.     BPB_SecPerTrk   dw 0x12                 ; секторов на дорожке
  23.     BPB_NumHeads    dw 2                    ; число читающих головок
  24.     BPB_HiddSec     dd 0
  25.     BPB_TotSec32    dd 0
  26.    
  27.     BS_DrvNum       db 0
  28.     BS_Reserved1    db 0
  29.     BS_BootSig      db 0
  30.     BS_VolID        dd 0
  31.     BS_VolLab       db '           '
  32.     BS_FiSysType    db 'FAT12   '
  33.  
  34. start:
  35.     cli
  36.     mov ax, cs
  37.     mov ds, ax
  38.     mov es, ax
  39.     mov ss, ax
  40.     mov sp, 0x7C00
  41.     sti
  42.    
  43.     push    dx
  44.  
  45.     call    k_read_fat
  46.     call    k_read_root_dir
  47.    
  48.     mov di, SBOOT
  49.     mov si, secondBoot
  50.     call    k_read_file
  51.     or  ax, ax                  ; файл не найден?
  52.     jz  @f
  53.    
  54.     cmp word [SBOOT], 0         ; Проверяем на всякий случай
  55.     je  @f
  56.         pop dx
  57.         mov ax, k_read_file
  58.         jmp SBOOT               ; Передаем управление вторичному загрузчику
  59.  
  60. @@:
  61.     mov si, msgErrorCode
  62.     call    k_puts
  63.    
  64.     ;hlt
  65.     jmp $
  66.  
  67. ;
  68. ; Процедура читает файл с дискеты в память
  69. ;
  70. ; Вход:
  71. ;  di - адрес буффера
  72. ;  si - имя файла строго в формате NNNNNNNNEEE
  73. ; Выход:
  74. ;  ax - 0 если файл не найден, 1 - найден
  75. ;
  76. k_read_file:
  77.     push    di
  78.     mov di, ROOT
  79.     mov cx, 0xE0        ;BPB_RootEntCnt
  80.     .next_item:
  81.         mov al, byte [di]
  82.         cmp al, 0xE5        ;Метка удаленного файла
  83.         je  .space_item
  84.         test al, al         ;Пустая запись
  85.         je  .space_item
  86.             pusha
  87.             mov cx, 11      ;8+3
  88.             repe    cmpsb   ;Сравниваем имя файла с искомым
  89.             test cx,cx
  90.             popa
  91.            
  92.             je  .read_file  ;break
  93.         .space_item:
  94.         add di, 32          ;Длина записи
  95.     loop    .next_item
  96.    
  97.     pop di
  98.     xor ax, ax
  99.     ret
  100.    
  101.     .read_file:
  102.     pop si
  103.     mov bp, word [di+0x1A]  ;Номер начальной ячейки FAT
  104.    
  105.     push es
  106.  
  107.     .read_next_claster:
  108.         pusha
  109.         mov dx, bp
  110.         sub dx, 3
  111.         add dx, 0x22
  112.         call    k_read_sector
  113.         popa
  114.        
  115.         cmp di, 0xFFF
  116.         je  .end_of_file
  117.        
  118.         mov di, bp
  119.         mov bx, bp          ; сохраняем на случай если будет 0xFFF
  120.         imul di, 3
  121.         shr di, 1
  122.         add di, FAT         ;FAT+num*3/2 - адрес записи
  123.    
  124.         mov di, word [ds:di]
  125.         test bp, 1          ;Делаем коррекцию т.к. запись 12-битная
  126.         jne @f
  127.             and di, 0xFFF
  128.             jmp .end_correct
  129.         @@:
  130.             shr di, 4
  131.         .end_correct:
  132.        
  133.         mov bp, di
  134.        
  135. ; Если ячейка конечная, то корректируем ее номер на старый+1
  136.         cmp di, 0xFFF
  137.         jne @f
  138.             inc bx
  139.             mov bp, bx
  140.         @@:
  141.        
  142.         add si, 512
  143.         jae @f
  144.             mov ax, es
  145.             add ax, 0x1000
  146.             mov es, ax
  147.         @@:
  148.         jmp .read_next_claster     
  149.     .end_of_file:
  150.     pop es
  151.     xor ax, ax
  152.     inc ax
  153. ret
  154.  
  155. ;
  156. ; Процедура чтения сектора дискеты по абсолютному номеру
  157. ;
  158. ; Вход:
  159. ;  dx - абсолютный номер сектора
  160. ;  si - адрес буффера
  161. ;
  162. k_read_sector:
  163.     ;S = N mod 18 + 1
  164.     ;T = N / 18
  165.     ;H = T mod 2
  166.     ;C = T / 2
  167.    
  168.     pusha
  169.  
  170.     mov ax, dx
  171.     mov cx, 0x12    ;BPB_SecPerTrk
  172.     mov bx, si
  173.    
  174.     xor dx, dx
  175.     div cx
  176.     mov ch, al
  177.     shr ch, 1
  178.     mov cl, dl
  179.     inc cx
  180.     mov dh, al
  181.     and dh, 1
  182.     mov ax, 0x0201
  183.     xor dl, dl
  184.     int 0x13
  185.     jnc @f
  186.         mov si, msgErrorRead
  187.         call    k_puts
  188.     @@:
  189.    
  190.     popa
  191. ret
  192.  
  193. ;
  194. ; Процедура последовательного чтения нескольких секторов
  195. ;
  196. ; Вход:
  197. ;  dx - начальный сектор
  198. ;  cx - сколько секторов подряд читать
  199. ;  si   - адрес памяти, куда читать
  200. ;
  201. k_read_sectors:
  202.     pusha
  203. @@:
  204.     call    k_read_sector
  205.        
  206.     inc dx
  207.     add si, 512
  208.  
  209.     loop @b
  210.    
  211.     popa
  212. ret
  213.  
  214. ;
  215. ; Процедура читает таблицу FAT в память
  216. ;
  217. k_read_fat:
  218.     mov dx, 1
  219.     mov cx, 9
  220.     mov si, FAT
  221.     call    k_read_sectors
  222. ret
  223.  
  224. ;
  225. ; Процедура читает корневой каталог в память
  226. ;
  227. k_read_root_dir:
  228.     mov dx, 19
  229.     mov cx, 15
  230.     mov si, ROOT
  231.     call    k_read_sectors
  232. ret
  233.  
  234. ;
  235. ; Процедура вывода ASCII-строки на экран.
  236. ;
  237. ; Вход:
  238. ;  si - адрес строки
  239. ;
  240. k_puts:
  241.     pusha
  242.     xor bx, bx
  243.     mov ah, 0x0E
  244.     cld
  245. @@:
  246.     lodsb
  247.     test al, al
  248.     jz @f
  249.         int 0x10        ; вывести символ в режиме teletype
  250.         jmp @b
  251. @@:
  252.     popa
  253.     ret
  254.  
  255. msgErrorRead    db 'Sector read fail!', 0
  256. msgErrorCode    db 'File SBOOT.BIN not found!',0
  257.  
  258. secondBoot      db 'SBOOT   BIN'
  259.  
  260.  
  261. times 510-($-$$) db 0
  262.     db 0x55, 0xaa
  263.  
RAW Paste Data