Category : System Diagnostics for your computer
Archive   : ATPERF.ZIP
Filename : TIME.ASM

 
Output of file : TIME.ASM contained in archive : ATPERF.ZIP
NAME TIME
include MASM.INC

_TEXT SEGMENT PARA PUBLIC 'CODE'
_TEXT ENDS
CONST SEGMENT PARA PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT PARA PUBLIC 'BSS'
_BSS ENDS
_DATA SEGMENT PARA PUBLIC 'DATA'
_DATA ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
TESTSEG SEGMENT PARA PUBLIC 'TEST'
TESTSEG_START DW 32767 DUP (?)
TESTSEG ENDS
PPI_PORT EQU 061H
TIMER2_PORT EQU 042H
TIMER_CTRL EQU 043H
_DATA SEGMENT
VIDBASE DW 0B800H
EMMBASE DW 9000H
PID DW ?
STATUSW DW ?
EMM_NAME DB "EMMXXXX0"

; Local flags for instruction relocation
; When set, instruction loop has been aligned on a dword boundary

LCL_FLAG DW 0 ; Initially, none aligned
@LCL_MUL equ 8000h ; _MULTIME
@LCL_WMOV equ 4000h ; _WMOVTIME
@LCL_DMOV equ 2000h ; _DMOVTIME
@LCL_DLOD equ 1000h ; _DLODTIME
@LCL_DRAM equ 0800h ; _DRAMTIME
@LCL_DIMM equ 0400h ; _DIMMTIME
@LCL_BCLC equ 0200h ; _BCLCTIME
@LCL_BDAA equ 0100h ; _BDAATIME
@LCL_WPSH equ 0080h ; _WPSHTIME
@LCL_DPSH equ 0040h ; _DPSHTIME
@LCL_FP equ 0020h ; _FPTIME
@LCL_WEMP equ 0010h ; _WEMPTIME
@LCL_DEMP equ 0008h ; _DEMPTIME

_DATA ENDS
_TEXT SEGMENT para
;***************************************************************;
; _MULTIME ;
; TIME EXECUTION OF MULTIPLY INSTRUCTIONS ;
;***************************************************************;
PUBLIC _MULTIME
_MULTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN MUL,M ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
MOV DI, 08000H ; SET DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
ML: REPT 100 ; DO 100 MULTIPLIES
MUL DI ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ MD ; JUMP IF COMPLETE
JMP ML ; LOOP BACK IF NOT DONE
MD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_MULTIME ENDP
;***************************************************************;
; _WMOVTIME ;
; TIME EXECUTION OF MOV INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;
PUBLIC _WMOVTIME
_WMOVTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN WMOV,I ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, IL ; PRIME TEST AREA
MOV CX, 200 ;
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
IL: REPT 100 ; DO 100 MOVES
MOV DX, BX ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ ID ; JUMP IF COMPLETE
JMP IL ; LOOP BACK IF NOT DONE
ID: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_WMOVTIME ENDP
;***************************************************************;
; _DMOVTIME ;
; TIME EXECUTION OF MOV INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;
PUBLIC _DMOVTIME
_DMOVTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN DMOV,N ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, NL ; PRIME TEST AREA
MOV CX, 400 ;
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
NL: REPT 100 ; DO 100 MOV DX,05555H
DB 0C7H, 0C2H, 055H, 055H ; THE LONG WAY (WITH MOD R/M)
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ ND ; JUMP IF COMPLETE
JMP NL ; LOOP BACK IF NOT DONE
ND: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_DMOVTIME ENDP
;***************************************************************;
; _DLODTIME ;
; TIME EXECUTION OF MOV INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;

PUBLIC FIRSTSEG,NEXTSEG
FIRSTSEG DW 0000h ; 0 KB in paras
NEXTSEG DW 1000h ; 64 KB in paras

PUBLIC _DLODTIME
_DLODTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI
PUSH DS ;

ALIGN DLOD,LOD ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, LODL ; PRIME TEST AREA
AND BX, not (4-1) ; Round down to dowrd boundary
MOV CX, LODD-LODL ; Length of test area
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV DS, FIRSTSEG ; Set to initial segment
ASSUME DS:NOTHING ; Tell the assembler about it
DB 03EH ; Use DS:
MOV AX,DS:[0] ; Ensure loop data value is cached

MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
LODL: REPT 100 ; DO 100:
DB 03EH ; Use DS:
MOV AX,DS:[0] ; Read constant data item
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ LODD ; JUMP IF COMPLETE
JMP LODL ; LOOP BACK IF NOT DONE
LODD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DS ;
ASSUME DS:DGROUP ; Tell the assembler about it
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_DLODTIME ENDP
;***************************************************************;
; _DRAMTIME ;
; TIME EXECUTION OF MOV INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;

