home *** CD-ROM | disk | FTP | other *** search
- PAGE 55,132
- TITLE I/O SIMULATION TEST PROGRAM
- .286
-
- ;
- ; This is a sample user qualified breakpoint.
- ;
-
- INT_NUM EQU 65H ;THIS IS THE PSUDEO INTERRUPT NUMBER
-
- REG_WORD STRUC
- REG_DI DW ?
- REG_SI DW ?
- REG_BP DW ?
- REG_SP DW ?
- REG_BX DW ?
- REG_DX DW ?
- REG_CX DW ?
- REG_AX DW ?
- REG_IP DW ?
- REG_CS DW ?
- REG_FLAGS DW ?
- REG_WORD ENDS
-
- REG_BYTE STRUC
- REG_DI1 DW ?
- REG_SI1 DW ?
- REG_BP1 DW ?
- REG_SP1 DW ?
- REG_BL DB ?
- REG_BH DB ?
- REG_DL DB ?
- REG_DH DB ?
- REG_CL DB ?
- REG_CH DB ?
- REG_AL DB ?
- REG_AH DB ?
- REG_BYTE ENDS
-
- STACK SEGMENT STACK
- DW 50 DUP(0)
- STACK ENDS
-
- DATA SEGMENT BYTE PUBLIC 'DATA'
-
- NEW_VAL DW ?
- NEXT_IN_LOC DW 0
- NEXT_OUT_LOC DW 0
- PUBLIC BUFFIN
- BUFFIN DW 1000H DUP(0)
- PUBLIC BUFFOUT
- BUFFOUT DW 1000H DUP(0)
- DATA ENDS
-
- CODE SEGMENT PUBLIC 'CODE'
- CODE ENDS
-
- LAST SEGMENT PUBLIC 'LAST'
- LAST ENDS
-
- CODE SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:CODE,DS:DATA
- PUBLIC START
- START: MOV BX,LAST ;THE END OF THE PROGRAM
- MOV AX,ES ;SUBTRACT FROM THE TOP OF THE HEADER
- SUB BX,AX ;BX NOW HAS THE SIZE TO KEEP WHEN WE
- ; TERMINATE AND STAY RESIDENT
-
- MOV AX,DATA ;GET OUR DATA SEGMENT
- MOV DS,AX
- XOR AX,AX ;POINT ES AT SEGMENT ZERO
- MOV ES,AX ;
-
- MOV AX,OFFSET IO_ROUTINE ;GET A POINTER TO THE I/O ROUTINE
- MOV ES:[INT_NUM*4],AX ;POINT THE INTERRUPT TO THE IO ROUTINE
- MOV AX,CS ;GET THE CURRENT SEGMENT
- MOV ES:[INT_NUM*4+2],AX ;MOVE IT IN
-
- MOV AH,31H ;USE THE MSDOS KEEP PROCESS FUNCTION
- MOV DX,BX ;GET THE SIZE OF OUR ROUTINES
- INT 21H ;THATS IT
-
- ;---------------------------------------------------------------------------
- ; This routine will be called when ever Soft-ICE reaches a break point
- ; and the ACTION is set to our INT_NUM. The stack will be set up as if
- ; a normal REAL mode interrupt had happend. ie;
- ;
- ; FLAGS
- ; CS
- ; IP
- ; The opcodes that we will be looking for are:
- ; 0ECH - IN AL,DX
- ; 0EDH - IN AX,DX
- ; 0EEH - OUT AL,DX
- ; 0EFH - OUT AX,DX
- ; Note that bit 02h tells us whether it is an IN or an OUT and bit 01h tells
- ; us whether it is a BYTE or a WORD.
- ;
- ;---------------------------------------------------------------------------
- IO_ROUTINE PROC FAR
- PUSHA ;SAVE ALL THE CURRENT REGISTERS
- MOV BP,SP ;USE BP TO POINT BACK ONTO THE STACK
- PUSH DS ;SAVE THE SEGMENTS ALSO
- PUSH ES ;
- MOV AX,DATA ;GET OUR DATA SEGMENT
- MOV DS,AX ;SET IT UP
- MOV AX,[BP].REG_CS ;GET THE OLD CS REGISTER
- MOV ES,AX ;SET ES TO THAT SEGMENT
- MOV SI,[BP].REG_IP ;USE SI TO POINT TO THE IP
- MOV AL,ES:[SI-1] ;GET THE OPCODE OF THE I/O INSTRUCTION
- CMP AL,0ECH ;WAS IT IN IT I/O OPCODE RANGE?
- JB NOT_AN_IO ;NOPE
- CMP AL,0EFH ;CHECK THE HIGH END
- JA NOT_AN_IO ;NOPE NOT THIS ONE EITHER
- MOV DX,[BP].REG_DX ;GET THE DX REGISTER FROM THE STACK
- MOV CL,0 ;ASSUME IT WAS A BYTE ACCESS
- TEST AL,01H ;WAS IT A BYTE OR A WORD?
- JZ BYTE_ACCESS ;YES, JUST A BYTE
- MOV CL,1 ;MARK IT AS WORD ACCESS
- BYTE_ACCESS:
- TEST AL,02H ;WAS IT AN IN OR AN OUT
- JNZ OUT_OPCODE ;IT WAS AN OUT
- IN_OPCODE:
- ;---------------------------------------------------------------------------
- ; ENTRY: CL = BYTE OR WORD ACCESS
- ; 0 = BYTE
- ; 1 = WORD
- ;
- ; DX = THE I/O PORT
- ;
- ; EXIT:
- ; [BP].REG_AX OR [BP].REG_AL SHOULD HAVE THE SIMULATED VALUE
- ;
- ;---------------------------------------------------------------------------
-
- MOV BX,NEXT_IN_LOC
- MOV AX,BUFFIN[BX+2]
- MOV [BP].REG_AL,AL ;MOVE IN JUST A BYTE
- ADD NEXT_IN_LOC,4
- MOV AX,NEW_VAL ;GET THE LAST OUTPUT VALUE
- OR CL,CL ;IS IT A BYTE OR A WORD
- JZ DO_BYTE ;JUST A BYTE
- MOV [BP].REG_AX,AX ;MOVE IT IN
- JMP IO_DONE
- DO_BYTE:
- MOV [BP].REG_AL,AL ;MOVE IN JUST A BYTE
- JMP IO_DONE
- OUT_OPCODE:
- ;---------------------------------------------------------------------------
- ; ENTRY: CL = BYTE OR WORD ACCESS
- ; 0 = BYTE
- ; 1 = WORD
- ;
- ; DX = THE I/O PORT
- ;
- ; [BP].REG_AX OR [BP].REG_AL THE VALUE GOING OUT
- ;
- ;---------------------------------------------------------------------------
- MOV AX,[BP].REG_AX ;GET THE VALUE
- MOV NEW_VAL,AX ;SAVE IT
-
- MOV BX,NEXT_OUT_LOC
- MOV BUFFOUT[BX],DX
- MOV BUFFOUT[BX+2],AX
- ADD NEXT_OUT_LOC,4
-
- IO_DONE:
- NOT_AN_IO:
- POP ES ;RESTORE ALL OF THE SEGMENTS AND REGS
- POP DS ;
- POPA ;
- IRET ;RETURN TO THE INSTRUCTION AFTER THE
- ; I/O
- IO_ROUTINE ENDP
-
-
- CODE ENDS
-
- END START
-