Metropoli BBS
VIEWER: memspeed.asm MODE: TEXT (CP437)
;***************************************************************************
; MEMSPEED.ASM      A program will show the video card memory trasnfer speed.
;
;
; This code is not written very effiecently at all. I only wrote it
; because I am soon going to upgrade my computer and I needed somthing
; to test the video and cpu memory transfer rates of variuos computers
; and video cards. This way I can be sure if I am buying a fast video card.
;
;***************************************************************************

.386

.MODEL FLAT
.STACK 4000h

PIC_FREQ	EQU	1193180 ;Hz
DURATION        EQU     18

CRLF		EQU     13,10


;  Macro to print some text on the screem
;
Print MACRO string
local @text,@skip
    mov edx,offset @text
    mov ah,9
    int 21h
    jmp @skip
@text db string,36
@skip:
ENDM

LOC STRUC
_d	dd ?
_w	dd 0
_b	dd 0
_mov32	dd 0
LOC ENDS

FILL_TYPE STRUC
Video		LOC <>
CPU		LOC <>
Video_Video	LOC <>
CPU_Video	LOC <>
CPU_CPU		LOC <>
FILL_TYPE ENDS


    .DATA

TempBuffer	DB 	1024*20 DUP (?)
TempBuffer2     DB 	1024*20 DUP (?)
VideoPtr        DD      ?
Ticks           DD      ?
old_INT8        DF      ?

extrn Debug :Near

    .CODE

NumberWrites	FILL_TYPE   <>

Print_Kbs PROC
        mov	ebx,PIC_FREQ
        mul	ebx
        mov     ebx,DURATION*65536
        div	ebx
        push	eax
        shr     eax,10
        call    Print_DecDword
        Print   ' Kb/s'
        pop	eax
	Ret
Print_Kbs ENDP


Video_Speed PROC                            ; Start of program

    ;****** make sure timer 0 is set to full scale **********

        mov     al,00110100b     ; SET TIMER VALUE TO ZERO ( 18.2 Hz )
        out     43h,al
        mov     al,0
        out     40h,al
        out     40h,al


        mov     ax,13h                    ; Reset TEXT mode
        int     10h

  ;******* get offset address (near pointer) to video text memory ********
        mov     ax,0EE02h
        int     31h
        neg     ebx
        add     ebx,0A0000h
        mov     VideoPtr,ebx

    ;****** hook timer interrupt **********
        mov     ax,204h
        mov     bl,8
        int     31h
        mov     dword ptr old_INT8,edx          ; save old vector
        mov     word ptr old_INT8[4],cx

        mov     ax,205h
        mov     edx,Offset Timer_ISR            ; put in new vector
        mov     cx,cs
        int     31h

 ;------------ fill video memory with REP STOSD for a set amount of time --------
        mov     Ticks,0
        mov	eax,0
Loop00:
        mov     edi,VideoPtr
        mov     ecx,320*20
        add     NumberWrites.Video._d, 320*20
        shr	ecx,2
        rep     stosd
        inc     al
        inc     ah
        push	ax
        push	ax
        pop	eax
        cmp     Ticks,DURATION
        jb Loop00

 ;------------ fill video memory with REP STOSW for a set amount of time --------
        mov     Ticks,0
        mov	eax,0
Loop01:
        mov     edi,VideoPtr
        mov     ecx,320*20
        add     NumberWrites.Video._w, ecx
        shr	ecx,1
        rep     stosw
        inc     al
        inc     ah
        cmp     Ticks,DURATION
        jb Loop01

 ;------------ fill video memory with REP STOSB for a set amount of time --------
        mov     Ticks,0
        mov	eax,0
Loop02:
        mov     edi,VideoPtr
        mov     ecx,320*20
        add     NumberWrites.Video._b, ecx
        rep     stosb
        inc     al
        cmp     Ticks,DURATION
        jb Loop02

 ;------------ fill CPU memory with REP STOSD for a set amount of time --------
        mov     Ticks,0
