Subversion Repositories Kolibri OS

Rev

Rev 1275 | Rev 1292 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 1289 $
  9.  
  10.  
  11. DRV_COMPAT   equ  5  ;minimal required drivers version
  12. DRV_CURRENT  equ  5  ;current drivers model version
  13.  
  14. DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
  15. PID_KERNEL  equ 1    ;os_idle thread
  16.  
  17. align 4
  18. proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword
  19.  
  20.          push ebx
  21.  
  22.          mov  ebx, [irq]                   ;irq num
  23.          test ebx, ebx
  24.          jz   .err
  25.          cmp  ebx, 15                      ; hidnplayr says: we only have 16 IRQ's
  26.          ja   .err
  27.          mov  eax, [handler]
  28.          test eax, eax
  29.          jz   .err
  30.          cmp  [irq_owner + 4 * ebx], 0
  31.          je   @f
  32.  
  33.          mov  ecx, [irq_rights + 4 * ebx]  ; Rights : 0 - full access, 1 - read only, 2 - forbidden
  34.          test ecx, ecx
  35.          jnz  .err
  36.  
  37. @@:
  38.          mov  [irq_tab+ebx*4], eax
  39.  
  40.          mov  eax, [access_rights]
  41.          mov  [irq_rights + 4 * ebx], eax
  42.  
  43.          mov  [irq_owner + 4 * ebx], PID_KERNEL  ; all handlers belong to a kernel
  44.  
  45.          stdcall enable_irq, [irq]
  46.          pop ebx
  47.          mov eax, 1
  48.          ret
  49. .err:
  50.          pop ebx
  51.          xor eax, eax
  52.          ret
  53. endp
  54.  
  55. uglobal
  56.  
  57.         irq_rights       rd      16
  58.  
  59. endg
  60.  
  61. proc get_int_handler stdcall, irq:dword
  62.  
  63.         mov     eax, [irq]
  64.  
  65.         cmp     [irq_rights + 4 * eax], dword 1
  66.         ja      .err
  67.  
  68.         mov     eax, [irq_tab + 4 * eax]
  69.         ret
  70.  
  71.      .err:
  72.         xor     eax, eax
  73.         ret
  74.  
  75. endp
  76.  
  77. align 4
  78. proc  detach_int_handler
  79.  
  80.            ret
  81. endp
  82.  
  83. align 4
  84. proc enable_irq stdcall, irq_line:dword
  85.            mov ebx, [irq_line]
  86.            mov edx, 0x21
  87.            cmp ebx, 8
  88.            jb @F
  89.            mov edx, 0xA1
  90.            sub ebx,8
  91. @@:
  92.            in al,dx
  93.            btr eax, ebx
  94.            out dx, al
  95.            ret
  96. endp
  97.  
  98. align 16
  99. ;; proc irq_serv
  100.  
  101. irq_serv:
  102.  
  103. .irq_1:
  104.            push 1
  105.            jmp .main
  106. align 4
  107. .irq_2:
  108.            push 2
  109.            jmp .main
  110. align 4
  111. .irq_3:
  112.            push 3
  113.            jmp .main
  114. align 4
  115. .irq_4:
  116.            push 4
  117.            jmp .main
  118. align 4
  119. .irq_5:
  120.            push 5
  121.            jmp .main
  122. ; align 4
  123. ; .irq_6:
  124. ;          push 6
  125. ;          jmp .main
  126. align 4
  127. .irq_7:
  128.            push 7
  129.            jmp .main
  130. align 4
  131. .irq_8:
  132.            push 8
  133.            jmp .main
  134. align 4
  135. .irq_9:
  136.            push 9
  137.            jmp .main
  138. align 4
  139. .irq_10:
  140.            push 10
  141.            jmp .main
  142. align 4
  143. .irq_11:
  144.            push 11
  145.            jmp .main
  146. align 4
  147. .irq_12:
  148.            push 12
  149.            jmp .main
  150. ; align 4
  151. ; .irq_13:
  152. ;          push 13
  153. ;          jmp .main
  154. ; align 4
  155. ; .irq_14:
  156. ;          push 14
  157. ;          jmp .main
  158. ; align 4
  159. ; .irq_15:
  160. ;          push 15
  161. ;          jmp .main
  162.  
  163. align 16
  164. .main:
  165.            save_ring3_context
  166.            mov   eax, [esp + 32]
  167.            mov   bx, app_data  ;os_data
  168.            mov   ds, bx
  169.            mov   es, bx
  170.  
  171.            cmp   [v86_irqhooks+eax*8], 0
  172.            jnz   v86_irq
  173.  
  174.            mov ebx, [irq_tab+eax*4]
  175.            test ebx, ebx
  176.            jz .exit
  177.  
  178.            call ebx
  179.            mov  [check_idle_semaphore],5
  180.  
  181. .exit:
  182.  
  183.            cmp dword [esp + 32], 8
  184.            mov al, 0x20
  185.            jb @f
  186.            out 0xa0, al
  187. @@:
  188.            out 0x20, al
  189.  
  190.            restore_ring3_context
  191.            add   esp, 4
  192.  
  193.            iret
  194.  
  195. align 4
  196. proc get_notify stdcall, p_ev:dword
  197.  
  198. .wait:
  199.            mov ebx,[current_slot]
  200.            test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
  201.            jz @f
  202.            and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
  203.            mov edi, [p_ev]
  204.            mov dword [edi], EV_INTR
  205.            mov eax, [ebx+APPDATA.event]
  206.            mov dword [edi+4], eax
  207.            ret
  208. @@:
  209.            call change_task
  210.            jmp .wait
  211. endp
  212.  
  213. align 4
  214. proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
  215.            push ebx
  216.            xor eax, eax
  217.            xor ebx, ebx
  218.            mov ah, byte [bus]
  219.            mov al, 6
  220.            mov bh, byte [devfn]
  221.            mov bl, byte [reg]
  222.            call pci_read_reg
  223.            pop ebx
  224.            ret
  225. endp
  226.  
  227. align 4
  228. proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
  229.            push ebx
  230.            xor eax, eax
  231.            xor ebx, ebx
  232.            mov ah, byte [bus]
  233.            mov al, 5
  234.            mov bh, byte [devfn]
  235.            mov bl, byte [reg]
  236.            call pci_read_reg
  237.            pop ebx
  238.            ret
  239. endp
  240.  
  241. align 4
  242. proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
  243.            push ebx
  244.            xor eax, eax
  245.            xor ebx, ebx
  246.            mov ah, byte [bus]
  247.            mov al, 4
  248.            mov bh, byte [devfn]
  249.            mov bl, byte [reg]
  250.            call pci_read_reg
  251.            pop ebx
  252.            ret
  253. endp
  254.  
  255. align 4
  256. proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  257.            push ebx
  258.            xor eax, eax
  259.            xor ebx, ebx
  260.            mov ah, byte [bus]
  261.            mov al, 8
  262.            mov bh, byte [devfn]
  263.            mov bl, byte [reg]
  264.            mov ecx, [val]
  265.            call pci_write_reg
  266.            pop ebx
  267.            ret
  268. endp
  269.  
  270. align 4
  271. proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  272.            push ebx
  273.            xor eax, eax
  274.            xor ebx, ebx
  275.            mov ah, byte [bus]
  276.            mov al, 9
  277.            mov bh, byte [devfn]
  278.            mov bl, byte [reg]
  279.            mov ecx, [val]
  280.            call pci_write_reg
  281.            pop ebx
  282.            ret
  283. endp
  284.  
  285. align 4
  286. proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  287.            push ebx
  288.            xor eax, eax
  289.            xor ebx, ebx
  290.            mov ah, byte [bus]
  291.            mov al, 10
  292.            mov bh, byte [devfn]
  293.            mov bl, byte [reg]
  294.            mov ecx, [val]
  295.            call pci_write_reg
  296.            pop ebx
  297.            ret
  298. endp
  299.  
  300. handle     equ  IOCTL.handle
  301. io_code    equ  IOCTL.io_code
  302. input      equ  IOCTL.input
  303. inp_size   equ  IOCTL.inp_size
  304. output     equ  IOCTL.output
  305. out_size   equ  IOCTL.out_size
  306.  
  307.  
  308. align 4
  309. proc srv_handler stdcall, ioctl:dword
  310.            mov esi, [ioctl]
  311.            test esi, esi
  312.            jz .err
  313.  
  314.            mov edi, [esi+handle]
  315.            cmp [edi+SRV.magic], ' SRV'
  316.            jne .fail
  317.  
  318.        cmp [edi+SRV.size], SRV.sizeof
  319.            jne .fail
  320.  
  321.            stdcall [edi+SRV.srv_proc], esi
  322.            ret
  323. .fail:
  324.            xor eax, eax
  325.            not eax
  326.            mov [esi+output], eax
  327.            mov [esi+out_size], 4
  328.            ret
  329. .err:
  330.            xor eax, eax
  331.            not eax
  332.            ret
  333. endp
  334.  
  335. ; param
  336. ;  ebx= io_control
  337. ;
  338. ; retval
  339. ;  eax= error code
  340.  
  341. align 4
  342. srv_handlerEx:
  343.            cmp ebx, OS_BASE
  344.            jae .fail
  345.  
  346.            mov eax, [ebx+handle]
  347.            cmp [eax+SRV.magic], ' SRV'
  348.            jne .fail
  349.  
  350.        cmp [eax+SRV.size], SRV.sizeof
  351.            jne .fail
  352.  
  353.            stdcall [eax+SRV.srv_proc], ebx
  354.            ret
  355. .fail:
  356.            or eax, -1
  357.            ret
  358.  
  359. restore  handle
  360. restore  io_code
  361. restore  input
  362. restore  inp_size
  363. restore  output
  364. restore  out_size
  365.  
  366. align 4
  367. proc get_service stdcall, sz_name:dword
  368.            mov eax, [sz_name]
  369.            test eax, eax
  370.            jnz @F
  371.            ret
  372. @@:
  373.            mov edx, [srv.fd]
  374. @@:
  375.            cmp edx, srv.fd-SRV_FD_OFFSET
  376.            je .not_load
  377.  
  378.            stdcall strncmp, edx, [sz_name], 16
  379.            test eax, eax
  380.            je .ok
  381.  
  382.            mov edx, [edx+SRV.fd]
  383.            jmp @B
  384. .not_load:
  385.            pop ebp
  386.            jmp load_driver
  387. .ok:
  388.            mov eax, edx
  389.            ret
  390. endp
  391.  
  392. align 4
  393. proc reg_service stdcall, name:dword, handler:dword
  394.  
  395.            push ebx
  396.  
  397.            xor eax, eax
  398.  
  399.            cmp [name], eax
  400.            je .fail
  401.  
  402.            cmp [handler], eax
  403.            je .fail
  404.  
  405.        mov eax, SRV.sizeof
  406.        call malloc
  407.            test eax, eax
  408.            jz .fail
  409.  
  410.            push esi
  411.            push edi
  412.            mov edi, eax
  413.            mov esi, [name]
  414.        movsd
  415.        movsd
  416.        movsd
  417.        movsd
  418.            pop edi
  419.            pop esi
  420.  
  421.            mov [eax+SRV.magic], ' SRV'
  422.        mov [eax+SRV.size], SRV.sizeof
  423.  
  424.            mov ebx, srv.fd-SRV_FD_OFFSET
  425.            mov edx, [ebx+SRV.fd]
  426.            mov [eax+SRV.fd], edx
  427.            mov [eax+SRV.bk], ebx
  428.            mov [ebx+SRV.fd], eax
  429.            mov [edx+SRV.bk], eax
  430.  
  431.            mov ecx, [handler]
  432.            mov [eax+SRV.srv_proc], ecx
  433.            pop ebx
  434.            ret
  435. .fail:
  436.            xor eax, eax
  437.            pop ebx
  438.            ret
  439. endp
  440.  
  441. align 4
  442. proc get_proc stdcall, exp:dword, sz_name:dword
  443.  
  444.            mov edx, [exp]
  445. .next:
  446.            mov eax, [edx]
  447.            test eax, eax
  448.            jz .end
  449.  
  450.            push edx
  451.            stdcall strncmp, eax, [sz_name], 16
  452.            pop edx
  453.            test eax, eax
  454.            jz .ok
  455.  
  456.            add edx,8
  457.            jmp .next
  458. .ok:
  459.            mov eax, [edx+4]
  460. .end:
  461.            ret
  462. endp
  463.  
  464. align 4
  465. proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
  466.  
  467. @@:
  468.            stdcall strncmp, [pSym], [sz_sym], 8
  469.            test eax,eax
  470.            jz .ok
  471.            add [pSym], 18
  472.            dec [count]
  473.            jnz @b
  474.            xor eax, eax
  475.            ret
  476. .ok:
  477.            mov eax, [pSym]
  478.            mov eax, [eax+8]
  479.            ret
  480. endp
  481.  
  482. align 4
  483. proc get_curr_task
  484.            mov eax,[CURRENT_TASK]
  485.            shl eax, 8
  486.            ret
  487. endp
  488.  
  489. align 4
  490. proc get_fileinfo stdcall, file_name:dword, info:dword
  491.            locals
  492.              cmd     dd ?
  493.              offset  dd ?
  494.                      dd ?
  495.              count   dd ?
  496.              buff    dd ?
  497.                      db ?
  498.              name    dd ?
  499.            endl
  500.  
  501.            xor eax, eax
  502.            mov ebx, [file_name]
  503.            mov ecx, [info]
  504.  
  505.            mov [cmd], 5
  506.            mov [offset], eax
  507.            mov [offset+4], eax
  508.            mov [count], eax
  509.            mov [buff], ecx
  510.            mov byte [buff+4], al
  511.            mov [name], ebx
  512.  
  513.            mov eax, 70
  514.            lea ebx, [cmd]
  515.            int 0x40
  516.            ret
  517. endp
  518.  
  519. align 4
  520. proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
  521.                                      bytes:dword
  522.            locals
  523.              cmd     dd ?
  524.              offset  dd ?
  525.                      dd ?
  526.              count   dd ?
  527.              buff    dd ?
  528.                      db ?
  529.              name    dd ?
  530.            endl
  531.  
  532.            xor eax, eax
  533.            mov ebx, [file_name]
  534.            mov ecx, [off]
  535.            mov edx, [bytes]
  536.            mov esi, [buffer]
  537.  
  538.            mov [cmd], eax
  539.            mov [offset], ecx
  540.            mov [offset+4], eax
  541.            mov [count], edx
  542.            mov [buff], esi
  543.            mov byte [buff+4], al
  544.            mov [name], ebx
  545.  
  546.            pushad
  547.            push eax
  548.            lea eax, [cmd]
  549.            call file_system_lfn
  550.            pop eax
  551.            popad
  552.            ret
  553. endp
  554.  
  555. ; description
  556. ;  allocate kernel memory and loads the specified file
  557. ;
  558. ; param
  559. ;  file_name= full path to file
  560. ;
  561. ; retval
  562. ;  eax= file image in kernel memory
  563. ;  ebx= size of file
  564. ;
  565. ; warging
  566. ;  You mast call kernel_free() to delete each file
  567. ;  loaded by the load_file() function
  568.  
  569. align 4
  570. proc load_file stdcall, file_name:dword
  571.            locals
  572.              attr       dd ?
  573.              flags      dd ?
  574.              cr_time    dd ?
  575.              cr_date    dd ?
  576.              acc_time   dd ?
  577.              acc_date   dd ?
  578.              mod_time   dd ?
  579.              mod_date   dd ?
  580.              file_size  dd ?
  581.  
  582.              file       dd ?
  583.              file2      dd ?
  584.            endl
  585.  
  586.            push esi
  587.            push edi
  588.  
  589.            lea eax, [attr]
  590.            stdcall get_fileinfo, [file_name], eax
  591.            test eax, eax
  592.            jnz .fail
  593.  
  594.            mov eax, [file_size]
  595.            cmp eax, 1024*1024*16
  596.            ja .fail
  597.  
  598.            stdcall kernel_alloc, [file_size]
  599.            mov [file], eax
  600.  
  601.            stdcall read_file, [file_name], eax, dword 0, [file_size]
  602.            cmp ebx, [file_size]
  603.            jne .cleanup
  604.  
  605.            mov eax, [file]
  606.            cmp dword [eax], 0x4B43504B
  607.            jne .exit
  608.            mov ebx, [eax+4]
  609.            mov [file_size], ebx
  610.            stdcall kernel_alloc, ebx
  611.  
  612.            test eax, eax
  613.            jz .cleanup
  614.  
  615.            mov [file2], eax
  616.        pushfd
  617.        cli
  618.            stdcall unpack, [file], eax
  619.        popfd
  620.            stdcall kernel_free, [file]
  621.            mov eax, [file2]
  622.            mov ebx, [file_size]
  623. .exit:
  624.            push eax
  625.            lea edi, [eax+ebx]     ;cleanup remain space
  626.            mov ecx, 4096          ;from file end
  627.            and ebx, 4095
  628.            jz  @f
  629.            sub ecx, ebx
  630.            xor eax, eax
  631.            cld
  632.            rep stosb
  633. @@:
  634.            mov ebx, [file_size]
  635.            pop eax
  636.            pop edi
  637.            pop esi
  638.            ret
  639. .cleanup:
  640.            stdcall kernel_free, [file]
  641. .fail:
  642.            xor eax, eax
  643.            xor ebx, ebx
  644.            pop edi
  645.            pop esi
  646.            ret
  647. endp
  648.  
  649. align 4
  650. proc get_proc_ex stdcall, proc_name:dword, imports:dword
  651.  
  652. .look_up:
  653.            mov edx, [imports]
  654.            test edx, edx
  655.            jz .end
  656.            mov edx, [edx]
  657.            test edx, edx
  658.            jz .end
  659. .next:
  660.            mov eax, [edx]
  661.            test eax, eax
  662.            jz .next_table
  663.  
  664.            push edx
  665.        stdcall strncmp, eax, [proc_name], 256
  666.            pop edx
  667.            test eax, eax
  668.            jz .ok
  669.  
  670.            add edx,8
  671.            jmp .next
  672. .next_table:
  673.            add [imports], 4
  674.            jmp .look_up
  675. .ok:
  676.            mov eax, [edx+4]
  677.            ret
  678. .end:
  679.            xor eax, eax
  680.            ret
  681. endp
  682.  
  683. align 4
  684. proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
  685.                       sym_count:dword, strings:dword, imports:dword
  686.            locals
  687.              retval dd ?
  688.            endl
  689.  
  690.            mov edi, [symbols]
  691.            mov [retval], 1
  692. .fix:
  693.            movzx ebx, [edi+CSYM.SectionNumber]
  694.            test ebx, ebx
  695.            jnz .internal
  696.            mov eax, dword [edi+CSYM.Name]
  697.            test eax, eax
  698.            jnz @F
  699.  
  700.            mov edi, [edi+4]
  701.            add edi, [strings]
  702. @@:
  703.            push edi
  704.            stdcall get_proc_ex, edi,[imports]
  705.            pop edi
  706.  
  707.            xor ebx, ebx
  708.            test eax, eax
  709.            jnz @F
  710.  
  711.            mov esi, msg_unresolved
  712.            call sys_msg_board_str
  713.            mov esi, edi
  714.            call sys_msg_board_str
  715.            mov esi, msg_CR
  716.            call sys_msg_board_str
  717.  
  718.            mov [retval],0
  719. @@:
  720.            mov edi, [symbols]
  721.            mov [edi+CSYM.Value], eax
  722.            jmp .next
  723. .internal:
  724.            cmp bx, -1
  725.            je .next
  726.            cmp bx, -2
  727.            je .next
  728.  
  729.            dec ebx
  730.            shl ebx, 3
  731.            lea ebx, [ebx+ebx*4]
  732.            add ebx, [sec]
  733.  
  734.            mov eax, [ebx+CFS.VirtualAddress]
  735.            add [edi+CSYM.Value], eax
  736. .next:
  737.            add edi, CSYM_SIZE
  738.            mov [symbols], edi
  739.            dec [sym_count]
  740.            jnz .fix
  741.            mov eax, [retval]
  742.            ret
  743. endp
  744.  
  745. align 4
  746. proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
  747.         delta:dword
  748.            locals
  749.              n_sec     dd ?
  750.            endl
  751.  
  752.            mov eax, [coff]
  753.            movzx ebx, [eax+CFH.nSections]
  754.            mov [n_sec], ebx
  755.            lea esi, [eax+20]
  756. .fix_sec:
  757.            mov edi, [esi+CFS.PtrReloc]
  758.            add edi, [coff]
  759.  
  760.            movzx ecx, [esi+CFS.NumReloc]
  761.            test ecx, ecx
  762.            jz .next
  763. .reloc_loop:
  764.            mov ebx, [edi+CRELOC.SymIndex]
  765.            add ebx,ebx
  766.            lea ebx,[ebx+ebx*8]
  767.            add ebx, [sym]
  768.  
  769.            mov edx, [ebx+CSYM.Value]
  770.  
  771.            cmp [edi+CRELOC.Type], 6
  772.            je .dir_32
  773.  
  774.            cmp [edi+CRELOC.Type], 20
  775.            jne .next_reloc
  776. .rel_32:
  777.            mov eax, [edi+CRELOC.VirtualAddress]
  778.            add eax, [esi+CFS.VirtualAddress]
  779.            sub edx, eax
  780.            sub edx, 4
  781.            jmp .fix
  782. .dir_32:
  783.            mov eax, [edi+CRELOC.VirtualAddress]
  784.            add eax, [esi+CFS.VirtualAddress]
  785. .fix:
  786.            add eax, [delta]
  787.            add [eax], edx
  788. .next_reloc:
  789.            add edi, 10
  790.            dec ecx
  791.            jnz .reloc_loop
  792. .next:
  793.            add esi, COFF_SECTION_SIZE
  794.            dec [n_sec]
  795.            jnz .fix_sec
  796. .exit:
  797.            ret
  798. endp
  799.  
  800. proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
  801.         delta:dword
  802.            locals
  803.              n_sec     dd ?
  804.            endl
  805.  
  806.            mov eax, [coff]
  807.            movzx ebx, [eax+CFH.nSections]
  808.            mov [n_sec], ebx
  809.            lea esi, [eax+20]
  810.            mov edx, [delta]
  811. .fix_sec:
  812.            mov edi, [esi+CFS.PtrReloc]
  813.            add edi, [coff]
  814.  
  815.            movzx ecx, [esi+CFS.NumReloc]
  816.            test ecx, ecx
  817.            jz .next
  818. .reloc_loop:
  819.            cmp [edi+CRELOC.Type], 6
  820.            jne .next_reloc
  821. .dir_32:
  822.            mov eax, [edi+CRELOC.VirtualAddress]
  823.            add eax, [esi+CFS.VirtualAddress]
  824.            add [eax+edx], edx
  825. .next_reloc:
  826.            add edi, 10
  827.            dec ecx
  828.            jnz .reloc_loop
  829. .next:
  830.            add esi, COFF_SECTION_SIZE
  831.            dec [n_sec]
  832.            jnz .fix_sec
  833. .exit:
  834.            ret
  835. endp
  836.  
  837. align 4
  838. proc load_driver stdcall, driver_name:dword
  839.            locals
  840.              coff      dd ?
  841.              sym       dd ?
  842.              strings   dd ?
  843.              img_size  dd ?
  844.              img_base  dd ?
  845.              start     dd ?
  846.  
  847.              exports   dd ?   ;fake exports table
  848.                        dd ?
  849.              file_name rb 13+16+4+1      ; '/sys/drivers/<up-to-16-chars>.obj'
  850.            endl
  851.  
  852.            lea     edx, [file_name]
  853.            mov     dword [edx], '/sys'
  854.            mov     dword [edx+4], '/dri'
  855.            mov     dword [edx+8], 'vers'
  856.            mov     byte [edx+12], '/'
  857.            mov     esi, [driver_name]
  858. .redo:
  859.            lea     edx, [file_name]
  860.            lea     edi, [edx+13]
  861.            mov     ecx, 16
  862. @@:
  863.            lodsb
  864.            test    al, al
  865.            jz      @f
  866.            stosb
  867.            loop    @b
  868. @@:
  869.            mov     dword [edi], '.obj'
  870.            mov     byte [edi+4], 0
  871.            stdcall load_file, edx
  872.  
  873.            test eax, eax
  874.            jz .exit
  875.  
  876.            mov [coff], eax
  877.  
  878.            movzx ecx, [eax+CFH.nSections]
  879.            xor ebx, ebx
  880.  
  881.            lea edx, [eax+20]
  882. @@:
  883.            add ebx, [edx+CFS.SizeOfRawData]
  884.            add ebx, 15
  885.            and ebx, not 15
  886.            add edx, COFF_SECTION_SIZE
  887.            dec ecx
  888.            jnz @B
  889.            mov [img_size], ebx
  890.  
  891.            stdcall kernel_alloc, ebx
  892.            test eax, eax
  893.            jz .fail
  894.            mov [img_base], eax
  895.  
  896.            mov edi, eax
  897.            xor eax, eax
  898.            mov ecx, [img_size]
  899.            add ecx, 4095
  900.            and ecx, not 4095
  901.            shr ecx, 2
  902.            cld
  903.            rep stosd
  904.  
  905.            mov edx, [coff]
  906.            movzx ebx, [edx+CFH.nSections]
  907.            mov edi, [img_base]
  908.            lea eax, [edx+20]
  909. @@:
  910.            mov [eax+CFS.VirtualAddress], edi
  911.            mov esi, [eax+CFS.PtrRawData]
  912.            test esi, esi
  913.            jnz .copy
  914.            add edi, [eax+CFS.SizeOfRawData]
  915.            jmp .next
  916. .copy:
  917.            add esi, edx
  918.            mov ecx, [eax+CFS.SizeOfRawData]
  919.            cld
  920.            rep movsb
  921. .next:
  922.            add edi, 15
  923.            and edi, not 15
  924.            add eax, COFF_SECTION_SIZE
  925.            dec ebx
  926.            jnz @B
  927.  
  928.            mov ebx, [edx+CFH.pSymTable]
  929.            add ebx, edx
  930.            mov [sym], ebx
  931.            mov ecx, [edx+CFH.nSymbols]
  932.            add ecx,ecx
  933.            lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
  934.            add ecx, [sym]
  935.            mov [strings], ecx
  936.  
  937.            lea ebx, [exports]
  938.            mov dword [ebx], kernel_export
  939.            mov dword [ebx+4], 0
  940.            lea eax, [edx+20]
  941.  
  942.            stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
  943.                                      [strings], ebx
  944.            test eax, eax
  945.            jz .link_fail
  946.  
  947.            mov ebx, [coff]
  948.            stdcall fix_coff_relocs, ebx, [sym], 0
  949.  
  950.            stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
  951.            test eax, eax
  952.            jz .link_fail
  953.  
  954.            mov eax, [eax]
  955.            shr eax, 16
  956.            cmp eax, DRV_COMPAT
  957.            jb .ver_fail
  958.  
  959.            cmp eax, DRV_CURRENT
  960.            ja .ver_fail
  961.  
  962.            mov ebx, [coff]
  963.            stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
  964.            mov [start], eax
  965.  
  966.            stdcall kernel_free, [coff]
  967.  
  968.            mov ebx, [start]
  969.            stdcall ebx, DRV_ENTRY
  970.            test eax, eax
  971.            jnz .ok
  972.  
  973.            stdcall kernel_free, [img_base]
  974.            cmp     dword [file_name+13], 'SOUN'
  975.            jnz     @f
  976.            cmp     dword [file_name+17], 'D.ob'
  977.            jnz     @f
  978.            cmp     word [file_name+21], 'j'
  979.            jnz     @f
  980.            mov     esi, aSis
  981.            jmp     .redo
  982. @@:
  983.            xor eax, eax
  984.            ret
  985. .ok:
  986.            mov ebx, [img_base]
  987.            mov [eax+SRV.base], ebx
  988.            mov ecx, [start]
  989.            mov [eax+SRV.entry], ecx
  990.            ret
  991.  
  992. .ver_fail:
  993.            mov esi, msg_CR
  994.            call sys_msg_board_str
  995.            mov esi, [driver_name]
  996.            call sys_msg_board_str
  997.            mov esi, msg_CR
  998.            call sys_msg_board_str
  999.            mov esi, msg_version
  1000.            call sys_msg_board_str
  1001.            mov esi, msg_www
  1002.            call sys_msg_board_str
  1003.            jmp .cleanup
  1004.  
  1005. .link_fail:
  1006.            mov esi, msg_module
  1007.            call sys_msg_board_str
  1008.            mov esi, [driver_name]
  1009.            call sys_msg_board_str
  1010.            mov esi, msg_CR
  1011.            call sys_msg_board_str
  1012. .cleanup:
  1013.            stdcall kernel_free,[img_base]
  1014. .fail:
  1015.            stdcall kernel_free, [coff]
  1016. .exit:
  1017.            xor eax, eax
  1018.            ret
  1019. endp
  1020.  
  1021. align 4
  1022. proc load_library stdcall, file_name:dword
  1023.            locals
  1024.              fullname  rb 260
  1025.              fileinfo  rb 40
  1026.              coff      dd ?
  1027.              img_base  dd ?
  1028.            endl
  1029.  
  1030.            cli
  1031.  
  1032. ; resolve file name
  1033.            mov ebx, [file_name]
  1034.            lea edi, [fullname+1]
  1035.            mov byte [edi-1], '/'
  1036.            stdcall get_full_file_name, edi, 259
  1037.            test al, al
  1038.            jz .fail
  1039.  
  1040. ; scan for required DLL in list of already loaded for this process,
  1041. ; ignore timestamp
  1042.            mov esi, [CURRENT_TASK]
  1043.            shl esi, 8
  1044.            lea ebx, [esi+SLOT_BASE+APP_OBJ_OFFSET]
  1045.            mov esi, [ebx+APPOBJ.fd]
  1046.            lea edi, [fullname]
  1047. .scan_in_process:
  1048.            cmp esi, ebx
  1049.            jz .not_in_process
  1050.            cmp dword [esi+APPOBJ.magic], 'HDLL'
  1051.            jnz .next_in_process
  1052.            mov eax, [esi+HDLL.parent]
  1053.            add eax, DLLDESCR.name
  1054.            stdcall strncmp, eax, edi, -1
  1055.            test eax, eax
  1056.            jnz .next_in_process
  1057. ; simple variant: load DLL which is already loaded in this process
  1058. ; just increment reference counters and return address of exports table
  1059.            inc [esi+HDLL.refcount]
  1060.            mov ecx, [esi+HDLL.parent]
  1061.            inc [ecx+DLLDESCR.refcount]
  1062.            mov eax, [ecx+DLLDESCR.exports]
  1063.            sub eax, [ecx+DLLDESCR.defaultbase]
  1064.            add eax, [esi+HDLL.base]
  1065.            ret
  1066. .next_in_process:
  1067.            mov esi, [esi+APPOBJ.fd]
  1068.            jmp .scan_in_process
  1069. .not_in_process:
  1070.  
  1071. ; scan in full list, compare timestamp
  1072.            lea eax, [fileinfo]
  1073.            stdcall get_fileinfo, edi, eax
  1074.            test eax, eax
  1075.            jnz .fail
  1076.            mov esi, [dll_list.fd]
  1077. .scan_for_dlls:
  1078.            cmp esi, dll_list
  1079.            jz .load_new
  1080.            lea eax, [esi+DLLDESCR.name]
  1081.            stdcall strncmp, eax, edi, -1
  1082.            test eax, eax
  1083.            jnz .continue_scan
  1084. .test_prev_dll:
  1085.            mov eax, dword [fileinfo+24] ; last modified time
  1086.            mov edx, dword [fileinfo+28] ; last modified date
  1087.            cmp dword [esi+DLLDESCR.timestamp], eax
  1088.            jnz .continue_scan
  1089.            cmp dword [esi+DLLDESCR.timestamp+4], edx
  1090.            jz .dll_already_loaded
  1091. .continue_scan:
  1092.            mov esi, [esi+DLLDESCR.fd]
  1093.            jmp .scan_for_dlls
  1094.  
  1095. ; new DLL
  1096. .load_new:
  1097. ; load file
  1098.            stdcall load_file, edi
  1099.            test eax, eax
  1100.            jz .fail
  1101.            mov [coff], eax
  1102.            mov dword [fileinfo+32], ebx
  1103.  
  1104. ; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
  1105.            mov esi, edi
  1106.            mov ecx, -1
  1107.            xor eax, eax
  1108.            repnz scasb
  1109.            not ecx
  1110.            lea eax, [ecx+DLLDESCR.sizeof]
  1111.            push ecx
  1112.            call malloc
  1113.            pop ecx
  1114.            test eax, eax
  1115.            jz .fail_and_free_coff
  1116. ; save timestamp
  1117.            lea edi, [eax+DLLDESCR.name]
  1118.            rep movsb
  1119.            mov esi, eax
  1120.            mov eax, dword [fileinfo+24]
  1121.            mov dword [esi+DLLDESCR.timestamp], eax
  1122.            mov eax, dword [fileinfo+28]
  1123.            mov dword [esi+DLLDESCR.timestamp+4], eax
  1124. ; initialize DLLDESCR struct
  1125.            and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
  1126.            mov [esi+DLLDESCR.fd], dll_list
  1127.            mov eax, [dll_list.bk]
  1128.            mov [dll_list.bk], esi
  1129.            mov [esi+DLLDESCR.bk], eax
  1130.            mov [eax+DLLDESCR.fd], esi
  1131.  
  1132. ; calculate size of loaded DLL
  1133.            mov edx, [coff]
  1134.            movzx ecx, [edx+CFH.nSections]
  1135.            xor ebx, ebx
  1136.  
  1137.            add edx, 20
  1138. @@:
  1139.            add ebx, [edx+CFS.SizeOfRawData]
  1140.            add ebx, 15
  1141.            and ebx, not 15
  1142.            add edx, COFF_SECTION_SIZE
  1143.            dec ecx
  1144.            jnz @B
  1145. ; it must be nonzero and not too big
  1146.            mov [esi+DLLDESCR.size], ebx
  1147.            test ebx, ebx
  1148.            jz .fail_and_free_dll
  1149.            cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
  1150.            ja .fail_and_free_dll
  1151. ; allocate memory for kernel-side image
  1152.            stdcall kernel_alloc, ebx
  1153.            test eax, eax
  1154.            jz .fail_and_free_dll
  1155.            mov [esi+DLLDESCR.data], eax
  1156. ; calculate preferred base address
  1157.            add ebx, 0x1FFF
  1158.            and ebx, not 0xFFF
  1159.            mov ecx, [dll_cur_addr]
  1160.            lea edx, [ecx+ebx]
  1161.            cmp edx, MAX_DEFAULT_DLL_ADDR
  1162.            jb @f
  1163.            mov ecx, MIN_DEFAULT_DLL_ADDR
  1164.            lea edx, [ecx+ebx]
  1165. @@:
  1166.            mov [esi+DLLDESCR.defaultbase], ecx
  1167.            mov [dll_cur_addr], edx
  1168.  
  1169. ; copy sections and set correct values for VirtualAddress'es in headers
  1170.            push esi
  1171.            mov edx, [coff]
  1172.            movzx ebx, [edx+CFH.nSections]
  1173.            mov edi, eax
  1174.            add edx, 20
  1175.            xor eax, eax
  1176.            cld
  1177. @@:
  1178.            mov [edx+CFS.VirtualAddress], ecx
  1179.            add ecx, [edx+CFS.SizeOfRawData]
  1180.            mov esi, [edx+CFS.PtrRawData]
  1181.            push ecx
  1182.            mov ecx, [edx+CFS.SizeOfRawData]
  1183.            test esi, esi
  1184.            jnz .copy
  1185.            rep stosb
  1186.            jmp .next
  1187. .copy:
  1188.            add esi, [coff]
  1189.            rep movsb
  1190. .next:
  1191.            pop ecx
  1192.            add edi, 15 ;-new_app_base
  1193.            add ecx, 15
  1194.            and edi, -16
  1195.            and ecx, -16
  1196.            add edx, COFF_SECTION_SIZE
  1197.            dec ebx
  1198.            jnz @B
  1199.            pop esi
  1200.  
  1201. ; save some additional data from COFF file
  1202. ; later we will use COFF header, headers for sections and symbol table
  1203. ; and also relocations table for all sections
  1204.            mov edx, [coff]
  1205.            mov ebx, [edx+CFH.pSymTable]
  1206.            mov edi, dword [fileinfo+32]
  1207.            sub edi, ebx
  1208.            jc .fail_and_free_data
  1209.            mov [esi+DLLDESCR.symbols_lim], edi
  1210.            add ebx, edx
  1211.            movzx ecx, [edx+CFH.nSections]
  1212.            lea ecx, [ecx*5]
  1213.            lea edi, [edi+ecx*8+20]
  1214.            add edx, 20
  1215. @@:
  1216.            movzx eax, [edx+CFS.NumReloc]
  1217.            lea eax, [eax*5]
  1218.            lea edi, [edi+eax*2]
  1219.            add edx, COFF_SECTION_SIZE
  1220.            sub ecx, 5
  1221.            jnz @b
  1222.            stdcall kernel_alloc, edi
  1223.            test eax, eax
  1224.            jz  .fail_and_free_data
  1225.            mov edx, [coff]
  1226.            movzx ecx, [edx+CFH.nSections]
  1227.            lea ecx, [ecx*5]
  1228.            lea ecx, [ecx*2+5]
  1229.            mov [esi+DLLDESCR.coff_hdr], eax
  1230.            push esi
  1231.            mov esi, edx
  1232.            mov edi, eax
  1233.            rep movsd
  1234.            pop esi
  1235.            mov [esi+DLLDESCR.symbols_ptr], edi
  1236.            push esi
  1237.            mov ecx, [edx+CFH.nSymbols]
  1238.            mov [esi+DLLDESCR.symbols_num], ecx
  1239.            mov ecx, [esi+DLLDESCR.symbols_lim]
  1240.            mov esi, ebx
  1241.            rep movsb
  1242.            pop esi
  1243.            mov ebx, [esi+DLLDESCR.coff_hdr]
  1244.            push esi
  1245.            movzx eax, [edx+CFH.nSections]
  1246.            lea edx, [ebx+20]
  1247. @@:
  1248.            movzx ecx, [edx+CFS.NumReloc]
  1249.            lea ecx, [ecx*5]
  1250.            mov esi, [edx+CFS.PtrReloc]
  1251.            mov [edx+CFS.PtrReloc], edi
  1252.            sub [edx+CFS.PtrReloc], ebx
  1253.            add esi, [coff]
  1254.            shr ecx, 1
  1255.            rep movsd
  1256.            adc ecx, ecx
  1257.            rep movsw
  1258.            add edx, COFF_SECTION_SIZE
  1259.            dec eax
  1260.            jnz @b
  1261.            pop esi
  1262.  
  1263. ; fixup symbols
  1264.            mov edx, ebx
  1265.            mov eax, [ebx+CFH.nSymbols]
  1266.            add edx, 20
  1267.            mov ecx, [esi+DLLDESCR.symbols_num]
  1268.            lea ecx, [ecx*9]
  1269.            add ecx, ecx
  1270.            add ecx, [esi+DLLDESCR.symbols_ptr]
  1271.  
  1272.            stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
  1273.                                      ecx, 0
  1274. ;          test eax, eax
  1275. ;          jnz @F
  1276. ;
  1277. ;@@:
  1278.  
  1279.            stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
  1280.            test eax, eax
  1281.            jnz @F
  1282.  
  1283.            stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
  1284. @@:
  1285.            mov [esi+DLLDESCR.exports], eax
  1286.  
  1287. ; fix relocs in the hidden copy in kernel memory to default address
  1288. ; it is first fix; usually this will be enough, but second fix
  1289. ; can be necessary if real load address will not equal assumption
  1290.            mov eax, [esi+DLLDESCR.data]
  1291.            sub eax, [esi+DLLDESCR.defaultbase]
  1292.            stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
  1293.  
  1294.            stdcall kernel_free, [coff]
  1295.  
  1296. .dll_already_loaded:
  1297.            inc [esi+DLLDESCR.refcount]
  1298.            push esi
  1299.            call init_heap
  1300.            pop  esi
  1301.  
  1302.            mov edi, [esi+DLLDESCR.size]
  1303.            stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
  1304.            test eax, eax
  1305.            jnz @f
  1306.            stdcall user_alloc, edi
  1307.            test eax, eax
  1308.            jz  .fail_and_dereference
  1309. @@:
  1310.            mov [img_base], eax
  1311.            mov ebx, [CURRENT_TASK]
  1312.            shl ebx, 5
  1313.            add ebx, [CURRENT_TASK+ebx+TASKDATA.pid]
  1314.            mov eax, HDLL.sizeof
  1315.            call create_kernel_object
  1316.            test eax, eax
  1317.            jz .fail_and_free_user
  1318.            mov [eax+APPOBJ.magic], 'HDLL'
  1319.            mov [eax+APPOBJ.destroy], destroy_hdll
  1320.            mov ebx, [img_base]
  1321.            mov [eax+HDLL.base], ebx
  1322.            mov [eax+HDLL.size], edi
  1323.            mov [eax+HDLL.refcount], 1
  1324.            mov [eax+HDLL.parent], esi
  1325.            mov edx, ebx
  1326.            shr edx, 12
  1327.            or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
  1328. ; copy entries of page table from kernel-side image to usermode
  1329. ; use copy-on-write for user-mode image, so map as readonly
  1330.            xor edi, edi
  1331.            mov ecx, [esi+DLLDESCR.data]
  1332.            shr ecx, 12
  1333. .map_pages_loop:
  1334.            mov eax, [page_tabs+ecx*4]
  1335.            and eax, not 0xFFF
  1336.            or al, PG_USER
  1337.            xchg eax, [page_tabs+edx*4]
  1338.            test al, 1
  1339.            jz @f
  1340.            call free_page
  1341. @@:
  1342.            invlpg [ebx+edi]
  1343.            inc ecx
  1344.            inc edx
  1345.            add edi, 0x1000
  1346.            cmp edi, [esi+DLLDESCR.size]
  1347.            jb .map_pages_loop
  1348.  
  1349. ; if real user-mode base is not equal to preferred base, relocate image
  1350.            mov ebx, [img_base]
  1351.            sub ebx, [esi+DLLDESCR.defaultbase]
  1352.            jz @f
  1353.            stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
  1354. @@:
  1355.  
  1356.            mov eax, [esi+DLLDESCR.exports]
  1357.            sub eax, [esi+DLLDESCR.defaultbase]
  1358.            add eax, [img_base]
  1359.            ret
  1360. .fail_and_free_data:
  1361.            stdcall kernel_free, [esi+DLLDESCR.data]
  1362. .fail_and_free_dll:
  1363.            mov eax, esi
  1364.            call free
  1365. .fail_and_free_coff:
  1366.            stdcall kernel_free, [coff]
  1367. .fail:
  1368.            xor eax, eax
  1369.            ret
  1370. .fail_and_free_user:
  1371.            stdcall user_free, [img_base]
  1372. .fail_and_dereference:
  1373.            mov eax, 1   ; delete 1 reference
  1374.            call dereference_dll
  1375.            xor eax, eax
  1376.            ret
  1377. endp
  1378.  
  1379. ; in: eax = number of references to delete, esi -> DLLDESCR struc
  1380. dereference_dll:
  1381.         sub     [esi+DLLDESCR.refcount], eax
  1382.         jnz     .ret
  1383.         mov     eax, [esi+DLLDESCR.fd]
  1384.         mov     edx, [esi+DLLDESCR.bk]
  1385.         mov     [eax+DLLDESCR.bk], edx
  1386.         mov     [edx+DLLDESCR.fd], eax
  1387.         stdcall kernel_free, [esi+DLLDESCR.symbols_ptr]
  1388.         stdcall kernel_free, [esi+DLLDESCR.data]
  1389.         mov     eax, esi
  1390.         call    free
  1391. .ret:
  1392.         ret
  1393.  
  1394. destroy_hdll:
  1395.         push    ebx esi edi
  1396.         push    eax
  1397.         mov     ebx, [eax+HDLL.base]
  1398.         push    ebx     ; argument for user_free
  1399.         push    eax
  1400.         mov     esi, [eax+HDLL.parent]
  1401.         mov     edx, [esi+DLLDESCR.size]
  1402.         mov     eax, ebx
  1403.         shr     ebx, 12
  1404.         push    ebx
  1405.         mov     esi, [esi+DLLDESCR.data]
  1406.         shr     esi, 12
  1407. .unmap_loop:
  1408.         push    eax
  1409.         mov     eax, 2
  1410.         xchg    eax, [page_tabs+ebx*4]
  1411.         cmp     eax, [page_tabs+esi*4]
  1412.         jnz     @f
  1413.         call    free_page
  1414. @@:
  1415.         pop     eax
  1416.         invlpg  [eax]
  1417.         add     eax, 0x1000
  1418.         inc     ebx
  1419.         inc     esi
  1420.         sub     edx, 0x1000
  1421.         ja      .unmap_loop
  1422.         pop     ebx eax
  1423.         and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
  1424.         mov     esi, [eax+HDLL.parent]
  1425.         mov     eax, [eax+HDLL.refcount]
  1426.         call    dereference_dll
  1427.         call    user_free
  1428.         pop     eax
  1429.         call    destroy_kernel_object
  1430.         pop     edi esi ebx
  1431.         ret
  1432.  
  1433. align 4
  1434. stop_all_services:
  1435.        push ebp
  1436.            mov edx, [srv.fd]
  1437. .next:
  1438.            cmp edx,  srv.fd-SRV_FD_OFFSET
  1439.            je .done
  1440.            cmp [edx+SRV.magic], ' SRV'
  1441.            jne .next
  1442.        cmp [edx+SRV.size], SRV.sizeof
  1443.            jne .next
  1444.  
  1445.            mov ebx, [edx+SRV.entry]
  1446.            mov edx, [edx+SRV.fd]
  1447.            test ebx, ebx
  1448.            jz .next
  1449.  
  1450.            push edx
  1451.            stdcall ebx, dword -1
  1452.            pop edx
  1453.            jmp .next
  1454. .done:
  1455.        pop ebp
  1456.            ret
  1457.  
  1458. ; param
  1459. ;  eax= size
  1460. ;  ebx= pid
  1461.  
  1462. align 4
  1463. create_kernel_object:
  1464.  
  1465.            push ebx
  1466.            call malloc
  1467.            pop ebx
  1468.            test eax, eax
  1469.            jz .fail
  1470.  
  1471.            mov ecx,[current_slot]
  1472.            add ecx, APP_OBJ_OFFSET
  1473.  
  1474.            pushfd
  1475.            cli
  1476.            mov edx, [ecx+APPOBJ.fd]
  1477.            mov [eax+APPOBJ.fd], edx
  1478.            mov [eax+APPOBJ.bk], ecx
  1479.            mov [eax+APPOBJ.pid], ebx
  1480.  
  1481.            mov [ecx+APPOBJ.fd], eax
  1482.            mov [edx+APPOBJ.bk], eax
  1483.            popfd
  1484. .fail:
  1485.            ret
  1486.  
  1487. ; param
  1488. ;  eax= object
  1489.  
  1490. align 4
  1491. destroy_kernel_object:
  1492.  
  1493.            pushfd
  1494.            cli
  1495.            mov ebx, [eax+APPOBJ.fd]
  1496.            mov ecx, [eax+APPOBJ.bk]
  1497.            mov [ebx+APPOBJ.bk], ecx
  1498.            mov [ecx+APPOBJ.fd], ebx
  1499.            popfd
  1500.  
  1501.            xor edx, edx        ;clear common header
  1502.            mov [eax], edx
  1503.            mov [eax+4], edx
  1504.            mov [eax+8], edx
  1505.            mov [eax+12], edx
  1506.            mov [eax+16], edx
  1507.  
  1508.            call free           ;release object memory
  1509.            ret
  1510.  
  1511.  
  1512.  
  1513. if 0
  1514.  
  1515. irq:
  1516.  
  1517. .irq0:
  1518.            pusfd
  1519.            pushad
  1520.            push IRQ_0
  1521.            jmp .master
  1522. .irq_1:
  1523.            pusfd
  1524.            pushad
  1525.            push IRQ_1
  1526.            jmp .master
  1527.  
  1528. .master:
  1529.            mov ax, app_data
  1530.            mov ds, eax
  1531.            mov es, eax
  1532.            mov ebx, [esp+4]  ;IRQ_xx
  1533.            mov eax, [irq_handlers+ebx+4]
  1534.            call intr_handler
  1535.            mov ecx, [esp+4]
  1536.            cmp [irq_actids+ecx*4], 0
  1537.            je @F
  1538.            in al, 0x21
  1539.            bts eax, ecx
  1540.            out 0x21, al
  1541.            mov al, 0x20
  1542.            out 0x20, al
  1543.            jmp .restart
  1544.  
  1545. .slave:
  1546.            mov ax, app_data
  1547.            mov ds, eax
  1548.            mov es, eax
  1549.            mov ebx, [esp+4]  ;IRQ_xx
  1550.            mov eax, [irq_handlers+ebx+4]
  1551.            call intr_handler
  1552.            mov ecx, [esp+4]
  1553.            sub ecx, 8
  1554.            cmp [irq_actids+ecx*4], 0
  1555.            je @F
  1556.            in al, 0xA1
  1557.            bts eax, ecx
  1558.            out 0xA1, al
  1559.            mov al, 0x20
  1560.            out 0xA0, al
  1561.            out 0x20, al
  1562. .restart:
  1563.            mov ebx, [next_slot]
  1564.            test ebx, ebx
  1565.            jz @F
  1566.            mov [next_task],0
  1567.            mov esi, [prev_slot]
  1568.            call do_change_task
  1569.            add esp, 4
  1570.            iretd
  1571.  
  1572. end if
  1573.  
  1574.  
  1575.  
  1576.  
  1577.