PUBLIC _DRAMTIME
_DRAMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI
PUSH DS ;
PUSH ES ;

ALIGN DRAM,RAM ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, RAML ; PRIME TEST AREA
AND BX, not (4-1) ; Round down to dowrd boundary
MOV CX, RAMD-RAML ; Length of test area
CALL PRIME ;
MOV DI, FIRSTSEG ; SET SEG REGS TO
MOV DS, DI ; 64K DISTANT LOCATIONS
ASSUME DS:NOTHING ; Tell the assembler about it
ADD DI,NEXTSEG ;
MOV ES, DI ; SET ES
ASSUME ES:NOTHING ; Tell the assembler about it
ADD DI,NEXTSEG ;
PUSH DI ;
DB 00FH, 0A1H ; POP FS
ADD DI,NEXTSEG ;
PUSH DI ;
DB 00FH, 0A9H ; POP GS
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
RAML: REPT 25 ; DO 100:
DB 03EH, 0A1H ; MOV AX, DS:WORD PTR 0
DW 0 ;
DB 026H, 0A1H ; MOV AX, ES:WORD PTR 0
DW 0 ;
DB 064H, 0A1H ; MOV AX, FS:WORD PTR 0
DW 0 ;
DB 065H, 0A1H ; MOV AX, GS:WORD PTR 0
DW 0 ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ RAMD ; JUMP IF COMPLETE
JMP RAML ; LOOP BACK IF NOT DONE
RAMD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP ES ;
ASSUME ES:DGROUP ; Tell the assembler about it
POP DS ;
ASSUME DS:DGROUP ; Tell the assembler about it
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_DRAMTIME ENDP
;***************************************************************;
; _DIMMTIME ;
; TIME EXECUTION OF MOV INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;
PUBLIC _DIMMTIME
_DIMMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN DIMM,IMM ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, IMML ; PRIME TEST AREA
MOV CX, 400 ;
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
IMML: REPT 100 ; DO 100:
REPT 8 ; 8X:
DB 066H ; MOV EDX, 00000000H
DB 0F7H, 0C2H, 0, 0, 0, 0 ;
ENDM ; END MACRO
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ IMMD ; JUMP IF COMPLETE
JMP IMML ; LOOP BACK IF NOT DONE
IMMD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_DIMMTIME ENDP
;***************************************************************;
; _BCLCTIME ;
; TIME EXECUTION OF CLC INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;
PUBLIC _BCLCTIME
_BCLCTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN BCLC,BI ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, BIL ; PRIME TEST AREA
MOV CX, 100 ;
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
BIL: REPT 100 ; DO 100 INC'S
INC DL ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ BID ; JUMP IF COMPLETE
JMP BIL ; LOOP BACK IF NOT DONE
BID: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_BCLCTIME ENDP
;***************************************************************;
; _BDAATIME ;
; TIME EXECUTION OF DAA INSTRUCTION (INSTR. READ TIME) ;
;***************************************************************;
PUBLIC _BDAATIME
_BDAATIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN BDAA,BX ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, BXL ; PRIME TEST AREA
MOV CX, 100 ;
CALL PRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
BXL: REPT 100 ; DO 100 DAA'S
DAA ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ BXD ; JUMP IF COMPLETE
JMP BXL ; LOOP BACK IF NOT DONE
BXD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_BDAATIME ENDP
;***************************************************************;
; _BMVSTIME ;
; TIME EXECUTION OF REP MOVSB INSTRUCTION ;
;***************************************************************;
PUBLIC _BMVSTIME
_BMVSTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI

MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START + 5 ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
CLD ; SET FORWARD DIRECTION
REP MOVSB ; RUN TEST

CALL SETUP_TIMER ; SET UP TIMER
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START + 5 ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSB ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT

POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_BMVSTIME ENDP
;***************************************************************;
; _WMVSTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION ;
;***************************************************************;
PUBLIC _WMVSTIME
_WMVSTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI

MOV DI, TESTSEG ;

MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START + 6 ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
CLD ; SET FORWARD DIRECTION
REP MOVSW ; RUN TEST

CALL SETUP_TIMER ; SET UP TIMER
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START + 6 ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT

POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_WMVSTIME ENDP
;***************************************************************;
; _DMVSTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION ;
;***************************************************************;
PUBLIC _DMVSTIME
_DMVSTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI

