Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
5.8 KiB

TITLE Sample 16 Bits DOS application
;---------------------------------------------------------------;
;
include 16bits.inc
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
DMAWriteBuffer label byte
db 64 dup (?)
DMA_BUFFER_SIZE equ $ - DMAWriteBuffer
DMAReadBuffer label byte
db DMA_BUFFER_SIZE dup (?)
MIOPattern label byte
db 00, 0FFh, 0AAh, 055h
MIOPATTERN_SIZE equ $ - MIOPattern
public start
.CODE
start:
jmp short RealStart
OldVector label dword
dd ?
DMACompleted db ?
RealStart:
mov ax,@DATA
mov ds,ax
mov es,ax
assume ds:@DATA, es:@DATA
;Hook interrupt(DMA terminate count notification)
push ds
mov al, DMA_INTERRUPT
mov ah, 35h
int 21h
mov word ptr cs:OldVector, bx
mov word ptr cs:OldVector + 2, es
mov dx, offset ISRDMACompleted
mov ax, cs
mov ds, ax
mov al, DMA_INTERRUPT
mov ah, 25h
int 21h
pop ds
;VDD operation.
;(1). Hook the I/O port.
;(2). Keep the port status up-to-date if a write operation is performed
; by 16 bits application(this program).
;(3). Simulate DMA operation and generate a fake interrupt for 16bits
; applicatiion if the DMA operation reaches its TC.
;
;
;16bits application
;(1). Output one byte to the port and then request DMA operation.
;(2). Wait for DMA operation completed.
;(3). goto step (1) if there are more data to be transferred.
;Note that the given I/O must be a R/W port.
;Here we do a DMA write operation upon I/O mapped I/O
mov cx, DMA_BUFFER_SIZE
mov si, offset DMAWriteBuffer
DMATransferLoop_Fast:
mov dx, IO_PORT_DMA
mov al, cl
out dx, al ;write I/O the current count
cli
mov cs:DMACompleted, FALSE ;reset TC flag
sti
;channel #1, write op, no auto init, addr inc, single transfer
mov al, 01000101B
call SetupDMAOperation
;Fire the DMA WRITE operation, this will cause VDD to gain control
;and start DMA operation.
mov dx, IO_PORT_FIRE_DMA_FAST
out dx, al
;In real world(there is a real hardware adapter), we won't do this
;idle loop, rather, we can do something useful(like, read the DMA current
;count and display the progress and so forth)provided that we can regain
;control while DMA operation is in progress(VDD spawns a new thread to
;handle DMA operation and returns to us immediately)
;
;Since we are simulating DMA operation without hardware, we always
;start the DMA operation with transfer count set to 1 byte. In reality
;this is should not be the case because it will slow down the data transfer.
WaitForDMA_Fast:
cmp cs:DMACompleted, TRUE
jnz WaitForDMA_Fast
inc si
loop DMATransferLoop_Fast
;
;Now do a DMA read operation
mov cx, DMA_BUFFER_SIZE
mov si, offset DMAWriteBuffer
mov di, offset DMAReadBuffer
DMATransferLoop_Slow:
;channel #1, read op, no auto init, addr inc, single transfer
mov al, 01001001B
cli
mov cs:DMACompleted, FALSE
sti
call SetupDMAOperation
;Fire the DMA READ operation
mov dx, IO_PORT_FIRE_DMA_SLOW
out dx, al
WaitForDMA_Slow:
cmp cs:DMACompleted, TRUE
jne WaitForDMA_Slow
mov dx, IO_PORT_DMA
in al, dx
mov [di], al
inc di ;advance our buffer
inc si ;and the DMA buffer
loop DMATransferLoop_Slow
;
;The DMAWriteBuffer and DMAReadBuffer should have the same contents.
;If they don't, it failed. ....
;Memory mapped I/O
mov ax, MIO_SEGMENT
mov es, ax
mov bx, MIOPATTERN_SIZE
mov si, offset MIOPattern
MIO_Loop:
cld
lodsb ;get next pattern
mov cx, MIO_PORT_RANGE
mov di, MIO_PORT_FIRST
rep stosb ;fill all I/O with the pattern
mov cx, MIO_PORT_RANGE
dec di
std
repe scasb ;
je @F
; call ErrorMIO ;if any i/o failed,
@@:
dec bx ;next pattern
jnz MIO_Loop
;Before terminate, retsore everything we have touched
push ds
lds dx, cs:OldVector
mov al, DMA_INTERRUPT
mov ah, 25h
int 21h
pop ds
mov ah, 04Ch
int 21h
;-------------------------------------------------------;
;Setup DMA operation
;Input: ds:si = seg:offset of memeory address
; al = DMA mode
;output: NONE
;Modified: AX, DX
;-------------------------------------------------------;
SetupDMAOperation proc
push cx
mov dx, DMA_PORT_FLIPFLOP
out dx, al
mov dx, DMA_PORT_MODE ;more register
out dx, al
mov ax, ds ;transfer address -> page:offset
mov cl, 4 ;page: A16 ~ A19, offset A0 ~ A15
rol ax, cl
mov ch, al
and al, 0F0h
add ax, si
jnc @F
inc ch
@@:
mov dx, DMA_PORT_ADDR
out dx, al ;offset lower byte
mov al, ah
out dx, al ;and higher byte
mov dx, DMA_PORT_PAGE ;page register
mov al, ch
and al, 0Fh ;only 4 bits allowed
out dx, al
mov al, 1 ;single transfer, one byte
mov dx, DMA_PORT_COUNT
out dx, al
dec al
out dx, al ;higher byte set to 0
mov dx, DMA_PORT_REQUEST ;request channel #1
mov al, 00000101B
out dx, al
mov dx, DMA_PORT_SNGLE_MASK ;start DMA transfer
mov al, 00000001B
out dx, al
pop cx
ret
SetupDMAOperation endp
ISRDMACompleted proc far
mov byte ptr DMACompleted, TRUE
mov al, 20h
out 20h, al
out 0A0h, al
iret
ISRDMACompleted endp
END start