--- /dev/null
+; MMURTL Operating System Source Code\r
+; Copyright 1991,1992,1993,1994 Richard A. Burgess\r
+; ALL RIGHTS RESERVED Version 1.0\r
+.DATA\r
+.INCLUDE MOSEDF.INC\r
+\r
+.CODE\r
+;=============================================================================\r
+; Set8259\r
+; This sets IRQ00-0F vectors in the 8259s\r
+; to be Int20 thru 2F.\r
+;\r
+; When the PICUs are initialized, all the hardware interrupts are MASKED.\r
+; Each driver that uses a hardware interrupt(s) is responsible\r
+; for unmasking that particular IRQ.\r
+;\r
+PICU1 EQU 0020h\r
+PICU2 EQU 00A0h\r
+\r
+PUBLIC Set8259:\r
+ MOV AL,00010001b\r
+ OUT PICU1+0,AL ;ICW1 - MASTER\r
+ PUSH EAX\r
+ POP EAX\r
+ OUT PICU2+0,AL ;ICW1 - SLAVE\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,20h\r
+ OUT PICU1+1,AL ;ICW2 - MASTER\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,28h\r
+ OUT PICU2+1,AL ;ICW2 - SLAVE\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,00000100b\r
+ OUT PICU1+1,AL ;ICW3 - MASTER\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,00000010b\r
+ OUT PICU2+1,AL ;ICW3 - SLAVE\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,00000001b\r
+ OUT PICU1+1,AL ;ICW4 - MASTER\r
+ PUSH EAX\r
+ POP EAX\r
+ OUT PICU2+1,AL ;ICW4 - SLAVE\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,11111010b ;Masked all but cascade/timer\r
+; MOV AL,01000000b ;Floppy masked\r
+ OUT PICU1+1,AL ;MASK - MASTER (0= Ints ON)\r
+ PUSH EAX\r
+ POP EAX\r
+ MOV AL,11111111b\r
+; MOV AL,00000000b\r
+ OUT PICU2+1,AL ;MASK - SLAVE\r
+ PUSH EAX\r
+ POP EAX\r
+ RETN\r
+\r
+;=====================================================\r
+;The following PUBLIC FAR calls support ISR operations:\r
+;\r
+; SetIRQVector(IRQnum, pVector)\r
+; GetIRQVector(IRQnum, pVectorRet)\r
+; EndOfIRQ(IRQnum)\r
+; MaskIRQ(IRQnum)\r
+; UnMaskIQR(IRQnum)\r
+;\r
+; In each case, IRQnum is the hardware interrupt request number for the\r
+; IRQ served. This will be 0-7 for interrupts on 8259 #1 and 8-15 for\r
+; interrupts on 8259 #2. The predetermined IRQ uses are:\r
+;\r
+; IRQ 0 8254 Timer\r
+; IRQ 1 Keyboard (8042)\r
+; IRQ 2 Cascade from PICU2 (handled internally)\r
+; IRQ 3 COMM 2 Serial port\r
+; IRQ 4 COMM 1 Serial port\r
+; IRQ 5 Line Printer 2\r
+; IRQ 6 Floppy disk controller\r
+; IRQ 7 Line Printer 1\r
+;\r
+; IRQ 8 CMOS Clock\r
+; IRQ 9 ?\r
+; IRQ 10 ?\r
+; IRQ 11 ?\r
+; IRQ 12 ?\r
+; IRQ 13 Math coprocessor\r
+; IRQ 14 Hard disk controller\r
+; IRQ 15 ?\r
+\r
+;=============================================================================\r
+;\r
+; SetIntVector(IRQNum, pISR)\r
+; This sets a 32 bit offset for an interrupt handler\r
+; that services one of the hardware interrupts. (0-15)\r
+; The ISR MUST reside in the OS Code segment. This means that only\r
+; device drivers or the OS can set and service interrupts!!\r
+; The DPL is set to 3 (all code can be hardware interrupted).\r
+;\r
+PUBLIC __SetIRQVector:\r
+ PUSH EBP\r
+ MOV EBP, ESP\r
+ MOV ECX, [EBP+16] ;Get IRQ number (0-15)\r
+ AND ECX, 0Fh ;0 to 15 max!\r
+ ADD ECX, 20h ;INT number is set for IRQ\r
+ MOV EAX, 08E00h ;Int gate description\r
+ MOV EBX, OSCodeSel ;\r
+ MOV ESI, [EBP+12] ;\r
+ CALL FWORD PTR _AddIDTGate ;\r
+ MOV ESP,EBP\r
+ POP EBP\r
+ RETF 8 ;\r
+\r
+;=============================================================================\r
+;\r
+; GetIntVector(IRQNum, pVectorRet)\r
+; This returns the vector (offset) of the ISR that is currently\r
+; serving the IRQ.\r
+;\r
+PUBLIC __GetIRQVector:\r
+ PUSH EBP\r
+ MOV EBP, ESP\r
+ MOV ESP,EBP\r
+ POP EBP\r
+ RETF 8 ;\r
+\r
+;=============================================================================\r
+;\r
+; Sends End Of Interrupt to PICU (or Both) based on IRQ number (0-15)\r
+; If IRQnum is 0-7 then we send to 1, else we send to 1 then 2.\r
+;\r
+PUBLIC __EndOfIRQ:\r
+ PUSH EBP\r
+ MOV EBP, ESP\r
+ PUSH EAX ;\r
+ MOV EAX, [EBP+0Ch] ;Get IRQ number (0-15)\r
+ MOV AH, AL\r
+ MOV AL,20h ;\r
+ OUT PICU1,AL ;\r
+ CMP AH, 7 ;PICU1 only?\r
+ JBE EOI00 ;Yes\r
+ OUT PICU2,AL ;Send to 2 also\r
+EOI00:\r
+ POP EAX ;\r
+ MOV ESP,EBP\r
+ POP EBP\r
+ RETF 4 ;\r
+\r
+;===============================================\r
+; MaskIRQ(IRQnum) masks the IRQ number specified (0-15).\r
+; The proper PICU is selected based on the IRQ number.\r
+;\r
+PUBLIC __MaskIRQ:\r
+ PUSH EBP\r
+ MOV EBP, ESP\r
+ PUSHFD\r
+ CLI\r
+ PUSH EAX ;\r
+ PUSH ECX\r
+ MOV EAX, 1\r
+ MOV ECX, [EBP+0Ch] ;Get IRQ number (0-15)\r
+ AND ECX, 0Fh ;(0-15)\r
+ SHL EAX, CL ;Set the bit for the IRQ (0-7) or (8-15)\r
+ AND AL,AL\r
+ JZ MIRQ2\r
+ MOV AH,AL\r
+ IN AL, PICU1+1\r
+ PUSH EAX\r
+ POP EAX\r
+ OR AL, AH\r
+ OUT PICU1+1, AL\r
+ JMP SHORT MIRQEnd\r
+MIRQ2:\r
+ IN AL, PICU2+1 ;AH already has correct value\r
+ PUSH EAX\r
+ POP EAX\r
+ OR AL, AH\r
+ OUT PICU2+1, AL\r
+MIRQEnd:\r
+ POP ECX ;\r
+ POP EAX ;\r
+ POPFD ;Give em their flags back\r
+ MOV ESP,EBP\r
+ POP EBP\r
+ RETF 4 ;\r
+;===============================================\r
+; UnMaskIRQ(IRQnum) UNmasks the IRQ number specified (0-15).\r
+; The proper PICU is selected based on the IRQ number.\r
+;\r
+PUBLIC __UnMaskIRQ:\r
+ PUSH EBP\r
+ MOV EBP, ESP\r
+ PUSHFD\r
+ CLI ;Previous state is reset on POPFD\r
+ PUSH EAX ;\r
+ PUSH ECX\r
+ MOV EAX,1\r
+ MOV ECX,[EBP+0Ch] ;Get IRQ number (0-15)\r
+ AND ECX, 0Fh ; (0-15 only)\r
+ SHL EAX, CL ;Set the bit for the IRQ (0-7)\r
+ AND AL,AL\r
+ JZ UMIRQ2\r
+ MOV AH, AL\r
+ IN AL, PICU1+1\r
+ PUSH EAX\r
+ POP EAX\r
+ NOT AH\r
+ AND AL, AH\r
+ OUT PICU1+1, AL\r
+ JMP SHORT UMIRQEnd\r
+UMIRQ2:\r
+ IN AL, PICU2+1\r
+ PUSH EAX\r
+ POP EAX\r
+ NOT AH\r
+ AND AL, AH\r
+ OUT PICU2+1, AL\r
+UMIRQEnd:\r
+ POP ECX ;\r
+ POP EAX ;\r
+ POPFD\r
+ MOV ESP,EBP\r
+ POP EBP\r
+ RETF 4 ;\r
+;\r
+;===== Module End ================\r