DB 066H ; 32 BIT OPERANDS:
XOR DI, DI ; CLEAR EDI
DB 066H ; 32 BIT OPERANDS:
XOR SI, SI ; CLEAR ESI
DB 066H ; 32 BIT OPERANDS:
XOR CX, CX ; CLEAR ECX
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
CLD ; SET FORWARD DIRECTION
DB 066H ; 32 BIT OPERANDS:
REP MOVSW ; RUN TEST

CALL SETUP_TIMER ; SET UP TIMER
DB 066H ; 32 BIT OPERANDS:
XOR DI, DI ; CLEAR EDI
DB 066H ; 32 BIT OPERANDS:
XOR SI, SI ; CLEAR ESI
DB 066H ; 32 BIT OPERANDS:
XOR CX, CX ; CLEAR ECX
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DS, DI ;
LEA SI, TESTSEG_START ; DS:SI -> TEST SEGMENT
LEA DI, TESTSEG_START + 0 ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
DB 066H ; 32 BIT OPERANDS:
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_DMVSTIME ENDP
;***************************************************************;
; _WPSHTIME ;
; TIME EXECUTION OF PUSHA INSTRUCTION ;
;***************************************************************;
PUBLIC _WPSHTIME
_WPSHTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;

ALIGN WPSH,WS ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
MOV AX, [BP+4] ; GET COUNT ARGUMENT
CWD ; MAKE DOUBLE WORD
MOV CX, 200 ;
DIV CX ; DIVIDE BY MOVS/LOOP
MOV CX, AX ;
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
MOV DX, SS ; SAVE SS, SP
MOV BX, TESTSEG ; SET STACK TO TEST SEGMENT
MOV SS, BX ;
MOV BX, SP ;
MOV SP, OFFSET TESTSEG_START + 4096
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
WSL: REPT 25 ; PUSH THE REGISTERS
DB 60H ;
ENDM ; END MACRO
LOOP WSL ; LOOP UNTIL DONE
WSD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
MOV SS, DX ; RESTORE SS, SP
MOV SP, BX ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
MOV SP, BP ; PUT THE STACK BACK
POP BP ; RESTORE BP
RET ; RETURN
_WPSHTIME ENDP
;***************************************************************;
; _DPSHTIME ;
; TIME EXECUTION OF PUSHA INSTRUCTION ;
;***************************************************************;
PUBLIC _DPSHTIME
_DPSHTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;

