Ladies_Man

#NUP lab2 (protected mode)

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