home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE Protected mode programming
- .286P ; Privliged programming
-
-
- ;=============================================================================;
- ; ;
- ; Example "skeleton" program that creates a GDT, IDT ;
- ; and enables Protected Mode as follows: ;
- ; ;
- ; 1) Provides GDT containing descriptors needed by the initial ;
- ; Protected Mode Task, ;
- ; ;
- ; 2) Provides IDT containing a full complement of gates for CPU ;
- ; Exceptions and eight 8259A interrupts, ;
- ; ;
- ; 3) Enables 80286 Protected Mode. ;
- ; ;
- ; This example enables access to the full 16MB physical address space. ;
- ; It DOES NOT perform task switching. ;
- ; ;
- ; Suggested that object code is burned into two 2764 EPROM's ;
- ;=============================================================================;
- PAGE
-
- Descriptor STRUC ; A descriptor structure
- Limit Dw ? ; A limit in bytes
- BaseLowWord Dw ? ; Base word
- BaseHighByte Db ? ; Base byte high
- Access Db ? ; Access rights byte
- Reserved Dw 0 ; Reserved word
- Descriptor ENDS
-
- ; EQUATES
-
- GDT_ELEMENTS EQU 16 ; Number of descriptor slots in GDT
- IDT_ELEMENTS EQU 64 ; Number of slots in IDT
-
- MAIN_CODE_SELECTOR EQU 0038h ; Selector for main code segment
- EX_CODE_SELECTOR EQU 0040h ; Selector for exception code
- INT_CODE_SELECTOR EQU 0048h ; Selector for interrupt code segment
-
- ; Physical mem equates -- This deals with the EPROM's
-
- MAIN_CODE_BASE EQU 0068h ;
- EXCEPTION_CODE_BASE EQU 0078h ;
- INTERRUPT_CODE_BASE EQU 0088h ;
-
- ; I/O address equates
-
- OUTPUT_DATA_PORT EQU 03BCh ; Address of Data out of printer
- OUTPUT_STATUS_PORT1 EQU 03BDh ; Address of control latch (in)
- OUTPUT_STATUS_PORT2 EQU 03BEh ; Control latch of ptr (out)
- STROBE_HIGH EQU 0Dh ;
- STROBE_LOW EQU 0Ch ;
- PAGE
- ;=============================================================================;
- ; Definition of EPROM contents. ;
- ; This example assumes two 2764 (8K x 8) at high end of memory. ;
- ; The Lowest address is thus FFC000h. ;
- ; Since the 80286 CS base initially equals FF0000h, the lowest EPROM ;
- ; address is referenced by an IP value of C000h. ;
- ;=============================================================================;
-
- ; EPROM RESIDENT IMAGE OF GDT and IDT
- ; Initlization copies image to RAM, starting at 000000h.
-
- INITIAL_DATA SEGMENT
- ASSUME cs:INITIAL_DATA
-
- ; The size of this GDT allows 16 slots for descriptors or gates
-
- Gdt_Image_Start:
-
- ;---The first GDT slot is always unused (The null selector, SLECTOR - 0000h---;
- Dw 0 ;
- Dw 0 ;
- Dw 0 ;
- Dw 0 ;
-
- ;---GDT_alias descriptor (SELECTOR - 0008h)-----------------------------------;
- Dw 7Fh ; Limit (16 * 8) - 1
- Dw 0 ; Base at 0
- Db 0 ;
- Db 10010011b ; Access rights for data segment
- Dw 0 ; Insure Compatability with 80386
-
- ;---IDT_alias secriptor (SELECTOR = 0010h)------------------------------------;
- Dw 1FFh ; IDT_alias limit (64 * 8) - 1
- Dw 80h ; Base is after GDT in RAM
- Db 0 ;
- Db 10010011b ; Access rights for data segment
- Dw 0 ;
-
- ;---Level 0 stack segment descriptor (SELECTOR = 0018h)-----------------------;
- Dw TOS - 1 ; Limit 1k (1024 - 1)
- Dw SEG TOS ; Follows IDT in RAM
- Db 0 ;
- Db 10010011b ; Access rights byte
- Dw 0 ;
-
- ;---Main data segment descriptor (SELECTOR - 0020h)---------------------------;
- Dw 0FFh ; Limit (256 - 1)
- Dw 680h ; Follows level 0 stack
- Db 0 ;
- Db 10010011b ; Access rights byte
- Dw 0 ;
-
- ;---Exception data segment descriptor (SELECTOR = 0028h)----------------------;
- Dw 0FFh ; Limit (256 -1)
- Dw 780h ; Base follows main
- Db 0 ;
- Db 10010011b ; Access rights byte
- Dw 0 ;
-
- ;---Interrupt data segment descriptor (SELECTOR = 0030h)---------------------;
- Dw 0FFh ; Limit of interrupt (256 - 1)
- Dw 880h ; Base after the data segment
- Db 0 ;
- Db 10010011b ; Acess rights byte
- Dw 0 ; Insure compatibility with 80386
-
- ;---Main CODE segment descriptor (SELECTOR = 0038h)---------------------------;
- Dw End_Of_Main_Code; Limit of main code
- Dw SEG End_Of_Main_Code ; Base address
- Db 0 ;
- Db 10011011b ; Access rights for CODE segment
- Dw 0 ;
-
- ;---Exception CODE segment descriptor (SELECTOR = 0040h)----------------------;
- Dw End_Of_Exception_Code ; Limit of Excpetion CODE
- Dw SEG End_Of_Exception_Code
- Db 0 ; Base address of Excpetion
- Db 10011011b ; Access rights of CODE
- Dw 0 ;
-
- ;---Interrupt CODE segment Descriptor (SELECTOR = 0048h)----------------------;
- Dw End_Of_Interrupt_Code ; Limit
- Dw SEG End_Of_Interrupt_Code
- Db 0 ; Base address
- Db 10011011b ; Interrupt Acess of CODE
- Dw 0 ;
-
- ;---Blank Descriptor slots (10-15)--------------------------------------------;
- Db (16-10)*8 Dup(0)
-
- Gdt_Image_End:
- PAGE
- Idt_Image_Start:
- ;=============================================================================;
- ; IDT image in EPROM to be copied to RAM diring INIT, note gate for each ;
- ; exception by the 80286, furthurmore, assuming one 8259A int controller, ;
- ; 8 int gates placed in slots 32-39. ;
- ; The sixe of this IDT allows 64 slots for gates. ;
- ;=============================================================================;
-
-
- ;---Divide Error (Exception 0)------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; Acess rights for TRAP gate
- Dw 0 ; 80386 comp.
-
- ;---Single Step (Exception 1)-------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ;
- Db 11100111b ; Access rights for TRAP gate
- Dw 0 ;
-
- ;---NMI int (Exception 2)-----------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100110b ; Access rights of INT gate
- Dw 0 ;
-
- ;---Breakpoint trap (Exception 3)---------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---INTO trap (Exception 4)---------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---BOUNDS trap (Exception 5)------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Invalid Opcode (Exception 6)----------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Math coprocessor not available (Exception 7)------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Double Fault (Exception 8)------------------------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Coproccessor operand partially beond segment (Exception 9)----------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Invalid task state segment (Exception 10)---------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---CS, DS, ES segment not present (Exception 11)-----------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---SS not present or stack segment violation (Exception 12)------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---General protection violation (Exception 13)-------------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Excpetion 14 reserved by intell but not used on 80286---------------------;
- Dw 0 ;
- Dw 0 ;
- Db 0 ;
- Db 0 ; Access code of 0 = invalid
- Dw 0 ;
-
- ;---Excpetion 15 reserved by intell but not used on 80286---------------------;
- Dw 0 ;
- Dw 0 ;
- Db 0 ;
- Db 0 ; Access code of 0 = invalid
- Dw 0 ;
-
- ;---Math coprocessor calculation error (Exception 16)-------------------------;
- Dw End_Of_Exception_Code
- Dw SEG End_Of_Exception_Code ;;
- Db 0 ; Base
- Db 11100111b ; TRAP access
- Dw 0 ;
-
- ;---Exception 17-31 reserved by intel, but unused by 80286--------------------;
- Db (32-17)*8 Dup(0); Reserve 0 on all slots
-
- PAGE
- ;-----------------------------------------------------------------------------;
- ; Interrupt gates are placed after intell reserved IDT slots 0-31. ;
- ; 8 gates for ones generated by 8259A are init for base of 32. ;
- ;-----------------------------------------------------------------------------;
-
-
- ;---Hardware Interrupt 32-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 33-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 34-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 35-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 36-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 37-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 38-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---Hardware Interrupt 39-----------------------------------------------------;
- Dw End_Of_Interrupt_Code
- Dw SEG End_Of_Interrupt_Code ;
- Db 0 ; Base
- Db 11100110b ; Interrupt gate access byte
- Dw 0 ; 0 for compat with 80386
-
- ;---IDT slots of interrupts numbered 40-63 are not used but available---------;
- Db (64-40)*8 Dup (0)
-
- Idt_Image_End:
- INITIAL_DATA ENDS
- PAGE
- ;=============================================================================;
- ; Initialization code -- setup. Made to put system in protected mode. ;
- ;=============================================================================;
- MAIN_CODE SEGMENT
- ASSUME cs:MAIN_CODE ;
-
- Jmp Flush ; Jump to flish
- ;
- Gdt_Pointer: ;
- Dw Gdt_Image_End - Gdt_Image_Start - 1 ; Size of GDT area
- Dw ? ; Location in ram
- Dw 0 ;
- ;
- Idt_Pointer: ;
- Dw Idt_Image_End - Idt_Image_Start-1 ; Size of IDT
- Dw ? ; Location
- Dw 0 ;
- ;
- Initialize: ; Jump far to here
- Push Cs ; First set up the main pointers
- Push Cs ; So that we can make prot mode
- Pop Ds ; Possible
- Pop Es ;
- Lea Di,Gdt_Pointer ; Get the offset of this
- Mov Ax,INITIAL_DATA ; Get the segment of this
- Mov [DI+2],Ax ; Save the segment
- Lea Di,Idt_Pointer ;
- Mov [Di+2],Ax ;
- ;
- Cli ;
- Lgdt DWORD PTR cs:Gdt_Pointer ; Load this
- Lidt DWORD PTR cs:Idt_Pointer ; And this
- ;
- Smsw Ax ; Get the machone status word
- Or Ax,1 ; Set the PE bit
- Lmsw Ax ; NOW WE ARE IN PROTECTED MODE
- Jmp Fls ; Clear the queue
- ;
- Fls: ;
- Mov Ax,18h ; Initialize SS:SP (SELECTOR 18h)
- Mov Ss,Ax ;
- Mov Sp,400h ; Inital for 1k stack
- ;
- ; JMP FAR MAIN_CODE:0 ; To make correct thing
- ;
- Db 0EAh ; Far jmp nm
- Dw 0 ;
- Dw MAIN_CODE_SELECTOR
- ;
- Flush: Sti ;
- Mov Al,'P' ; Char P
- Tag: Mov Bx,Ax ; Save
- Mov Dx,OUTPUT_DATA_PORT
- Out Dx,Al ; Do this
- Mov Dx,OUTPUT_STATUS_PORT1
- Tl1a: In Al,Dx ; Get the status of printer
- Test Al,80h ; Check if ready
- Jz Tl1a ;
- Mov Dx,OUTPUT_STATUS_PORT2
- Mov Al,STROBE_HIGH ; Strobe high
- Out Dx,Al ;
- Mov Al,STROBE_LOW ; Strobe low
- Jmp NextInst ; Delay
- NextInst: Out Dx,Al ;
- Cmp Bl,'P' ; First or second time
- Jne Forever ;
- Mov Al,0Dh ; Carriage return
- Jmp Tag ;
- ;
- Forever: Jmp Forever ;
- Entry: Cli ;
- Jmp Initialize ;
-
- End_Of_Main_Code Equ $ ;
- MAIN_CODE ENDS
- PAGE
- ;=============================================================================;
- ; Exception handler code segment. ;
- ;=============================================================================;
- EXCEPTION_CODE SEGMENT
- Assume Cs:EXCEPTION_CODE
-
- Ex_0: ;
- Push Ax ;
- Mov Al,0 ;
- Call Report_Exception;
- Pop Ax ;
- Iret ;
- Ex_1: ;
- Push Ax ; Save AX
- Mov Al,1 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- ; -- NMI handled as int ;
- Ex_3: ;
- Push Ax ; Save AX
- Mov Al,3 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_4: ;
- Push Ax ; Save AX
- Mov Al,4 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_5: ;
- Push Ax ; Save AX
- Mov Al,5 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_6: ;
- Push Ax ; Save AX
- Mov Al,6 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_7: ;
- Push Ax ; Save AX
- Mov Al,7 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_8: ;
- Push Ax ; Save AX
- Mov Al,8 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_9: ;
- Push Ax ; Save AX
- Mov Al,9 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_10: ;
- Push Ax ; Save AX
- Mov Al,10 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_11: ;
- Push Ax ; Save AX
- Mov Al,11 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_12: ;
- Push Ax ; Save AX
- Mov Al,12 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- Ex_13: ;
- Push Ax ; Save AX
- Mov Al,13 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- ; 80286 will not generate 14,15
- Ex_16: ;
- Push Ax ; Save AX
- Mov Al,16 ; Put EXP number in Al
- Call Report_Exception; Report to user
- Pop Ax ; Get number
- Iret ; And return
- ; Expection 17-31 not here
-
- Report_Exception: ;
- Push Ax ;
- Push Bx ;
- Push Dx ;
- ;
- Tg1: Mov Bx,Ax ; Save the value passed
- Mov Dx,OUTPUT_DATA_PORT
- Out Dx,Al ; Do this
- Mov Dx,OUTPUT_STATUS_PORT1
- Xl1a: In Al,Dx ; Get the status of printer
- Test Al,80h ; Check if ready
- Jz Xl1a ;
- Mov Dx,OUTPUT_STATUS_PORT2
- Mov Al,STROBE_HIGH ; Strobe high
- Out Dx,Al ;
- Mov Al,STROBE_LOW ; Strobe low
- Jmp NextInst2 ; Delay
- NextInst2: Out Dx,Al ;
- Cmp Bl,0Ah ; First or second time or last
- Je ByBye ;
- Cmp Bl,0Dh ; Carriage return?
- Je ThrowLf ;
- Mov Al,0Dh ;
- Jmp Tg1 ;
- ThrowLf: Mov Al,0Ah ;
- Jmp Tg1 ;
- ;
- ByBye: Pop Dx ;
- Pop Bx ;
- Pop Ax ;
- Ret ;
-
- End_Of_Exception_Code EQU $
- EXCEPTION_CODE ENDS
- PAGE
- ;=============================================================================;
- ; Interrrupt Code Segment. ;
- ;=============================================================================;
- INTERRUPT_CODE Segment
- Assume Cs:INTERRUPT_CODE
-
- NMI: ;
- Push Ax ;
- Mov Al,2 ; NMI call
- Call Report_Interrupt;
- Pop Ax ;
- Iret ;
- Int_32: ;
- Push Ax ;
- Mov Al,32 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_33: ;
- Push Ax ;
- Mov Al,33 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_34: ;
- Push Ax ;
- Mov Al,34 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_35: ;
- Push Ax ;
- Mov Al,35 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_36: ;
- Push Ax ;
- Mov Al,36 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_37: ;
- Push Ax ;
- Mov Al,37 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_38: ;
- Push Ax ;
- Mov Al,38 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- Int_39: ;
- Push Ax ;
- Mov Al,39 ; Place INT in al
- Call Report_Interrupt; Call to report
- Pop Ax ; Get Ax
- Iret ; And Int Return
- ;
- Report_Interrupt: ;
- Push Ax ;
- Push Bx ;
- Push Dx ;
- ;
- Tg2: Mov Bx,Ax ; Save the value passed
- Mov Dx,OUTPUT_DATA_PORT
- Out Dx,Al ; Do this
- Mov Dx,OUTPUT_STATUS_PORT1
- Zl1a: In Al,Dx ; Get the status of printer
- Test Al,80h ; Check if ready
- Jz Zl1a ;
- Mov Dx,OUTPUT_STATUS_PORT2
- Mov Al,STROBE_HIGH ; Strobe high
- Out Dx,Al ;
- Mov Al,STROBE_LOW ; Strobe low
- Jmp NextInst3 ; Delay
- NextInst3: Out Dx,Al ;
- Cmp Bl,0Ah ; First or second time or last
- Je ByeBye ;
- Cmp Bl,0Dh ; Carriage return?
- Je ThrowLf2 ;
- Mov Al,0Dh ;
- Jmp Tg2 ;
- ThrowLf2: Mov Al,0Ah ;
- Jmp Tg2 ;
- ;
- ByeBye: Pop Dx ;
- Pop Bx ;
- Pop Ax ;
- Ret ;
-
- End_Of_Interrupt_Code EQU $
- INTERRUPT_CODE ENDS
-
- STACKSEG Segment PARA STACK 'STACK'
- db 1024 dup (0)
-
- TOS EQU $
- STACKSEG ENDS
-
-
- END Entry
-