ALIGN DPSH,DS ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
MOV AX, [BP+4] ; GET COUNT ARGUMENT
CWD ; MAKE DOUBLE WORD
MOV CX, 200 ;
DIV CX ; DIVIDE BY MOVS/LOOP
MOV CX, AX ;
AND SP, 0FFFCH ; ALIGN SP
PUSH AX ; DUMMY
PUSH BP ; SAVE BP
MOV BP, SP ;
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
MOV DX, SS ; SAVE SS, SP
MOV BX, TESTSEG ; SET STACK TO TEST SEGMENT
MOV SS, BX ;
MOV BX, SP ;
MOV SP, OFFSET TESTSEG_START + 4096
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
DSL: REPT 25 ; PUSH THE BIG REGISTERS
DB 66H, 60H ;
ENDM ; END MACRO
LOOP DSL ; LOOP UNTIL DONE
DSD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
MOV SS, DX ; RESTORE SS, SP
MOV SP, BX ;
STI ; START INTERRUPTS
POP BP ;
CALL GET_TIMER ; OBTAIN FINAL COUNT
MOV SP, BP ; PUT THE STACK BACK
POP BP ; RESTORE BP
RET ; RETURN
_DPSHTIME ENDP
;***************************************************************;
; _BROMTIME ;
; TIME EXECUTION OF REP MOVSB INSTRUCTION FROM ROM ;
;***************************************************************;
PUBLIC _BROMTIME
_BROMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DI, 0F000H ; SET DS TO ROM START
MOV DS, DI ;
MOV SI, 5 ; DS:SI -> ROM
LEA DI, TESTSEG_START ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSB ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_BROMTIME ENDP
;***************************************************************;
; _WROMTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION FROM ROM ;
;***************************************************************;
PUBLIC _WROMTIME
_WROMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DI, 0F000H ; SET DS TO ROM START
MOV DS, DI ;
MOV SI, 6 ; DS:SI -> ROM
LEA DI, TESTSEG_START ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_WROMTIME ENDP
;***************************************************************;
; _DROMTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION FROM ROM ;
;***************************************************************;
PUBLIC _DROMTIME
_DROMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
DB 066H ; 32 BIT OPERANDS:
XOR DI, DI ; CLEAR EDI
DB 066H ; 32 BIT OPERANDS:
XOR SI, SI ; CLEAR ESI
DB 066H ; 32 BIT OPERANDS:
XOR CX, CX ; CLEAR ECX
MOV DI, TESTSEG ;
MOV ES, DI ;
MOV DI, 0F000H ; SET DS TO ROM START
MOV DS, DI ;
MOV SI, 0 ; DS:SI -> ROM
LEA DI, TESTSEG_START ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
DB 066H ; 32 BIT OPERANDS:
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_DROMTIME ENDP
;***************************************************************;
; _BVIDTIME ;
; TIME EXECUTION OF REP STOSB INTO VIDEO MEMORY ;
;***************************************************************;
PUBLIC _BVIDTIME
_BVIDTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH ES ; SAVE ES
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV AX, VIDBASE ; GET BASE ADDRESS
MOV ES, AX ;
MOV DI, 0 ; ES:DI -> VIDEO MEMORY
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP STOSB ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP ES ; RESTORE ES
POP BP ; RESTORE BP
RET ; RETURN
_BVIDTIME ENDP
;***************************************************************;
; _WVIDTIME ;
; TIME EXECUTION OF REP STOSW INTO VIDEO MEMORY ;
;***************************************************************;
PUBLIC _WVIDTIME
_WVIDTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH ES ; SAVE ES
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV AX, VIDBASE ; GET BASE ADDRESS
MOV ES, AX ;
MOV DI, 0 ; ES:DI -> VIDEO MEMORY
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP STOSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP ES ; RESTORE ES
POP BP ; RESTORE BP
RET ; RETURN
_WVIDTIME ENDP
;***************************************************************;
; _DVIDTIME ;
; TIME EXECUTION OF REP STOSW INTO VIDEO MEMORY ;
;***************************************************************;
PUBLIC _DVIDTIME
_DVIDTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH ES ; SAVE ES
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
DB 066H ; 32 BIT OPERANDS:
XOR DI, DI ; CLEAR EDI
DB 066H ; 32 BIT OPERANDS:
XOR CX, CX ; CLEAR ECX
MOV AX, VIDBASE ; GET BASE ADDRESS
MOV ES, AX ;
DB 066H ; 32 BIT OPERANDS:
MOV AX, 0700H ; MOV EAX, 07000700H
DW 0700H ;
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
DB 066H ; 32 BIT OPERANDS:
REP STOSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP ES ; RESTORE ES
POP BP ; RESTORE BP
RET ; RETURN
_DVIDTIME ENDP
;***************************************************************;
; _SETUP_VIDEO ;
; DETECT THE TYPE OF VIDEO CARD AND SAVE THE BASE ;
;***************************************************************;
PUBLIC _SETUP_VIDEO
_SETUP_VIDEO PROC NEAR
PUSH BP ; SAVE REGISTERS
PUSH ES ;
PUSH SI ;
PUSH DI ;
INT 11H ; EQUIPMENT DETERMINATION
AND AL, 30H ; MASK DISPLAY BITS
CMP AL, 30H ; CHECK FOR MONOCHROME
MOV AX, 0B000H ; MONOCHROME BASE
JE SVM ; JUMP IF MONOCHROME
MOV AX, 0B800H ; COLOR BASE
SVM: MOV VIDBASE, AX ; SAVE BASE ADDRESS
POP DI ; RESTORE REGISTERS
POP SI ;
POP ES ;
POP BP ;
RET ; RETURN 0
_SETUP_VIDEO ENDP
;***************************************************************;
; _FPTIME ;
; TIME EXECUTION OF FLOATING POINT DIVIDE ;
;***************************************************************;
PUBLIC _FPTIME
_FPTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DI ; SAVE DI

ALIGN FP,F ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
LEA BX, FL ; UNPRIME TEST AREA
MOV CX, 300 ;
CALL UNPRIME ;
MOV DI, 0 ; CLEAR DI
MOV AX, [BP+4] ; GET COUNT ARGUMENT
ADD AX, 99 ; ROUND UP
MOV CX, 100 ; DIVIDE BY 100 =
DIV CL ; NUMBER OF INSTRUCTIONS
MOV CL, AL ; PER PASS
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
FNINIT ; INIT FP
FLD1 ; DIVIDE 1.0
FLD1 ; BY 1.0
CLI ; STOP INTERRUPTS
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
FL: REPT 100 ; DO 100 DIVIDES
FDIV ST(1), ST ;
ENDM ; END MACRO
DEC CX ; COUNT THIS PASS
JZ FD ; JUMP IF COMPLETE
JMP FL ; LOOP BACK IF NOT DONE
FD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_FPTIME ENDP
;***************************************************************;
; _WEMPTIME ;
; TIME EXECUTION OF PUSHA INSTRUCTION ;
;***************************************************************;
PUBLIC _WEMPTIME
_WEMPTIME PROC NEAR
PUSH BP ; SAVE FRAME
PUSH DI ; SAVE DI
MOV BP, SP ;

