home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / communic / iomon / ioisr.asm < prev    next >
Encoding:
Assembly Source File  |  1992-01-20  |  18.5 KB  |  454 lines

  1. ;---------------------------------------------------------------
  2. ;ioisr - Interrupt Service Routines for I/O Monitor            |
  3. ;--------------------------------------------------------------|
  4. ;Copyright 1991 ASMicro Co.                                    |
  5. ;--------------------------------------------------------------|
  6. ; 5/25/91                      Rick Knoblaugh                  |
  7. ;--------------------------------------------------------------|
  8. ;include files                                                 |
  9. ;---------------------------------------------------------------
  10.                 .386P
  11.                 include ioequ.inc
  12.                 include iomac.inc
  13.                 include iostruc.inc
  14.  
  15.  
  16. data            segment para public 'data16' use16
  17.                 extrn   start_port:WORD
  18.                 extrn   end_port:WORD
  19.                 extrn   old_int1:DWORD
  20.                 extrn   old_user_int:DWORD
  21.                 extrn   io_table:BYTE
  22.                 extrn   IO_TAB_ENTRIES:ABS
  23.                 extrn   access_port:word
  24.                 extrn   access_info:byte
  25.                 extrn   store_buf:byte
  26.                 extrn   store_buf_end:ABS
  27.                 extrn   store_ptr:word
  28.                 extrn   store_wrapped:byte
  29.                 extrn   display_loc:word
  30.                 extrn   trap_status:byte
  31. data            ends
  32.  
  33. gdt_seg         segment para public 'data16' use16
  34.                 extrn   sel_databs:byte
  35.                 extrn   sel_video:byte
  36.                 extrn   sel_data:byte
  37.                 extrn   sel_tss_alias:byte
  38. gdt_seg         ends
  39.  
  40. tss_seg         segment para public 'data16' use16
  41. tss_seg         ends
  42.  
  43.  
  44. isrcode         segment para public 'icode16' use16
  45.                 assume cs:isrcode, ds:nothing, es:nothing
  46. ;--------------------------------------------------------------
  47. ;PUBLICS                                                      |
  48. ;--------------------------------------------------------------
  49.                 public  int1_isr
  50.                 public  user_int_isr
  51.                 public  int_0
  52.                 public  int_2
  53.                 public  int_3
  54.                 public  int_4
  55.                 public  int_5
  56.                 public  int_6
  57.                 public  int_7
  58.                 public  except_8
  59.                 public  except_9
  60.                 public  except_0ah
  61.                 public  except_0bh
  62.                 public  except_0ch
  63.                 public  except_0dh
  64.                 public  except_0eh
  65.                 public  except_0fh
  66.                 public  int_20h
  67.                 public  int_21h
  68.                 public  int_22h
  69.                 public  int_23h
  70.                 public  int_24h
  71.                 public  int_25h
  72.                 public  int_26h
  73.                 public  int_27h
  74.  
  75.                 public  int_70h
  76.                 public  int_71h
  77.                 public  int_72h
  78.                 public  int_73h
  79.                 public  int_74h
  80.                 public  int_75h
  81.                 public  int_76h
  82.                 public  int_77h
  83.  
  84.         irp     z, <0, 2, 3, 4, 5, 6, 7>
  85.         DOINT   &z
  86.         endm
  87.  
  88.         irp     z, <8, 9, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh>
  89.         DOEXCP  &z
  90.         endm
  91.  
  92.         irp     z, <20h, 21h, 22h, 23h, 24h, 25h, 26h, 27h>
  93.         DOEXCPH &z
  94.         endm
  95.  
  96.         irp     z, <70h, 71h, 72h, 73h, 74h, 75h, 76h, 77h>
  97.         DOINT   &z
  98.         endm
  99.  
  100. ;--------------------------------------------------------------
  101. ;int1_isr -  ISR for single step interrupt.  If trap_status   |
  102. ;            has EXPECT_INT1 bit set, this is the trap        |
  103. ;            that occurs just after the I/O instruction       |
  104. ;            we are monitoring executes.  Store the I/O data  |
  105. ;            from ax into our buffer.                         |
  106. ;--------------------------------------------------------------
  107. int1_isr        proc    far
  108.                 push    bp
  109.                 mov     bp, sp
  110.                 push    bx
  111.                 push    ds
  112.                 mov     bx, offset gdt_seg:sel_data
  113.                 mov     ds, bx
  114.                 assume  ds:data
  115.                 test    trap_status, EXPECT_INT1 ;expecting an int 1?
  116.                 jnz     int1_050
  117.                 pop     ds
  118.                 pop     bx
  119.                 push    1
  120.                 jmp     pass_thru               ;if not, do old int 1
  121. int1_050:
  122.                 push    ax
  123.                 push    cx
  124.                 push    dx
  125.                 mov     trap_status, 0
  126.                 and     [bp].s_eflags, NOT TRAP_FLAG ;no more single step
  127.                 mov     bx, store_ptr
  128.                 mov     cl, access_info
  129.                 or      cl, CONTAINS_DATA       ;indicate data stored
  130.                 mov     [bx].buf_info, cl       ;store info re i/o
  131.                 mov     dx, access_port
  132.                 mov     [bx].buf_port, dx       ;store port number
  133.                 test    cl, AWORD               ;word access?
  134.                 jnz     int1_100
  135.                 sub     ah, ah                  ;if not, clear half
  136. int1_100:
  137.                 mov     [bx].buf_data, ax
  138.                 add     bx, size buf_record     ;advance buf ptr
  139.                 cmp     bx, store_buf_end - size buf_record  ;at end?
  140.                 jb      int1_200
  141.                 mov     bx, offset store_buf
  142.                 mov     store_wrapped,1
  143. int1_200:
  144.                 mov     store_ptr, bx           ;save new ptr
  145.                 and     cx, (AWORD OR ABYTE)    ;number of bits
  146.                 mov     ah, 1                   ;indicate set
  147.                 mov     dx, access_port
  148.                 call    do_bit_map      ;set the bits again
  149.                 pop     dx
  150.                 pop     cx
  151.                 pop     ax
  152.                 pop     ds
  153.                 pop     bx
  154.                 pop     bp
  155.                 iretd
  156. int1_isr        endp
  157.  
  158. ;--------------------------------------------------------------
  159. ;except_handler - Process as follows:                         |
  160. ;                                                             |
  161. ;                      Int 0dh - Go look for software int or  |
  162. ;                                I/O instruction.             |
  163. ;                    Any other                                |
  164. ;                    exception - go display exception number  |
  165. ;                                and halt.                    |
  166. ;--------------------------------------------------------------
  167. except_handler  proc    near
  168.                 mov     bp, sp
  169.                 cmp     [bp].e_pushed_int , GEN_PROT_EXCEP
  170.                 je      gen_prot_isr
  171.                 mov     ax, [bp].e_pushed_int ;int in ax, go display
  172.                 jmp short fatal_error
  173. except_handler  endp
  174.  
  175. fatal_error     proc    near
  176.                 call    display_it
  177.                 jmp     $
  178. fatal_error     endp
  179.  
  180. ;--------------------------------------------------------------
  181. ;display_it - Display hex number on screen at next display    |
  182. ;             offset.                                         |
  183. ;                                                             |
  184. ;             Enter:  number in AX                            |
  185. ;                     processor in protected mode             |
  186. ;                                                             |
  187. ;             All registers saved                             |
  188. ;--------------------------------------------------------------
  189. display_it      proc    near
  190.                 pusha
  191.                 push    ds
  192.                 push    es
  193.  
  194.                 mov     dx, offset gdt_seg:sel_data
  195.                 mov     ds, dx                  ;get our data segment
  196.                 assume  ds:data
  197.                 mov     dx, offset gdt_seg:sel_video
  198.                 mov     es, dx                  ;and video segment
  199.                 mov     di, display_loc
  200.                 xchg    al, ah                  ;print MSB first
  201.                 call    put_hex_digit
  202.                 xchg    al, ah                  ;get LSB
  203.                 call    put_hex_digit
  204.                 add     di, 2                   ;past space and attribute
  205.                 cmp     di, VID_PAGE_SIZE
  206.                 jb      display_i100
  207.                 xor     di, di                  ;back to start of page
  208. display_i100:
  209.                 mov     display_loc, di
  210.                 pop     es
  211.                 pop     ds
  212.                 popa
  213.                 ret
  214. display_it      endp
  215.  
  216. put_hex_digit   proc    near
  217.                 push    ax
  218.                 mov     cx, 2                   ;2 digits in al
  219.                 mov     ah, al
  220. put_hex_100:
  221.                 shr     al, 4
  222.                 cmp     al, 9
  223.                 ja      put_hex_200
  224.                 add     al, '0'
  225.                 jmp     short put_hex_300
  226. put_hex_200:
  227.                 add     al, 'A' - 10
  228. put_hex_300:
  229.                 cld
  230.                 stosb
  231.                 inc     di                      ;past attrib
  232.                 mov     al, ah
  233.                 shl     al, 4
  234.                 loop    put_hex_100
  235.                 pop     ax
  236.                 ret
  237. put_hex_digit   endp
  238.  
  239. ;--------------------------------------------------------------
  240. ;pass_thru - This procedure is JMPed to by any interrupt      |
  241. ;            handler which wishes to pass control to the      |
  242. ;            original ISR per the interrupt vector table.     |
  243. ;                                                             |
  244. ;            Entry:                                           |
  245. ;                  See stack_area struc for stack layout      |
  246. ;                  Any error code has been removed from stack.|
  247. ;                  EIP on stack has been adjusted if          |
  248. ;                  necessary.                                 |
  249. ;--------------------------------------------------------------
  250. pass_thru       proc    near
  251.                 mov     bp, sp
  252.                 pushad
  253.                 push    ds
  254.                 mov     ax, offset gdt_seg:sel_databs
  255.                 mov     ds, ax                  ;address all base memory
  256.                 movzx   ebx, [bp].s_ss          ;user stack
  257.                 shl     ebx, 4                  ;make linear
  258.                 mov     edx, [bp].s_esp         ;user stack pointer
  259.                 sub     edx, 6                  ;flags, cs, ip
  260.                 mov     [bp].s_esp, edx         ;adjust it
  261.                 mov     eax, [bp].s_eflags      ;put on flags
  262.                 mov     [ebx][edx].user_flags, ax
  263. ;
  264. ;change flags on stack so that original ISR will be entered with
  265. ;interrupts cleared and trap flag cleared to be consistent with their
  266. ;state upon entering an ISR (the normal way).
  267. ;
  268.                 and     ax, not (TRAP_FLAG + INT_FLAG)
  269.                 mov     [bp].s_eflags, eax      ;put back flags
  270.                 mov     ax, [bp].s_cs           ;put on user cs
  271.                 mov     [ebx][edx].user_cs, ax
  272.                 mov     eax, [bp].s_eip         ;put on ip
  273.                 mov     [ebx][edx].user_ip, ax
  274.                 movzx   ebx, [bp].s_pushed_int  ;get int number
  275.                 movzx   eax, [ebx * 4].d_offset  ;offset portion
  276.                 mov     [bp].s_eip, eax
  277.                 mov     ax, [ebx * 4].d_segment  ;segment portion
  278.                 mov     [bp].s_cs, ax
  279.                 pop     ds
  280.                 popad
  281.                 add     sp, 2                   ;get rid of int number
  282.                 pop     bp
  283.                 iretd
  284. pass_thru       endp
  285.  
  286. ;--------------------------------------------------------------
  287. ;gen_prot_isr - JMP here if int 0dh.  Process as follows:     |
  288. ;                                                             |
  289. ;               Look for software int.  If found, go route to |
  290. ;               appropriate ISR.                              |
  291. ;                                                             |
  292. ;               Look for I/O instructions we currently        |
  293. ;               support.  If found, store port, size and      |
  294. ;               direction of I/O.  Also, set trap flag and    |
  295. ;               return (we will get control at int 1 to       |
  296. ;               inspect data).                                |
  297. ;                                                             |
  298. ;               If other than software int or I/O, go         |
  299. ;               display 0dh and halt.                         |
  300. ;                                                             |
  301. ;--------------------------------------------------------------
  302. gen_prot_isr    proc    near
  303.                 push    ds
  304.                 pushad
  305.                 mov     bx, offset gdt_seg:sel_databs
  306.                 mov     ds, bx
  307.                 movzx   ebx, [bp].e_cs  ;get cs of user instruction
  308.                 shl     ebx, 4          ;make linear
  309.                 add     ebx, [bp].e_eip ;add ip
  310.                 mov     ax, [ebx]       ;get bytes at cs:ip
  311.                 cmp     al, INT_OPCODE
  312.                 jne     get_prot100
  313.                 inc     [bp].e_eip      ;get past the 0cdh
  314. get_prot050:
  315.                 inc     [bp].e_eip
  316. ;
  317. ;Adjust stack so that error code goes away and int number retrieved from
  318. ;instruction goes in spot on stack where pushed int number is (for stacks
  319. ;with no error code).  Stack will be the way pass_thru routine likes it.
  320. ;
  321.                 mov     bx, [bp].e_pushed_bp
  322.                 shl     ebx, 16         ;get into high word
  323.                 mov     bl, ah          ;interrupt number
  324.                 mov     [bp].e_errcode, ebx
  325.                 popad
  326.                 pop     ds
  327.                 add     sp, 4           ;error code gone
  328.                 jmp     pass_thru
  329. get_prot100:
  330.                 cmp     al, INT3_OPCODE
  331.                 jne     get_prot150
  332.                 mov     ah, 3           ;interrupt 3
  333.                 jmp     short get_prot050
  334. get_prot150:
  335.  
  336.                 mov     bx, offset gdt_seg:sel_data
  337.                 mov     ds, bx
  338.                 mov     bx, offset io_table
  339.                 mov     cx, IO_TAB_ENTRIES
  340. get_prot200:
  341.                 cmp     al, [bx].io_opcode
  342.                 jne     get_prot300
  343.                 mov     trap_status, EXPECT_INT1
  344.                 mov     cl, [bx].io_info ;get info about instruction
  345.                 mov     access_info, cl
  346.                 mov     access_port, dx  ;save port
  347.                 test    cl, CONSTANT    ;is port number in instruction?
  348.                 jz      get_prot250     ;if not, we have it
  349.                 xchg    ah, al           ;ah = 2nd byte of instruction
  350.                 sub     ah, ah
  351.                 mov     access_port, ax ;save port
  352.                 mov     dx, ax
  353. get_prot250:
  354.                 and     cx, (AWORD OR ABYTE)   ;number of bits
  355.                 sub     ah, ah          ;indicate clear
  356.                 call    do_bit_map
  357.  
  358.                 popad
  359.                 pop     ds
  360.                 or      [bp].e_eflags, TRAP_FLAG ;single step i/o
  361.  
  362.                 add     sp, 2           ;int number pushed
  363.                 pop     bp
  364.                 add     sp, 4           ;error code
  365.                 iretd
  366.  
  367. get_prot300:
  368.                 add     bx, size io_struc ;advance to next table entry
  369.                 loop    get_prot200
  370.                 mov     ax, [bp].e_cs   ;get cs of user instruction
  371.                 call    display_it
  372.                 mov     eax, [bp].e_eip ;add ip
  373.                 call    display_it
  374.                 popad
  375.                 pop     ds
  376.                 mov     ax, [bp].e_pushed_int
  377.                 jmp     fatal_error
  378. gen_prot_isr    endp
  379.  
  380. ;--------------------------------------------------------------
  381. ;do_bit_map - For the number of ports specified, clear/set    |
  382. ;             corresponding I/O permission map bits.          |
  383. ;                                                             |
  384. ;             Enter:  Ah = 0 clear, ah = 1 set                |
  385. ;                     dx = starting port                      |
  386. ;                     cx = number of ports                    |
  387. ;                                                             |
  388. ;  All registers saved.                                       |
  389. ;--------------------------------------------------------------
  390. do_bit_map      proc    near
  391.                 push    ax
  392.                 push    bx
  393.                 push    cx
  394.                 push    dx
  395.                 push    ds
  396.                 mov     bx, offset gdt_seg:sel_tss_alias
  397.                 mov     ds, bx
  398.                 assume  ds:tss_seg
  399.                 mov     bx, t_iomap
  400.                 push    cx
  401.                 mov     cx, dx                  ;port
  402.                 and     cl, 7                   ;get non byte boundary
  403.                 mov     al, 1                   ;first bit position
  404.                 shl     al, cl                  ;get out corresponding bit
  405.                 shr     dx, 3                   ;start_port/8
  406.                 pop     cx
  407.                 add     bx, dx                  ;starting offset in map
  408. do_bit100:
  409.                 or      ah, ah
  410.                 jnz     do_bit200
  411.                 mov     dl, al
  412.                 not     dl
  413.                 and     byte ptr [bx], dl       ;turn off permission bit
  414.                 jmp     short do_bit250
  415. do_bit200:
  416.                 or byte ptr [bx], al            ;turn on permission bit
  417. do_bit250:
  418.                 rcl     al, 1                   ;next bit position
  419.                 jnc     do_bit300
  420.                 inc     bx
  421.                 rcl     al, 1
  422. do_bit300:
  423.                 loop    do_bit100
  424.                 pop     ds
  425.                 pop     dx
  426.                 pop     cx
  427.                 pop     bx
  428.                 pop     ax
  429.                 ret
  430. do_bit_map      endp
  431.  
  432. ;--------------------------------------------------------------
  433. ;user_int_isr - return buffer address to caller.              |
  434. ;                                                             |
  435. ;             Exit: dx:bx= far ptr to store_buf               |
  436. ;                   ax = 1 if wrapped                         |
  437. ;                   cx = head                                 |
  438. ;--------------------------------------------------------------
  439. user_int_isr    proc    near
  440.                 mov     dx, data
  441.                 mov     bx, offset data:store_buf
  442.                 push    ds
  443.                 mov     ds,dx
  444.                 assume  ds:data
  445.                 mov     cx,store_ptr
  446.                 sub     cx,offset store_buf
  447.                 xor     ax,ax
  448.                 mov     al,store_wrapped
  449.                 pop     ds
  450.                 iret
  451. user_int_isr    endp
  452. isrcode         ends
  453.                 end
  454.