Loop03:
        mov     edi,OFFSET TempBuffer
        mov     ecx,SIZE TempBuffer
        add     NumberWrites.CPU._d,ecx
        shr	ecx,2
        rep     stosd
        cmp     Ticks,DURATION
        jb Loop03

 ;------------ fill CPU memory with MOV for a set amount of time --------
        mov     Ticks,0
        xor     eax,eax

Loop03a:
        mov     edi,OFFSET TempBuffer
     align 4
Loop03a_:
REPT 8
        mov     [edi],eax
        mov     [edi+4],eax
        mov     [edi+8],eax
        mov     [edi+12],eax
        mov     [edi+16],eax
        mov     [edi+20],eax
        mov     [edi+24],eax
        mov     [edi+28],eax
        add     edi,32
ENDM
        add     NumberWrites.CPU._mov32,32*8
        cmp     edi,SIZE TempBuffer + OFFSET TempBuffer
        jae     Loop03a
        cmp     Ticks,DURATION
        jb Loop03a_

 ;------- trasnfer CPU 2 Video memory with REP MOVSD for a set amount of time --------
        mov     Ticks,0
Loop04:
        mov     edi,VideoPtr
        mov     esi,OFFSET TempBuffer
        mov     ecx,SIZE TempBuffer
        add     NumberWrites.CPU_Video._d,ecx
        shr	ecx,2
        rep     movsd
        cmp     Ticks,DURATION
        jb Loop04

 ;---- trasnfer CPU 2 Video memory with MOV 32 bit for a set amount of time --------
        mov     Ticks,0
Loop05:
        mov     edi,VideoPtr
        mov     esi,OFFSET TempBuffer
        mov     ecx,SIZE TempBuffer
        Align 4
flop05:
REPT    4
	MOV	EAX,[ESI]
	MOV	[EDI],EAX
	MOV	EAX,[ESI+4]
	MOV	[EDI+4],EAX
	MOV	EAX,[ESI+8]
	MOV	[EDI+8],EAX
	MOV	EAX,[ESI+12]
	MOV	[EDI+12],EAX
	MOV	EAX,[ESI+16]
	MOV	[EDI+16],EAX
	MOV	EAX,[ESI+20]
	MOV	[EDI+20],EAX
	MOV	EAX,[ESI+24]
	MOV	[EDI+24],EAX
	MOV	EAX,[ESI+28]
	MOV	[EDI+28],EAX
        ADD     EDI,32
        ADD     ESI,32
	SUB	ECX,32
ENDM
        add     NumberWrites.CPU_Video._mov32,4*32
	and	ecx,ecx
        jz      Loop05
	cmp     Ticks,DURATION
        jb      flop05

 ;------------ CPU 2 CPU using MOVSD  for a set amount of time --------
        mov     Ticks,0
Loop06:
        mov     esi,OFFSET TempBuffer
        mov     edi,OFFSET TempBuffer2
        mov     ecx,SIZE TempBuffer
        add     NumberWrites.CPU_CPU._d,ecx
        shr	ecx,2
        rep     movsd
	cmp     Ticks,DURATION
        jb Loop06

 ;------------ CPU 2 CPU using 32bit MOV  for a set amount of time --------
        mov     Ticks,0
Loop07:
        mov     esi,OFFSET TempBuffer
        mov     edi,OFFSET TempBuffer
        mov     ecx,SIZE TempBuffer
        Align 4
flop07:
REPT    4
	MOV	EAX,[ESI]
	MOV	[EDI],EAX
	MOV	EAX,[ESI+4]
	MOV	[EDI+4],EAX
	MOV	EAX,[ESI+8]
	MOV	[EDI+8],EAX
	MOV	EAX,[ESI+12]
	MOV	[EDI+12],EAX
	MOV	EAX,[ESI+16]
	MOV	[EDI+16],EAX
	MOV	EAX,[ESI+20]
	MOV	[EDI+20],EAX
	MOV	EAX,[ESI+24]
	MOV	[EDI+24],EAX
	MOV	EAX,[ESI+28]
	MOV	[EDI+28],EAX
        ADD     EDI,32
        ADD     ESI,32
        SUB     ECX,32