ALIGN WEMP,EP ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
MOV AX, [BP+6] ; GET COUNT ARGUMENT
CWD ; MAKE DOUBLE WORD
MOV CX, 200 ;
DIV CX ; DIVIDE BY MOVS/LOOP
MOV CX, AX ;
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
MOV DX, SS ; SAVE STACK SEGMENT
MOV SS, EMMBASE ; PUT STACK IN EMM
MOV SP, 400 ; SET SP FOR PUSHES
MOV DI, SP ; SAVE THIS NUMBER
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
EPL: REPT 25 ; PUSH THE REGISTERS
DB 60H ;
ENDM ;
MOV SP, DI ; PUT THE STACK BACK
LOOP EPL ; LOOP UNTIL DONE
EPD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
MOV SS, DX ; RESTORE ORIGINAL STACK
MOV SP, BP ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_WEMPTIME ENDP
;***************************************************************;
; _DEMPTIME ;
; TIME EXECUTION OF PUSHA INSTRUCTION ;
;***************************************************************;
PUBLIC _DEMPTIME
_DEMPTIME PROC NEAR
PUSH BP ; SAVE FRAME
PUSH DI ; SAVE DI
MOV BP, SP ;

ALIGN DEMP,ED ; Align instructions on dword boundary

CALL SETUP_TIMER ; SET UP TIMER
MOV AX, [BP+6] ; GET COUNT ARGUMENT
CWD ; MAKE DOUBLE WORD
MOV CX, 200 ;
DIV CX ; DIVIDE BY MOVS/LOOP
MOV CX, AX ;
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
MOV DX, SS ; SAVE STACK SEGMENT
MOV SS, EMMBASE ; PUT STACK IN EMM
MOV SP, 800 ; SET SP FOR PUSHES
MOV DI, SP ; SAVE THIS NUMBER
OUT PPI_PORT, AL ; ENABLE TIMER
INSTR_ALIGN ; Ensure instruction alignment
EDL: REPT 25 ; PUSH THE BIG REGISTERS
DB 66H, 60H ;
ENDM ; END MACRO
MOV SP, DI ; PUT THE STACK BACK
LOOP EDL ; LOOP UNTIL DONE
EDD: MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
MOV SS, DX ; RESTORE ORIGINAL STACK
MOV SP, BP ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP BP ; RESTORE BP
RET ; RETURN
_DEMPTIME ENDP
;***************************************************************;
; _BEMMTIME ;
; TIME EXECUTION OF REP MOVSB INSTRUCTION ;
;***************************************************************;
PUBLIC _BEMMTIME
_BEMMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV DI, EMMBASE ; SET UP EMM BASE ADDRESS
MOV ES, DI ;
MOV DS, DI ;
MOV SI, 5 ; ES:SI -> BYTE IN TEST SEGMENT
XOR DI, DI ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSB ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_BEMMTIME ENDP
;***************************************************************;
; _WEMMTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION ;
;***************************************************************;
PUBLIC _WEMMTIME
_WEMMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
MOV DI, EMMBASE ; SET UP EMM BASE ADDRESS
MOV ES, DI ;
MOV DS, DI ;
MOV SI, 6 ; ES:SI -> WORD IN TEST SEGMENT
XOR DI, DI ; ES:DI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_WEMMTIME ENDP
;***************************************************************;
; _DEMMTIME ;
; TIME EXECUTION OF REP MOVSW INSTRUCTION ;
;***************************************************************;
PUBLIC _DEMMTIME
_DEMMTIME PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSH DS ; SAVE DS
PUSH ES ; SAVE ES
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
CALL SETUP_TIMER ; SET UP TIMER
DB 066H ; 32 BIT OPERANDS:
XOR DI, DI ; CLEAR EDI
DB 066H ; 32 BIT OPERANDS:
XOR SI, SI ; CLEAR ESI
DB 066H ; 32 BIT OPERANDS:
XOR CX, CX ; CLEAR ECX
MOV DI, EMMBASE ; SET UP EMM BASE ADDRESS
MOV ES, DI ;
MOV DS, DI ;
XOR DI, DI ; ES:DI -> TEST SEGMENT
XOR SI, SI ; DS:SI -> TEST SEGMENT
MOV CX, [BP+4] ; GET COUNT ARGUMENT
IN AL, PPI_PORT ; GET CURRENT CONTROL
MOV BL, AL ; SAVE IN BL
OR AL, 1 ; SET TIMER ENABLE BIT
CLI ; STOP INTERRUPTS
CLD ; SET FORWARD DIRECTION
OUT PPI_PORT, AL ; ENABLE TIMER
DB 066H ; 32 BIT OPERANDS:
REP MOVSW ; RUN TEST
MOV AL, BL ; RESTORE CONTROL VALUE
OUT PPI_PORT, AL ;
STI ; START INTERRUPTS
CALL GET_TIMER ; OBTAIN FINAL COUNT
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP ES ; RESTORE ES
POP DS ; RESTORE DS
POP BP ; RESTORE BP
RET ; RETURN
_DEMMTIME ENDP
;***************************************************************;
; _SETUP_EMM ;
; SET UP EXPANDED MEMORY AND RETURN THE BASE ;
;***************************************************************;
PUBLIC _SETUP_EMM
_SETUP_EMM PROC NEAR
PUSH BP ; SAVE REGISTERS
PUSH ES ;
PUSH SI ;
PUSH DI ;
MOV AH, 35H ; GET EMM INTERRUPT
MOV AL, 67H ; VECTOR
INT 21H ;
MOV DI, 000AH ; OFFSET OF DRIVER NAME
LEA SI, EMM_NAME ; COMPARE STRING
MOV CX, 8 ; LENGTH OF STRING
CLD ;
REPE CMPSB ; COMPARE THE NAME
JNE SENO ; JUMP IF NO GOOD
SE1: MOV AH, 40H ; FUNCTION 1:
INT 67H ; GET MANAGER STATUS
CMP AH, 82H ; CHECK FOR BUSY
JE SE1 ; TRY AGAIN IF BUSY
OR AH, AH ; CHECK FOR ERROR
JNZ SENO ; JUMP ON ERROR
SE2: MOV AH, 41H ; FUNCTION 2:
INT 67H ; GET PAGE FRAME BASE
CMP AH, 82H ; CHECK FOR BUSY
JE SE2 ; TRY AGAIN IF BUSY
OR AH, AH ; CHECK FOR ERROR
JNZ SENO ; JUMP ON ERROR
MOV EMMBASE, BX ; SAVE THE BASE
SE3: MOV AH, 42H ; FUNCTION 3:
INT 67H ; GET NUMBER OF PAGES
CMP AH, 82H ; CHECK FOR BUSY
JE SE3 ; TRY AGAIN IF BUSY
OR AH, AH ; CHECK FOR ERROR
JNZ SENO ; JUMP ON ERROR
OR BX, BX ; CHECK UNALLOCATED PAGES
JZ SENO ; JUMP IF NONE AVAILABLE
SE4: MOV AH, 43H ; FUNCTION 4:
MOV BX, 1 ; ALLOCATE ONE PAGE
INT 67H ;
CMP AH, 82H ; CHECK FOR BUSY
JE SE4 ; TRY AGAIN IF BUSY
OR AH, AH ; CHECK FOR ERROR
JNZ SENO ; JUMP ON ERROR
MOV PID, DX ; SAVE THE PROCESS ID
SE5: MOV AH, 44H ; FUNCTION 5:
XOR BX, BX ; MAP THE PAGE TO
XOR AL, AL ; FRAME BASE
INT 67H ;
CMP AH, 82H ; CHECK FOR BUSY
JE SE5 ; TRY AGAIN IF BUSY
OR AH, AH ; CHECK FOR ERROR
JNZ SENC ; JUMP ON ERROR
XOR AX, AX ;
POP DI ; RESTORE REGISTERS
POP SI ;
POP ES ;
POP BP ;
RET ; RETURN 0
SENC: MOV AH, 45H ; FUNCTION 6:
INT 67H ; CLOSE EMM
CMP AH, 82H ; CHECK FOR BUSY
JE SENC ; TRY AGAIN IF BUSY
SENO: MOV AX, 0FFFFH ;
POP DI ; RESTORE REGISTERS
POP SI ;
POP ES ;
POP BP ;
RET ; RETURN -1
_SETUP_EMM ENDP
;***************************************************************;
; _FINISH_EMM ;
; CLOSE THE EMM DEVICE, RELEASE THE PAGE ;
;***************************************************************;
PUBLIC _FINISH_EMM
_FINISH_EMM PROC NEAR
PUSH BP ; SAVE REGISTERS
PUSH ES ;
PUSH SI ;
PUSH DI ;
SE6: MOV AH, 45H ; FUNCTION 6:
MOV DX, PID ; CLOSE EMM
INT 67H ;
CMP AH, 82H ; CHECK FOR BUSY
JE SE6 ; TRY AGAIN IF BUSY
POP DI ; RESTORE REGISTERS
POP SI ;
POP ES ;
POP BP ;
RET ; RETURN
_FINISH_EMM ENDP
;***************************************************************;
; PRIME ;
; PRIME THE CACHE, IF ANY, BY SCANNING TEST AREA ;
;***************************************************************;
PRIME PROC NEAR
PUSH AX ; SAVE ALL REGISTERS USED
PUSH DI ; SAVE SI (START ADDRESS)
PUSH CX ; SAVE CX (COUNT)
PUSH ES ; SAVE ES
MOV AX, CS ; SET ES TO DS
MOV ES, AX ;
MOV DI, BX ; PUT ADDRESS IN DI
MOV AL, 111 ; USE UNLIKELY VALUE IN AL
CLD ; SET FORWARD DIRECTION
PL: REPNE SCASB ; SCAN MEMORY
JCXZ PE ; JUMP IF DONE
JMP PL ; JUMP BACK IF NOT DONE
PE: POP ES ;
POP CX ; RESTORE REGISTERS
POP DI ;
POP AX ;
RET ; RETURN
PRIME ENDP
;***************************************************************;
; UNPRIME ;
; PRIME THE CACHE, IF ANY, BY SCANNING AWAY FROM TEST AREA;
;***************************************************************;
UNPRIME PROC NEAR
PUSH AX ; SAVE ALL REGISTERS USED
PUSH DI ; SAVE SI (START ADDRESS)
PUSH CX ; SAVE CX (COUNT)
PUSH ES ; SAVE ES
MOV AX, CS ; SET ES TO CS + 64K
ADD AX, 1000H ;
MOV ES, AX ;
MOV DI, BX ; PUT ADDRESS IN DI
MOV AL, 111 ; USE UNLIKELY VALUE IN AL
CLD ; SET FORWARD DIRECTION
UPL: REPNE SCASB ; SCAN MEMORY
JCXZ UPE ; JUMP IF DONE
JMP UPL ; JUMP BACK IF NOT DONE
UPE: POP ES ;
POP CX ; RESTORE REGISTERS
POP DI ;
POP AX ;
RET ; RETURN
UNPRIME ENDP
;***************************************************************;
; SETUP_TIMER ;
; SET UP THE TIMER FOR MAXIMUM COUNT, TO TIME A RUN ;
;***************************************************************;
SETUP_TIMER PROC NEAR
PUSH AX ; SAVE AX
IN AL, PPI_PORT ; STOP THE TIMER
AND AL, 0FCH ;
OUT PPI_PORT, AL ;
MOV AL, 0B4H ; INITIALIZE THE TIMER
OUT TIMER_CTRL, AL ;
JMP $+2 ; Drain PIQ
MOV AL, 0 ; CLEAR THE COUNT
OUT TIMER2_PORT, AL ;
JMP $+2 ; Drain PIQ
OUT TIMER2_PORT, AL ;
POP AX ; RESTORE AX
RET ; RETURN
SETUP_TIMER ENDP
;***************************************************************;
; GET_TIMER ;
; TAKE THE COUNT FROM THE TIMER ;
;***************************************************************;
GET_TIMER PROC NEAR
IN AL, TIMER2_PORT ; GET LOW BYTE OF TIME
MOV AH, AL ;
IN AL, TIMER2_PORT ; GET HIGH BYTE
XCHG AL, AH ; TIME IN AX
NEG AX ; CORRECT FOR COUNT-DOWN
RET ; RETURN
GET_TIMER ENDP
;***************************************************************;
; _NDP_PRESENT ;
; CHECK IF 80287 IS PRESENT ;
;***************************************************************;
PUBLIC _NDP_PRESENT
_NDP_PRESENT PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
INT 11H ; BIOS EQUIP CHECK
TEST AL,02H ; IS 80287 BIT SET?
JZ NO ; NO MEANS NO 80287
MOV AX,01h ; RETURN TRUE
JMP NDPEXIT ; ALL DONE
NO: XOR AX,AX ; SET AX TO FALSE
NDPEXIT:MOV SP, BP ; RESTORE SP
POP BP ; RESTORE BP
RET ; RETURN
_NDP_PRESENT ENDP
;***************************************************************;
; _DETECT_387 ;
; CHECK IF MATH COPROCESSOR IS 80387 ;
;***************************************************************;
PUBLIC _DETECT_387
_DETECT_387 PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
FINIT ; USE DEFAULT INFINITY MODE
FLD1 ; GENERATE INFINITY
FLDZ ;
FDIV ;
FLD ST ; FORM NEGATIVE INFINITY
FCHS ; BY CHANGING SIGN
FCOMPP ; COMPARE +/-INFINITY
FSTSW STATUSW ; EQUAL FOR 8087/287
FWAIT ; WAIT
MOV AX,STATUSW ;
SAHF ; STORE RESULT IN FLAGS
JZ NO387 ; NOT A 80387
MOV AX,01h ; RETURN TRUE
JMP D3EXIT ; ALL DONE
NO387: XOR AX,AX ; SET AX TO FALSE
D3EXIT: MOV SP, BP ; RESTORE SP
POP BP ; RESTORE BP
RET ; RETURN
_DETECT_387 ENDP
;***************************************************************;
; _CPU_TYPE ;
; CHECK IF CPU IS 8088/8086, 80188/80186, 80286, 80386 ;
;***************************************************************;
PUBLIC _CPU_TYPE
_CPU_TYPE PROC NEAR
PUSH BP ; SAVE FRAME
MOV BP, SP ;
PUSHF ;
MOV CL,20H ; INITIALIZE SHIFT COUNT
MOV AX,1 ; DESTINATION
SHR AX,CL ; SHIFT RIGHT
TEST AX,1 ; IS AX THE SAME?
JZ _8X ; IS 8086 OR 8088
PUSH SP ; SEE IF SP IS UPDATED
POP BX ; BEFORE OR AFTER IT IS
CMP BX,SP ; PUSHED
JNE _18X ; IS 80188 OR 80186
MOV AX,0F000H ; TRY TO SET HIGH BITS
PUSH AX ;
POPF ; IN THE FLAGS
PUSHF ;
POP AX ; LOOK AT ACTUAL FLAGS
AND AX,0F000H ; ANY HIGH BITS SET?
JE _286 ; IS 80286
_386: MOV AX,03 ; IS AN 80386
JMP CTEXIT ;
_286: MOV AX,02 ; IS AN 80286
JMP CTEXIT ;
_18X: MOV AX,01 ; IS AN 80188/80186
JMP CTEXIT ;
_8X: MOV AX,00 ; IS AN 8088/8086
CTEXIT: POPF ; RESTORE ORIGINAL FLAGS
MOV SP, BP ; RESTORE SP
POP BP ; RESTORE BP
RET ; RETURN
_CPU_TYPE ENDP
;***************************************************************;
; DD_ALIGN ;
; Ensure instruction fectches are on a dword boundary. ;
;***************************************************************;
PUBLIC DD_ALIGN
DD_ALIGN PROC NEAR
assume ds:nothing,es:nothing ; Tell the assembler about it

