]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/PROFIL.ASM
1 TITLE PROFIL
- MS-DOS Profile program
3 ;Profiler for MS-DOS 1.25 2.00
5 ; Lots of stuff stolen from debug.
6 ; User provides # of paragraphs per bucket, program is cut up accordingly.
7 ; User also specifies clock interval
31 ;Segments in load order
42 DG GROUP
CODE,DATA,INIT
48 ENDMES
DB 13,10,"Program terminated normally",13,10,"$"
49 ABORTMES
DB 13,10,"Program aborted",13,10,"$"
50 TOOBIG
DB "Program too big",13,10,"$"
51 EXEBAD
DB "EXE file bad",13,10,"$"
61 BYTEBUF
DB BUFLEN
DUP(?
) ;Processed input queue
62 AXSAVE
DW ?
;See interrupt routine
64 PROG_AREA
DW ?
;Segment of program start
77 PROG_SS
LABEL WORD ;Program stack seg
79 PROG_SP
LABEL WORD ;Program SP
82 PROG_ENTRY EQU THIS
DWORD
83 PROG_RA
LABEL WORD ;Program start offset
85 PROG_SA
LABEL WORD ;Program start segment (may be different from PROG_AREA)
88 RUNVARSIZ EQU
$-RUNVAR
90 EXEFILE
DB 0 ;Flag to indicate EXE file
91 DRV_VALID
DW ?
;Init for AX register
92 OUTPUT_DATA
LABEL WORD ;Start of the profile data
93 CLOCK_GRAIN
DW ?
;Clock interval micro-seconds
94 BUCKET_NUM
DW ?
;Number of buckets
95 BUCKET_SIZE
DW ?
;Paragraphs per bucket
96 PROG_LOW_PA
DW ?
;Start of program (PARA #)
97 PROG_HIGH_PA
DW ?
;End of program (PARA #)
98 DOS_PA
DW ?
;IO-DOS PARA boundry
99 HIT_IO
DW 0 ;IO bucket
100 HIT_DOS
DW 0 ;DOS bucket
101 HIT_HIGH
DW 0 ;Above Program bucket
102 NUM_DATA_WORDS EQU
($-OUTPUT_DATA
)/2 ;Number of word items
103 BUCKET
LABEL WORD ;Bucket count area
105 ;The following data will be overwritten when the buckets are initialized
106 LINEBUF
DB BUFLEN
,1,0DH ;Raw input buffer
109 NOFILE
DB "File not found",13,10,"$"
110 OUTERR
DB "Cannot open output file",13,10,"$"
111 GRAIN_PROMPT
DB "Sample time (micro-sec) >= 60 ? ","$"
112 SIZE_PROMPT
DB "Number of paragraphs (16 bytes) per bucket? ","$"
113 PARAM_PROMPT
DB "Parameters to program? ","$"
116 ;The resident code portion
118 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
120 ;The clock interrupt routine
123 ;Stuff provided by external clock handler routine
124 EXTRN CLOCKON
:NEAR,CLOCKOFF
:NEAR,LEAVE_INT
:NEAR
129 MOV SP,OFFSET DG
:STACK ;Use internal stack
131 ;The following setup stuff cannot be done in SETUP because we're probably
132 ; overwritting the INIT area
135 INT 21H
;Set base for program
137 PUSH SI ;Points to BYTEBUF
138 MOV DI,81H
;Set unformatted params
144 SUB DI,82H
;Figure length
146 MOV BYTE PTR ES:[80H
],AL
148 MOV DI,FCB
;First param
151 MOV BYTE PTR [DRV_VALID
],AL
153 MOV DI,6
CH ;Second param
155 MOV BYTE PTR [DRV_VALID
+1],AL
157 MOV AX,ES ;Prog segment to AX
158 MOV DX,[PROG_RA
] ;Offset
161 JMP BINFIL
;Regular file (.COM)
164 MOV AX,[HEADSIZ
] ;Size of header in paragraphs
167 ROL AX,CL ;Size in bytes
171 MOV WORD PTR DS:[FCB
+RR
],AX ;Position in file of program
172 MOV WORD PTR DS:[FCB
+RR
+2],BX ;Record size
173 MOV DX,[PAGES
] ;Size in 512 byte blocks
199 MOV AX,WORD PTR DS:[2]
201 MOV DX,OFFSET DG
:TOOBIG
214 MOV DX,OFFSET DG
:EXEBAD
217 MOV AH,PRINTBUF
;Print the message in DX
222 MOV AX,[RELTAB
] ;Get position of relocation table
223 MOV WORD PTR DS:[FCB
+RR
],AX
224 MOV WORD PTR DS:[FCB
+RR
+2],0
225 MOV DX,OFFSET DG
:RELPT
;Four byte buffer
234 INT 21H
;Read in one relocation pointer
237 MOV DI,[RELPT
] ;Pointer offset
238 MOV AX,[RELSEG
] ;pointer segment
239 ADD AX,BP ;Bias with actual load segment
241 ADD ES:[DI],BP ;Relocate
251 MOV WORD PTR DS:[FCB
+RECLEN
],1
255 MOV ES,[PROG_SA
] ;Prog segment to ES
256 MOV AX,WORD PTR ES:[6]
257 MOV [PROG_SP
],AX ;Default SP for non EXE files
259 MOV WORD PTR ES:[6],AX ;Fix size
267 INT 21H
;Set default disk transfer address
270 SHL BX,1 ;Mult by 2 to get #bytes in bucket area
272 MOV BUCKET
[BX],0 ;Zero counts
278 CLI ;Don't collect data yet
279 CALL CLOCKON
;Set the interrupt
289 PUSH CX ;0 on prog stack
292 MOV DS,DI ;Set up segments
294 STI ;Start collecting data
300 ; AX:DX is disk transfer address (segment:offset)
301 ; SI:DI is 32 bit length
317 MOV CX,0FFF0H ;Keep request in segment
318 OR SI,SI ;Need > 64K?
320 MOV CX,DI ;Limit to amount requested
324 SUB DI,CX ;Subtract off amount done
325 SBB SI,0 ;Ripple carry
328 POP AX ;Restore transfer address
330 ADD DX,CX ;Bump transfer address by last read
332 OR BX,DI ;Finished with request
338 ;Return here on termination or abort
341 CLI ;Stop collecting data
342 MOV DX,OFFSET DG
:ENDMES
345 CLI ;Stop collecting data
346 MOV DX,OFFSET DG
:ABORTMES
351 MOV SP,OFFSET DG
:STACK ;Use internal stack
353 CALL CLOCKOFF
;Restore original clock routine
354 STI ;Back to normal clock
357 INT 21H
;Apropriate termination message
358 MOV [OUT_FCB
+14],2 ;Word size records
359 MOV DX,OFFSET DG
:OUTPUT_DATA
361 INT 21H
;Set the transfer address
362 MOV CX,NUM_DATA_WORDS
364 MOV DX,OFFSET DG
:OUT_FCB
366 INT 21H
;Write out data
367 MOV DX,OFFSET DG
:OUT_FCB
373 ;The clock interrupt routine
378 POP DS ;Get profile segment
382 MOV BX,OFFSET DG
:LEAVE_INT
392 ;Stack looks like this
397 ; +12 RETURN TO LEAVE_INT
406 LES BX,DWORD PTR SS:[BX+14] ;Get CS:IP
411 ADD AX,CX ;Paragraph of CS:IP
412 CMP AX,[DOS_PA
] ;Below DOS?
414 CMP AX,[PROG_LOW_PA
] ;Below program?
416 CMP AX,[PROG_HIGH_PA
] ;Above program?
419 SUB AX,[PROG_LOW_PA
] ;Paragraph offset
424 SHL BX,1 ;Mult by 2 to get byte offset
453 ;The init segment contains code to process input parameters
454 ; It will be blasted as soon as the program to be run is read in
455 ; And/or the bucket area is initialized
463 INT 21H
;Open program file
466 MOV DX,OFFSET DG
:NOFILE
471 MOV WORD PTR DS:[FCB
+RR
],BX
472 MOV WORD PTR DS:[FCB
+RR
+2],BX ;RR to 0
474 MOV DI,OFFSET DG
:OUT_FCB
477 MOVSB ;Transfer drive spec and file to output
478 MOV DX,OFFSET DG
:OUT_FCB
480 INT 21H
;Try to create the output file
483 MOV DX,OFFSET DG
:OUTERR
486 GETSIZE: ;Get bucket size
487 MOV DX,OFFSET DG
:SIZE_PROMPT
492 JZ GETSIZE
;SCANB went to CR
496 JC GETSIZE
;Bad number
499 CMP WORD PTR DS:[FCB
+9],5800H
+"E" ;"EX"
501 CMP BYTE PTR DS:[FCB
+11],"E"
504 LOADEXEHEAD: ;Load the EXE header
506 MOV DX,OFFSET DG
:RUNVAR
;Read header in here
511 MOV WORD PTR DS:[FCB
+RECLEN
],1
515 CMP [RELPT
],5A4DH
;Magic number
519 MOV AX,[PAGES
] ;Size of file in 512 byte blocks
521 SHL AX,CL ;Size in paragraphs
525 MOV AX,WORD PTR DS:[FCB
+FILELEN
]
526 MOV DX,WORD PTR DS:[FCB
+FILELEN
+2] ;Size of file in bytes DX:AX
528 ADC DX,0 ;Round to PARA
535 OR AX,DX ;Size in paragraphs to AX
536 MOV [PROG_RA
],100H
;Default offset
544 MOV BX,OFFSET DG
:BUCKET
545 SHL AX,1 ;Number of bytes in bucket area
546 ADD AX,BX ;Size of profil in bytes
547 ADD AX,15 ;Round up to PARA boundry
549 SHR AX,CL ;Number of paragraphs in profil
557 MOV AX,[PROG_AREA
] ;Set up .COM segments
561 SETBOUNDS: ;Set the sample window
562 MOV BX,10H
;Get start offset
563 ADD BX,[PROG_AREA
] ;PARA # of start
565 POP AX ;Recall size of PROG in paragraphs
567 MOV [PROG_HIGH_PA
],BX
571 MOV ES,DX ;look in interrupt area
572 MOV DX,WORD PTR ES:[82H
] ;From int #20
577 GETGRAIN: ;Get sample interval
578 MOV DX,OFFSET DG
:GRAIN_PROMPT
583 JZ GETGRAIN
;SCANB went to CR
584 MOV BX,60 ;Grain >=60
586 JC GETGRAIN
;Bad number
589 MOV DX,OFFSET DG
:PARAM_PROMPT
592 CALL INBUF
;Get program parameters
594 MOV AX,2522H
;Set vector 22H
595 MOV DX,OFFSET DG
:TERMINATE
597 MOV AL,23H
;Set vector 23H
598 MOV DX,OFFSET DG
:ABORT
600 RET ;Back to resident code
602 GETNUM: ;Get a number, DS:SI points to buffer, carry set if bad
636 INBUF: ;Read in from console, SI points to start on exit
638 MOV DX,OFFSET DG
:LINEBUF
640 MOV SI,2 + OFFSET DG
:LINEBUF
641 MOV DI,OFFSET DG
:BYTEBUF
648 ADD AL,"A"-"a" ;Convert to upper case
669 MOV SI,OFFSET DG
:BYTEBUF
689 SCANB: ;Scan to first non-blank