Hi, find enclosed pic.asi, iodelay.asi, and pic.asm. These are modules of a 386 assembly language program that deal with reprogramming the pics. Actually reprogramming the pics is the simple part; you just output appropriate initialization values to the controller ports. See picini and related data structures for the detail and the values to use. The remainder of this routine is basically swapping interrupt vectors around to the point of use... that was the hard part. Note that one of the initialize values is the vector base address for the PIC; there are two pics and each can have an individual base vector. all interrupts on the pic are then done relative to the base vector. You SHOULD have interrupts disabled while reprogramming the pics and moving vectors around... David ------------------------iodelay.asi------------------------- ; ; LSD ; ; Copyright(c) LADsoft ; ; David Lindauer, gclind01@starbase.spd.louisville.edu ; IODELAY MACRO REPT 3 JMP $+2 ENDM ENDM ---------------------------pic.asi-------------------------- ; ; LSD ; ; Copyright(c) LADsoft ; ; David Lindauer, gclind01@starbase.spd.louisville.edu ; PIC0ADR EQU 020h PIC1ADR EQU 0A0h NSEOI EQU 020h PIC0VECTOR EQU 30h PIC1VECTOR EQU 38h BIOSPIC0VECTOR EQU 8h BIOSPIC1VECTOR EQU 70h PR_INSERVICE EQU 0bh ; ; Read from PIC ; ; adr = offset in PIC ; pic (defaults to first PIC) = address of pic ; PICREAD MACRO adr,pic local temp ifnb temp = adr else temp = 0 endif ifnb temp = temp + pic else temp = temp + PIC0ADR endif in al,temp ENDM ; ; Write to PIC ; ; adr = offset in PIC ; pic (defaults to first PIC) = address of pic ; PICWRITE MACRO adr,pic local temp ifnb temp = adr else temp = 0 endif ifnb temp = temp + pic else temp = temp + PIC0ADR endif out temp,al ENDM ; ; Delay for a bit ; PICDELAY MACRO jmp $+2 jmp $+2 ENDM ; ; Enable an interrupt by turning off a bit in the PIC ; ; number = bit number ; status = an optional place to store initial status ; pic (defaults to first PIC) = address of pic ; ; PICENABLE MACRO number, status, pic PICREAD 1,pic ifnb ; If we're restoring it exactly later mov status,al ; Save the status endif and al,NOT (1 SHL number) ; Now and out the bit PICWRITE 1,pic ENDM ; ; Disable an interrupt by turning on a bit in the PIC ; ; number = bit number ; status = an optional place to store initial status ; pic (defaults to first PIC) = address of pic ; PICDISABLE MACRO number,status, pic ifnb ; If we previously saved the status mov al,status ; Get it else PICREAD 1,pic or al,1 SHL NUMBER ; And or in the bit endif PICWRITE 1,pic ENDM ; ; While in an interrupt, reset the PIC to enable more interrupts ; ; pic = PIC ; PICACK MACRO pic mov al,NSEOI ; Status bit PICWRITE 0,pic ENDM -------------------------pic.asm------------------------------ ; ; LSD ; ; Copyright(c) LADsoft ; ; David Lindauer, gclind01@starbase.spd.louisville.edu ; ; ; Pic.asm ; ; Function: Programmable interrupt controller functionality ; Handles mapping interrupts to the DOS or Kernel locations ; ;MASM MODE .386p MODEL SMALL, PROLOG PUBLIC pic386, pic8086 include segs.asi include pic.asi include iodelay.asi ; ; Macro to move interrupt vectors around ; MOVVECT MACRO source,dest,ds,es cld mov esi,offset dgroup:source ; Get source mov edi,offset dgroup:dest ; And dest mov ecx,8 ; 8 vectors / pic ifnb ; If absolute DS push ds ; Load absolute DS push fs pop ds endif ifnb ; If absolute ES push es ; Load absolute ES push fs pop es endif rep movsd ; Move 8 vectors ifnb ; Restore ES pop es endif ifnb ; Restore DS pop ds endif ENDM absdata SEGMENT org BIOSPIC0VECTOR * 4 bios0vectors dd 8 DUP (?) ; Original PIC 0 interrupts org BIOSPIC1VECTOR * 4 bios1vectors dd 8 DUP (?) ; Original PIC 1 interrupts org PIC0VECTOR * 4 new0vectors dd 8 DUP (?) ; New PIC 0 interrupts org PIC1VECTOR * 4 new1vectors dd 8 DUP (?) ; New PIC 1 interrupts absdata ENDS seg386data SEGMENT align save0vectors dd 8 DUP (?) ; Holds original values save1vectors dd 8 DUP (?) ; of real-mode interrupts ; we're about to step on setup8086 db 11h ; ICW1 db BIOSPIC0VECTOR ; ICW2 db 4 ; ICW3 db 1 ; icw4 pic0stat db 0 ; Original interrupt enable db 11h ; ICW1 db BIOSPIC1VECTOR ; ICW2 db 2 ; ICW3 db 1 ; icw4 pic1stat db 0 ; Original interrupt enable setup386 db 11h ; ICW1 db PIC0VECTOR ; ICW2 db 4 ; ICW3 db 1 ; icw4 pic0stat2 db 0 ; Original interrupt enable db 11h ; ICW1 db PIC1VECTOR ; ICW2 db 2 ; ICW3 db 1 ; icw4 pic1stat2 db 0 ; Original interrupt enable seg386data ENDS ; ; Initialize PIC ; seg386 SEGMENT picini PROC cld ; Upward dir mov dx,PIC0ADR ; Do PIC0 call picout mov dl,PIC1ADR ; Do PIC 1 picout: lodsb ; GET ICW1 out dx,al ; output inc dx ; Set to control reg mov ecx,4 ; 4 more to output piclp: outsb ; Output one IODELAY loop piclp ; Loop ret ; Done picini ENDP pic8086 PROC pushf cli MOVVECT save0vectors,new0vectors,,es ; Restore trodden vectors MOVVECT save1vectors,new1vectors,,es mov esi,offset dgroup:setup8086 call picini ; Initialize PIC popf ret pic8086 ENDP pic386 PROC pushfd cli MOVVECT new0vectors,save0vectors,ds ; Save vectors we'll tread on MOVVECT new1vectors,save1vectors,ds MOVVECT bios0vectors,new0vectors,ds,es ; Use original hardware ints MOVVECT bios1vectors,new1vectors,ds,es PICREAD 1,PIC0ADR ; Read interrupt enable status mov [pic0stat],al mov [pic0stat2],al PICREAD 1,PIC1ADR mov [pic1stat],al mov [pic1stat2],al mov esi,offset dgroup:setup386 call picini ; Initialize PIC popfd ret pic386 ENDP seg386 ENDS END wc