home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
method1.asm
< prev
next >
Wrap
Assembly Source File
|
1986-01-31
|
11KB
|
328 lines
PAGE ,132
TITLE Method 1
.286C ; Tell MASM 2.0 about 286 instructions
;--------------------------------------------------------------:
; Sample Program 1 :
; :
; This program switches into Protected Virtual Mode, changes :
; the display attribute to reverse video, and returns to Real :
; Mode to exit to DOS :
; :
; Once entered into a file, do the following: :
; MASM SAMPLE1; :
; LINK SAMPLE1; :
; EXE2BIN SAMPLE1 SAMPLE1.COM :
; DEL SAMPLE1.EXE :
; :
; WARNING: This program will "kill" a PC. I should only :
; be run on an AT. :
;--------------------------------------------------------------:
bios_data_seg SEGMENT at 0040h
ORG 0067h
io_rom_init dw ? ; dword variable in BIOS data segment
- More (Y/N/NS)? ns
io_rom_seg dw ? ; used to store a dword address
bios_data_seg ENDS
descriptor STRUC
seg_limit dw 0 ; segment limit (1-65536 bytes)
base_lo_word dw 0 ; 24 bit physical address
base_hi_byte db 0 ; (0 - (16M-1))
access_rights db 0 ; access rights byte
dw 0 ; reserved_386
descriptor ENDS
cmos_port equ 070h
code_seg_access equ 10011011b ;access rights byte for code seg
data_seg_access equ 10010011b ;access rights byte for data seg
disable_bit20 equ 11011101b ;8042 function code to de-gate A20
enable_bit20 equ 11011111b ;8042 function code to gate A20
inta01 equ 021h ;8259 Int Controller #1
intb01 equ 0A1h ;8259 Int Controller #2
port_a equ 060h ;8042 port A
shut_cmd equ 0FEh ;cmd to 8042: shut down AT
shut_down equ 00Fh ;CMOS shut down byte index
status_port equ 064h ;8042 status port
virtual_enable equ 0001h ;LSB=1: Protected Virtual Mode
SUBTTL Macro Definitions
PAGE
;--------------------------------------------------------------:
; These mnemonics are not supported in MASM 2.0 therefore :
; they are supplied here as MACROS. :
;--------------------------------------------------------------:
lgdt MACRO lgdt1 ;; Load Global Descriptor Table
LOCAL lgdt2,lgdt3
db 00Fh
lgdt2 label byte
mov dx,word ptr lgdt1
lgdt3 label byte
org offset lgdt2
db 001h
org offset lgdt3
ENDM
lmsw MACRO lmsw1 ;; Load Machine Status Word
LOCAL lmsw2,lmsw3
db 00Fh
lmsw2 label byte
mov si,ax
lmsw3 label byte
org offset lmsw2
db 001h
org offset lmsw3
ENDM
;; This is a "hard coded" far jump
jumpfar MACRO jumpfar1,jumpfar2
db 0EAh
dw (offset jumpfar1)
dw jumpfar2
ENDM
SUBTTL Program entry point and data area
PAGE
cseg SEGMENT para public 'code'
ASSUME cs:cseg
ORG 100h
start: jmp short main
EVEN
gdt LABEL word
gdt_desc EQU (($-gdt)/8)*8 + 0000000000000000b
gdt1 descriptor <gdt_leng,,,data_seg_access,>
cs_code EQU (($-gdt)/8)*8 + 0000000000000000b
gdt2 descriptor <cseg_leng,,,code_seg_access,>
cs_data EQU (($-gdt)/8)*8 + 0000000000000000b
gdt3 descriptor <cseg_leng,,,data_seg_access,>
ss_desc EQU (($-gdt)/8)*8 + 0000000000000000b
gdt4 descriptor <0FFFFh,,,data_seg_access,>
ds_desc equ (($-gdt)/8)*8 + 0000000000000000b
gdt5 descriptor <0FFFFh,,,data_seg_access,>
es_desc equ (($-gdt)/8)*8 + 0000000000000000b
gdt6 descriptor <0FFFFh,,,data_seg_access,>
gdt_leng EQU $-gdt
PAGE
;--------------------------------------------------------------:
; Format of the Segment Selector Component: :
; :
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ :
; | INDEX +TI+ RPL + :
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ :
; :
; TI = Table Indicator (0=GDT, 1=LDT) :
; RPL = Requested Privelege Level (00 = highest; 11 = Lowest) :
;--------------------------------------------------------------:
; Format of the Global Descriptor Table :
; .-----------+ +---> TI :
; V | |++-> RPL :
; GDT ==> +---------------+ | ||| :
; | GDT_DESC | --+ 0000000000000000b :
; +---------------+ :
; | CS_CODE | 0000000000001000b :
; +---------------+ :
; | CS_DATA | 0000000000010000b :
; +---------------+ :
; | SS_DESC | 0000000000011000b :
; +---------------+ :
; | DS_DESC | 0000000000100000b :
; +---------------+ :
; | ES_DESC | 0000000000101000b :
; +---------------+ :
;--------------------------------------------------------------:
i8259_1 db ? ; store for status of 8259 #1
i8259_2 db ? ; store for status of 8259 #2
SUBTTL Program Main
PAGE
;--------------------------------------------------------------:
; MAIN :
;--------------------------------------------------------------:
ASSUME ds:cseg
main PROC ;ES=DS=CS
cld ;forward
mov dx,cs ;form 24bit address out of
mov cx,offset gdt ; CS:GDT
call form_24bit_address
mov gdt1.base_lo_word,dx ;DESC now points to gdt
mov gdt1.base_hi_byte,cl
mov dx,cs ;form 24bit address out of
xor cx,cx ; CS:0000
call form_24bit_address
mov gdt2.base_lo_word,dx ;CS_CODE now points to
mov gdt2.base_hi_byte,cl ; CSEG as a code segment
mov gdt3.base_lo_word,dx ;CS_DATA now points to
mov gdt3.base_hi_byte,cl ; CSEG as a data segment
mov dx,ss ;form 24bit address out of
xor cx,cx ; SS:0000
call form_24bit_address
mov gdt4.base_lo_word,dx ;SS_DESC now points to
mov gdt4.base_hi_byte,cl ; stack segment
lgdt gdt ;Load the GDTR
mov ah,enable_bit20 ;gate address bit 20 on
call gate_a20
or al,al ; was the command accepted?
jz m_10 ; go if yes
mov dx,offset gate_failure ;print error msg
mov ah,9 ; and terminate
int 21h
int 20h
gate_failure db "Address line A20 failed to Gate open$"
m_10: cli ;No interrupts
in al,inta01 ;get status of Int Controller #1
mov i8259_1,al
in al,intb01 ;get status of Int Controller #2
mov i8259_2,al
ASSUME ds:bios_data_seg
mov dx,bios_data_seg ;Real Mode Return address
mov ds,dx
mov io_rom_seg,cs
mov io_rom_init,offset real
mov al,shut_down ;Set shutdown byte
out cmos_port,al ; to shut down x05.
jmp short $+2 ;I/O delay
mov al,5
out cmos_port+1,al
mov ax,virtual_enable ;machine status word needed to
lmsw ax ;switch to virtual mode
jumpfar m_20,cs_code ;Must purge prefetch queue
m_20: ASSUME ds:cseg ;IN VIRTUAL MODE ...
mov ax,ss_desc ;stack segment selector
mov ss,ax ;user's ss+sp is not a descriptor
mov ax,cs_data
mov ds,ax ;DS = CSEG as data
mov gdt5.base_lo_word,0000h ;use 8000 for COLOR
mov gdt5.base_hi_byte,0Bh
mov gdt6.base_lo_word,0000h
mov gdt6.base_hi_byte,0Bh
mov ax,ds_desc
mov ds,ax
mov ax,es_desc
mov es,ax
mov cx,80*25
xor si,si
xor di,di
m_30: lodsw
mov ah,70h ;attribute reverse video
stosw
loop m_30
mov al,shut_cmd ;shutdown cmd
out status_port,al ;get back into REAL mode
m_40: hlt
jmp short m_40
SUBTTL Gate A20
PAGE
;--------------------------------------------------------------:
; GATE_A20 :
; This routine controls a signal which gates address bit 20. :
; The gate A20 signal is an output of the 8042 slave processor.:
; Address bit 20 should be gated on before entering protected :
; mode. It should be gated off after entering real mode from :
; protected mode. :
; Input: (AH)=0DDh addr bit 20 gated off (A20 always 0) :
; (AH)=0DFh addr bit 20 gated on (286 controls A20) :
; Output: (AL)=0 operation successful. 8042 has accepted cmd :
; (AL)=2 Failure -- 8042 unable to accept command. :
;--------------------------------------------------------------:
gate_a20 PROC
cli ;disable ints while using 8042
call empty_8042 ;insure 8042 input buffer empty
jnz gate_a20_01 ;ret if 8042 unable to accept cmd
mov al,0D1h ;8042 command to write output port
out status_port,al ;output cmd to 8042
call empty_8042 ;wait for 8042 to accept command
jnz gate_a20_01 ;ret if 8042 unable to accept cmd
mov al,ah ;8042 port data
out port_a,al ;output port data to 8042
call empty_8042 ;wait for 8042 to port data
gate_a20_01:
ret
gate_a20 ENDP
;--------------------------------------------------------------:
; EMPTY_8042 :
; This routine waits for the 8042 buffer to empty :
; Input: None :
; Output: (AL)=0 8042 input buffer empty (ZF=1) :
; (AL)=2 Time out, 8042 buffer full (ZF=0) :
;--------------------------------------------------------------:
empty_8042 PROC
push cx ;save CX
sub cx,cx ;CX=0 will be the time out value
empty_8042_01:
in al,status_port ;read 8042 status port
and al,00000010b ;test input buffer full flag (D1)
loopnz empty_8042_01 ;loop until input buffer empty
; or time out
pop cx ;restore CX
ret
empty_8042 ENDP
SUBTTL form_24bit_address
PAGE
;--------------------------------------------------------------:
; FORM_24BIT_ADDRESS :
; Input: DX has some segment :
; CX has some offset :
; Output: DX has base_lo_word :
; CL has base_hi_byte :
;--------------------------------------------------------------:
form_24bit_address PROC
push ax
;DX == s15 s14 s13 s12 s11 ... s04 s03 s02 s01 s00
rol dx,4
;DX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
mov ax,dx
;AX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
and dl,0F0h
;DX == s11 ... s04 s03 s02 s01 s00 0 0 0 0
and ax,0Fh
;AX == 0 ... 0 0 0 0 0 s15 s14 s13 s12
add dx,cx ;form_24bit_address
mov cx,ax ;get base_hi_byte in CL
adc cl,ch ;carry in (CH=0)
pop ax
ret
form_24bit_address ENDP
SUBTTL Real Mode re-entry point.
PAGE
ASSUME ds:cseg ;IN REAL MODE ...
real: mov dx,cs
mov ds,dx ;DS = CS
mov ah,disable_bit20 ;gate address bit 20 on
call gate_a20
mov al,i8259_1
out inta01,al ;set status of Int Controller #1
mov al,i8259_2
out intb01,al ;set status of Int Controller #2
sti ;turn the interrupts on
int 20h ;back to DOS
main ENDP
cseg_leng EQU $
cseg ENDS
END start