DD_ALIGN_STR struc

dw ? ; Caller's BP
dw ? ; Caller's IP
DD_ALIGN_START dw ? ; Offset of alignment start
DD_ALIGN_LEN dw ? ; Length of alignment area

DD_ALIGN_STR ends

push bp ; Prepare to address the stack
mov bp,sp ; Hello, Mr. Stack

REGSAVE ; Save registers

push cs ; Setup DS and ES for code references
pop ds
assume ds:_TEXT ; Tell the assembler about it
push cs
pop es
assume es:_TEXT ; Tell the assembler about it

mov si,[bp].DD_ALIGN_START ; Get source offset
mov di,si ; Copy as destination offset
and di,not (4-1) ; Round down to DD boundary
mov cx,[bp].DD_ALIGN_LEN ; Get length in bytes
rep movsb ; Move it down

; Fill in the tail with NOPs

mov cx,si ; Get current source offset
sub cx,di ; Less current destin to get length of tail
mov al,90h ; Fill with NOPs
rep stosb ; Fill it up

REGREST ; Restore
assume ds:nothing,es:nothing ; Tell the assembler about it

pop bp ; Restore

ret 2*2 ; Return to caller, popping arguments

assume ds:nothing,es:nothing ; Tell the assembler about it

DD_ALIGN ENDP
_TEXT ENDS
END


  3 Responses to “Category : System Diagnostics for your computer
Archive   : ATPERF.ZIP
Filename : TIME.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/