; benchmarks under ASPI envilonment ; .286 PAGE 55,132 ; ; >SPV /D0 /T2 ; NX ASPI ADOPTER NUMBER ; ? HELP ; ; 1995.10.30. VER.1.00 ; 1996.10.31. VER.1.10 ; 1997. 1.20. VER.1.11 from KB to kB ; 1997. 4. 2. VER.1.12 random calculation bug fix ; 1998. 9. 3. Ver.1.20 for large count (Ultra2..) ; VERSION equ 120 ;version number ; FALSE EQU 0 TRUE EQU NOT FALSE ; VER_NUM1 equ VERSION/100+30h VER_NUM2 equ (VERSION/10)-((VER_NUM1-30h)*10)+30h VER_NUM3 equ VERSION-((VER_NUM2-30h)*10)-((VER_NUM1-30h)*100)+30h ; ; EQUATIONS OF DOS FUNCTIONS ; CCNDIR EQU 6 ;DIRECT CONSOLE ACCESS CSTRING equ 9 ;console out string CRDBUF EQU 10 ;READ CONSOLE BUFFER CCURDRV equ 19h ; take corrent drive CGETDATE equ 2ah ;get date CGETTIME equ 2ch ;get time CCREATE EQU 3CH ;CREATE HANDLE CCLOSE EQU 3EH ;CLOSE FILE CWRITE EQU 40H ;WRITE FILE CSETBLK EQU 4AH ;SET BLOCK SIZE CEXIT EQU 4CH ;EXIT TO SYSTEM CEXIST equ 4eh ; check file exist ; MSDOS EQU 21H ;DOS FUNCTION VECTOR ; ; EQUATIONS OF DATA ; LF equ 0ah ;line feed CR equ 0dh ;carriage return ESCC equ 1bh ;escape ; code segment public code ends ; psp segment at 0 org 80h command_line label byte ;COMMAND LINE DATA ADDRESS psp ends ; data segment public ; ; works ; even psp_seg dw ? ;psp segment time_count dw 0 ;second base end time rand_data dw 1234h ;random data cur_time db ? ;current displayed time ; scsi_id db 0 ;scsi id search work id_buf db 16 dup (0) ;device existance flags ; modify_cnt db 0 ;retry cnt without clear map USED_MAP_SIZE equ (100h/8)*100h ;64kbit map even used_map db USED_MAP_SIZE dup (0) ;random access used bit map ; ; work for aspi access ; scsimgrstr db 'SCSIMGR$',0 ;aspi manager ID aspi_handle dw 0 ;aspi handle save aspi_entry dd 0 ;aspi driver entry srb db 0d0h dup (0) ;aspi parameter block error_level db 0 ; capa_buf db 8 dup (0) ;read capacity data con_drive db 0 ;connected drive count db 0 host_adpt db 0 ;host adopter number ; ; work for test operation selection ; ch_buf db 0 ;0 main menu (row) db 0 ;1 drive ID db 0 ;2 command (read/write) db 0 ;3 block size (512KB,..) time_step db 10 ;4 time value for measure db 0 ;5 access mode (same/seq/rand) ; auto_buff db 0 ;automatic mode ;b0:single/automatic ;b4:no file/with file even ex_count dw 0 ;scsi command execution count dw 0 ;scsi command execution count+2 buff_seg dw 0 ;buffer segment ; disp_zb dw 0 ;current column position in test ; ; work for output file ; file_n db 'spvdata.' file_atr db '001',0 ;output file name handle dw ? ; data ends ; code segment assume cs:code, ds:data, ss:data ; ; main ; start: mov ax,seg data mov ss,ax mov sp,offset stack_top call initial ;initialize call disp_clr ;clear display & display title call connect_ch ;get connected scsi devices main_loop: call get_select ;get selection call autop ;do test cmp auto_buff,0 jz main_loop ;single mode so repeat ; ; return to dos ; end_s: mov al,00h ;no error code end_er: mov dx,offset disp_end end_erre: mov sp,offset stack_top mov bx,seg data mov ds,bx push ax call disp_str pop ax ;restore error code mov ah,CEXIT int MSDOS ;to os ; ; error end to os ; input dx:message point (end by $) ; why_end: call disp_str ;display error string mov al,01h ;error code jmp end_er ;error end ; ; execute test ; autop: cmp auto_buff,0 jne autopg ;automatic mode call ac_aspi ;single mode call l_time ;display transfer rate ret ; autopg: ;automatic mode call choi_dr ;get device id & version mov ch_buf[2],0 ; read or write mov ch_buf[3],0 ; block size mov ch_buf[5],0 ; access mode mov bx,offset inx_file_result ;menu index autop_lp: ;auto test loop push bx ;save current index point call choice_b ;display current testing screen call ac_aspi ;do scsi access test boddy pop bx ;restore current index point call set_result ;set one result call check_abort ;check operator abort jz autop_ab ;aborted call up_item ;up test item jc autop_lp ;to next call file_out ;out result data to file autope: ret autop_ab: ;aborted jmp end_s ; ; do scsi access test boddy ; ac_aspi: call clear_used_map ;clear used map mov ex_count,0 ;loop count mov ex_count+2,0 ;loop count call setup_srb ;setup srb structure cmp auto_buff,0 jne ac_aspia ;auto mode mov dx,offset disp_d1 ;single mode call disp_str ;speed mesuring ac_aspia: mov cur_time,-1 ;dummy for first display call set_time ;set time for time up wait ac_aspi_lp: ;do command loop ;al current second value call disp_time_val ;display time mov srb[0],02 mov srb[1],0 call aspi_g ;do command call modify_lba ;modify lba for next access add ex_count,1 ;up loop count adc ex_count+2,0 call check_time ;check time up jnc ac_aspi_lp ret ; ac_aspi_ab: ;aborted jmp end_s ; ; set time for time up to minute ; input time_step:required time value ; output time_count:second base (0 to 3599)+time_step+1 ; al:left time ; set_time: mov ah,CGETTIME int MSDOS mov ch,dh push cx ;current time mov al,60 mul cl ;get minute base mov dl,dh xor dh,dh add dl,time_step ;last time base add ax,dx inc ax mov time_count,ax ;keep second based time pop bx set_timew: ;wait start time push bx mov ah,CGETTIME int MSDOS mov ch,dh pop bx cmp bx,cx jz set_timew ;wait to second start timing mov al,time_step ;start timing ret ; ; check time up ; output cf:on time up ; al:current second ; check_time: mov ah,CGETTIME int MSDOS mov al,60 mul cl ;get minute base add al,dh adc ah,0 ;get second/hour mov bx,time_count xchg ax,bx sub ax,bx jbe check_timee ;time up cmp ax,1800 cmc jnc check_timen ;not time up sub ax,3600 ;overflow jbe check_timee ;time up check_timen: ret ; check_timee: stc ret ; ; display time value ; input al:value ; disp_time_val: cmp al,cur_time jz disp_time_vale ;not change mov cur_time,al ;changed cbw mov cl,10 div cl ;get high or al,al jz disp_time_vals ;zero suppress or al,10h ;some number disp_time_vals: add ax,3020h mov bx,offset disp_z30 mov [bx],ax mov dx,bx mov ah,CSTRING int MSDOS ;display it disp_time_vale: ret ; ; set one result to display & output file ; bx:current index point ; set_result: push bx call cdisp ;locate cursor to curr position call x_time ;make transfer rate by code mov byte ptr[disp_z31+0],bh mov byte ptr[disp_z31+1],bl mov byte ptr[disp_z31+2],ch mov byte ptr[disp_z31+3],cl mov byte ptr[disp_z31+4],dh mov dx,offset disp_z31 call disp_str push ds pop es pop bx mov di,[bx] ;get file data destination add bx,2 mov si,offset disp_z31 mov cx,05 rep movsb ;save result for output file ret ; ; check abort ; outout zf:on abort requested ; bx:bx ; check_abort: push bx mov ah,CCNDIR mov dl,0ffh int MSDOS ;get key pop bx cmp al,ESCC ret ; ; up test item ; output cf:off end ; up_item: inc ch_buf[5] ;up access mode cmp ch_buf[5],3 jc up_iteme ;to next mode mov ch_buf[5],0 inc ch_buf[3] ;up block size cmp ch_buf[3],8 jc up_iteme ;to next size mov ch_buf[3],0 inc ch_buf[2] ;up read/write mode cmp ch_buf[2],2 up_iteme: ret ; ; out result data to file ; file_out: test auto_buff,10h jz file_oute ;no file write call setup_date ;with file write setup date mov ah,CCREATE mov dx,offset file_n xor cx,cx int MSDOS mov dx,offset disp_x8 jc file_outerr ;file open error mov handle,ax mov ah,CWRITE mov dx,offset file_b7 mov cx,file_length ;length of data mov bx,handle int MSDOS mov dx,offset disp_x9 jc file_outerr ;file write error mov ah,CCLOSE mov bx,handle int MSDOS file_oute: ret ; file_outerr: jmp why_end ; ; initialize ; initial: mov bx,seg data mov es,bx mov es:psp_seg,ds ;set psp segment mov ds,bx call aloc_mem ;allocation memory for dma call take_option call take_aspi_p ;take aspi handle ret ; ; error end in initial state ; input dx:message point (end by $) ; init_error: mov al,02h ;error code jmp end_erre ;error end ; ; allocate dma memory ; aloc_mem: mov ax,ds mov es,ax mov bx,offset mem_last add bx,15 shr bx,4 ;to paragraph count in dseg add bx,ax ;get segment mov buff_seg,bx ;TBL_ROOT_DIR Segment add bx,1000H*8 ;+512KB end of required segment mov ax,psp_seg ;psp segment as top segment mov es,ax sub bx,ax ;get paragraph size mov ah,CSETBLK int MSDOS jc aloc_merr ;error in allocation ret ; aloc_merr: ;error of allocation mov dx,offset disp_aloc_err jmp init_error ; ; get option parameters ; spt n*:host adoptor number ; spt ? :help ; take_option: mov host_adpt,0 mov es,psp_seg ;command line segment mov si,offset command_line+1 mov bl,es:-1[si] mov bh,0 mov es:byte ptr [si+bx],0 ;SET END MARK cld option_r: lods es:byte ptr [si] or al,al je option_end ;end of command line cmp al,' ' je option_r ;pass space cmp al,'/' je option_h ;help message cmp al,'?' je option_h ;help message and al,0dfh cmp al,'N' je option_in ;adoptor number ;undefined ignored option_h: ;help mode or parameter error mov dx,offset option_help jmp init_error ; option_end: ret ; option_in: ;with adoptor number lods es:byte ptr [si] sub al,'0' jb option_h ;error code cmp al,9 ja option_h ;error code mov host_adpt,al ret ; ; take aspi handle ; take_aspi_p: mov ax,3d00h ; take handle aspi-driver mov dx,offset scsimgrstr ; int MSDOS ; jc take_aspi_pe ;error to get aspi handle mov aspi_handle,ax mov ax,4402h ; take aspi-driver entry point mov bx,aspi_handle mov cx,04 mov dx,offset aspi_entry int MSDOS mov ax,3e00h ; close to aspi_handle mov bx,aspi_handle int MSDOS ret ; take_aspi_pe: mov dx,offset disp_aspi_err jmp init_error ;error end ; ; clear display & display title ; disp_clr: mov dx,offset crt_clr call disp_str ;clear screen mov dx,offset title_s call disp_str ;set title ret ; ; check connected drive & display selection screen ; connect_ch: mov time_step,10 mov scsi_id,0 call inquiry_setup ;inquiry setup mov dx,offset disp_t1 call disp_str xor bx,bx connect_ch1: ;check loop mov al,scsi_id mov srb[08],al push bx call aspi_g pop bx mov id_buf[bx],al inc scsi_id inc bx cmp bx,07 jnz connect_ch1 xor ax,ax xor bx,bx mov cx,7 connect_ch3: add al,id_buf[bx] inc bx loop connect_ch3 cmp ax,0 jne connect_ch4 mov dx,offset disp_t3 jmp why_end ; connect_ch4: mov con_drive,al mov dx,offset disp_t2 call disp_str ;erase under test message xor bx,bx connect_ch5: ;connected loop cmp id_buf[bx],01 jne connect_ch6 ;not connected mov ch,'0' ;connected add ch,bl mov ah,con_drive+1 mov al,DISP_DRV_LEN mul ah mov si,ax mov disp_r1[si+09],ch ;set id inc con_drive+1 ;up connected drive count connect_ch6: inc bx cmp bx,07 jb connect_ch5 ret ; ; get selection ; get_select: call disp_drive ;display drive ID call choi_dr ;get device id & version get_select_lp: ;selection loop mov auto_buff,0 ;clear auto mode call choice_a ;display current choise mov dx,offset disp_x1 call disp_str ;display prompt get_select_n: push offset get_select_lp ;return address call key_int cmp ax,4b00h je get_select_l ; left cmp ax,5000h je get_select_d ; down cmp ax,4800h je get_select_u ; up cmp ax,4d00h je get_select_r ; right cmp al,'+' je get_select_sec ;up time cmp al,'-' je get_select_sec ;down time pop dx ;discard retrun address cmp ah,01 ; esc je get_select_a ;abort cmp al,'x' je get_select_auto ;auto mode cmp al,'X' je get_select_auto ;auto mode cmp al,CR jnz get_select_n ;not match get_select_e: ;end of selection mov dx,offset disp_x2 call disp_str ;clear prompt call capa_d ;get capacity data ret ; get_select_a: ;abort jmp end_s ; get_select_d: ;down add ch_buf,01 ;up main menu cmp ch_buf,04+1 jc get_select_de ;in range mov ch_buf,0 get_select_de: ret ; get_select_u: ;up sub ch_buf,01 jnc get_select_ue ;down main menu mov ch_buf,04 get_select_ue: ret ; get_select_l: ;left jmp ch_l ; get_select_r: ;right jmp ch_r ; get_select_sec: ;up down time jmp ch_sec ; get_select_auto: ;auto test mode mov si,offset test_fix_inx call disp_menu ;display menu mov auto_buff,01 ;auto mode get_select_aw: ;wait key input of g or f call key_int and al,0dfh ;lower case to upper case cmp al,'G' je get_select_e ;go as auto mode cmp al,'F' je get_select_autof ;with file cmp ah,01 jnz get_select_aw ;check again jmp get_select_n ;retrun to previous ; get_select_autof: ;with file output call make_file_name ;make file name mov dx,offset disp_x4 call disp_str ;prompt for G with file name get_select_autog: ;wait for final G call key_int and al,0dfh ;lower case to upper cmp al,'G' jnz get_select_autog ;wait until go mov auto_buff,11h jmp get_select_e ;ok end ; ; make file name ; make_file_name: mov ah,CEXIST mov dx,offset file_n xor cx,cx int MSDOS jc make_file_name_g ;not existed add disp_x5[2],01 ;existed so up file name add file_atr[2],01 cmp file_atr[2],'9'+1 jne make_file_name mov disp_x5[2],'0' ;round mov file_atr[2],'0' add disp_x5[1],01 add file_atr[1],01 cmp file_atr[1],'9'+1 jne make_file_name mov disp_x5[1],'0' ;round mov file_atr[1],'0' add disp_x5[0],01 add file_atr[0],01 jmp make_file_name ; make_file_name_g: ret ; ; up down time value ; input al:code '+'/'-' ; ch_sec: cmp ch_buf,04 jnz ch_sec_end ;not in time selection cmp al,'+' je ch_sec_p ;+ dec time_step ;- jne ch_sec_end mov time_step,59 ch_sec_end: ret ; ch_sec_p: ;+ inc time_step cmp time_step,60 jc ch_sec_end mov time_step,1 ret ; ; left arrow ; ch_l: mov ah,con_drive sub ah,01 mov bl,ch_buf cmp bl,0 jz ch_l_s ;0 is drive xor bh,bh mov ah,inx_max_value[bx] ;maximum selection value ch_l_s: shl bx,1 mov bx,inx_value_para[bx] ;get parameter point sub byte ptr [bx],1 jnc ch_l_e mov [bx],ah ;set as max ch_l_e: cmp ch_buf,0 jnz ch_l_en ;not drive call choi_dr ;check drive & get parameters ch_l_en: ret ; ; right arrow ; ch_r: mov ah,con_drive sub ah,01 mov bl,ch_buf cmp bl,0 jz ch_r_s ;0 is drive xor bh,bh mov ah,inx_max_value[bx] ;maximum selection value ch_r_s: shl bx,1 mov bx,inx_value_para[bx] ;get parameter point add byte ptr [bx],1 cmp ah,[bx] jnc ch_r_e mov byte ptr [bx],0 ;rewind ch_r_e: cmp ch_buf,0 jnz ch_r_en ;not drive call choi_dr ;check drive & get parameters ch_r_en: ret ; ; get capacity data ; capa_d: call setup_srb ;setup srb mov word ptr srb[0ah],8 ;data length mov word ptr srb[0ch],0 mov srb[17h],0ah ;command length mov srb[40h],25h ; read capa mov srb[44h],00h mov word ptr srb[47h],0 call aspi_g ;read capacity mov bx,ds mov es,bx mov ds,buff_seg cld mov cx,8 mov di,offset capa_buf xor si,si rep movsb ;copy data mov ds,bx ret ; ; do aspi process ; aspi_g proc push ds ; set parameter segment push offset srb ; set parameter offset call aspi_entry add sp,04 ; back to sp ; aspi_gr: mov al,srb[1] or al,al ; aspi status[0] to not end je aspi_gr cmp al,01 je aspi_ge ; normal end to al=01 xor ax,ax ; error end to al=0 aspi_ge: mov srb[1],0ffh ; clr to status ret aspi_g endp ; ; display current choise in selection memue ; choice_a: mov si,offset menu_inx call disp_menu ;display menu call disp_drive ;display drive ID ;display main menu selection call green_s ;to green mov si,offset menu_row ;row display mov bl,ch_buf ;get row value call disp_select ;display main selection call off_crt_attr ;display selected menu call reverse_s mov ah,ch_buf+1 ;get drive ID value mov al,DISP_DRV_LEN mul ah ;get bias to string mov dx,offset disp_r1 add dx,ax call disp_str ;display selected drive ID mov si,offset menu_cmd ;command (read/write) mov bl,ch_buf+2 ;get command value call disp_select ;display (read/write) mov si,offset menu_size ;block size mov bl,ch_buf+3 ;get block size value call disp_select ;display block size ; call disp_time ;display time value mov si,offset menu_mode ;access mode mov bl,ch_buf+5 ;get value call disp_select ;display access mode call off_crt_attr ret ; ; display drive ID ; disp_drive: mov cl,con_drive xor ch,ch ;get connected number mov dx,offset disp_r1 disp_drivel: call disp_str ;display drive ID add dx,DISP_DRV_LEN loop disp_drivel ret ; ; display time value ; disp_time: xor ax,ax mov al,time_step call decimal call zero_clr mov disp_s11[0],cl ;set second value high mov disp_s11[1],dh ;set second value low mov dx,offset disp_s10 call disp_str ret ; ; display current testing screen ; choice_b: mov si,offset test_inx call disp_menu ;display testing screen base ; call reverse_s mov si,offset test_col ;column display mov al,ch_buf+3 ;get column value (block size) mov bl,al mov ah,COLUMN_SIZE mul ah mov disp_zb,ax ;set testing column position call disp_select ;display main selection mov si,offset test_cmd ;read/write mov bl,ch_buf+2 ;get value call disp_select ;display command mode mov si,offset test_rmode ;access mode cmp ch_buf+2,0 jz choice_brw ;read mode mov si,offset test_wmode ;write mode add disp_zb,MODE_SIZE ;to write base choice_brw: mov al,ch_buf+5 ;get value mov bl,al mov ah,ROW_SIZE mul ah add disp_zb,ax ;to target position call disp_select ;display access mode call off_crt_attr ; call cdisp ;locate to current test mov dx,offset disp_z37 call disp_str ;clear it ret ; ; locate cursor to current testing position ; cdisp: mov dx,offset disp_z100 add dx,disp_zb call disp_str ret ; ; setup date ; setup_date: mov ah,CGETDATE int MSDOS ;get date push dx mov ax,cx call decimal mov file_b8d[0],bl ;year mov file_b8d[1],ch mov file_b8d[2],cl mov file_b8d[3],dh pop dx push dx xor ax,ax mov al,dh call decimal mov file_b8d[5],cl ;month mov file_b8d[6],dh pop ax xor ah,ah call decimal mov file_b8d[8],cl ;date mov file_b8d[9],dh ret ; ; get device id & version ; choi_dr: call inquiry_setup ;inquiry setup call aspi_g ;do inquiry mov bx,ds ;save data segment mov es,bx mov ds,buff_seg mov si,16 ;device id offset mov cx,16 mov di,offset disp_z34 rep movsb mov si,16 ;device id offset mov di,offset file_b7p mov cx,16 rep movsb ;setup device id mov si,32 ;version offset mov di,offset disp_z36 movsw ;setup version movsw mov si,32 ;version offset mov di,offset file_b8p movsw movsw mov ds,bx ;restore segment mov dx,offset disp_z33 call disp_str ;display device id & version ret ; ; inquiry setup ; inquiry_setup: call setup_srb ;setup srb mov word ptr srb[0ah],36 ;transfer counter mov word ptr srb[0ch],0 mov srb[17h],6 ;command length mov srb[40h],12h ;inquiry command mov srb[44h],36 ;length ret ; ; clear random access used map ; clear_used_map: mov di,offset used_map mov ax,ds mov es,ax cld mov cx,USED_MAP_SIZE/2 xor ax,ax rep stosw ;clear map mov used_map,1 ;start lba is 0 ret ; ; setup parameters of srb structure ; setup_srb: mov srb[40h],2ah cmp ch_buf[2],01 ; read or write je setup_srbrw ;write command mov srb[40h],28h ;read command setup_srbrw: mov al,host_adpt mov srb[2],al mov ah,ch_buf[1] ;drive number mov al,DISP_DRV_LEN mul ah mov bx,ax mov al,disp_r1+9[bx] ;id number sub al,'0' mov srb[8],al ; set scsi ID to SRB mov srb[09],0 ; lun xor ax,ax mov word ptr srb[42h],ax ; low lba mov word ptr srb[44h],ax ; high lba mov word ptr srb[0fh],ax ; buffer offset mov bx,buff_seg mov word ptr srb[11h],bx ; buffer segment mov srb[17h],10 ; scsi command length mov srb[0eh],080h ; max sense data length xor bx,bx mov bl,ch_buf+3 ;block size shl bx,1 mov bx,inx_block_size[bx] mov srb[0ah],al ;LSB mov word ptr srb[0bh],bx ;data size *100h mov srb[0dh],al shr bx,1 ;to sector size cmp capa_buf+6,02h jz setup_srbblk ;512Byte/Sector shr bx,1 ;1024Byte/Sector setup_srbblk: xchg bh,bl mov word ptr srb[47h],bx ;lbn in CDB mov srb[0],02 ;scsi command execute request mov srb[1],0 ret ; ; modify lba for next access ; modify_lba: cmp ch_buf+5,1 ;access mode jz modify_lba_seq ;sequential cmp ch_buf+5,2 ;access mode jz modify_lba_rnd ;random ret ;same address ; modify_lba_seq: ;sequential mov dx,word ptr srb[42h] mov ax,word ptr srb[44h] ;lba xchg dh,dl xchg ah,al mov bx,word ptr srb[47h] ;lbn xchg bh,bl add ax,bx ;to next lba adc dx,0 xchg dh,dl xchg ah,al mov word ptr srb[42h],dx ;save next lba mov word ptr srb[44h],ax ret ; modify_lba_rnd: ;random mov modify_cnt,0 modify_lba_rndl: call rand ;get random data call get_max_lba ;get maximum lba as start call get_rand_lba ;get randamized lba call get_jump_size ;get non overrup jump size mov cx,bx dec cx not cx ;make mask code and ax,cx ;mask lower address to boundary call check_overrup ;check address overrup jnc modify_lba_rnds ;get unoverrupped inc modify_cnt cmp modify_cnt,3 jc modify_lba_rndl ;check 3 times without clear call clear_used_map ;clear used map jmp modify_lba_rnd ; modify_lba_rnds: xchg dh,dl xchg ah,al mov word ptr srb[42h],dx ;set higher mov word ptr srb[44h],ax ;set lower ret ; ; get maximum lba as start ; output dx:cx:max lba as start ; get_max_lba: mov bx,word ptr srb[47h] ;lbn xchg bh,bl mov dx,word ptr capa_buf mov cx,word ptr capa_buf+2 xchg ch,cl xchg dh,dl ;get max lbn inc bx sub cx,bx sbb dx,0 ;available max lba as start ret ; ; get randamized lba ; input dx:cx: max lba ; ax:randamize data 0-7fffh ; output dx:ax: randamized lba ; get_rand_lba: mov bx,ax push dx mul cx ;lower mov cx,dx pop ax mul bx ;higher add ax,cx adc dx,0 shl ax,1 ;shift right 15 bits rcl dx,1 ret ; ; get lba jump size ; output bx:jump size for non overrup ; get_jump_size: xor bx,bx mov bl,ch_buf+3 ;block size shl bx,1 mov bx,inx_block_jump[bx] ret ; ; check & get next unoverruped address ; input dx:ax : lba ; bx : lba jump size ; output dx:ax : dx:ax or next unoverruped ; cf : on not matched in down side ; check_overrup: mov cx,bx push dx push ax check_overrupr: ;masked bit cancel loop shr dx,1 rcr ax,1 shr cx,1 jnc check_overrupr ;masked bit mov si,offset used_map mov cx,ax shr ax,1 ;ignore dx shr ax,1 shr ax,1 ;1/8 for byte bit add si,ax ;get start address and cl,07h mov ch,1 shl ch,cl ;get start bit pop ax pop dx check_overrupl: ;check loop test ch,[si] jz check_overrupe ;get unused bit shr ch,1 ;used so search down side jnc check_overrupb ;in byte mov ch,80h ;one down byte dec si cmp si,offset used_map jc check_overrupn ;to top not found check_overrupb: sub ax,bx ;down one size sbb dx,0 jmp check_overrupl ;check next lba ; check_overrupe: or [si],ch ;not used so set used bit check_overrupn: ret ; ; display transfer rate by word code ; l_time: call x_time ;get transfer data mov disp_d2,bh mov disp_d2+1,bl mov disp_d2+2,ch mov disp_d2+3,cl mov disp_d2+4,dh ;set data call blue_s mov dx,offset disp_d2_1 call disp_str ;display it call off_crt_attr ret ; ; make transfer rate by byte code ; output bx:cx:number ; x_time: call get_trans ;get transfer data call decimalw call zero_clr ret ; ; get transfer data rate by kB/S ; output dx:ax:data ; get_trans: xor bx,bx mov bl,ch_buf+3 ;block size shl bx,1 mov bx,inx_block_size[bx] ;data size/100h mov dx,ex_count+2 mov ax,ex_count mov cx,bx call mul_word mov cx,125 call div_word mov cx,20h call mul_word xor cx,cx mov cl,time_step call div_word ret ; ; multiple word ; input dx:ax ; cx ; output dx:ax ; bx mul_word: mov bx,ax mov ax,dx mul cx push dx push ax mov ax,bx mul cx pop cx pop bx add dx,cx adc bx,0 ret ; ; divide word ; input dx:ax ; cx ; output dx:ax ; bx div_word: xor bx,bx cmp dx,cx jb div_word_sm push ax mov ax,dx xor dx,dx div cx mov bx,ax pop ax div_word_sm: div cx xchg dx,bx ret ; hex to decimal ; input dx:ax : binary code ; output bx:cx:dh : code ; decimal: xor dx,dx ; decimalw: mov cx,10000 div cx mov bx,ax mov ax,dx mov cx,1000 xor dx,dx div cx mov ah,bl push ax ;10000 order in ah & 1000 order in al mov ax,dx mov cx,100 xor dx,dx div cx mov bx,ax ;100 order in bl mov ax,dx mov cl,10 div cl ;10 order in al, 1 order in ah mov dx,ax ;1 order in dh mov cx,ax ;10 order in cl mov ch,bl ;100 order in ch pop bx ;10000 order in bh 1000 order in bl add bx,3030h ;to ascii code add cx,3030h add dh,30h ret ; ; zero suppress for byte code ; input bx:cx:dh : 30h+ ; output bx:cx:dh : suppressed ; zero_clr: cmp bh,30h jnz ze_e mov bh,20h cmp bl,30h jnz ze_e mov bl,20h cmp ch,30h jnz ze_e mov ch,20h cmp cl,30h jnz ze_e mov cl,20h ze_e: ret ; ; setup display attribute ; off_crt_attr: ;off attribute mov dx,offset off_attr call disp_str ret ; blink_s: ;blink mode on mov dx,offset blink call disp_str ret ; reverse_s: ;reverse mode on mov dx,offset red call disp_str ret ; blue_s: ;blue mov dx,offset blue call disp_str ret ; green_s: ;green mov dx,offset green call disp_str ret ; ; display string ; input dx:string top (end by $) ; disp_str: mov ah,CSTRING int MSDOS ret ; ; display memu ; input si:display message index ; disp_menu: mov dx,[si] or dx,dx jz disp_menue ;end of data push si call disp_str ;display string pop si add si,2 jmp disp_menu ;to next string ; disp_menue: ret ; ; display selected value by sprite ; input si:index point (start from max value) ; bl:value ; disp_select: mov bh,[si] ;get max value inc si cmp bl,bh jbe disp_selects ;in range mov bl,bh ;out of range so do as max disp_selects: xor bh,bh shl bx,1 add si,bx mov dx,[si] ;get display point call disp_str ;display it ret ; ; get key input ; output al:key code ; key_int: xor ax,ax int 16h ret ; ; make random data ; output ax:0-7fffh random data ; rand: mov ax,rand_data add ah,al inc ax and ax,7fffh mov rand_data,ax ret ; code ends data segment ; ; data ; menu_inx label word ;end by 0 dw disp_s1 ; drive ID dw disp_s2 ; command (read/write) dw disp_s3 ; block size (512KB,...) dw disp_s4 ; mesuring time dw disp_s5 ; read dw disp_s6 ; write dw disp_s7 ; 512KB dw disp_s8 ; 256KB dw disp_s9 ; 128KB dw disp_s20 ; 64KB dw disp_s21 ; 32KB dw disp_s22 ; 16KB dw disp_s23 ; 8KB dw disp_s24 ; 4KB dw disp_s10 ; 10 second dw disp_s11s ; use + or - dw disp_s13 ; access mode dw disp_s14 ; same dw disp_s15 ; sequential dw disp_s16 ; random dw 0 ;end mark ; menu_row label word ;main menu db 4 ;menu max count dw disp_s1 ;0 drive id dw disp_s2 ;1 command (read/write) dw disp_s13 ;2 same/seq/rand dw disp_s3 ;3 block size dw disp_s4 ;4 time ; menu_cmd label word db 1 ;menu max count dw disp_s5 ;read dw disp_s6 ;write ; menu_size label word db 7 ;menu max count dw disp_s7 ;512KB dw disp_s8 ;256KB dw disp_s9 ;128KB dw disp_s20 ;64KB dw disp_s21 ;32KB dw disp_s22 ;16KB dw disp_s23 ;8KB dw disp_s24 ;4KB ; menu_mode label word db 2 ;menu max count dw disp_s14 ;same dw disp_s15 ;sequential dw disp_s16 ;random ; inx_max_value label byte ;maximum selection value db 1 ;0 drive dummy db 1 ;1 read/write db 2 ;2 same/seq/rand db 7 ;3 block size db 59 ;4 time ; inx_value_para label word ;value address dw ch_buf+1 ;0 drive dw ch_buf+2 ;1 read/write dw ch_buf+5 ;2 access mode (same/seq/rand) dw ch_buf+3 ;3 block size dw time_step ;4 time ; ; transfer data length * 100h ; inx_block_size label word ;512Byte/Sector dw 2048 ;512KB dw 1024 ;256KB dw 512 ;128KB dw 256 ;64KB dw 128 ;32KB dw 64 ;16KB dw 32 ;8KB dw 16 ;4KB ; inx_block_jump label word ;jump size for non overrup ;must be 2**n dw 4096 ;512KB dw 2048 ;256KB dw 1024 ;128KB dw 512 ;64KB dw 256 ;32KB dw 128 ;16KB dw 64 ;8KB dw 32 ;4KB ; title_s db 1BH,'[02;08H' db 'SPEED CHECK for AT PCI(ASPI) ' db 'Ver.',VER_NUM1,'.',VER_NUM2,VER_NUM3,' ' db 'by TEXA Corporation$' crt_clr db 1bh,'[2J','$' ;display clear code off_attr db 1BH,'[0m','$' ;off attribute blink db 1BH,'[5m','$' ;blink mode on green db 1BH,'[32m','$' red db 1BH,'[31m','$' blue db 1BH,'[36m','$' yellow db 1BH,'[33m','$' ; disp_d1 db 1BH,'[36m',1BH,'[17;06H','Transfer Speed' db 1BH,'[17;38H',' Measuring ' db 1BH,'[0m','$' disp_d2_1 db 1BH,'[17;38H' disp_d2 db ' k Bytes / Second $' ; disp_x1 label byte ;for menu selection prompt db 1BH,'[19;05H' db 'Enter [x] for the Automatic Mode. (CR) for Single Step. $' disp_x2 db 1BH,'[22;05H' db ' ' db 1BH,'[23;05H' db ' ' db ' $' disp_x4 db 1BH,'[22;41H',' ' db 1BH,'[23;05H','File Name:[spvdata.' disp_x5 db '001] ' db 1BH,'[23;35H' db 'Enter [G] to Start.$' disp_x8 db 1BH,'[23;35H' db 'File Open Error.$' disp_x9 db 1BH,'[23;35H' db 'File Write Error.$' ; ; slection menu data ; disp_s1 db 1BH,'[06;06H','Drive ID Number$' disp_s2 db 1BH,'[08;06H','Command$' disp_s3 db 1BH,'[12;06H','Transfer Block Length$' disp_s4 db 1BH,'[14;06H','Total Byte Length$' disp_s5 db 1BH,'[08;37H','Read$' disp_s6 db 1BH,'[08;49H','Write$' disp_s7 db 1BH,'[12;37H','512K$' disp_s8 db 1BH,'[12;42H','256K$' disp_s9 db 1BH,'[12;47H','128K$' disp_s20 db 1BH,'[12;52H','64K$' disp_s21 db 1BH,'[12;56H','32K$' disp_s22 db 1BH,'[12;60H','16K$' disp_s23 db 1BH,'[12;64H','8K$' disp_s24 db 1BH,'[12;67H','4K$' disp_s10 db 1BH,'[14;37H' disp_s11 db ' Sec.$' disp_s11s db 1BH,'[14;47H','Use + or -$' disp_s13 db 1BH,'[10;06H','Mode$' disp_s14 db 1BH,'[10;37H','Same LBA$' disp_s15 db 1BH,'[10;47H','Sequential$' disp_s16 db 1BH,'[10;63H','Random$' ; ;drive number disp_r1 db 1BH,'[06;37H',' $' DISP_DRV_LEN = $-disp_r1 disp_r2 db 1BH,'[06;41H',' $' disp_r3 db 1BH,'[06;45H',' $' disp_r4 db 1BH,'[06;49H',' $' disp_r5 db 1BH,'[06;53H',' $' disp_r6 db 1BH,'[06;57H',' $' disp_r7 db 1BH,'[06;61H',' $' ; ; disp_t1 db 1BH,'[06;05H' db 'Checking Connected Drives. $' disp_t2 db 1BH,'[06;05H' db ' $' disp_t3 db 1BH,'[06;05H' db 'No SCSI Drive was Found. ' db 1BH,'[08;05H' db 'Aborted.$' disp_end db 1BH,'[23;40H$' ; ; testing screen data ; disp_z db 1BH,'[06;37H','Transfer Byte Count (kB/S)' db 1BH,'[08;07H' db ' Mode \ Block Size' db 1BH,'[08;29H' db ' 512K 256K 128K 64K 32K 16K 8K 4K' db 1BH,'[10;07H' db 'Read Same LBA' db 1BH,'[12;07H' db 'Read Sequential' db 1BH,'[14;07H' db 'Read Random' db 1BH,'[16;07H' db 'Write Same LBA' db 1BH,'[18;07H' db 'Write Sequential' db 1BH,'[20;07H' db 'Write Random' disp_x3 db 1BH,'[22;05H' db 'Test all Read / Write Automatically. ' db 'Enter [G] to Start. ' db 1BH,'[23;05H' db 'Enter [F] for Result Data File Output. $' ; test_fix_inx label word ;test fix parameter dw crt_clr ;clear display dw title_s dw disp_z dw disp_x3 dw 0 ; disp_z1 db 1BH,'[10;12H',' Same LBA$' ;in read disp_z2 db 1BH,'[12;12H',' Sequential$' ;in read disp_z3 db 1BH,'[14;12H',' Random$' ;in read disp_z4 db 1BH,'[08;30H','512K$' disp_z5 db 1BH,'[08;36H','256K$' disp_z6 db 1BH,'[08;42H','128K$' disp_z7 db 1BH,'[08;49H','64K$' disp_z8 db 1BH,'[08;55H','32K$' disp_z20 db 1BH,'[08;61H','16K$' disp_z21 db 1BH,'[08;68H','8K$' disp_z22 db 1BH,'[08;74H','4K$' disp_z10 db 1BH,'[10;07H','Read' db 1BH,'[11;07H',' ' db 1BH,'[12;07H','Read' db 1BH,'[13;07H',' ' db 1BH,'[14;07H','Read$' disp_z11 db 1BH,'[16;07H','Write' db 1BH,'[17;07H',' ' db 1BH,'[18;07H','Write' db 1BH,'[19;07H',' ' db 1BH,'[20;07H','Write$' disp_z12 db 1BH,'[16;12H',' Same LBA$' ;in write disp_z13 db 1BH,'[18;12H',' Sequential$' ;in write disp_z14 db 1BH,'[20;12H',' Random$' ;in write ; ; testing screen value display position list ; ;read, same disp_z100 db 1BH,'[10;29H','$' COLUMN_SIZE = $-disp_z100 ;one value length db 1BH,'[10;35H','$' db 1BH,'[10;41H','$' db 1BH,'[10;47H','$' db 1BH,'[10;53H','$' db 1BH,'[10;59H','$' db 1BH,'[10;65H','$' db 1BH,'[10;71H','$' ROW_SIZE = $-disp_z100 ;one line length ;read, sequential db 1BH,'[12;29H','$' db 1BH,'[12;35H','$' db 1BH,'[12;41H','$' db 1BH,'[12;47H','$' db 1BH,'[12;53H','$' db 1BH,'[12;59H','$' db 1BH,'[12;65H','$' db 1BH,'[12;71H','$' ;read, random db 1BH,'[14;29H','$' db 1BH,'[14;35H','$' db 1BH,'[14;41H','$' db 1BH,'[14;47H','$' db 1BH,'[14;53H','$' db 1BH,'[14;59H','$' db 1BH,'[14;65H','$' db 1BH,'[14;71H','$' MODE_SIZE = $-disp_z100 ;one mode length ;write, same db 1BH,'[16;29H','$' db 1BH,'[16;35H','$' db 1BH,'[16;41H','$' db 1BH,'[16;47H','$' db 1BH,'[16;53H','$' db 1BH,'[16;59H','$' db 1BH,'[16;65H','$' db 1BH,'[16;71H','$' ;write, sequential db 1BH,'[18;29H','$' db 1BH,'[18;35H','$' db 1BH,'[18;41H','$' db 1BH,'[18;47H','$' db 1BH,'[18;53H','$' db 1BH,'[18;59H','$' db 1BH,'[18;65H','$' db 1BH,'[18;71H','$' ;write, random db 1BH,'[20;29H','$' db 1BH,'[20;35H','$' db 1BH,'[20;41H','$' db 1BH,'[20;47H','$' db 1BH,'[20;53H','$' db 1BH,'[20;59H','$' db 1BH,'[20;65H','$' db 1BH,'[20;71H','$' disp_z30 db ' ',1BH,'[2D$' disp_z31 db ' $' disp_z33 db 1BH,'[22;05H','Device ID: ' disp_z34 db ' ' disp_z35 db 1BH,'[23;05H','Revision : ' disp_z36 db ' $' ; disp_z37 db ' $' ; test_inx label word ;testing screen base dw disp_z1 ;same in read dw disp_z2 ;sequential in read dw disp_z3 ;random in read dw disp_z4 ;512KB dw disp_z5 ;256KB dw disp_z6 ;128KB dw disp_z7 ;64KB dw disp_z8 ;32KB dw disp_z20 ;16KB dw disp_z21 ;8KB dw disp_z22 ;4KB dw disp_z10 ;read dw disp_z11 ;write dw disp_z12 ;same in write dw disp_z13 ;sequential in write dw disp_z14 ;random in write dw 0 ; test_col label word db 7 dw disp_z4 ;0 512KB dw disp_z5 ;1 256KB dw disp_z6 ;2 128KB dw disp_z7 ;3 64KB dw disp_z8 ;4 32KB dw disp_z20 ;5 16KB dw disp_z21 ;6 8KB dw disp_z22 ;7 4KB ; test_cmd label word db 1 dw disp_z10 ;read dw disp_z11 ;write ; test_rmode label word db 2 dw disp_z1 ;same dw disp_z2 ;sequential dw disp_z3 ;random ; test_wmode label word db 2 dw disp_z12 ;same dw disp_z13 ;sequential dw disp_z14 ;random ; option_help db cr,lf db 'You can change the Host Adoptor Number by Option' db ' ''N*''.' db cr,lf,' ' db '* is number from 0.$' ; file_b7 db'Device ID: ' file_b7p db ' ',0dh,0ah file_b8 db'Revision : ' file_b8p db ' ' file_b8d db '0000/00/00 ',0dh,0ah db' ------------------------------------------------------------------ ' db cr,lf db'| | Transfer Byte Count (kB/S) |' db cr,lf db'| |-----------------------------------------------|' db cr,lf db'| Mode \ Block Size| 512K| 256K| 128K| 64K| 32K| 16K| 8K| 4K|' db cr,lf db'|------------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b1 db'|R| Same LBA | | | | | | | | |' db cr,lf db'|E|----------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b2 db'|A| Sequential | | | | | | | |ª@ |' db cr,lf db'|D|----------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b3 db'| | Random | | | | | | | | ª@ |' db cr,lf db'|-|----------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b4 db'|W| Same LBA | | | | | | | |ª@ ª@|' db cr,lf db'|R|----------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b5 db'|I| Sequential | | | | | | | | ª@ |' db cr,lf db'|T|----------------|-----|-----|-----|-----|-----|-----|-----|-----|' db cr,lf fle_b6 db'|E| Random | | | | | | | |ª@ |' db cr,lf db' ------------------------------------------------------------------ ' db cr,lf,'$' file_length = $-file_b7-1 ; inx_file_result label word ;for result file ;read 512KB dw fle_b1+20 ;same dw fle_b2+20 ;sequential dw fle_b3+20 ;random ;read 256KB dw fle_b1+26 ;same dw fle_b2+26 ;sequential dw fle_b3+26 ;random ;read 128KB dw fle_b1+32 ;same dw fle_b2+32 ;sequential dw fle_b3+32 ;random ;read 64KB dw fle_b1+38 ;same dw fle_b2+38 ;sequential dw fle_b3+38 ;random ;read 32KB dw fle_b1+44 ;same dw fle_b2+44 ;sequential dw fle_b3+44 ;random ;read 16KB dw fle_b1+50 ;same dw fle_b2+50 ;sequential dw fle_b3+50 ;random ;read 8KB dw fle_b1+56 ;same dw fle_b2+56 ;sequential dw fle_b3+56 ;random ;read 4KB dw fle_b1+62 ;same dw fle_b2+62 ;sequential dw fle_b3+62 ;random ;write 512KB dw fle_b4+20 ;same dw fle_b5+20 ;sequential dw fle_b6+20 ;random ;write 256KB dw fle_b4+26 ;same dw fle_b5+26 ;sequential dw fle_b6+26 ;random ;write 128KB dw fle_b4+32 ;same dw fle_b5+32 ;sequential dw fle_b6+32 ;random ;write 64KB dw fle_b4+38 ;same dw fle_b5+38 ;sequential dw fle_b6+38 ;random ;write 32KB dw fle_b4+44 ;same dw fle_b5+44 ;sequential dw fle_b6+44 ;random ;write 16KB dw fle_b4+50 ;same dw fle_b5+50 ;sequential dw fle_b6+50 ;random ;write 8KB dw fle_b4+56 ;same dw fle_b5+56 ;sequential dw fle_b6+56 ;random ;write 4KB dw fle_b4+62 ;same dw fle_b5+62 ;sequential dw fle_b6+62 ;random ; disp_aspi_err db CR,LF db 'No ASPI Driver was Found. Please Configure with ASPI Driver.$' disp_aloc_err db CR,LF,'Memory Allocation Error.$' ; ; stack area ; dw 128 dup (?) stack_top label word db 16 dup (?) mem_last label byte ; end of code & data data ends ; end