home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / PROTEX.ZIP / PROT5.ASM < prev    next >
Assembly Source File  |  1991-03-14  |  11KB  |  291 lines

  1.     PAGE    ,132
  2.     TITLE    Method 2
  3.     .286p   ; Tell MASM 2.0 about 286 instructions
  4. ;--------------------------------------------------------------:
  5. ;   Sample Program 2                                           :
  6. ;                                                              :
  7. ; This program switches into Protected Virtual Mode, changes   :
  8. ; the display attribute to reverse video, and returns to Real  :
  9. ; Mode to exit to DOS                                          :
  10. ;                                                              :
  11. ; Once entered into a file, do the following:                  :
  12. ;   MASM SAMPLE2;                                              :
  13. ;   LINK SAMPLE2;                                              :
  14. ;   EXE2BIN SAMPLE2 SAMPLE2.COM                                :
  15. ;   DEL SAMPLE2.EXE                                            :
  16. ;                                                              :
  17. ; WARNING: This program will "kill" a PC.  It should only      :
  18. ; be run on an AT.                                             :
  19. ;--------------------------------------------------------------:
  20.  
  21. bios_data_seg    SEGMENT at    0040h
  22.         ORG        0067h
  23. io_rom_init    dw ?    ; dword variable in BIOS data segment
  24. io_rom_seg    dw ?    ;  used to store a dword address
  25. bios_data_seg    ENDS
  26.  
  27. descriptor    STRUC
  28. seg_limit    dw    0    ; segment limit (1-65536 bytes)
  29. base_lo_word    dw    0    ; 24 bit physical address
  30. base_hi_byte    db    0    ;    (0 - (16M-1))
  31. access_rights    db    0    ; access rights byte
  32.         dw    0    ; reserved_386
  33. descriptor    ENDS
  34.  
  35. cmos_port    equ 070h
  36. code_seg_access equ 10011011b    ;access rights byte for code seg
  37. data_seg_access equ 10010011b    ;access rights byte for data seg
  38. enable_bit20    equ 11011111b    ;8042 function code to gate A20
  39. port_a        equ 060h    ;8042 port A
  40. shut_cmd    equ 0FEh    ;cmd to 8042: shut down AT
  41. shut_down    equ 00Fh    ;CMOS shut down byte index
  42. status_port    equ 064h    ;8042 status port
  43. virtual_enable    equ 0001h    ;LSB=1: Protected Virtual Mode
  44.  
  45.  
  46. jumpfar MACRO    jumpfar1,jumpfar2
  47.     db    0EAh
  48.     dw    (offset jumpfar1)
  49.     dw    jumpfar2
  50.     ENDM
  51.  
  52.     SUBTTL    Program entry point and data area
  53.     PAGE
  54. cseg    SEGMENT para        public        'code'
  55.     ASSUME    cs:cseg
  56.  
  57.     ORG    100h
  58. start:    jmp    short    main
  59.  
  60.     EVEN
  61. gdt        LABEL    word
  62.  
  63. gdt_desc    EQU    (($-gdt)/8)*8 + 0000000000000000b
  64. gdt1    descriptor    <gdt_leng,,,data_seg_access,>
  65. cs_code     EQU    (($-gdt)/8)*8 + 0000000000000000b
  66. gdt2    descriptor    <cseg_leng,,,code_seg_access,>
  67. cs_data     EQU    (($-gdt)/8)*8 + 0000000000000000b
  68. gdt3    descriptor    <cseg_leng,,,data_seg_access,>
  69. ss_desc     EQU    (($-gdt)/8)*8 + 0000000000000000b
  70. gdt4    descriptor    <0FFFFh,,,data_seg_access,>
  71. ds_desc     equ    (($-gdt)/8)*8 + 0000000000000000b
  72. gdt5    descriptor    <0FFFFh,,,data_seg_access,>
  73. es_desc     equ    (($-gdt)/8)*8 + 0000000000000000b
  74. gdt6    descriptor    <0FFFFh,,,data_seg_access,>
  75. gdt_leng    EQU    $-gdt
  76.         PAGE
  77. ;--------------------------------------------------------------:
  78. ; Format of the Segment Selector Component:                    :
  79. ;                                                              :
  80. ; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+            :
  81. ; |         INDEX                +TI+ RPL +       :            :
  82. ; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+            :
  83. ;                                                              :
  84. ; TI = Table Indicator (0=GDT, 1=LDT)                          :
  85. ; RPL = Requested Privelege Level (00 = highest; 11 = Lowest)  :
  86. ;--------------------------------------------------------------:
  87. ; Format of the Global Descriptor Table                        :
  88. ;         .-----------+          +---> TI                      :
  89. ;         V       |          |++-> RPL                         :
  90. ; GDT ==> +---------------+   |          |||                   :
  91. ;     |   GDT_DESC    | --+ 0000000000000000b                  :
  92. ;     +---------------+                                        :
  93. ;     |    CS_CODE    | 0000000000001000b                      :
  94. ;     +---------------+                                        :
  95. ;     |    CS_DATA    | 0000000000010000b                      :
  96. ;     +---------------+                                        :
  97. ;     |    SS_DESC    | 0000000000011000b                      :
  98. ;     +---------------+                                        :
  99. ;     |    DS_DESC    | 0000000000100000b                      :
  100. ;     +---------------+                                        :
  101. ;     |    ES_DESC    | 0000000000101000b                      :
  102. ;     +---------------+                                        :
  103. ;--------------------------------------------------------------:
  104.  
  105.     SUBTTL    Program Main
  106.     PAGE
  107. ;--------------------------------------------------------------:
  108. ; MAIN                                                         :
  109. ;--------------------------------------------------------------:
  110.     ASSUME    ds:cseg
  111. main    PROC                  ;ES=DS=CS
  112.     cld                  ;forward
  113.  
  114.     mov    dx,cs              ;form 24bit address out of
  115.     mov    cx,offset gdt          ;CS:GDT
  116.     call    form_24bit_address
  117.     mov    gdt1.base_lo_word,dx  ;DESC now points to gdt
  118.     mov    gdt1.base_hi_byte,cl
  119.  
  120.     mov    dx,cs              ;form 24bit address out of
  121.     xor    cx,cx              ; CS:0000
  122.     call    form_24bit_address
  123.     mov    gdt2.base_lo_word,dx  ;CS_CODE now points to 
  124.     mov    gdt2.base_hi_byte,cl  ; CSEG as a code segment
  125.     mov    gdt3.base_lo_word,dx  ;CS_DATA now points to 
  126.     mov    gdt3.base_hi_byte,cl  ; CSEG as a data segment
  127.  
  128.     mov    dx,ss              ;form 24bit address out of
  129.     xor    cx,cx              ;SS:0000
  130.     call    form_24bit_address
  131.     mov    gdt4.base_lo_word,dx  ;SS_DESC now points to 
  132.                       ; stack segment
  133.     mov    gdt4.base_hi_byte,cl
  134.  
  135.     lgdt    gdt              ;Load the GDTR
  136.  
  137.     mov    ah,enable_bit20       ;gate address bit 20 on
  138.     call    gate_a20
  139.     or    al,al              ;was the command accepted?
  140.     jz    m_10              ;go if yes
  141.     mov    dx,offset gate_failure    ;print error msg 
  142.     mov    ah,9            ; and terminate
  143.     int    21h
  144.     int    20h
  145.  
  146. gate_failure    db    "Address line A20 failed to Gate open$"
  147.  
  148. m_10:    cli            ;No interrupts
  149.     pushf            ;Simulate INT by pushing Flags,
  150.     push    cs        ; CS,
  151.     mov    ax,offset real    ; and offset of return address.
  152.     push    ax
  153.  
  154.     pusha        ;Now, set up stack the way BIOS block-
  155.     push    es    ; move logic will expect it.
  156.     push    ds    ;On return, this is the way 
  157.             ; the regs will be.
  158.  
  159.     ASSUME    ds:bios_data_seg
  160.     mov    dx,bios_data_seg   ;Place on Stack current SS:SP
  161.     mov    ds,dx
  162.     mov    io_rom_seg,ss
  163.     mov    io_rom_init,sp
  164.  
  165.     mov    al,shut_down       ;Set shutdown byte to 
  166.     out    cmos_port,al       ; shut down code x"09"
  167.     jmp    short    $+2       ;I/O delay
  168.     mov    al,9
  169.     out    cmos_port+1,al
  170.  
  171.     mov    ax,virtual_enable  ;machine status word needed
  172.     lmsw    ax           ; to switch to virtual mode
  173.     jumpfar m_20,cs_code       ;Must purge prefetch queue
  174.  
  175. m_20:    ASSUME    ds:cseg        ;IN VIRTUAL MODE ...
  176.     mov    ax,ss_desc       ;stack segment selector
  177.     mov    ss,ax           ;user's ss+sp 
  178.                    ; is not a descriptor
  179.  
  180.     mov    ax,cs_data
  181.     mov    ds,ax           ;DS = CSEG as data
  182.  
  183.     mov gdt5.base_lo_word,8000h  ;use 8000 for COLOR
  184.     mov    gdt5.base_hi_byte,0Bh
  185.     mov gdt6.base_lo_word,8000h
  186.     mov    gdt6.base_hi_byte,0Bh
  187.  
  188.     mov    ax,ds_desc
  189.     mov    ds,ax
  190.     mov    ax,es_desc
  191.     mov    es,ax
  192.     mov    cx,80*25
  193.     xor    si,si
  194.     xor    di,di
  195. m_30:    lodsw
  196.     mov ah,80h         ;attribute reverse video
  197.     stosw
  198.     loop    m_30
  199.  
  200.     mov    al,shut_cmd       ;shutdown cmd
  201.     out    status_port,al       ;get back into REAL mode 
  202. m_40:    hlt
  203.     jmp    short    m_40
  204.  
  205.     SUBTTL    Gate A20
  206.     PAGE
  207. ;--------------------------------------------------------------:
  208. ; GATE_A20                                                     :
  209. ; This routine controls a signal which gates address bit 20.   :
  210. ; The gate A20 signal is an output of the 8042 slave processor.:
  211. ; Address bit 20 should be gated on before entering protected  :
  212. ; mode.  It should be gated off after entering real mode from  :
  213. ; protected mode.                                              :
  214. ; Input:  (AH)=0DDh addr bit 20 gated off (A20 always 0)       :
  215. ;     (AH)=0DFh addr bit 20 gated on (286 controls A20)        :
  216. ; Output: (AL)=0 operation successful.  8042 has accepted cmd  :
  217. ;     (AL)=2 Failure -- 8042 unable to accept command.         :
  218. ;--------------------------------------------------------------:
  219. gate_a20    PROC
  220.     cli             ;disable ints while using 8042
  221.     call    empty_8042   ;insure 8042 input buffer empty
  222.     jnz    gate_a20_01  ;ret if 8042 unable to accept cmd
  223.     mov    al,0D1h      ;8042 command to write output port
  224.     out    status_port,al    ;output cmd to 8042
  225.     call    empty_8042   ;wait for 8042 to accept command
  226.     jnz    gate_a20_01  ;ret if 8042 unable to accept cmd
  227.     mov    al,ah         ;8042 port data
  228.     out    port_a,al    ;output port data to 8042
  229.     call    empty_8042   ;wait for 8042 to port data
  230. gate_a20_01:
  231.     ret
  232. gate_a20    ENDP
  233. ;--------------------------------------------------------------:
  234. ; EMPTY_8042                                                   :
  235. ;   This routine waits for the 8042 buffer to empty            :
  236. ;   Input:  None                                               :
  237. ;   Output: (AL)=0 8042 input buffer empty (ZF=1)              :
  238. ;       (AL)=2 Time out, 8042 buffer full (ZF=0)               :
  239. ;--------------------------------------------------------------:
  240. empty_8042    PROC
  241.     push    cx        ;save CX
  242.     sub    cx,cx        ;CX=0 will be time out value
  243. empty_8042_01:
  244.     in    al,status_port    ;read 8042 status port
  245.     and    al,00000010b    ;test inp. buffer full flag (D1)
  246.     loopnz    empty_8042_01    ;loop until input buffer empty 
  247.                 ; or time out
  248.     pop    cx        ;restore CX
  249.     ret
  250. empty_8042    ENDP
  251.  
  252.     SUBTTL    form_24bit_address
  253.     PAGE
  254. ;--------------------------------------------------------------:
  255. ; FORM_24BIT_ADDRESS                                           :
  256. ;   Input:  DX has some segment                                :
  257. ;       CX has some offset                                     :
  258. ;   Output: DX has base_lo_word                                :
  259. ;       CL has base_hi_byte                                    :
  260. ;--------------------------------------------------------------:
  261. form_24bit_address    PROC
  262.     push    ax    
  263.          ;DX == s15 s14 s13 s12 s11 ... s04 s03 s02 s01 s00
  264.     rol    dx,4    
  265.          ;DX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
  266.     mov    ax,dx    
  267.          ;AX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
  268.     and    dl,0F0h 
  269.          ;DX == s11 ... s04 s03 s02 s01 s00   0   0   0   0
  270.     and    ax,0Fh    
  271.          ;AX ==   0 ...   0   0   0   0   0 s15 s14 s13 s12
  272.     add    dx,cx    ;form_24bit_address
  273.     mov    cx,ax    ;get base_hi_byte in CL
  274.     adc    cl,ch    ;carry in (CH=0)
  275.     pop    ax
  276.     ret
  277. form_24bit_address    ENDP
  278.  
  279.     SUBTTL    Real Mode re-entry point.
  280.     PAGE
  281.     ASSUME    ds:cseg         ; IN REAL MODE ...
  282. real:    sti                ; turn the int's on
  283.     int    20h            ; back to DOS
  284.  
  285. main        ENDP
  286.  
  287. cseg_leng    EQU    $
  288. cseg        ENDS
  289.         END    start
  290.  
  291.