home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c222 / 1.ddi / SOURCE / IBMLIB / IN_DRIVE.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-09-25  |  9.5 KB  |  425 lines

  1. ;
  2. ;  in_drive.asm
  3. ;
  4. ;  Purpose: Interrupt primitives.
  5. ;
  6. ;  Blackstar C Function Libarary
  7. ;  (c) Copyright 1985,1989 Sterling Castle Software
  8. ;
  9.  
  10.     include model
  11.     include blackstr.mac
  12.  
  13.  
  14.     busyf   equ     'B';    busy flag - already servicing
  15.     msdosf    equ    21h;    interrupt for msdos function
  16.     EOI    equ    20h;    end of interrupt
  17.     m8259   equ     20h;    interrupt controller port
  18.     i8259    equ    21h;
  19.  
  20.     dseg    'DATA'
  21.  
  22.     ; interrupt structure and tables
  23.  
  24.     interrupt struc
  25.         vector        dw    ?    ;service vector offset
  26.         chainf         db    0    ;interrupt type    (repl/chain)
  27.         no        db    0    ;int vector number
  28.         roff         dw    ?    ;interrupt routine
  29.         rseg        dw    ?    ;routine segment
  30.         soff        dw    ?    ;stack location
  31.         sseg        dw    ?    ;stack segment
  32.         coff        dw    ?    ;chain to vector
  33.         csegg           dw      ?       ;chain to segment
  34.     interrupt ends
  35.  
  36.     int_table LABEL WORD
  37.         int0  interrupt <,,,,,>
  38.         int1  interrupt <,,,,,>
  39.         int2  interrupt <,,,,,>
  40.         int3  interrupt <,,,,,>
  41.  
  42.     no_ints         db      0       ;number of interrupts set
  43.     int_set        db    0    ;interrupt number to set
  44.     ifdef   Large_code
  45.         ALIAS    function DWORD
  46.     else
  47.         ALIAS    function WORD
  48.     endif
  49.     funoff        dw    00    ;function offset
  50.     funseg        dw    00    ;function segment
  51.  
  52.     ; Local stack
  53.  
  54.     sstk            db      'Start of stack';start of stack
  55.     stck_m        db    256 dup(?)
  56.     pstack        equ    $-2        ;start it here
  57.     estk        db    'End of stack'    ;end of stack
  58.  
  59.     enddseg
  60.  
  61.  
  62.     cseg in_servc_
  63.  
  64.     istatus        db    0    ;busy/idle for all interrupts
  65.     int_no        db    ?    ;interrupt being serviced
  66.     itype        db    0    ;type of interrupt
  67.     choff        dw    ?    ;function to chain to
  68.     chseg        dw    ?
  69.  
  70.     ;--------------------------------
  71.     ;       Interrupt service vectors
  72.     ;---------------------------------
  73. public int0_vec
  74.  
  75.     int0_vec        proc    far
  76.             mov     cs:int_no,0
  77.             jmp    in_servc_
  78.     int0_vec    endp
  79.     int1_vec    proc    far
  80.             mov     cs:int_no,1
  81.             jmp    in_servc_
  82.     int1_vec    endp
  83.     int2_vec    proc    far
  84.             mov    cs:int_no,2
  85.             jmp    in_servc_
  86.     int2_vec    endp
  87.     int3_vec    proc    far
  88.             mov    cs:int_no,3
  89.             jmp    in_servc_
  90.     int3_vec    endp
  91.  
  92.     ; Interrupt service vector table
  93.  
  94.     int_vtbl:
  95.     ifdef   Small_code
  96.         dw      offset cgroup: int0_vec
  97.         dw      offset cgroup: int1_vec
  98.         dw      offset cgroup: int2_vec
  99.         dw      offset cgroup; int3_vec
  100.     else
  101.         dw      int0_vec
  102.         dw      int1_vec
  103.         dw      int2_vec
  104.         dw      int3_vec
  105.     endif
  106.  
  107.  
  108. ;-----------------
  109. ;   in_servc_           dispatcher for interrupt service routine
  110. ;-----------------
  111.  
  112.     public in_servc_
  113.  
  114. in_servc_ proc
  115.     cmp     byte ptr cs:istatus,busyf ;already servicing
  116.     je      short int_x
  117.  
  118. servc1: mov     byte ptr cs:istatus,busyf ;make it busy
  119.     push    eax
  120.     push    ebx
  121.     push    ecx
  122.     push    edx
  123.     push    edi
  124.     push    esi
  125.     push    ebp
  126.     push    ds
  127.     push    es
  128.  
  129.     ; set to this data seg
  130.  
  131.     mov     eax,seg dgroup
  132.     mov     ds,eax          ;point ds to dgroup
  133.     mov     es,eax          ;and es
  134.  
  135.     ; find interrupt number to use for stack,service,and vector
  136.  
  137.     mov     al,int_no
  138.     cbw
  139.     mov     cl,4
  140.     sal     eax,cl                  ;*16 bytes per int struc
  141.     mov     ebx,offset dgroup:int_table
  142.     add     ebx,eax
  143.  
  144.     ; set up our own stack
  145.  
  146.     mov     edx,ss                  ;save old stack on stack
  147.     mov     ecx,esp
  148.     cli
  149.     mov     ss,[ebx.sseg]           ;set stack segment to here
  150.     mov     esp,[ebx.soff]
  151.     push    edx
  152.     push    ecx                     ;save old stack
  153.     sti
  154.     mov     eax,[ebx.coff]          ;get chain to
  155.     mov     cs:choff,eax
  156.     mov     eax,[ebx.csegg]         ;chain seg
  157.     mov     cs:chseg,eax
  158.     mov     eax,[ebx.rseg]          ;get segment
  159.     mov     funseg,eax
  160.     mov     eax,[ebx.roff]          ;and offset to function area
  161.     mov     funoff,eax
  162.  
  163.     ifdef   Large_code
  164.         call    dword ptr [function]
  165.     else
  166.         call    [function]
  167.     endif
  168.  
  169.  
  170.     ;------------
  171.     ;  int_exit             exit from  interrupt
  172.     ;------------
  173.  
  174.     ; restore beginning stack
  175.  
  176.     pop     ecx
  177.     pop     ebx
  178.     cli
  179.     mov     esp,ecx
  180.     mov     ss,ebx
  181.     sti
  182.     pop     es
  183.     pop     ds
  184.     pop     ebp
  185.     pop     esi
  186.     pop     edi
  187.     pop     edx
  188.     pop     ecx
  189.     pop     ebx
  190.     pop     eax
  191.     mov     byte ptr cs:istatus,0   ;no more busy
  192.     cmp     cs:itype,1
  193.     jnz     short int_x
  194.  
  195.     ; do end of interrupt for hardware - no chain
  196.  
  197.     push    eax             ;save eax
  198.     mov     al,EOI          ;get end
  199.     out     m8259,al        ;output it
  200.     pop     eax
  201.  
  202.     int_x   LABEL NEAR
  203.     jmp dword ptr cs:[choff]                ;chain to next
  204. in_servc_ endp
  205.  
  206.  
  207. ;------------------                           
  208. ;    in_set_            set interrupts on/off
  209. ;------------------
  210. ;                               Usage: in_set(ON/OFF);
  211. ;
  212. ;                               int in_set(int toggle);
  213.  
  214.     public  in_set_
  215.  
  216. in_set_ proc
  217.     parm386<<toggle,dword>>
  218.     parm86<<toggle,word>>
  219.     prolog
  220.  
  221.     mov eax,toggle
  222.     cmp eax,0
  223.     cli                     ;disable interrupts is default
  224.     jnz     dis
  225.     sti                     ; turn on interrupts
  226. dis:
  227.     epilog
  228. in_set_ endp
  229.  
  230.  
  231. ;--------------------
  232. ;    in_setvec_        set interrupt vector
  233. ;--------------------
  234. ;
  235. ;            Usage:    vec# = in_setvec_(vec#,function,stack,type)
  236. ;                where type   = 0 <no hardware, no chain)    
  237. ;                           1 (hardware,no chain)
  238. ;                           2 (no hardware, chain)
  239. ;                           3 (hardware, chain)
  240.  
  241.     public  in_setvec_
  242.  
  243. in_setvec_ proc
  244.     parm386<<vec,dword>,<foff,dword>,<fseg,word>,<stoff,dword>,<stseg,word>,<choice,dword>>
  245.     parm86<<vec,word>,<foff,word>,<fseg,word>,<stoff,word>,<stseg,word>,<choice,word>>
  246.     prolog
  247.  
  248.     ; point ebx to interrupt vector structures
  249.  
  250.     ifdef   Large_data
  251.     mov     ax,seg dgroup
  252.     mov     ds,ax
  253.     endif
  254.  
  255.     mov     al,no_ints      ;update # interrupts
  256.     mov     int_set,al      ;save it
  257.     inc     no_ints         ;update number
  258.     cbw
  259.     mov     ebx,offset dgroup:int_table
  260.     mov     cl,4            ;16 bytes per struc
  261.     shl     eax,cl
  262.     add     ebx,eax
  263.     mov     eax,vec         ;get vector #
  264.     mov     [ebx.no],al     ;save in interrupt struc
  265.  
  266.     ; now get function to service interrupt
  267.  
  268.     mov     eax,foff        ;get offset of routine
  269.     mov     [ebx.roff],eax
  270.     mov     eax,fseg        ;get segment
  271.     mov     [ebx.rseg],eax
  272.  
  273.  
  274.     ; get stack to use with interrupt
  275.  
  276.     mov     eax,stoff               ;save stack offset
  277.     mov     [ebx.soff],eax
  278.     mov     eax,stseg               ;save stack segment
  279.     mov     [ebx.sseg],eax
  280.  
  281.     ; get chain to function
  282.  
  283.     mov     eax,choice                ;chainf flag
  284.     mov     byte ptr [ebx.chainf], al ;save in interrupt struc
  285.     mov     cs:itype,al             ;and interrupt type
  286.     cmp     eax,2                   ;0&1 are no chain,3&4=chain
  287.     jge     short set2
  288.  
  289.     ; No chain, use dummy iret
  290.  
  291.     mov     eax,offset cs:in_iret
  292.     mov     edx,cs
  293.     jmp     short set3
  294.  
  295.     ; get existing interrupt function to chain to
  296.  
  297. set2:   mov     al,[ebx.no]             ;get int vector #
  298.     push    es
  299.     push    ebx
  300.     doscall 35h                     ;get interrupt vector function
  301.     mov     eax,ebx
  302.     mov     edx,es                  ;to eax,edx
  303.     pop     ebx
  304.     pop     es
  305.  
  306. set3:   mov     [ebx.coff],eax
  307.     mov     [ebx.csegg],edx          ;put chain routine in
  308.  
  309.     ; now set the bios vector interrupt
  310.  
  311.     mov     ebp,offset cs:int_vtbl  ;point to vector table
  312.     mov     al,int_set              ;get number being set
  313.     cbw
  314.     sal     eax,1                   ;times 2 bytes/address
  315.     add     ebp,eax
  316.     mov     edx,cs:[ebp]            ;offset of int
  317.     mov     al,[ebx.no]             ;interrupt # to set
  318.     mov     ecx,cs                  ;use this segment
  319.     push    ds
  320.     mov     ds,ecx
  321.     doscall 25h                     ;set interrupt vector function
  322.     pop     ds                      ;restore ds
  323.     mov     al,int_set              ;return vector #
  324.     cbw
  325.  
  326.     epilog
  327. in_setvec_ endp
  328.  
  329.  
  330. ;--------------------
  331. ;    in_remvec_        remove an interrupt vector
  332. ;--------------------
  333. ;                               Usage:  in_remvec_(number);
  334. ;                where number was returned by in_setvec_
  335. ;
  336. ;                               int in_remvec_(int number);
  337.  
  338.     public  in_remvec_
  339.  
  340. in_remvec_ proc
  341.     parm386<<number,dword>>
  342.     parm86<<number,word>>
  343.     prolog
  344.  
  345.     ifdef   Large_data
  346.     mov     ax, seg dgroup
  347.     mov     ds,ax
  348.     endif
  349.  
  350.     mov     eax,number      ;get vector number
  351.     mov     ebx,offset dgroup:int_table
  352.     mov     cl,4
  353.     sal     eax,cl          ;16 bytes/table
  354.     mov     al,[ebx.no]     ;get vector number to set
  355.     mov     edx,[ebx.coff]  ;reset to chain routine
  356.     mov     ecx,[ebx.csegg]
  357.     push    ds
  358.     mov     ds,ecx
  359.     doscall 25h             ; do dos set interrupt call
  360.     pop     ds
  361.  
  362.     ifdef    asm_386
  363.     movsx    eax,ax
  364.     endif
  365.  
  366.     epilog
  367. in_remvec_ endp
  368.  
  369.  
  370. ;--------------------
  371. ;    in_hdwren_        hardware enable/disable
  372. ;--------------------
  373. ;                               Usage: in_hdwren_ (level,ON/OFF)
  374. ;
  375. ;                               in_hdwren_(int level, int toggle);
  376.  
  377.     public  in_hdwren_
  378.  
  379. in_hdwren_ proc
  380.     parm386<<level,dword>,<toggle,dword>>
  381.     parm86<<level,word>,<toggle,word>>
  382.     prolog
  383.  
  384.     ifdef   Large_data
  385.     mov     ax,seg dgroup
  386.     mov     ds,ax
  387.     endif
  388.  
  389.     mov     eax,1                   ;start with bit 0
  390.     mov     ecx,level               ;get number to set
  391.     shl     eax,cl                  ;shift to bit
  392.     not     al
  393.     mov     ebx,eax
  394.     in      al,i8259                ;get current
  395.     and     al,bl                   ;turn it off
  396.     mov     edx,toggle              ;on or off
  397.     cmp     edx,0
  398.     jz      hdrw1
  399.  
  400.     not     al
  401.     or      al,bl                   ;add this one
  402.  
  403. hdrw1:  out     i8259,al                ;enable it
  404.  
  405.     epilog
  406. in_hdwren_ endp
  407.  
  408.  
  409. ;---------------------
  410. ;    in_iret            dummy chain function
  411. ;--------------------
  412. ;                               Usage: in_iret();
  413. ;
  414. ;                               int in_iret(void);
  415.  
  416.     public  in_iret
  417.  
  418. in_iret proc
  419.     iret
  420. in_iret endp
  421.  
  422.     endcseg in_servc_
  423.     end
  424.  
  425.