1 ;------------------------------------------------------------------------------
3 ;* Copyright 2006 - 2007, Intel Corporation
4 ;* All rights reserved. This program and the accompanying materials
5 ;* are licensed and made available under the terms and conditions of the BSD License
6 ;* which accompanies this distribution. The full text of the license may be found at
7 ;* http://opensource.org/licenses/bsd-license.php
9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 ;------------------------------------------------------------------------------
23 FAT_DIRECTORY_ENTRY_SIZE
EQU 020h
24 FAT_DIRECTORY_ENTRY_SHIFT
EQU 5
31 jmp BootSectorEntryPoint
; JMP inst - 3 bytes
34 OemId
db "INTEL " ; OemId - 8 bytes
35 SectorSize
dw 0 ; Sector Size - 2 bytes
36 SectorsPerCluster
db 0 ; Sector Per Cluster - 1 byte
37 ReservedSectors
dw 0 ; Reserved Sectors - 2 bytes
38 NoFats
db 0 ; Number of FATs - 1 byte
39 RootEntries
dw 0 ; Root Entries - 2 bytes
40 Sectors
dw 0 ; Number of Sectors - 2 bytes
41 Media
db 0 ; Media - 1 byte
42 SectorsPerFat16
dw 0 ; Sectors Per FAT for FAT12/FAT16 - 2 byte
43 SectorsPerTrack
dw 0 ; Sectors Per Track - 2 bytes
44 Heads
dw 0 ; Heads - 2 bytes
45 HiddenSectors
dd 0 ; Hidden Sectors - 4 bytes
46 LargeSectors
dd 0 ; Large Sectors - 4 bytes
48 ;******************************************************************************
50 ;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
51 ;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
53 ;******************************************************************************
55 SectorsPerFat32
dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
56 ExtFlags
dw 0 ; Mirror Flag - 2 bytes
57 FSVersion
dw 0 ; File System Version - 2 bytes
58 RootCluster
dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
59 FSInfo
dw 0 ; Sector Number of FSINFO - 2 bytes
60 BkBootSector
dw 0 ; Sector Number of Bk BootSector - 2 bytes
61 Reserved
db 12 dup
(0) ; Reserved Field - 12 bytes
62 PhysicalDrive
db 0 ; Physical Drive Number - 1 byte
63 Reserved1
db 0 ; Reserved Field - 1 byte
64 Signature
db 0 ; Extended Boot Signature - 1 byte
65 VolId
db " " ; Volume Serial Number - 4 bytes
66 FatLabel
db " " ; Volume Label - 11 bytes
67 FileSystemType
db "FAT32 " ; File System Type - 8 bytes
72 ; ds = 1000, es = 2000 + x (size of first cluster >> 4)
73 ; cx = Start Cluster of EfiLdr
74 ; dx = Start Cluster of Efivar.bin
76 ; Re use the BPB data stored in Boot Sector
82 ; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
91 ; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
92 mov byte ptr es:[4],al
97 cmp dword ptr ds:[di+2], 04000h
103 mov byte ptr es:[4],al
113 mov ax,word ptr [bp+VolId
]
114 mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
115 mov ax,word ptr [bp+VolId
+2]
116 mov word ptr es:[2],ax
120 ; cx = Start Cluster of Efildr -> BS.com has filled already
121 ; ES:DI = 2000:0, first cluster will be read again
127 mov word ptr cs:[JumpSegment
],ax
138 ; ****************************************************************************
142 ; CX = Start Cluster of File
143 ; ES:DI = Buffer to store file content read from disk
146 ; (ES << 4 + DI) = end of file content Buffer
148 ; ****************************************************************************
150 ; si = NumberOfClusters
152 ; dx = CachedFatSectorNumber
153 ; ds:0000 = CacheFatSectorBuffer
154 ; es:di = Buffer to load file
155 ; bx = NextClusterNumber
157 mov si,1 ; NumberOfClusters = 1
158 push cx ; Push Start Cluster onto stack
159 mov dx,0fffh
; CachedFatSectorNumber = 0xfff
161 mov ax,cx ; ax = ClusterNumber
162 and ax,0fff8h
; ax = ax & 0xfff8
163 cmp ax,0fff8h
; See if this is the last cluster
164 je FoundLastCluster
; Jump if last cluster found
165 mov ax,cx ; ax = ClusterNumber
166 shl ax,2 ; FatOffset = ClusterNumber * 4
168 mov si,ax ; si = FatOffset
169 shr ax,BLOCK_SHIFT
; ax = FatOffset >> BLOCK_SHIFT
170 add ax,word ptr [bp+ReservedSectors
] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
171 and si,BLOCK_MASK
; si = FatOffset & BLOCK_MASK
172 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
178 call ReadBlocks
; Read 2 blocks starting at AX storing at ES:DI
180 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
182 mov bx,word ptr [si] ; bx = NextClusterNumber
183 mov ax,cx ; ax = ClusterNumber
185 dec bx ; bx = NextClusterNumber - 1
186 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
188 inc bx ; bx = NextClusterNumber
189 inc si ; NumberOfClusters++
190 mov cx,bx ; ClusterNumber = NextClusterNumber
194 pop ax ; ax = StartCluster
195 push bx ; StartCluster = NextClusterNumber
196 mov cx,bx ; ClusterNumber = NextClusterNumber
197 sub ax,2 ; ax = StartCluster - 2
199 mov bl,byte ptr [bp+SectorsPerCluster
] ; bx = SectorsPerCluster
200 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
201 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
202 push ax ; save start sector
203 mov ax,si ; ax = NumberOfClusters
204 mul bx ; ax = NumberOfClusters * SectorsPerCluster
205 mov bx,ax ; bx = Number of Sectors
206 pop ax ; ax = Start Sector
208 mov si,1 ; NumberOfClusters = 1
216 ; ****************************************************************************
217 ; ReadBlocks - Reads a set of blocks from a block device
220 ; BX = Number of Blocks to Read
221 ; ES:DI = Buffer to store sectors read from disk
222 ; ****************************************************************************
225 ; bx = NumberOfBlocks
230 add eax,dword ptr [bp+LBAOffsetForBootSector
] ; Add LBAOffsetForBootSector to Start LBA
231 add eax,dword ptr [bp+HiddenSectors
] ; Add HiddenSectors to Start LBA
232 mov esi,eax ; esi = Start LBA
233 mov cx,bx ; cx = Number of blocks to read
235 mov bp,07bfch
; bp = 0x7bfc
236 mov eax,esi ; eax = Start LBA
237 xor edx,edx ; edx = 0
238 movzx ebx,word ptr [bp] ; bx = MaxSector
239 div ebx ; ax = StartLBA / MaxSector
240 inc dx ; dx = (StartLBA % MaxSector) + 1
242 mov bx,word ptr [bp] ; bx = MaxSector
243 sub bx,dx ; bx = MaxSector - Sector
244 inc bx ; bx = MaxSector - Sector + 1
245 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
247 mov bx,cx ; bx = Blocks
251 shr ax,(BLOCK_SHIFT
-4) ; ax = Number of blocks into mem system
252 and ax,07fh
; ax = Number of blocks into current seg
253 add ax,bx ; ax = End Block number of transfer
254 cmp ax,080h ; See if it crosses a 64K boundry
255 jle NotCrossing64KBoundry
; Branch if not crossing 64K boundry
256 sub ax,080h ; ax = Number of blocks past 64K boundry
257 sub bx,ax ; Decrease transfer size by block overage
258 NotCrossing64KBoundry:
262 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
264 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
265 ; dx = ax % (MaxHead + 1) = Head
267 push bx ; Save number of blocks to transfer
268 mov dh,dl ; dh = Head
269 mov bp,07c00h
; bp = 0x7c00
270 mov dl,byte ptr [bp+PhysicalDrive
] ; dl = Drive Number
271 mov ch,al ; ch = Cylinder
272 mov al,bl ; al = Blocks
273 mov ah,2 ; ah = Function 2
274 mov bx,di ; es:bx = Buffer address
280 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
281 sub cx,bx ; Blocks = Blocks - NumberOfBlocks
283 shl bx,(BLOCK_SHIFT
-4)
285 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
294 lea si, [ErrorString
]
296 jmp PrintStringAndHalt
307 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
310 LBAOffsetForBootSector:
316 ;******************************************************************************
317 ;******************************************************************************
318 ;******************************************************************************
320 DELAY_PORT
equ 0edh
; Port to use for 1uS delay
321 KBD_CONTROL_PORT
equ 060h ; 8042 control port
322 KBD_STATUS_PORT
equ 064h ; 8042 status port
323 WRITE_DATA_PORT_CMD
equ 0d1h
; 8042 command to write the data port
324 ENABLE_A20_CMD
equ 0dfh
; 8042 command to enable A20
329 db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
340 ; mov byte ptr es:[160],'a'
358 sub edi,eax ; Get the address of the memory map
359 mov dword ptr [MemoryMapSize
],edi ; Save the size of the memory map
362 mov bx,cs ; BX=segment
363 shl ebx,4 ; BX="linear" address of segment base
364 lea eax,[GDT_BASE
+ ebx] ; EAX=PHYSICAL address of gdt
365 mov dword ptr [gdtr
+ 2],eax ; Put address of gdt into the gdtr
366 lea eax,[IDT_BASE
+ ebx] ; EAX=PHYSICAL address of idt
367 mov dword ptr [idtr
+ 2],eax ; Put address of idt into the idtr
368 lea edx,[MemoryMapSize
+ ebx] ; Physical base address of the memory map
370 add ebx,01000h ; Source of EFI32
371 mov dword ptr [JUMP
+2],ebx
373 mov esi,ebx ; Source of EFILDR32
377 ; mov byte ptr es:[162],'b'
385 mov ax,2401h ; Enable A20 Gate
387 jnc A20GateEnabled
; Jump if it suceeded
390 ; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
393 call Empty8042InputBuffer
; Empty the Input Buffer on the 8042 controller
394 jnz Timeout8042
; Jump if the 8042 timed out
395 out DELAY_PORT
,ax ; Delay 1 uS
396 mov al,WRITE_DATA_PORT_CMD
; 8042 cmd to write output port
397 out KBD_STATUS_PORT
,al ; Send command to the 8042
398 call Empty8042InputBuffer
; Empty the Input Buffer on the 8042 controller
399 jnz Timeout8042
; Jump if the 8042 timed out
400 mov al,ENABLE_A20_CMD
; gate address bit 20 on
401 out KBD_CONTROL_PORT
,al ; Send command to thre 8042
402 call Empty8042InputBuffer
; Empty the Input Buffer on the 8042 controller
403 mov cx,25 ; Delay 25 uS for the command to complete on the 8042
405 out DELAY_PORT
,ax ; Delay 1 uS
413 ; DISABLE INTERRUPTS - Entering Protected Mode
420 ; mov byte ptr es:[164],'c'
425 lgdt fword
ptr [gdtr
]
427 lidt fword
ptr [idtr
]
433 mov eax,0008h ; Flat data descriptor
434 mov ebp,000400000h ; Destination of EFILDR32
435 mov ebx,000070000h ; Length of copy
438 ; jmp far 0010:00020000
444 Empty8042InputBuffer:
447 out DELAY_PORT
,ax ; Delay 1us
448 in al,KBD_STATUS_PORT
; Read the 8042 Status Port
449 and al,02h ; Check the Input Buffer Full Flag
450 loopnz Empty8042Loop
; Loop until the input buffer is empty or a timout of 65536 uS
453 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
455 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
459 gdtr
dw GDT_END
- GDT_BASE
- 1 ; GDT limit
460 dd 0 ; (GDT base gets set above)
461 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
462 ; global descriptor table (GDT)
463 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
470 NULL_SEL
equ $
-GDT_BASE
475 db 0 ; limit 19:16, flags
478 ; linear data segment descriptor
479 LINEAR_SEL
equ $
-GDT_BASE
480 dw 0FFFFh
; limit 0xFFFFF
483 db 092h ; present, ring 0, data, expand-up, writable
484 db 0CFh
; page-granular, 32-bit
487 ; linear code segment descriptor
488 LINEAR_CODE_SEL
equ $
-GDT_BASE
489 dw 0FFFFh
; limit 0xFFFFF
492 db 09Ah ; present, ring 0, data, expand-up, writable
493 db 0CFh
; page-granular, 32-bit
496 ; system data segment descriptor
497 SYS_DATA_SEL
equ $
-GDT_BASE
498 dw 0FFFFh
; limit 0xFFFFF
501 db 092h ; present, ring 0, data, expand-up, writable
502 db 0CFh
; page-granular, 32-bit
505 ; system code segment descriptor
506 SYS_CODE_SEL
equ $
-GDT_BASE
507 dw 0FFFFh
; limit 0xFFFFF
510 db 09Ah ; present, ring 0, data, expand-up, writable
511 db 0CFh
; page-granular, 32-bit
514 ; spare segment descriptor
515 SPARE3_SEL
equ $
-GDT_BASE
519 db 0 ; present, ring 0, data, expand-up, writable
520 db 0 ; page-granular, 32-bit
523 ; spare segment descriptor
524 SPARE4_SEL
equ $
-GDT_BASE
528 db 0 ; present, ring 0, data, expand-up, writable
529 db 0 ; page-granular, 32-bit
532 ; spare segment descriptor
533 SPARE5_SEL
equ $
-GDT_BASE
537 db 0 ; present, ring 0, data, expand-up, writable
538 db 0 ; page-granular, 32-bit
547 idtr
dw IDT_END
- IDT_BASE
- 1 ; IDT limit
548 dd 0 ; (IDT base gets set above)
549 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
550 ; interrupt descriptor table (IDT)
552 ; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
553 ; mappings. This implementation only uses the system timer and all other
554 ; IRQs will remain masked. The descriptors for vectors 33+ are provided
556 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
563 ; divide by zero (INT 0)
564 DIV_ZERO_SEL
equ $
-IDT_BASE
566 dw SYS_CODE_SEL
; selector 15:0
567 db 0 ; 0 for interrupt gate
568 db 0eh
OR 80h ; type = 386 interrupt gate, present
571 ; debug exception (INT 1)
572 DEBUG_EXCEPT_SEL
equ $
-IDT_BASE
574 dw SYS_CODE_SEL
; selector 15:0
575 db 0 ; 0 for interrupt gate
576 db 0eh
OR 80h ; type = 386 interrupt gate, present
580 NMI_SEL
equ $
-IDT_BASE
582 dw SYS_CODE_SEL
; selector 15:0
583 db 0 ; 0 for interrupt gate
584 db 0eh
OR 80h ; type = 386 interrupt gate, present
587 ; soft breakpoint (INT 3)
588 BREAKPOINT_SEL
equ $
-IDT_BASE
590 dw SYS_CODE_SEL
; selector 15:0
591 db 0 ; 0 for interrupt gate
592 db 0eh
OR 80h ; type = 386 interrupt gate, present
596 OVERFLOW_SEL
equ $
-IDT_BASE
598 dw SYS_CODE_SEL
; selector 15:0
599 db 0 ; 0 for interrupt gate
600 db 0eh
OR 80h ; type = 386 interrupt gate, present
603 ; bounds check (INT 5)
604 BOUNDS_CHECK_SEL
equ $
-IDT_BASE
606 dw SYS_CODE_SEL
; selector 15:0
607 db 0 ; 0 for interrupt gate
608 db 0eh
OR 80h ; type = 386 interrupt gate, present
611 ; invalid opcode (INT 6)
612 INVALID_OPCODE_SEL
equ $
-IDT_BASE
614 dw SYS_CODE_SEL
; selector 15:0
615 db 0 ; 0 for interrupt gate
616 db 0eh
OR 80h ; type = 386 interrupt gate, present
619 ; device not available (INT 7)
620 DEV_NOT_AVAIL_SEL
equ $
-IDT_BASE
622 dw SYS_CODE_SEL
; selector 15:0
623 db 0 ; 0 for interrupt gate
624 db 0eh
OR 80h ; type = 386 interrupt gate, present
627 ; double fault (INT 8)
628 DOUBLE_FAULT_SEL
equ $
-IDT_BASE
630 dw SYS_CODE_SEL
; selector 15:0
631 db 0 ; 0 for interrupt gate
632 db 0eh
OR 80h ; type = 386 interrupt gate, present
635 ; Coprocessor segment overrun - reserved (INT 9)
636 RSVD_INTR_SEL1
equ $
-IDT_BASE
638 dw SYS_CODE_SEL
; selector 15:0
639 db 0 ; 0 for interrupt gate
640 db 0eh
OR 80h ; type = 386 interrupt gate, present
643 ; invalid TSS (INT 0ah)
644 INVALID_TSS_SEL
equ $
-IDT_BASE
646 dw SYS_CODE_SEL
; selector 15:0
647 db 0 ; 0 for interrupt gate
648 db 0eh
OR 80h ; type = 386 interrupt gate, present
651 ; segment not present (INT 0bh)
652 SEG_NOT_PRESENT_SEL
equ $
-IDT_BASE
654 dw SYS_CODE_SEL
; selector 15:0
655 db 0 ; 0 for interrupt gate
656 db 0eh
OR 80h ; type = 386 interrupt gate, present
659 ; stack fault (INT 0ch)
660 STACK_FAULT_SEL
equ $
-IDT_BASE
662 dw SYS_CODE_SEL
; selector 15:0
663 db 0 ; 0 for interrupt gate
664 db 0eh
OR 80h ; type = 386 interrupt gate, present
667 ; general protection (INT 0dh)
668 GP_FAULT_SEL
equ $
-IDT_BASE
670 dw SYS_CODE_SEL
; selector 15:0
671 db 0 ; 0 for interrupt gate
672 db 0eh
OR 80h ; type = 386 interrupt gate, present
675 ; page fault (INT 0eh)
676 PAGE_FAULT_SEL
equ $
-IDT_BASE
678 dw SYS_CODE_SEL
; selector 15:0
679 db 0 ; 0 for interrupt gate
680 db 0eh
OR 80h ; type = 386 interrupt gate, present
683 ; Intel reserved - do not use (INT 0fh)
684 RSVD_INTR_SEL2
equ $
-IDT_BASE
686 dw SYS_CODE_SEL
; selector 15:0
687 db 0 ; 0 for interrupt gate
688 db 0eh
OR 80h ; type = 386 interrupt gate, present
691 ; floating point error (INT 10h)
692 FLT_POINT_ERR_SEL
equ $
-IDT_BASE
694 dw SYS_CODE_SEL
; selector 15:0
695 db 0 ; 0 for interrupt gate
696 db 0eh
OR 80h ; type = 386 interrupt gate, present
699 ; alignment check (INT 11h)
700 ALIGNMENT_CHECK_SEL
equ $
-IDT_BASE
702 dw SYS_CODE_SEL
; selector 15:0
703 db 0 ; 0 for interrupt gate
704 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
707 ; machine check (INT 12h)
708 MACHINE_CHECK_SEL
equ $
-IDT_BASE
710 dw SYS_CODE_SEL
; selector 15:0
711 db 0 ; 0 for interrupt gate
712 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
715 ; SIMD floating-point exception (INT 13h)
716 SIMD_EXCEPTION_SEL
equ $
-IDT_BASE
718 dw SYS_CODE_SEL
; selector 15:0
719 db 0 ; 0 for interrupt gate
720 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
723 ; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
726 ; IRQ 0 (System timer) - (INT 68h)
727 IRQ0_SEL
equ $
-IDT_BASE
729 dw SYS_CODE_SEL
; selector 15:0
730 db 0 ; 0 for interrupt gate
731 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
734 ; IRQ 1 (8042 Keyboard controller) - (INT 69h)
735 IRQ1_SEL
equ $
-IDT_BASE
737 dw SYS_CODE_SEL
; selector 15:0
738 db 0 ; 0 for interrupt gate
739 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
742 ; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
743 IRQ2_SEL
equ $
-IDT_BASE
745 dw SYS_CODE_SEL
; selector 15:0
746 db 0 ; 0 for interrupt gate
747 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
750 ; IRQ 3 (COM 2) - (INT 6bh)
751 IRQ3_SEL
equ $
-IDT_BASE
753 dw SYS_CODE_SEL
; selector 15:0
754 db 0 ; 0 for interrupt gate
755 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
758 ; IRQ 4 (COM 1) - (INT 6ch)
759 IRQ4_SEL
equ $
-IDT_BASE
761 dw SYS_CODE_SEL
; selector 15:0
762 db 0 ; 0 for interrupt gate
763 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
766 ; IRQ 5 (LPT 2) - (INT 6dh)
767 IRQ5_SEL
equ $
-IDT_BASE
769 dw SYS_CODE_SEL
; selector 15:0
770 db 0 ; 0 for interrupt gate
771 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
774 ; IRQ 6 (Floppy controller) - (INT 6eh)
775 IRQ6_SEL
equ $
-IDT_BASE
777 dw SYS_CODE_SEL
; selector 15:0
778 db 0 ; 0 for interrupt gate
779 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
782 ; IRQ 7 (LPT 1) - (INT 6fh)
783 IRQ7_SEL
equ $
-IDT_BASE
785 dw SYS_CODE_SEL
; selector 15:0
786 db 0 ; 0 for interrupt gate
787 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
790 ; IRQ 8 (RTC Alarm) - (INT 70h)
791 IRQ8_SEL
equ $
-IDT_BASE
793 dw SYS_CODE_SEL
; selector 15:0
794 db 0 ; 0 for interrupt gate
795 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
799 IRQ9_SEL
equ $
-IDT_BASE
801 dw SYS_CODE_SEL
; selector 15:0
802 db 0 ; 0 for interrupt gate
803 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
807 IRQ10_SEL
equ $
-IDT_BASE
809 dw SYS_CODE_SEL
; selector 15:0
810 db 0 ; 0 for interrupt gate
811 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
815 IRQ11_SEL
equ $
-IDT_BASE
817 dw SYS_CODE_SEL
; selector 15:0
818 db 0 ; 0 for interrupt gate
819 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
822 ; IRQ 12 (PS/2 mouse) - (INT 74h)
823 IRQ12_SEL
equ $
-IDT_BASE
825 dw SYS_CODE_SEL
; selector 15:0
826 db 0 ; 0 for interrupt gate
827 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
830 ; IRQ 13 (Floating point error) - (INT 75h)
831 IRQ13_SEL
equ $
-IDT_BASE
833 dw SYS_CODE_SEL
; selector 15:0
834 db 0 ; 0 for interrupt gate
835 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
838 ; IRQ 14 (Secondary IDE) - (INT 76h)
839 IRQ14_SEL
equ $
-IDT_BASE
841 dw SYS_CODE_SEL
; selector 15:0
842 db 0 ; 0 for interrupt gate
843 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
846 ; IRQ 15 (Primary IDE) - (INT 77h)
847 IRQ15_SEL
equ $
-IDT_BASE
849 dw SYS_CODE_SEL
; selector 15:0
850 db 0 ; 0 for interrupt gate
851 db 0eh
OR 80h ; (10001110)type = 386 interrupt gate, present
859 MemoryMap
dd 0,0,0,0,0,0,0,0
890 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
891 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
895 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
896 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
897 ; known low address (20f00) so it can be set up by PlMapIrqToVect in