home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / cpu / protex / prot4.asm < prev    next >
Assembly Source File  |  1991-03-14  |  14KB  |  302 lines

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