ENDM
        add     NumberWrites.CPU_CPU._mov32,4*32
        and     ecx,ecx
        jz      Loop07
	cmp     Ticks,DURATION
        jb      flop07




        ;******* reset text mode **********
        mov     ax,3
        int     10h


        ;******* return origonal interrupt vector **********
        mov     ax,205h
        mov     edx,dword ptr old_INT8
        mov     cx,word ptr old_INT8[4]
        mov     bl,8
        int     31h

        ;******* print transfer rates on the screen **********

        Print   <'             Memory transfer rates using various methods                ',CRLF>
        Print   <'░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓░▓',CRLF>
        Print   <CRLF,' Video memory fill using REP STOSD ──────────────── '>
        mov     eax,NumberWrites.Video._d
        call	Print_Kbs
        Print   <CRLF,' Video memory fill using REP STOSW ──────────────── '>
        mov     eax,NumberWrites.Video._w
        call	Print_Kbs
        Print   <CRLF,' Video memory fill using REP STOSB ──────────────── '>
        mov     eax,NumberWrites.Video._b
        call	Print_Kbs
        Print   <CRLF,' CPU memory fill  using REP STOSD ───────────────── '>
        mov     eax,NumberWrites.CPU._d
        call	Print_Kbs
        Print   <CRLF,' CPU memory fill 32bit MOV ──────────────────────── '>
        mov     eax,NumberWrites.CPU._mov32
        call	Print_Kbs
        Print   <CRLF,' CPU to CPU transfer using REP MOVSD ────────────── '>
        mov     eax,NumberWrites.CPU_CPU._d
        call	Print_Kbs
        Print   <CRLF,' CPU to CPU transfer using 32bit MOV ────────────── '>
        mov     eax,NumberWrites.CPU_CPU._mov32
        call	Print_Kbs
        Print   <CRLF,' CPU to Video transfer using REP MOVSD ──────────── '>
        mov     eax,NumberWrites.CPU_Video._d
        call	Print_Kbs
        Print   <CRLF,' CPU to Video transfer using 32bit MOV ──────────── '>
        mov     eax,NumberWrites.CPU_Video._mov32
        call	Print_Kbs


        Print   <CRLF,CRLF>
        Print   <'  The 32bit MOV is using the following instructions repetivily', CRLF>
        Print   <'	mov eax,[esi]                mov [edi],eax    ',CRLF>
        Print   <'	mov [edi],eax                mov [edi+4],eax  ',CRLF>
        Print   <'	mov eax,[esi+4]     or       mov [edi+8],eax  ',CRLF>
        Print   <'	mov [edi+4],eax              mov [edi+12],eax ',CRLF>
        Print   <'	.. ect                       .. ect ',CRLF>

        Print   <CRLF>

	Print   <'Values may viary upto ±2% when ran at different times.', CRLF, CRLF>
	Print   <'Press any key to exit.', CRLF>

        mov     ah,0        ; Wait for a key ( using BIOS service )
        int     16h


        mov   ax,4C00h                          ; Termiate the program
        int   21h

Video_Speed ENDP

Timer_ISR PROC
        Push    eax
        Push    ds
        mov     ax,SEG Timer_ISR
        mov     ds,ax
        inc     Ticks
        mov     al,20h
        out     20h,al
        Pop     ds
        Pop     eax
        iretd
Timer_ISR ENDP


;╒══════════════════════════════════════════════════════════════════════════╕
;│                                                                          │
;│  procedure to print the Decimal value of EAX                             │
;│                                                                          │
;└──────────────────────────────────────────────────────────────────────────
; ***************  prints decimal EAX  ******************
Print_DecDword   PROC
        pushad
        mov     ESI,4*5
        mov     ecx,eax
dec83:
        mov	eax,ECX
        xor	edx,edx
        div     dec_divider[ESI]
        mov	ECX,EDX		; reuse remainder
                add al,'0'      ; use quotient as digit number
                mov     dl,al
                mov     ah,2
                int     21h             ; send character to screen
        sub ESI,4
        jge dec83
        popad
        RET
Print_DecDword        ENDP


align 4
dec_divider dd 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000
;-------------------------------------------------------


END  Video_Speed

[ RETURN TO DIRECTORY ]