summaryrefslogtreecommitdiff
path: root/v2.0/source/PROFIL.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/PROFIL.ASM')
-rw-r--r--v2.0/source/PROFIL.ASM705
1 files changed, 705 insertions, 0 deletions
diff --git a/v2.0/source/PROFIL.ASM b/v2.0/source/PROFIL.ASM
new file mode 100644
index 0000000..08a5ada
--- /dev/null
+++ b/v2.0/source/PROFIL.ASM
@@ -0,0 +1,705 @@
1 TITLE PROFIL - MS-DOS Profile program
2
3;Profiler for MS-DOS 1.25 2.00
4;
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
8
9
10;System calls
11PRINTBUF EQU 9
12SETDMA EQU 26
13CREATE EQU 22
14OPEN EQU 15
15CLOSE EQU 16
16GETBUF EQU 10
17BLKWRT EQU 40
18BLKRD EQU 39
19OUTCH EQU 2
20SETBASE EQU 38
21
22FCB EQU 5CH
23BUFLEN EQU 80
24
25; FCB offsets
26RR EQU 33
27RECLEN EQU 14
28FILELEN EQU 16
29
30
31;Segments in load order
32
33CODE SEGMENT PUBLIC
34CODE ENDS
35
36DATA SEGMENT BYTE
37DATA ENDS
38
39INIT SEGMENT BYTE
40INIT ENDS
41
42DG GROUP CODE,DATA,INIT
43
44;The data segment
45
46DATA SEGMENT BYTE
47 ORG 0
48ENDMES DB 13,10,"Program terminated normally",13,10,"$"
49ABORTMES DB 13,10,"Program aborted",13,10,"$"
50TOOBIG DB "Program too big",13,10,"$"
51EXEBAD DB "EXE file bad",13,10,"$"
52
53OUT_FCB LABEL WORD
54 DB 0
55OUTNAME DB " PRF"
56 DB 30 DUP(0)
57
58 DB 80H DUP(?)
59STACK LABEL WORD
60
61BYTEBUF DB BUFLEN DUP(?) ;Processed input queue
62AXSAVE DW ? ;See interrupt routine
63BXSAVE DW ? ; " " "
64PROG_AREA DW ? ;Segment of program start
65
66;EXE file header
67RUNVAR LABEL WORD
68RELPT DW ?
69LASTP LABEL WORD
70RELSEG DW ?
71PSIZE LABEL WORD
72PAGES DW ?
73RELCNT DW ?
74HEADSIZ DW ?
75 DW ?
76LOADLOW DW ?
77PROG_SS LABEL WORD ;Program stack seg
78INITSS DW ?
79PROG_SP LABEL WORD ;Program SP
80INITSP DW ?
81 DW ?
82PROG_ENTRY EQU THIS DWORD
83PROG_RA LABEL WORD ;Program start offset
84INITIP DW ?
85PROG_SA LABEL WORD ;Program start segment (may be different from PROG_AREA)
86INITCS DW ?
87RELTAB DW ?
88RUNVARSIZ EQU $-RUNVAR
89
90EXEFILE DB 0 ;Flag to indicate EXE file
91DRV_VALID DW ? ;Init for AX register
92OUTPUT_DATA LABEL WORD ;Start of the profile data
93CLOCK_GRAIN DW ? ;Clock interval micro-seconds
94BUCKET_NUM DW ? ;Number of buckets
95BUCKET_SIZE DW ? ;Paragraphs per bucket
96PROG_LOW_PA DW ? ;Start of program (PARA #)
97PROG_HIGH_PA DW ? ;End of program (PARA #)
98DOS_PA DW ? ;IO-DOS PARA boundry
99HIT_IO DW 0 ;IO bucket
100HIT_DOS DW 0 ;DOS bucket
101HIT_HIGH DW 0 ;Above Program bucket
102NUM_DATA_WORDS EQU ($-OUTPUT_DATA)/2 ;Number of word items
103BUCKET LABEL WORD ;Bucket count area
104
105;The following data will be overwritten when the buckets are initialized
106LINEBUF DB BUFLEN,1,0DH ;Raw input buffer
107 DB BUFLEN DUP(?)
108
109NOFILE DB "File not found",13,10,"$"
110OUTERR DB "Cannot open output file",13,10,"$"
111GRAIN_PROMPT DB "Sample time (micro-sec) >= 60 ? ","$"
112SIZE_PROMPT DB "Number of paragraphs (16 bytes) per bucket? ","$"
113PARAM_PROMPT DB "Parameters to program? ","$"
114DATA ENDS
115
116;The resident code portion
117CODE SEGMENT PUBLIC
118ASSUME CS:DG,DS:DG,ES:DG,SS:DG
119
120;The clock interrupt routine
121 PUBLIC CLK_INTER
122
123;Stuff provided by external clock handler routine
124 EXTRN CLOCKON:NEAR,CLOCKOFF:NEAR,LEAVE_INT:NEAR
125
126 ORG 100H
127START:
128 CLD
129 MOV SP,OFFSET DG:STACK ;Use internal stack
130 CALL SETUP
131;The following setup stuff cannot be done in SETUP because we're probably
132; overwritting the INIT area
133 MOV DX,[PROG_AREA]
134 MOV AH,SETBASE
135 INT 21H ;Set base for program
136 MOV ES,[PROG_AREA]
137 PUSH SI ;Points to BYTEBUF
138 MOV DI,81H ;Set unformatted params
139COMTAIL:
140 LODSB
141 STOSB
142 CMP AL,13
143 JNZ COMTAIL
144 SUB DI,82H ;Figure length
145 XCHG AX,DI
146 MOV BYTE PTR ES:[80H],AL
147 POP SI
148 MOV DI,FCB ;First param
149 MOV AX,2901H
150 INT 21H
151 MOV BYTE PTR [DRV_VALID],AL
152 MOV AX,2901H
153 MOV DI,6CH ;Second param
154 INT 21H
155 MOV BYTE PTR [DRV_VALID+1],AL
156
157 MOV AX,ES ;Prog segment to AX
158 MOV DX,[PROG_RA] ;Offset
159 CMP [EXEFILE],1
160 JZ EXELOAD ;EXE file
161 JMP BINFIL ;Regular file (.COM)
162
163EXELOAD:
164 MOV AX,[HEADSIZ] ;Size of header in paragraphs
165 ADD AX,31
166 MOV CL,4
167 ROL AX,CL ;Size in bytes
168 MOV BX,AX
169 AND AX,0FE00H
170 AND BX,0FH
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
174 DEC DX
175 XCHG DH,DL
176 ROL DX,1
177 MOV DI,DX
178 MOV SI,DX
179 AND DI,0FE00H
180 AND SI,1FFH
181 SUB DI,AX
182 SBB SI,BX
183 MOV AX,[LASTP]
184 OR AX,AX
185 JNZ PARTP
186 MOV AX,200H
187PARTP:
188 ADD DI,AX
189 ADC SI,0
190 MOV AX,DI
191 ADD AX,15
192 AND AL,0F0H
193 OR AX,SI
194 MOV CL,4
195 ROR AX,CL
196 XCHG AX,CX
197 MOV BX,[PROG_AREA]
198 ADD BX,10H
199 MOV AX,WORD PTR DS:[2]
200 SUB AX,CX
201 MOV DX,OFFSET DG:TOOBIG
202 JB ERROR
203 CMP BX,AX
204 JA ERROR
205 CMP [LOADLOW],-1
206 JNZ LOADEXE
207 XCHG AX,BX
208LOADEXE:
209 MOV BP,AX
210 XOR DX,DX
211 CALL READ
212 JC HAVEXE
213BADEXE:
214 MOV DX,OFFSET DG:EXEBAD
215
216ERROR:
217 MOV AH,PRINTBUF ;Print the message in DX
218 INT 21H
219 INT 20H ;Exit
220
221HAVEXE:
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
226 MOV AH,SETDMA
227 INT 21H
228 CMP [RELCNT],0
229 JZ NOREL
230RELOC:
231 MOV AH,BLKRD
232 MOV DX,FCB
233 MOV CX,4
234 INT 21H ;Read in one relocation pointer
235 OR AL,AL
236 JNZ BADEXE
237 MOV DI,[RELPT] ;Pointer offset
238 MOV AX,[RELSEG] ;pointer segment
239 ADD AX,BP ;Bias with actual load segment
240 MOV ES,AX
241 ADD ES:[DI],BP ;Relocate
242 DEC [RELCNT]
243 JNZ RELOC
244
245NOREL:
246 ADD [INITSS],BP
247 ADD [INITCS],BP
248 JMP SHORT PROGGO
249
250BINFIL:
251 MOV WORD PTR DS:[FCB+RECLEN],1
252 MOV SI,-1
253 MOV DI,SI
254 CALL READ
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
258 DEC AH
259 MOV WORD PTR ES:[6],AX ;Fix size
260
261PROGGO:
262 PUSH DS
263 MOV AX,[PROG_AREA]
264 MOV DS,AX
265 MOV DX,80H
266 MOV AH,SETDMA
267 INT 21H ;Set default disk transfer address
268 POP DS
269 MOV BX,[BUCKET_NUM]
270 SHL BX,1 ;Mult by 2 to get #bytes in bucket area
271CLEAR:
272 MOV BUCKET[BX],0 ;Zero counts
273 SUB BX,2
274 JGE CLEAR
275 MOV DX,[CLOCK_GRAIN]
276 PUSH DS
277 POP ES
278 CLI ;Don't collect data yet
279 CALL CLOCKON ;Set the interrupt
280 MOV SI,[PROG_RA]
281 MOV DI,[PROG_AREA]
282 MOV BX,[PROG_SS]
283 MOV CX,[PROG_SP]
284 MOV AX,[DRV_VALID]
285 MOV DX,[PROG_SA]
286 MOV SS,BX
287 MOV SP,CX
288 XOR CX,CX
289 PUSH CX ;0 on prog stack
290 PUSH DX
291 PUSH SI
292 MOV DS,DI ;Set up segments
293 MOV ES,DI
294 STI ;Start collecting data
295XXX PROC FAR
296 RET ;Hop to program
297XXX ENDP
298
299READ:
300; AX:DX is disk transfer address (segment:offset)
301; SI:DI is 32 bit length
302
303RDLOOP:
304 MOV BX,DX
305 AND DX,000FH
306 MOV CL,4
307 SHR BX,CL
308 ADD AX,BX
309 PUSH AX
310 PUSH DX
311 PUSH DS
312 MOV DS,AX
313 MOV AH,SETDMA
314 INT 21H
315 POP DS
316 MOV DX,FCB
317 MOV CX,0FFF0H ;Keep request in segment
318 OR SI,SI ;Need > 64K?
319 JNZ BIGRD
320 MOV CX,DI ;Limit to amount requested
321BIGRD:
322 MOV AH,BLKRD
323 INT 21H
324 SUB DI,CX ;Subtract off amount done
325 SBB SI,0 ;Ripple carry
326 CMP AL,1 ;EOF?
327 POP DX
328 POP AX ;Restore transfer address
329 JZ RET10
330 ADD DX,CX ;Bump transfer address by last read
331 MOV BX,SI
332 OR BX,DI ;Finished with request
333 JNZ RDLOOP
334RET10: STC
335 RET
336
337
338;Return here on termination or abort
339
340TERMINATE:
341 CLI ;Stop collecting data
342 MOV DX,OFFSET DG:ENDMES
343 JMP SHORT WRITEOUT
344ABORT:
345 CLI ;Stop collecting data
346 MOV DX,OFFSET DG:ABORTMES
347WRITEOUT:
348 MOV AX,CS
349 MOV DS,AX
350 MOV SS,AX
351 MOV SP,OFFSET DG:STACK ;Use internal stack
352 PUSH DX
353 CALL CLOCKOFF ;Restore original clock routine
354 STI ;Back to normal clock
355 POP DX
356 MOV AH,PRINTBUF
357 INT 21H ;Apropriate termination message
358 MOV [OUT_FCB+14],2 ;Word size records
359 MOV DX,OFFSET DG:OUTPUT_DATA
360 MOV AH,SETDMA
361 INT 21H ;Set the transfer address
362 MOV CX,NUM_DATA_WORDS
363 ADD CX,[BUCKET_NUM]
364 MOV DX,OFFSET DG:OUT_FCB
365 MOV AH,BLKWRT
366 INT 21H ;Write out data
367 MOV DX,OFFSET DG:OUT_FCB
368 MOV AH,CLOSE
369 INT 21H
370 INT 20H ;Exit
371
372
373;The clock interrupt routine
374CLK_INTER PROC NEAR
375 CLI
376 PUSH DS
377 PUSH CS
378 POP DS ;Get profile segment
379 MOV [AXSAVE],AX
380 MOV [BXSAVE],BX
381 POP AX ;old DS
382 MOV BX,OFFSET DG:LEAVE_INT
383 PUSH BX
384 PUSH AX
385 PUSH ES
386 PUSH [AXSAVE]
387 PUSH [BXSAVE]
388 PUSH CX
389 PUSH DX
390
391
392;Stack looks like this
393;
394; +18 OLDFLAGS
395; +16 OLDCS
396; +14 OLDIP
397; +12 RETURN TO LEAVE_INT
398; +10 OLDDS
399; +8 OLDES
400; +6 OLDAX
401; +4 OLDBX
402; +2 OLDCX
403;SP-> OLDDX
404
405 MOV BX,SP
406 LES BX,DWORD PTR SS:[BX+14] ;Get CS:IP
407 MOV AX,BX
408 MOV CL,4
409 SHR AX,CL
410 MOV CX,ES
411 ADD AX,CX ;Paragraph of CS:IP
412 CMP AX,[DOS_PA] ;Below DOS?
413 JB IOHIT
414 CMP AX,[PROG_LOW_PA] ;Below program?
415 JB DOSHIT
416 CMP AX,[PROG_HIGH_PA] ;Above program?
417 JAE MISSH
418
419 SUB AX,[PROG_LOW_PA] ;Paragraph offset
420 XOR DX,DX
421
422 DIV [BUCKET_SIZE]
423 MOV BX,AX
424 SHL BX,1 ;Mult by 2 to get byte offset
425 INC BUCKET[BX]
426 JMP SHORT DONE
427
428IOHIT:
429 INC [HIT_IO]
430 JMP SHORT DONE
431
432DOSHIT:
433 INC [HIT_DOS]
434 JMP SHORT DONE
435
436MISSH:
437 INC [HIT_HIGH]
438
439DONE:
440 POP DX
441 POP CX
442 POP BX
443 POP AX
444 POP ES
445 POP DS
446 STI
447 RET ;To LEAVE_INT
448
449CLK_INTER ENDP
450
451CODE ENDS
452
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
456
457INIT SEGMENT BYTE
458 ORG 0
459
460SETUP:
461 MOV DX,FCB
462 MOV AH,OPEN
463 INT 21H ;Open program file
464 AND AL,AL
465 JZ OPENOK
466 MOV DX,OFFSET DG:NOFILE
467 JMP ERROR
468
469OPENOK:
470 XOR BX,BX
471 MOV WORD PTR DS:[FCB+RR],BX
472 MOV WORD PTR DS:[FCB+RR+2],BX ;RR to 0
473 MOV SI,FCB
474 MOV DI,OFFSET DG:OUT_FCB
475 MOV CX,4
476 REP MOVSW
477 MOVSB ;Transfer drive spec and file to output
478 MOV DX,OFFSET DG:OUT_FCB
479 MOV AH,CREATE
480 INT 21H ;Try to create the output file
481 AND AL,AL
482 JZ GETSIZE
483 MOV DX,OFFSET DG:OUTERR
484 JMP ERROR
485
486GETSIZE: ;Get bucket size
487 MOV DX,OFFSET DG:SIZE_PROMPT
488 MOV AH,PRINTBUF
489 INT 21H
490 CALL INBUF
491 CALL SCANB
492 JZ GETSIZE ;SCANB went to CR
493 XOR BX,BX
494 INC BX ;Size >=1
495 CALL GETNUM
496 JC GETSIZE ;Bad number
497 MOV [BUCKET_SIZE],DX
498
499 CMP WORD PTR DS:[FCB+9],5800H+"E" ;"EX"
500 JNZ NOTEXE
501 CMP BYTE PTR DS:[FCB+11],"E"
502 JNZ NOTEXE
503
504LOADEXEHEAD: ;Load the EXE header
505 MOV [EXEFILE],1
506 MOV DX,OFFSET DG:RUNVAR ;Read header in here
507 MOV AH,SETDMA
508 INT 21H
509 MOV CX,RUNVARSIZ
510 MOV DX,FCB
511 MOV WORD PTR DS:[FCB+RECLEN],1
512 OR AL,AL
513 MOV AH,BLKRD
514 INT 21H
515 CMP [RELPT],5A4DH ;Magic number
516 JZ EXEOK
517 JMP BADEXE
518EXEOK:
519 MOV AX,[PAGES] ;Size of file in 512 byte blocks
520 MOV CL,5
521 SHL AX,CL ;Size in paragraphs
522 JMP SHORT SETBUCKET
523
524NOTEXE:
525 MOV AX,WORD PTR DS:[FCB+FILELEN]
526 MOV DX,WORD PTR DS:[FCB+FILELEN+2] ;Size of file in bytes DX:AX
527 ADD AX,15
528 ADC DX,0 ;Round to PARA
529 MOV CL,4
530 SHR AX,CL
531 AND AX,0FFFH
532 MOV CL,12
533 SHL DX,CL
534 AND DX,0F000H
535 OR AX,DX ;Size in paragraphs to AX
536 MOV [PROG_RA],100H ;Default offset
537
538SETBUCKET:
539 PUSH AX ;Save size
540 XOR DX,DX
541 DIV [BUCKET_SIZE]
542 INC AX ;Round up
543 MOV [BUCKET_NUM],AX
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
548 MOV CL,4
549 SHR AX,CL ;Number of paragraphs in profil
550 INC AX ;Insurance
551 MOV BX,CS
552 ADD AX,BX
553 MOV [PROG_AREA],AX
554
555 CMP [EXEFILE],1
556 JZ SETBOUNDS
557 MOV AX,[PROG_AREA] ;Set up .COM segments
558 MOV [PROG_SS],AX
559 MOV [PROG_SA],AX
560
561SETBOUNDS: ;Set the sample window
562 MOV BX,10H ;Get start offset
563 ADD BX,[PROG_AREA] ;PARA # of start
564 MOV [PROG_LOW_PA],BX
565 POP AX ;Recall size of PROG in paragraphs
566 ADD BX,AX
567 MOV [PROG_HIGH_PA],BX
568
569SETDOS:
570 XOR DX,DX
571 MOV ES,DX ;look in interrupt area
572 MOV DX,WORD PTR ES:[82H] ;From int #20
573 MOV [DOS_PA],DX
574 PUSH DS
575 POP ES
576
577GETGRAIN: ;Get sample interval
578 MOV DX,OFFSET DG:GRAIN_PROMPT
579 MOV AH,PRINTBUF
580 INT 21H
581 CALL INBUF
582 CALL SCANB
583 JZ GETGRAIN ;SCANB went to CR
584 MOV BX,60 ;Grain >=60
585 CALL GETNUM
586 JC GETGRAIN ;Bad number
587 MOV [CLOCK_GRAIN],DX
588
589 MOV DX,OFFSET DG:PARAM_PROMPT
590 MOV AH,PRINTBUF
591 INT 21H
592 CALL INBUF ;Get program parameters
593
594 MOV AX,2522H ;Set vector 22H
595 MOV DX,OFFSET DG:TERMINATE
596 INT 21H
597 MOV AL,23H ;Set vector 23H
598 MOV DX,OFFSET DG:ABORT
599 INT 21H
600 RET ;Back to resident code
601
602GETNUM: ;Get a number, DS:SI points to buffer, carry set if bad
603 XOR DX,DX
604 MOV CL,0
605 LODSB
606NUMLP:
607 SUB AL,"0"
608 JB NUMCHK
609 CMP AL,9
610 JA NUMCHK
611 CMP DX,6553
612 JAE BADNUM
613 MOV CL,1
614 PUSH BX
615 MOV BX,DX
616 SHL DX,1
617 SHL DX,1
618 ADD DX,BX
619 SHL DX,1
620 CBW
621 POP BX
622 ADD DX,AX
623 LODSB
624 JMP NUMLP
625NUMCHK:
626 CMP CL,0
627 JZ BADNUM
628 CMP BX,DX
629 JA BADNUM
630 CLC
631 RET
632BADNUM:
633 STC
634 RET
635
636INBUF: ;Read in from console, SI points to start on exit
637 MOV AH,GETBUF
638 MOV DX,OFFSET DG:LINEBUF
639 INT 21H
640 MOV SI,2 + OFFSET DG:LINEBUF
641 MOV DI,OFFSET DG:BYTEBUF
642CASECHK:
643 LODSB
644 CMP AL,'a'
645 JB NOCONV
646 CMP AL,'z'
647 JA NOCONV
648 ADD AL,"A"-"a" ;Convert to upper case
649NOCONV:
650 STOSB
651 CMP AL,13
652 JZ INDONE
653 CMP AL,'"'
654 JNZ QUOTSCAN
655 CMP AL,"'"
656 JNZ CASECHK
657QUOTSCAN:
658 MOV AH,AL
659KILLSTR:
660 LODSB
661 STOSB
662 CMP AL,13
663 JZ INDONE
664 CMP AL,AH
665 JNZ KILLSTR
666 JMP SHORT CASECHK
667
668INDONE:
669 MOV SI,OFFSET DG:BYTEBUF
670
671;Output CR/LF
672
673CRLF:
674 MOV AL,13
675 CALL OUT
676 MOV AL,10
677
678OUT:
679 PUSH AX
680 PUSH DX
681 AND AL,7FH
682 XCHG AX,DX
683 MOV AH,OUTCH
684 INT 21H
685 POP DX
686 POP AX
687 RET
688
689SCANB: ;Scan to first non-blank
690 PUSH AX
691SCANNEXT:
692 LODSB
693 CMP AL," "
694 JZ SCANNEXT
695 CMP AL,9
696 JZ SCANNEXT
697 DEC SI
698 POP AX
699EOLCHK:
700 CMP BYTE PTR[SI],13
701 RET
702
703INIT ENDS
704 END START
705