Advertisement
Ladies_Man

#NUP lab3 (page mode)

Feb 18th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .586p
  2.  
  3. include mymacro.asm
  4.  
  5. ;========================================================================
  6. ;-----------------------ADDRESSES-AND-VARIABLES-------------------------
  7. ;========================================================================
  8.  
  9. ;------------------------DESCRIPTORS-AND-PAGES--------------------------
  10. DCODE       equ 8           ;дескриптор кода
  11. DDATA       equ 10h         ;дескриптор данных
  12. DSTACK      equ 18h         ;дескриптор стека
  13. DIOAPIC     equ 20h
  14. DLAPIC      equ 28h
  15. DNEWDATA    equ 30h
  16.  
  17.  
  18. STARTGDT    equ 50h         ;начальный адрес GDT
  19. STARTIDT    equ 60h         ;начальный адрес IDT
  20.  
  21. VIDEOB      equ 6000h       ;база видеопамяти
  22. STACK       equ 9F000h      ;база стека
  23. CODE        equ 0F0000h     ;сегмент кода
  24.  
  25. ;PDE        equ 5000h
  26. ;CODE_PG    equ 8F0000h     ;новый сегмент кода (пункт c)
  27. ;BDA_PG     equ 400000h     ;физ адреса для Bios Data Area
  28. ;DEVICE_PG  equ 1400000h        ;лин. адреса для физических устройств
  29. ;--------------------------------UART-----------------------------------
  30. COM1        equ 3F8h
  31. COM2        equ 2F8h
  32. COM3        equ 3E8h
  33. COM4        equ 2E8h
  34.  
  35. PORT        equ 000h
  36. THR     equ     000h        ;write only
  37. RBR     equ     000h        ;read only
  38. IER     equ 001h
  39. DLL     equ 000h
  40. DLH     equ 001h
  41. IIR     equ     002h        ;read only
  42. FCR     equ 002h        ;write only
  43. LCR     equ 003h
  44. MCR     equ 004h
  45. LSR     equ 005h        ;read only
  46. MSR     equ 006h        ;read only
  47. SR      equ     007h        ;scratch
  48. ;-------------------------------BUFFER-----------------------------------
  49. SBUFADR     equ 0h      ;адрес текущего начала буфера
  50. EBUFADR     equ 2h      ;адрес текущего конца буфера
  51. SBUF        equ     6h      ;начало буфера
  52. EBUF        equ 3Ah     ;конец буфера
  53. ;-----------------------------CONTROLLERS--------------------------------
  54. TESTOK      equ 0AAh       
  55. ACK     equ 0FAh
  56. ;---------------------------IOAPICS-LAPICS-------------------------------
  57. IOAPICB     equ 0FEC00000h  ;адрес иоапика
  58. LAPICB      equ 0FEE00000h  ;адрес лапика
  59.  
  60. ;========================================================================
  61. ;--------------------------------START----------------------------------
  62. ;========================================================================
  63. _TEXT32 segment byte public 'code' use32
  64. assume cs:_TEXT32, ds:nothing
  65. _TEXT32START = $
  66.         org 100h
  67. start32:
  68.         mov ax, DDATA                   ;перезагружаем сегментные регистры.
  69.         mov ds, ax
  70.         mov es, ax
  71.         mov fs, ax
  72.         mov gs, ax
  73.         mov ax, DSTACK
  74.         mov ss, ax
  75.         mov esp, 0FFCh
  76.        
  77.         cli
  78.         call    pages_on
  79. tibet:
  80.         call    permit_NMI              ;NMI - Not Masked Interruptions
  81.  
  82.         sti
  83.         call    init_PIC
  84.         call    init_IOAPIC
  85.         call    init_LAPIC
  86.         call    init_UART
  87.         call    FINAL_CYCLE
  88.         call    stop
  89.  
  90. ;------------------------------------------------------------------------
  91. permit_NMI:
  92.         in al, 70h
  93.         and al, 7Fh
  94.         out 70h, al
  95.         ret
  96.  
  97. ;------------------------------------------------------------------------
  98. PDE     equ 5000h
  99. CODE_PG     equ 8F0000h     ;новый сегмент кода (пункт c)
  100. BDA_PG      equ 400000h     ;физ адреса для Bios Data Area
  101. DEVICE_PG   equ 1400000h        ;лин. адреса для физических устройств
  102.  
  103. NEWGDTR:    dw GDT_SIZE-1       ;новая табличка на 8м мегабайте (на самом деле не новая а скопированная старая
  104.         dd 0800000h+(STARTGDT SHL 4)
  105. NEWIDTR:    dw IDT_SIZE-1
  106.         dd 0800000h+(STARTIDT SHL 4)
  107.  
  108. create_page macro lin, phys, properties:vararg
  109.         _g=1            ;глобальная страница
  110.         _ps=1           ;размер страницы
  111.         _access=0
  112.         _pcd=0          ;бит сброшен -> кэширование страниц разрешено  (ДЛЯ ФИЗ УСТРОЙСТВ ВСЕГДА ВЗВЕДЕН!)
  113.         _pwt=1          ;если 1 то write-through кэширование разрешено
  114.         _rw=1           ;r/w
  115.         _user=1        
  116.         _p=1            ;бит присутствия
  117.  
  118. mov edi, PDE+(lin SHR 22)*4
  119. mov eax, ((phys AND 0FFFFF000h)+(_g SHL 8)+(_ps SHL 7)+(_access SHL 5)+(_pcd SHL 4)+(_pwt SHL 3)+(_user SHL 2)+(_rw SHL 1)+_p)
  120. stosd
  121. endm
  122.  
  123. pages_on:
  124. ;a) Было включено защищённое страничное преобр: страницы 4M, обычное 32-х битовое страничное преобразование.   ....check
  125. ;b) Для тех страниц, для которых возможно, использовалось наиболее эффективный режим кэширования.       ....check
  126. ;c) Для выполняемого кода bios (диапазон физических адресов 0xF0000..0xFFFFF)                   ....check
  127.     ;использовать линейные адреса из диапазона 0x8F0000..0x8FFFFF.
  128. ;d) Для диапазона линейных адресов BDA (Bios Data Area) использовать физические адреса,
  129.     ;начинающиеся c адреса 0x400000.
  130. ;e) Для физических адресов устройств (отображаемые регистры, видеопамять и т.п.) использовать
  131.     ;линейные адреса, начинающиеся с 0x1400000 (возможно, в смежных страницах для различных устройств).
  132.        
  133. ;8F0000-8FFFFF  --->    F0000
  134. ;0...1k     --->    400000
  135. ;1400000    --->    FE....
  136.  
  137.         mov ax, DNEWDATA           
  138.         mov es, ax
  139.         mov ds, ax
  140.  
  141.         mov edi, PDE                ;создаем каталог страниц, размер кактлога 4кб
  142.         mov ecx, 1024               ;в 4кб помещается 1024 32битных записи (4байта)
  143.         xor eax, eax   
  144.         rep stosd               ;обнуляем элементы каталога
  145. ;для 4Мб-страниц таблица страниц никак не используется - все решают PDE
  146. ;БАЗУ КОДА CS ПОДВИНУТЬ НА 8Й МЕГАБАЙТ              (спец задание от Макарова)
  147.         ;create_page linear_adr -> phys_adr
  148.         create_page 0, 0            ;F0000 или 0
  149.         create_page CODE_PG, 0          ;F0000 или 0
  150.         create_page DEVICE_PG, IOAPICB, _pcd=1  ;кэшировать адреса физ устройств нельзя
  151.        
  152.         mov eax, PDE                ;кладем адрес каталога страниц в %cr3
  153.         mov cr3, eax
  154.  
  155.         mov eax, cr4
  156.         or  eax, 10h
  157.         mov cr4, eax
  158.  
  159.         mov eax, cr0                ;включаем стр. преобразование
  160.         or  eax, 80000000h
  161.         mov cr0, eax
  162.  
  163.         lgdt fword ptr NEWGDTR          ;копируем таблички обновленные
  164.         lidt fword ptr NEWIDTR
  165.  
  166.     ;передвигаем старый дескриптор кода на 8й МБ
  167.         mov edi, (STARTGDT SHL 4)+DCODE    
  168.         xor eax, eax
  169.         stosd
  170.         mov eax, 0C09B8Fh           ;дескр сегмента кода:G=1,B=1,P=1, #43=1 и #44=1, C(code segm)=1,
  171.                             ;база сегмента=8F -8й мегабайт, далее 0
  172.         stosd
  173.  
  174.         db 0EAh                 ;просто так перейти на след. инструкцию мы не можем, нужен дальний джамп
  175.         dd offset last_page
  176.         dw 8
  177.  
  178. last_page:
  179.         create_page 0, BDA_PG       ;F0000 или 0
  180.        
  181.         mov esp, 0FFCh
  182.         jmp tibet               ;стек сбился так что возвращаемся джампом
  183.         push offset tibet
  184.         ret
  185.  
  186.  
  187. ;========================================================================
  188. ;-------------------------------TABLES----------------------------------
  189. ;========================================================================
  190. ;--------------------------- KEYBOARD INITIALIZATION TABLE -------------
  191. KBD_INIT    db  0AAh,   064h,   1,  055h,              
  192.             0ABh,   064h,   1,  000h,              
  193.             0AEh,   064h,   0,                     
  194.             0FFh,   060h,   2,  ACK, TESTOK            
  195.         db  0EEh            ;stop-symbol               
  196. ;------------------------------------------------------------------------
  197.  
  198. ;----------------------------- COM INTERVIEW TABLE ---------------------    
  199. COM_TABLE   dw  COM1,   COM2,   COM3,   COM4
  200. ;------------------------------------------------------------------------
  201.  
  202. ;----------------------------- UART INITIALIZATION TABLE ---------------
  203. COM_INIT    db  10000000b,  LCR,   
  204.             60h,        DLL,   
  205.             0,      DLH,   
  206.             00000010b,  LCR,   
  207.             0,      IER,
  208.             00000110b,  FCR,       
  209.             00001000b,  MCR                                
  210.         db  0FEh            ;stop-symbol
  211.  
  212. ;1200 baud, 7 bit, 1 stop bit, no parity        <---- SERIAL MOUSE (COM)
  213. ;------------------------------------------------------------------------
  214.  
  215. move_out macro  port, value
  216.     mov al, value
  217.     out port, al
  218. endm
  219. ;------------------------------------------------------------------------
  220. mov_segm macro  sreg, value, treg:vararg
  221.     _treg equ ax
  222.     for t, <treg>
  223.         t
  224.     endm
  225.     mov _treg, value
  226.     mov sreg, _treg
  227. endm
  228. ;------------------------------------------------------------------------
  229. req_resp macro port, rq, rp:vararg
  230.     mov dx, port
  231.     mov bl, rq
  232.     call request
  233.     for rsp, <rp>
  234.         mov bl, rsp
  235.         call respond
  236.         cmp al, bl
  237.         ;jnz stop
  238.     endm
  239. endm
  240. ;------------------------------------------------------------------------
  241. send_com macro  port, value
  242.     push dx
  243.     mov     dx, port
  244.     mov     al, value
  245.     out     dx, al
  246.     pop dx
  247. endm
  248. ;========================================================================
  249. ;---------------------------------init_PIC------------------------------
  250. ;========================================================================
  251. init_PIC proc near
  252. ;начальный сброс обоих контроллеров
  253.  
  254.     mov al, 20h     ;1
  255.     out 20h, al
  256.     mov al, 20h     ;2
  257.     out 0A0h, al
  258.  
  259.     mov al, 11h     ;1
  260.     out 20h, al
  261.     mov al, 11h     ;2
  262.     out 0A0h, al
  263.  
  264.     mov al, 08h     ;1
  265.     out 21h, al
  266.     mov al, 70h     ;2
  267.     out 0A1h, al
  268.  
  269.     mov al, 04h     ;1
  270.     out 21h, al
  271.     mov al, 02h     ;2
  272.     out 0A1h, al
  273.    
  274.     mov al, 05h     ;1
  275.     out 21h, al
  276.     mov al, 01h     ;2
  277.     out 0A1h, al
  278.  
  279. ;разршение выбранных IRQ
  280. ;PIC0
  281.     mov al, 0FBh    ;1111 1011
  282.     out 21h, al
  283. ;PIC1
  284.     mov al, 0FFh   
  285.     out 0A1h, al
  286.     ret
  287. init_PIC endp
  288.  
  289.  
  290.  
  291. ;========================================================================
  292. ;---------------------------------COUTS---------------------------------
  293. ;========================================================================
  294. space proc near
  295.                 mov al, 20h
  296.                 call pushbuf
  297.                 ret
  298. space endp
  299.  
  300. cout_kb proc near
  301.                 mov al, 6Bh                             ;"kb:"
  302.                 call pushbuf
  303.                 mov al, 62h
  304.                 call pushbuf
  305.                 mov al, 3Ah
  306.                 call pushbuf
  307.                 ret
  308. cout_kb endp
  309.  
  310. cout_mf proc near
  311.                 mov al, 'M'                             ;"MF"
  312.                 call pushbuf
  313.                 mov al, 'F'
  314.                 call pushbuf
  315.                 ret
  316. cout_mf endp
  317.  
  318. cout_at proc near
  319.                 mov al, 'A'                             ;"AT"
  320.                 call pushbuf
  321.                 mov al, 'T'
  322.                 call pushbuf
  323.                 ret
  324. cout_at endp
  325.  
  326. cout_xt proc near
  327.                 mov al, 'X'                             ;"XT"
  328.                 call pushbuf
  329.                 mov al, 'T'
  330.                 call pushbuf
  331.                 ret
  332. cout_xt endp
  333.  
  334. cout_minus proc near                    ;"-"
  335.                 mov al, '-'
  336.                 call pushbuf
  337.                 ret
  338. cout_minus endp
  339.  
  340. cout_id proc near
  341.                 mov al, 69h                             ;"id:"
  342.                 call pushbuf
  343.                 mov al, 64h
  344.                 call pushbuf
  345.                 mov al, 3Ah
  346.                 call pushbuf
  347.                 ret
  348. cout_id endp
  349.  
  350. cout_ms proc near                               ;"  ms:"      
  351.                 call space
  352.                 call space
  353.                 mov al, 'm'
  354.                 call pushbuf
  355.                 mov al, 73h
  356.                 call pushbuf
  357.                 mov al, 3Ah
  358.                 call pushbuf
  359.                 ret
  360. cout_ms endp
  361.  
  362. cout_ps2 proc near
  363.                 mov al, 'p'
  364.                 call pushbuf
  365.                 mov al, 's'
  366.                 call pushbuf
  367.                 mov al, '/'
  368.                 call pushbuf
  369.                 mov al, '2'
  370.                 call pushbuf
  371.                 ret
  372. cout_ps2 endp
  373.  
  374. cout_im1 proc near
  375.                 mov al, 'i'
  376.                 call pushbuf
  377.                 mov al, 'm'
  378.                 call pushbuf
  379.                 mov al, '1'
  380.                 call pushbuf
  381.                 ret
  382. cout_im1 endp
  383.  
  384. cout_im2 proc near
  385.                 mov al, 'i'
  386.                 call pushbuf
  387.                 mov al, 'm'
  388.                 call pushbuf
  389.                 mov al, '2'
  390.                 call pushbuf
  391.                 ret
  392. cout_im2 endp
  393.  
  394. cout_uart proc near                             ;"  uart:"
  395.                 call space
  396.                 call space
  397.                 mov al, 'u'                                    
  398.                 call pushbuf
  399.                 mov al, 'a'                                    
  400.                 call pushbuf
  401.                 mov al, 'r'                                    
  402.                 call pushbuf
  403.                 mov al, 't'                                    
  404.                 call pushbuf
  405.                 mov al, 3Ah
  406.                 call pushbuf
  407.                 ret
  408. cout_uart endp
  409.  
  410. cout_16 proc near                               ;"16"
  411.                 mov al, '1'
  412.                 call pushbuf
  413.                 mov al, '6'
  414.                 call pushbuf
  415.                 ret
  416. cout_16 endp
  417.  
  418. cout_bps proc near
  419.                 mov al, 'b'
  420.                 call pushbuf
  421.                 mov al, '/'
  422.                 call pushbuf
  423.                 mov al, 's'
  424.                 call pushbuf
  425.                 ret
  426. cout_bps endp
  427.  
  428. cout_00 proc near
  429.                 mov al, '0'
  430.                 call pushbuf
  431.                 mov al, '0'
  432.                 call pushbuf
  433.                 ret
  434. cout_00 endp
  435.  
  436. cout_type16750 proc near                ;"16750 "
  437.                 call cout_16
  438.                 mov al, '7'
  439.                 call pushbuf
  440.                 mov al, '5'
  441.                 call pushbuf
  442.                 mov al, '0'
  443.                 call pushbuf
  444.                 call space
  445.                 ret
  446. cout_type16750 endp
  447.  
  448. cout_type16550A proc near               ;"16550A "
  449.                 call cout_16
  450.                 mov al, '5'
  451.                 call pushbuf
  452.                 mov al, '5'
  453.                 call pushbuf
  454.                 mov al, '0'
  455.                 call pushbuf
  456.                 mov al, 'A'
  457.                 call pushbuf
  458.                 call space
  459.                 ret
  460. cout_type16550A endp
  461.  
  462. cout_type16550 proc near                ;"16550 "
  463.                 call cout_16
  464.                 mov al, '5'
  465.                 call pushbuf
  466.                 mov al, '5'
  467.                 call pushbuf
  468.                 mov al, '0'
  469.                 call pushbuf
  470.                 call space
  471.                 ret
  472. cout_type16550 endp
  473.  
  474. cout_type16450 proc near                ;"16450 "
  475.                 call cout_16
  476.                 mov al, '4'
  477.                 call pushbuf
  478.                 mov al, '5'
  479.                 call pushbuf
  480.                 mov al, '0'
  481.                 call pushbuf
  482.                 call space
  483.                 ret
  484. cout_type16450 endp
  485.  
  486. cout_type8250 proc near                 ;"8250 "
  487.                 mov al, '8'
  488.                 call pushbuf
  489.                 mov al, '2'
  490.                 call pushbuf
  491.                 mov al, '5'
  492.                 call pushbuf
  493.                 mov al, '0'
  494.                 call pushbuf
  495.                 call space
  496.                 ret
  497. cout_type8250 endp
  498.  
  499. cout_2400bps proc near                  ;"2400b/s "
  500.                 mov al, '2'
  501.                 call pushbuf
  502.                 mov al, '4'
  503.                 call pushbuf
  504.                 call cout_00
  505.                 call cout_bps
  506.                 call space
  507.                 ret
  508. cout_2400bps endp
  509.  
  510. cout_9600bps proc near                  ;"9600b/s "
  511.                 mov al, '9'
  512.                 call pushbuf
  513.                 mov al, '6'
  514.                 call pushbuf
  515.                 call cout_00
  516.                 call cout_bps
  517.                 call space
  518.                 ret
  519. cout_9600bps endp
  520.  
  521. cout_19200bps proc near                 ;"19200b/s "
  522.                 mov al, '1'
  523.                 call pushbuf
  524.                 mov al, '9'
  525.                 call pushbuf
  526.                 mov al, '2'
  527.                 call pushbuf
  528.                 call cout_00
  529.                 call cout_bps
  530.                 call space
  531.                 ret
  532. cout_19200bps endp
  533.  
  534. cout_115200bps proc near                        ;"115200b/s "
  535.                 mov al, '1'
  536.                 call pushbuf
  537.                 mov al, '1'
  538.                 call pushbuf
  539.                 mov al, '5'
  540.                 call pushbuf
  541.                 mov al, '2'
  542.                 call pushbuf
  543.                 call cout_00
  544.                 call cout_bps
  545.                 call space
  546.                 ret
  547. cout_115200bps endp
  548. ;========================================================================
  549. ;---------------------------------init_IOAPIC---------------------------
  550. ;========================================================================
  551. ;1.IOAPIC обычно отображается на адрес IOAPICBASE 0xFEC00000 (адрес может быть несколько изменен средствами северного моста)
  552. ;2.IOZPIC представлен двумя регистрами: "селектор" (selector) по адресу IOAPICBASE и "окно" (window) по адресу IOAPICBASE+0x10
  553. ;3.При работе с IOAPIC в селектор записывается номер регистра IOAPIC, а из окна производится чтение или запись регистра
  554. ;4.Термин "Reserved", определяющий те или иные биты регистров IOAPIC обозначает не "MBZ", а то, что содержимое этих разрядов нельзя изменять,
  555. ;при необходимости изменить регистр надо сначала прочитать прежнее значение, потом только нужные биты обнулить или установить, а затем записать обратно.
  556. .586p
  557. init_IOAPIC proc near
  558.         push    DS
  559.         push    cx
  560.         smov    DS, DIOAPIC
  561.  
  562. ;0 линия, 10 рег
  563.         mov             dword ptr DS:[0h], 10h     ;номер регистра отвечающего за 0-ю линию -> в адрес селектора (0-я линия - 10,11 рег, 23-я линия - 3E,3F рег)
  564.         mov     eax, dword ptr DS:[10h]            ;работа с регистром в окне
  565.         and     eax, 0FFFE60FFh                    ;Физическая адресация LAPIC, обнуляем Trigger Mode(15), Pin Polarity(13), возбуждение прерывания передним фронтом (состояние 1) (т.к. настройка irq0)
  566.         or              eax, 0700h                 ;Delivery Mod = 111 = ExtInt - Causes the processor to respond the intr as if the intr originated in an externally connected intr controller                                                          
  567.         mov     dword ptr DS:[10h], eax
  568. ;0 линия, 11 рег
  569.         mov     dword ptr DS:[0h], 011h
  570.         mov     eax, dword ptr DS:[10h]
  571.         and     eax, 0FFFFFFh                       ;Обнулить целевой ID лапика приёмника (0-й lapic единственного процессора, который эмулирует бочс)
  572.         mov     dword ptr DS:[10h], eax
  573.  
  574.         mov     ecx, 012h                                                              
  575. loop_masking:
  576.         mov     DS:[0h], ecx                         ;номер очередного регистра в селектор
  577.         mov     eax, dword ptr DS:[10h]
  578.         or              eax, 010000h                 ;16-й бит MASK
  579.         mov     dword ptr DS:[10h], eax
  580.         add     ecx, 2                                                                
  581.         cmp     ecx, 040h                                                              
  582.         jnz     loop_masking
  583.  
  584.         pop     cx                                                            
  585.         pop     DS                                    
  586.         ret
  587. init_IOAPIC endp
  588.  
  589. ;========================================================================
  590. ;---------------------------------init_LAPIC----------------------------
  591. ;========================================================================
  592. init_LAPIC proc near
  593.                 push DS
  594.                 push cx
  595.                 mov     ecx, 01Bh
  596.                 rdmsr
  597.                 or      eax, 0800h
  598.                 wrmsr
  599.                 smov DS, DLAPIC
  600.  
  601.                 ;mov DS:[040h], offset spur_intr        ;обработка фиктивных прерываний
  602.                 ;mov DS:[042h], cs
  603.                 mov dword ptr DS:[0F0h], 0110h          ;apicen = ApicEnabled и бит разрешения -> в дескриптор spurious вектора
  604.                 or dword ptr DS:[350h], 010000h         ;максирование LINT0
  605.                 or dword ptr DS:[360h], 010000h         ;маскирование LINT1
  606.                 ;mov DS:[080h], offset interrupt                              
  607.                 ;mov DS:[082h], cs
  608.                
  609.                 mov     eax, dword ptr DS:[320h]         ;LVT[0] - Timer
  610.                 and     eax, 06F00h
  611.                 or      eax, 020020h                                                  
  612.                 mov dword ptr DS:[320h], eax
  613.                 or dword ptr DS:[3E0h], 0Bh               ;Timer Divide Config: 1011, d0=1, d1=1, d3=1 => делитель частоты = 1
  614.                 ;mov dword ptr DS:[380h], 123B64Fh        ;Timer Initial Count: 1,3 GHz / 68Hz
  615.                 mov dword ptr DS:[380h], 30000000         ;new frequency for interview result showing
  616.                 smov DS, DDATA
  617.                 mov dword ptr DS:[0FCh], 0
  618.  
  619.                 pop cx
  620.                 pop DS
  621.                 ret
  622. init_LAPIC endp
  623.  
  624. spur_intr:  
  625. iret  ;Ends without EndOfInterrupt!
  626.  
  627. I20             equ $-_TEXT32START
  628. i20_localtimer_handler:
  629.                 push DS
  630.                 push ax
  631.                 smov DS, DLAPIC
  632.                 mov dword ptr DS:[0B0h], 0
  633.                 smov ds, DDATA
  634.                 inc dword ptr DS:[0FCh]
  635.                 pop ax
  636.                 pop DS
  637. iretd
  638.  
  639.  
  640. ;========================================================================
  641. ;---------------------------------init_INTERVIEW------------------------
  642. ;========================================================================
  643. rebuf proc near
  644.                 cmp di, EBUF
  645.                 jnz exit
  646.                 mov di, SBUF
  647. exit:   ret
  648. rebuf endp
  649. ;------------------------------------------------------------------------
  650. pushbuf proc near
  651.                 push di
  652.                 push es
  653.                 smov es, DDATA, <_treg equ bx>  ;вполнить смов используя не ax (который по умолчанию, но сейчас занят) , а bx
  654.                 mov di, word ptr es:[EBUFADR]
  655.                 stosb
  656.                 call rebuf
  657.                 cmp di, word ptr es:[SBUFADR]
  658.                 jz exit1
  659.                 mov word ptr es:[EBUFADR], di
  660.         exit1:
  661.                 pop es
  662.                 pop di
  663.                 ret
  664. pushbuf endp
  665. ;-----------------------------------------------------------------------
  666. request proc near
  667.                 mov cx, 0FFF0h
  668. w0:    
  669.                 in al, 064h
  670.                 test 2, al
  671.                 jz w1
  672.                 loop w0
  673.                 ;call stop
  674. w1:
  675.                 move_out dx, bl
  676.                 ret
  677. request endp
  678. ;------------------------------------------------------------------------
  679. respond proc near
  680.                 mov cx, 0FFFFh
  681.                 ;mov ecx, 0FFFFFFh
  682. w2:
  683.                 in al, 064h
  684.                 test 1, al
  685.                 jnz w3
  686.                 dec     ecx
  687.                 jnz w2
  688.                 ;call stop
  689. w3:
  690.                 in al, 060h
  691.                 ret
  692. respond endp
  693. ;------------------------------------------------------------------------
  694.  
  695. init_INTERVIEW proc near
  696.                 push    DS
  697.                 push    ax
  698.                 push    dx            
  699.                 push    cx            
  700.                 push    bx            
  701.                 push    si            
  702.  
  703. ;-----------------K E Y B O A R D - I N T E R V I E W-------------------
  704. ;keyboard_interview:
  705.  
  706.                 call cout_kb
  707.                
  708.                 req_resp 64h, 0AAh, 55h                         ;сброс и автотест 8042
  709.                 req_resp 64h, 0ABh, 0                           ;тест синхронизации с 8031
  710.                 req_resp 64h, 0AEh                                      ;разрешить клавиатуру
  711.                 req_resp 60h, 0FFh, ACK, TESTOK         ;сброс и тест 8031
  712.  
  713. ;http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#keyboardid
  714. ;An XT keyboard does not reply
  715. ;an AT keyboard only replies with an "ACK".
  716. ;An MF2 AT keyboard reports ID "ab 83". Translation turns this into "ab 41".
  717.  
  718.                 req_resp 60h, 0F2h, 0FAh                        ;запрос 2х байтного ID
  719.                 call respond                                            ;got 1st byte, lets check it
  720.  
  721.                 cmp eax, 000200abh                                      ;ab (MF)
  722.                 je      its_mf
  723.                                 cmp eax, 000200fah                              ;fa==ACK (AT)
  724.                                 je      its_at
  725.                                         ;otherwise its XT (if it doesnt reply)
  726.                                         call cout_xt
  727.                                         call respond    ;just in case lets get 2nd byte of id (but we dont really need it)
  728.                                         jmp mouse_i
  729.  
  730.                                 its_at:
  731.                                         call cout_at  
  732.                                         call respond    ;just in case lets get 2nd byte of id (but we dont really need it)
  733.                                         jmp     mouse_i
  734.  
  735.                 its_mf:
  736.                         call cout_mf
  737.                         call respond            ;lets get 2nd byte and check it
  738.  
  739. ;------------------M O U S E - I N T E R V I E W-------------------
  740. mouse_i:
  741.                 mov     al, ';'
  742.                 call pushbuf
  743.  
  744.                 call cout_ms
  745.                
  746.                 req_resp 64h, 0A8h                                              ;разрешить мышь
  747.                 req_resp 64h, 60h                                               ;запись управл. регистра
  748.                 req_resp 60h, 0                                                 ;запрещаем IRQ1, IRQ12  разрешение интерфейсов клав. и мыши
  749.                 req_resp 64h, 0D4h                                              ;передать след. байт мыши
  750.                 req_resp 60h, 0FFh, ACK, TESTOK, 0            
  751.                 req_resp 64h, 0D4h                                              ;передать след. байт мыши
  752.  
  753. ;http://www.win.tue.nl/~aeb/linux/kbd/scancodes-13.html
  754. ;Read mouse ID command is answered by 00.
  755. ;In Intellimouse mode, the Read mouse ID command returns 03.
  756. ;In Intellimouse Explorer mode, the Read mouse ID command returns 04.
  757.  
  758.                 req_resp 60h, 0F2h, 0FAh                                ;получить ID (ответы FA (ack) и 00 (id))
  759.                 call respond
  760.                
  761.                 cmp     al, 0                           ;ps/2 id at initialization = 0
  762.                 je      its_ps2
  763.                                 cmp al, 3                               ;imps id = 3
  764.                                 je      its_imps1
  765.                                                 cmp al, 4                               ;imps2 id = 4
  766.                                                 je      its_imps2
  767.                                                 jmp uart_i
  768.                                                
  769.                                                 its_imps2:
  770.                                                         call cout_im2
  771.                                                         jmp     uart_i
  772.  
  773.                                 its_imps1:
  774.                                         call cout_im1
  775.                                         jmp uart_i
  776.  
  777.                 its_ps2:
  778.                         call cout_ps2
  779.  
  780. ;--------------------U A R T - I N T E R V I E W-------------------
  781. uart_i:
  782.                 mov al, ';'
  783.                 call pushbuf
  784.                 call cout_uart
  785.  
  786. ;Test UART chip type:
  787.  
  788.                 send_com <COM4+FCR>, 0E7h
  789.                 mov             dx, COM4+IIR
  790.                 in              al, dx
  791.                 test    al, 64d                                         ;check 6th bit
  792.                 jz oldtype
  793.                                 test    al, 128d                                ;check 7th bit
  794.                                 jz t16550
  795.                                                 test    al, 32d                         ;check 5th bit
  796.                                                 jz t16550A
  797.                                                                 call cout_type16750
  798.                                                                 jmp     @f
  799.  
  800.                                                 t16550A:
  801.                                                         call cout_type16550A
  802.                                                         jmp @f
  803.                                 t16550:
  804.                                         call cout_type16550
  805.                                         jmp @f
  806.  
  807.         oldtype:                        ;Else we know the chip doesnt use FIFO, so we need to check the scratch register
  808.                 send_com <COM4+SR>, 05Ah                        ;Arbitary value (can be any but not 0xFF or 0x00)
  809.                 mov             dx, COM4+SR
  810.                 in              al, dx
  811.                 cmp             al, 05Ah                        ;If the arbitrary value comes back identical, UART is 16450
  812.                 je t16450
  813.                                 call cout_type8250
  814.                                 jmp @f
  815.                 t16450:
  816.                         call cout_type16450
  817.  
  818. ;Test UART speed:
  819. @@:            
  820.                 send_com <COM4+LCR>, 128d                       ;set DLAB
  821.                 send_com <COM4+DLL>, 12d                        ;check 9600 bps
  822.                 send_com <COM4+DLH>, 0
  823.                 mov             dx, COM4+DLL
  824.                 in              al, dx
  825.                 cmp             al, 12d
  826.                 jne s2400
  827.  
  828.                                 send_com <COM4+DLL>, 6d                 ;check 19200 bps
  829.                                 send_com <COM4+DLH>, 0
  830.                                 in              al, dx
  831.                                 cmp             al, 6d
  832.                                 jne s9600
  833.  
  834.                                                 send_com <COM4+DLL>, 1          ;check 115200 bps (top speed)
  835.                                                 send_com <COM4+DLH>, 0
  836.                                                 in              al, dx
  837.                                                 cmp             al, 1
  838.                                                 jne s19200
  839.  
  840.                                                                 call cout_115200bps
  841.                                                                 jmp @f
  842.  
  843.                                                 s19200:
  844.                                                         call cout_19200bps
  845.                                                         jmp @f
  846.                                 s9600:
  847.                                         call cout_9600bps
  848.                                         jmp @f
  849.                 s2400:
  850.                         call cout_2400bps
  851.  
  852. @@:             send_com <COM4+LCR>, 0
  853.  
  854. ;----------------------------------------------
  855.                 mov si, 10d
  856. @@:             call space                              ;fill free space in buffer with spaces
  857.                 dec si
  858.                 jnz @b
  859.  
  860.                 pop     si
  861.                 pop     bx
  862.                 pop     cx
  863.                 pop     dx
  864.                 pop     ax
  865.                 pop     DS
  866.                 ret
  867. init_INTERVIEW endp
  868.  
  869.  
  870.  
  871. ;========================================================================
  872. ;---------------------------------init_UART-----------------------------
  873. ;========================================================================
  874. ;При настройке UART необходимо задать: размер слова (5..8 бит);
  875. ;                                                                          число т.н. «стоп-битов» (1 или 1.5(2) бита),
  876. ;                                                                          способ задания бита чётности,
  877. ;                                                                          скорость передачи данных (от 50 до 115200 бод).
  878. ComRead proc near
  879.                 xor ax, ax
  880.                 xor bx, bx
  881.                
  882.                 mov dx, COM1 + LSR
  883.                 mov ecx, 0FFFFFFh
  884. w4:    
  885.                 in      al, dx
  886.                 and al, 8Fh            
  887.                 jnz     w5
  888.                 dec ecx
  889.                 jnz w4
  890. w5:
  891.                 and al, 08Eh
  892.                 jnz stop
  893.                 mov dx, COM1 + RBR
  894.                 in al, dx
  895.  
  896.                 move_out 0E9h, al
  897.                 cmp al, 'M'
  898.                 jne skppp
  899.  
  900.                 mov al, '!'
  901.                 move_out 0E9h, al
  902. skppp:
  903.                 ret
  904. ComRead endp
  905. ;------------------------------------------------------------------------
  906. ComWrite        proc near
  907.  
  908.                 mov dx, COM1 + LSR
  909.                 mov cx, 0FFFFh
  910. xxx:    in      al, dx
  911.                 and             al, 0AEh
  912.                 jnz             xxy
  913.                 loop xxx
  914. xxy:
  915.                 and             al, 08Eh
  916.                 jnz             stop
  917.  
  918.                 mov dx, COM1 + THR
  919.                 mov al, 'M'
  920.                 out dx, al
  921.  
  922.             ret
  923. ComWrite endp
  924. ;------------------------------------------------------------------------
  925. sendcomport proc near
  926.                 push            dx
  927.                 add                     bx, cx          ;its implied we have COM address in 'cx' and it's REGISTER in bx(bl)
  928.                 mov                     dx, bx
  929.                 out                     dx, al          ;in 'al' we have value
  930.                 pop                     dx
  931.                 ret
  932. sendcomport endp
  933.  
  934. ;Биты 2 и 1 регистра FCR используются при первоначальной настройке порта,
  935. ;чтобы очистить содержимое FIFO, если туда что-то уже успело попасть;
  936. ;это вполне может случиться, так как включение устройства на другой стороне линии
  937. ;могло выполниться гораздо раньше и оно уже могло пытаться передать какие-либо данные..
  938.  
  939. init_UART proc near
  940.                 push    si
  941.                 push    ax
  942.                 push    bx
  943.                 push    cx
  944.                 push    DS
  945.  
  946.                 xor             si, si
  947.  
  948. ;http://www.sci.muni.cz/docs/pc/serport.txt
  949. unicorns:
  950.                 mov             cl,     byte ptr [COM_TABLE+si]
  951.                 inc             si
  952.                 mov             ch, byte ptr [COM_TABLE+si]
  953.                 inc             si
  954.                 push    si
  955.  
  956.                 xor             si, si
  957.  
  958.                 comloop:
  959.                                         mov             al, [COM_INIT+si]
  960.                                         inc             si
  961.                                         cmp             al, 0FEh
  962.                                         jz              endcom
  963.  
  964.                                         mov             bl, [COM_INIT+si]                      
  965.                                         inc             si
  966.                                         call    sendcomport
  967.                                         jmp             comloop
  968.                 endcom:
  969.  
  970.                 pop             si
  971.                 cmp             si, 8
  972.                 jnz unicorns
  973.        
  974.                 send_com <COM1+MCR>, 3                  ;set 0,1 bits of MCR (DTR, RTS)
  975.                 send_com <COM2+MCR>, 3                  ;set 0,1 bits of MCR (DTR, RTS)
  976.                 send_com <COM3+MCR>, 3                  ;set 0,1 bits of MCR (DTR, RTS)
  977.                 send_com <COM4+MCR>, 3                  ;set 0,1 bits of MCR (DTR, RTS)
  978.  
  979.                 ;call ComRead
  980.  
  981.                 pop             DS
  982.                 pop             cx
  983.                 pop             bx
  984.                 pop             ax
  985.                 pop             si
  986.                 ret
  987. init_UART endp
  988.  
  989.  
  990. ;========================================================================
  991. ;---------------------------------FINAL_CYCLE--------------------------- by IVAN, (c)
  992. ;========================================================================
  993. FINAL_CYCLE proc near
  994.                 push ax
  995.                 push edi
  996.                 push es
  997.  
  998.                 smov            ds, DDATA
  999.                 mov                     word ptr DS:[SBUFADR], SBUF             ;start buffer
  1000.                 mov                     word ptr DS:[EBUFADR], SBUF
  1001.                
  1002. inf_cycle:
  1003.                 mov                     dword ptr ds:[0FCh], 0
  1004.                 ;               xchg bx, bx
  1005.                 call            init_INTERVIEW
  1006.                 ;               xchg bx, bx
  1007. aw0:
  1008.                
  1009.                 cmp                     dword ptr ds:[0FCh], 0          ;connect interviews with timer's freq
  1010.                 jz              aw0
  1011.  
  1012.                 mov                     di, ds:[SBUFADR]      
  1013. aw1:
  1014.                 cmp                     di, word ptr ds:[EBUFADR]               ;check if need to restart buffer
  1015.                 jnz             aw2
  1016.  
  1017.                 move_out        0E9h, 10                                                ;\n
  1018.                 move_out        0E9h, 13
  1019.                 jz              inf_cycle
  1020. aw2:
  1021.                 mov                     al, ds:[di]
  1022.                 inc                     di
  1023.                 call            rebuf
  1024.                 mov                     word ptr ds:[SBUFADR], di
  1025.                 move_out        0E9h, al
  1026.                 jmp             aw1                                                                     ;come back with renewed buffer
  1027.  
  1028.                 ret
  1029. FINAL_CYCLE endp
  1030.  
  1031.  
  1032. ;========================================================================
  1033. ;---------------------------------stop----------------------------------
  1034. ;========================================================================
  1035. stop    proc near
  1036.         cli
  1037.         hlt
  1038.         jmp     short stop
  1039. stop    endp
  1040.  
  1041. end32   equ     $-_TEXT32START
  1042. _TEXT32 ends
  1043.  
  1044.  
  1045.  
  1046. ;----------------------------------------------------------------------
  1047.  
  1048.  
  1049. ;----------------------------------------------------------------------
  1050. ;чтобы было понятно что все начинается именно здесь а !не! на верху в старте32
  1051.  
  1052. ;__$$$$____$$__$$__$$$$$__$$$$$__$$_____$$_$$____$$_
  1053. ;_$$_______$$__$$_$$___$$_$$___$_$$_____$$_$$$__$$$_
  1054. ;_$$_______$$$$$$_$$___$$_$$$$$__$$$$$__$$_$$_$$_$$_
  1055. ;_$$_______$$__$$_$$___$$_$$___$_$$___$_$$_$$____$$_
  1056. ;__$$$$____$$__$$__$$$$$__$$$$$__$$$$$__$$_$$____$$_
  1057. ;___________________________________________________
  1058. ;__$$$$$$___$$$$$_____$$$$$$_____$$$$$____$$____$$__
  1059. ;__$$______$$___$$____$$__$$____$$___$$___$$$__$$$__
  1060. ;__$$______$$___$$____$$__$$____$$___$$___$$_$$_$$__
  1061. ;__$$______$$___$$____$$__$$____$$___$$___$$____$$__
  1062. ;__$$_______$$$$$_____$$$$$$_____$$$$$____$$____$$__
  1063. ;___________________$$______$$______________________
  1064.  
  1065.  
  1066.  
  1067.  
  1068. _TEXT   segment byte public 'CODE' use16
  1069. assume cs:_TEXT, ds:nothing
  1070. _TEXTSTART = $
  1071. start:
  1072.         cli
  1073.         lss     SP, dword ptr STKPTR
  1074.         sti
  1075.         call init_BIOS
  1076.  
  1077.         jmp protected_mode_on
  1078.  
  1079.  
  1080. ;========================================================================
  1081. ;------------------------------init_BIOS--------------------------------
  1082. ;========================================================================
  1083.  
  1084. STKPTR      dw      0FFFEh, 09000h
  1085. init_BIOS:      mov     dx, 0C000h 
  1086. cycle:      mov     DS, dx
  1087.         mov     ax, 80h        
  1088.         cmp     word ptr DS:[0], 0AA55h
  1089.         jnz     nxt
  1090.         call scanbios
  1091.  
  1092.         movzx   ax, byte ptr DS:[2]
  1093.         add     al, 3h     
  1094.         and     al, 0FCh
  1095.         shl     ax, 5  
  1096.  
  1097. nxt:        add     dx, ax         
  1098.         cmp     dx, 0F000h         
  1099.         jb      cycle      
  1100.         ret
  1101.  
  1102. scanbios proc near
  1103.         cld
  1104.         xor     si, si
  1105.         xor     cx, cx
  1106.         mov     ch, DS:[2]     
  1107.         xor     bl, bl
  1108. chcksm: lodsw  
  1109.         add     al, ah         
  1110.         add     bl, al         
  1111.         dec     cx
  1112.         jnz     short chcksm
  1113.         or      bl, bl 
  1114.         jnz     short skip     
  1115.         pusha
  1116.         push    ds
  1117.         push    es
  1118.         push    fs
  1119.         push    gs
  1120.         push    CS
  1121.         push    offset __ret
  1122.         push    DS
  1123.         push    3h
  1124.         retf
  1125. __ret:
  1126.         pop     gs
  1127.         pop     fs
  1128.         pop     es
  1129.         pop     ds
  1130.         popa
  1131. skip:   ret     0
  1132. scanbios endp
  1133.  
  1134.  
  1135. ;========================================================================
  1136. ;-----------------------------DESCRIPTORS-------------------------------
  1137. ;========================================================================
  1138. ;
  1139. ; Usage:
  1140. ;   .descriptor                             # all zeroes descriptor, must be #0 in table
  1141. ;   .descriptor limit=0x12345678, base=0x9ABCDEF0, r=1, p=1, dpl=0  # flag 'r' used, 'w' is'nt used => code segment
  1142. ;   .descriptor limit=0x12345678, base=0x9ABCDEF0, w=1, p=1, dpl=0  # flag 'r' is'nt used, 'w' is used => data segment
  1143. ;
  1144. ; g - granularity (0 or 1), set to 1 automatically, when limit > 0x100000; elsewhere g defines bytes/pages for limit field
  1145. ; x - default operation size (0 or 1); means 32-bit instructions for code segment
  1146.                                                         ;or 32-bit pointers for stack segment
  1147.                                                         ;or 2^16 vs 2^32 limit for expand down segments
  1148. ; l - 64-bit long mode segment
  1149. ; p - presence in memory (0 or 1)
  1150. ; dpl - DPL
  1151. ; a - accessed (0 or 1)
  1152. ; only for code segments:
  1153. ;  r - execute only or execute/read (0 or 1) NOTE: r=0 or r=1 assumes code segment
  1154. ;  c - (only for code segment, 0 or 1) conforming segment
  1155. ; only for data segments:
  1156. ;  w - read only or read/write (0 or 1) NOTE: w=0 or w=1 assumes data segment
  1157. ;  ed - (only for data segment, 0 or 1) expand down segment
  1158. ; type - 1,3,9,11 or 2 can be used only (TSSes, LDT)
  1159. ;  type, r and w bits are mutually defined
  1160.  
  1161. GDT:
  1162.         dd 0, 0
  1163.         descriptor _limit=0Fh, _base=0F0000h, _g=1, _x=1, _d_c=1    ;32х разрядный сегмент кода
  1164.         descriptor _limit=100h, _base=400h, _g=0                    ;16х данные BIOS (BDA)
  1165.         descriptor _limit=0FFFFh, _base=90000h, _g=0                ;32х разрядный стек
  1166.         descriptor _base=1400000h, _g=1, _x=1
  1167.         descriptor _base=1600000h, _g=1, _x=1
  1168.         descriptor _base=0h, _limit=0Fh, _g=1
  1169. GDT_SIZE equ $-GDT
  1170. GDTR:   dw GDT_SIZE-1
  1171.     dd STARTGDT SHL 4
  1172.          
  1173. ;----------------------------------------------------------------------
  1174. IDT:
  1175.         intdescriptor _offset=I20, _selector=8, _use32=1
  1176. IDT_SIZE equ $-IDT+256
  1177. IDTR:   dw IDT_SIZE-1
  1178.     dd STARTIDT SHL 4
  1179.  
  1180.  
  1181. ;========================================================================
  1182. ;--------------------------PROTECTED-MODE-ON----------------------------
  1183. ;========================================================================
  1184. protected_mode_on:
  1185.         call open_A20           ;Для обращенний за пределы первого мегабайта надо включить режим «Линия А20 разрешена»
  1186.         call copy_gdt
  1187.         call copy_idt
  1188.         call restrict_NMI
  1189.        
  1190.         mov eax, cr0            ;Очищаем бит PE в CR0 (выключаем сегментацию)
  1191.         or  eax, 1
  1192.         mov cr0, eax
  1193.  
  1194.         db 0EAh
  1195.         dw offset start32, 8
  1196.  
  1197. ;----------------------------------------------------------------------
  1198. copy_gdt:
  1199.         smov ds, cs
  1200.         mov si, offset GDT
  1201.         smov es, STARTGDT
  1202.         xor di, di
  1203.         mov cx, GDT_SIZE/4
  1204.         cld
  1205.         rep movsd
  1206.         lgdt fword ptr GDTR
  1207.         ret
  1208.  
  1209. ;----------------------------------------------------------------------
  1210. copy_idt:
  1211.         mov si, offset IDT
  1212.         smov es, STARTIDT
  1213.         mov di, 256         ;пропускаем 21 интеррапт и копируем только интеррапт таймера лапика
  1214.         mov cx, IDT_SIZE/4  ;cx=2
  1215.         cld
  1216.         rep movsd
  1217.         lidt fword ptr IDTR
  1218.         ret
  1219.  
  1220. ;----------------------------------------------------------------------
  1221. restrict_NMI:
  1222.         cli
  1223.         in al, 70h
  1224.         or al, 80h
  1225.         out 70h, al
  1226.         ret
  1227.  
  1228. ;----------------------------------------------------------------------
  1229. open_A20:
  1230.         in al, 92h
  1231.         or al, 2
  1232.         out 92h, al
  1233.         ret
  1234.  
  1235.  
  1236.  
  1237. ;------------------------------------------------------------------------
  1238. org 0FFF0h-end32
  1239.     db  0EAh                ; JMP FAR
  1240.     dw  offset start            ; offset
  1241.     dw  0F000h+(end32 SHR 4)        ; segment
  1242.  
  1243. org 0FFFEh-end32
  1244.     dw  99FCh               ; PC
  1245.  
  1246. _TEXT   ends
  1247. end     start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement